PackageManagerService.java revision 788c8423d19972389b82a23dec297eb27d819c86
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_DEXOPT; 39import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE; 40import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION; 41import static android.content.pm.PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID; 42import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 43import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 44import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK; 45import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 46import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY; 47import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED; 48import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE; 49import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE; 50import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY; 51import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE; 52import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED; 53import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 54import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK; 55import static android.content.pm.PackageManager.INSTALL_INTERNAL; 56import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; 57import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 58import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK; 59import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 60import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER; 61import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 62import static android.content.pm.PackageManager.MATCH_ALL; 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_SYSTEM_ONLY; 69import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES; 70import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN; 71import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST; 72import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR; 73import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING; 74import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE; 75import static android.content.pm.PackageManager.PERMISSION_DENIED; 76import static android.content.pm.PackageManager.PERMISSION_GRANTED; 77import static android.content.pm.PackageParser.PARSE_IS_PRIVILEGED; 78import static android.content.pm.PackageParser.isApkFile; 79import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; 80import static android.system.OsConstants.O_CREAT; 81import static android.system.OsConstants.O_RDWR; 82 83import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE; 84import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT; 85import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME; 86import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME; 87import static com.android.internal.util.ArrayUtils.appendInt; 88import static com.android.server.pm.Installer.DEXOPT_PUBLIC; 89import static com.android.server.pm.InstructionSets.getAppDexInstructionSets; 90import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet; 91import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets; 92import static com.android.server.pm.InstructionSets.getPreferredInstructionSet; 93import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet; 94import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason; 95import static com.android.server.pm.PackageManagerServiceCompilerMapping.getFullCompilerFilter; 96import static com.android.server.pm.PackageManagerServiceCompilerMapping.getNonProfileGuidedCompilerFilter; 97import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE; 98import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS; 99import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED; 100 101import android.Manifest; 102import android.annotation.NonNull; 103import android.annotation.Nullable; 104import android.annotation.UserIdInt; 105import android.app.ActivityManager; 106import android.app.ActivityManagerNative; 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.Context; 115import android.content.IIntentReceiver; 116import android.content.Intent; 117import android.content.IntentFilter; 118import android.content.IntentSender; 119import android.content.IntentSender.SendIntentException; 120import android.content.ServiceConnection; 121import android.content.pm.ActivityInfo; 122import android.content.pm.ApplicationInfo; 123import android.content.pm.AppsQueryHelper; 124import android.content.pm.ComponentInfo; 125import android.content.pm.EphemeralApplicationInfo; 126import android.content.pm.EphemeralResolveInfo; 127import android.content.pm.EphemeralResolveInfo.EphemeralDigest; 128import android.content.pm.EphemeralResolveInfo.EphemeralResolveIntentInfo; 129import android.content.pm.FeatureInfo; 130import android.content.pm.IOnPermissionsChangeListener; 131import android.content.pm.IPackageDataObserver; 132import android.content.pm.IPackageDeleteObserver; 133import android.content.pm.IPackageDeleteObserver2; 134import android.content.pm.IPackageInstallObserver2; 135import android.content.pm.IPackageInstaller; 136import android.content.pm.IPackageManager; 137import android.content.pm.IPackageMoveObserver; 138import android.content.pm.IPackageStatsObserver; 139import android.content.pm.InstrumentationInfo; 140import android.content.pm.IntentFilterVerificationInfo; 141import android.content.pm.KeySet; 142import android.content.pm.PackageCleanItem; 143import android.content.pm.PackageInfo; 144import android.content.pm.PackageInfoLite; 145import android.content.pm.PackageInstaller; 146import android.content.pm.PackageManager; 147import android.content.pm.PackageManager.LegacyPackageDeleteObserver; 148import android.content.pm.PackageManagerInternal; 149import android.content.pm.PackageParser; 150import android.content.pm.PackageParser.ActivityIntentInfo; 151import android.content.pm.PackageParser.PackageLite; 152import android.content.pm.PackageParser.PackageParserException; 153import android.content.pm.PackageStats; 154import android.content.pm.PackageUserState; 155import android.content.pm.ParceledListSlice; 156import android.content.pm.PermissionGroupInfo; 157import android.content.pm.PermissionInfo; 158import android.content.pm.ProviderInfo; 159import android.content.pm.ResolveInfo; 160import android.content.pm.ServiceInfo; 161import android.content.pm.Signature; 162import android.content.pm.UserInfo; 163import android.content.pm.VerifierDeviceIdentity; 164import android.content.pm.VerifierInfo; 165import android.content.res.Resources; 166import android.graphics.Bitmap; 167import android.hardware.display.DisplayManager; 168import android.net.Uri; 169import android.os.Binder; 170import android.os.Build; 171import android.os.Bundle; 172import android.os.Debug; 173import android.os.Environment; 174import android.os.Environment.UserEnvironment; 175import android.os.FileUtils; 176import android.os.Handler; 177import android.os.IBinder; 178import android.os.Looper; 179import android.os.Message; 180import android.os.Parcel; 181import android.os.ParcelFileDescriptor; 182import android.os.PatternMatcher; 183import android.os.Process; 184import android.os.RemoteCallbackList; 185import android.os.RemoteException; 186import android.os.ResultReceiver; 187import android.os.SELinux; 188import android.os.ServiceManager; 189import android.os.SystemClock; 190import android.os.SystemProperties; 191import android.os.Trace; 192import android.os.UserHandle; 193import android.os.UserManager; 194import android.os.UserManagerInternal; 195import android.os.storage.IMountService; 196import android.os.storage.MountServiceInternal; 197import android.os.storage.StorageEventListener; 198import android.os.storage.StorageManager; 199import android.os.storage.VolumeInfo; 200import android.os.storage.VolumeRecord; 201import android.provider.Settings.Global; 202import android.security.KeyStore; 203import android.security.SystemKeyStore; 204import android.system.ErrnoException; 205import android.system.Os; 206import android.text.TextUtils; 207import android.text.format.DateUtils; 208import android.util.ArrayMap; 209import android.util.ArraySet; 210import android.util.DisplayMetrics; 211import android.util.EventLog; 212import android.util.ExceptionUtils; 213import android.util.Log; 214import android.util.LogPrinter; 215import android.util.MathUtils; 216import android.util.PrintStreamPrinter; 217import android.util.Slog; 218import android.util.SparseArray; 219import android.util.SparseBooleanArray; 220import android.util.SparseIntArray; 221import android.util.Xml; 222import android.util.jar.StrictJarFile; 223import android.view.Display; 224 225import com.android.internal.R; 226import com.android.internal.annotations.GuardedBy; 227import com.android.internal.app.IMediaContainerService; 228import com.android.internal.app.ResolverActivity; 229import com.android.internal.content.NativeLibraryHelper; 230import com.android.internal.content.PackageHelper; 231import com.android.internal.logging.MetricsLogger; 232import com.android.internal.os.IParcelFileDescriptorFactory; 233import com.android.internal.os.InstallerConnection.InstallerException; 234import com.android.internal.os.SomeArgs; 235import com.android.internal.os.Zygote; 236import com.android.internal.telephony.CarrierAppUtils; 237import com.android.internal.util.ArrayUtils; 238import com.android.internal.util.FastPrintWriter; 239import com.android.internal.util.FastXmlSerializer; 240import com.android.internal.util.IndentingPrintWriter; 241import com.android.internal.util.Preconditions; 242import com.android.internal.util.XmlUtils; 243import com.android.server.AttributeCache; 244import com.android.server.EventLogTags; 245import com.android.server.FgThread; 246import com.android.server.IntentResolver; 247import com.android.server.LocalServices; 248import com.android.server.ServiceThread; 249import com.android.server.SystemConfig; 250import com.android.server.Watchdog; 251import com.android.server.net.NetworkPolicyManagerInternal; 252import com.android.server.pm.PermissionsState.PermissionState; 253import com.android.server.pm.Settings.DatabaseVersion; 254import com.android.server.pm.Settings.VersionInfo; 255import com.android.server.storage.DeviceStorageMonitorInternal; 256 257import dalvik.system.CloseGuard; 258import dalvik.system.DexFile; 259import dalvik.system.VMRuntime; 260 261import libcore.io.IoUtils; 262import libcore.util.EmptyArray; 263 264import org.xmlpull.v1.XmlPullParser; 265import org.xmlpull.v1.XmlPullParserException; 266import org.xmlpull.v1.XmlSerializer; 267 268import java.io.BufferedOutputStream; 269import java.io.BufferedReader; 270import java.io.ByteArrayInputStream; 271import java.io.ByteArrayOutputStream; 272import java.io.File; 273import java.io.FileDescriptor; 274import java.io.FileInputStream; 275import java.io.FileNotFoundException; 276import java.io.FileOutputStream; 277import java.io.FileReader; 278import java.io.FilenameFilter; 279import java.io.IOException; 280import java.io.PrintWriter; 281import java.nio.charset.StandardCharsets; 282import java.security.DigestInputStream; 283import java.security.MessageDigest; 284import java.security.NoSuchAlgorithmException; 285import java.security.PublicKey; 286import java.security.cert.Certificate; 287import java.security.cert.CertificateEncodingException; 288import java.security.cert.CertificateException; 289import java.text.SimpleDateFormat; 290import java.util.ArrayList; 291import java.util.Arrays; 292import java.util.Collection; 293import java.util.Collections; 294import java.util.Comparator; 295import java.util.Date; 296import java.util.HashSet; 297import java.util.Iterator; 298import java.util.List; 299import java.util.Map; 300import java.util.Objects; 301import java.util.Set; 302import java.util.concurrent.CountDownLatch; 303import java.util.concurrent.TimeUnit; 304import java.util.concurrent.atomic.AtomicBoolean; 305import java.util.concurrent.atomic.AtomicInteger; 306 307/** 308 * Keep track of all those APKs everywhere. 309 * <p> 310 * Internally there are two important locks: 311 * <ul> 312 * <li>{@link #mPackages} is used to guard all in-memory parsed package details 313 * and other related state. It is a fine-grained lock that should only be held 314 * momentarily, as it's one of the most contended locks in the system. 315 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose 316 * operations typically involve heavy lifting of application data on disk. Since 317 * {@code installd} is single-threaded, and it's operations can often be slow, 318 * this lock should never be acquired while already holding {@link #mPackages}. 319 * Conversely, it's safe to acquire {@link #mPackages} momentarily while already 320 * holding {@link #mInstallLock}. 321 * </ul> 322 * Many internal methods rely on the caller to hold the appropriate locks, and 323 * this contract is expressed through method name suffixes: 324 * <ul> 325 * <li>fooLI(): the caller must hold {@link #mInstallLock} 326 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package 327 * being modified must be frozen 328 * <li>fooLPr(): the caller must hold {@link #mPackages} for reading 329 * <li>fooLPw(): the caller must hold {@link #mPackages} for writing 330 * </ul> 331 * <p> 332 * Because this class is very central to the platform's security; please run all 333 * CTS and unit tests whenever making modifications: 334 * 335 * <pre> 336 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core 337 * $ cts-tradefed run commandAndExit cts -m AppSecurityTests 338 * </pre> 339 */ 340public class PackageManagerService extends IPackageManager.Stub { 341 static final String TAG = "PackageManager"; 342 static final boolean DEBUG_SETTINGS = false; 343 static final boolean DEBUG_PREFERRED = false; 344 static final boolean DEBUG_UPGRADE = false; 345 static final boolean DEBUG_DOMAIN_VERIFICATION = false; 346 private static final boolean DEBUG_BACKUP = false; 347 private static final boolean DEBUG_INSTALL = false; 348 private static final boolean DEBUG_REMOVE = false; 349 private static final boolean DEBUG_BROADCASTS = false; 350 private static final boolean DEBUG_SHOW_INFO = false; 351 private static final boolean DEBUG_PACKAGE_INFO = false; 352 private static final boolean DEBUG_INTENT_MATCHING = false; 353 private static final boolean DEBUG_PACKAGE_SCANNING = false; 354 private static final boolean DEBUG_VERIFY = false; 355 private static final boolean DEBUG_FILTERS = false; 356 357 // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService 358 // and PackageDexOptimizer. All these classes have their own flag to allow switching a single 359 // user, but by default initialize to this. 360 static final boolean DEBUG_DEXOPT = false; 361 362 private static final boolean DEBUG_ABI_SELECTION = false; 363 private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE; 364 private static final boolean DEBUG_TRIAGED_MISSING = false; 365 private static final boolean DEBUG_APP_DATA = false; 366 367 /** REMOVE. According to Svet, this was only used to reset permissions during development. */ 368 static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false; 369 370 private static final boolean DISABLE_EPHEMERAL_APPS = !Build.IS_DEBUGGABLE; 371 372 private static final int RADIO_UID = Process.PHONE_UID; 373 private static final int LOG_UID = Process.LOG_UID; 374 private static final int NFC_UID = Process.NFC_UID; 375 private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID; 376 private static final int SHELL_UID = Process.SHELL_UID; 377 378 // Cap the size of permission trees that 3rd party apps can define 379 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768; // characters of text 380 381 // Suffix used during package installation when copying/moving 382 // package apks to install directory. 383 private static final String INSTALL_PACKAGE_SUFFIX = "-"; 384 385 static final int SCAN_NO_DEX = 1<<1; 386 static final int SCAN_FORCE_DEX = 1<<2; 387 static final int SCAN_UPDATE_SIGNATURE = 1<<3; 388 static final int SCAN_NEW_INSTALL = 1<<4; 389 static final int SCAN_NO_PATHS = 1<<5; 390 static final int SCAN_UPDATE_TIME = 1<<6; 391 static final int SCAN_DEFER_DEX = 1<<7; 392 static final int SCAN_BOOTING = 1<<8; 393 static final int SCAN_TRUSTED_OVERLAY = 1<<9; 394 static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10; 395 static final int SCAN_REPLACING = 1<<11; 396 static final int SCAN_REQUIRE_KNOWN = 1<<12; 397 static final int SCAN_MOVE = 1<<13; 398 static final int SCAN_INITIAL = 1<<14; 399 static final int SCAN_CHECK_ONLY = 1<<15; 400 static final int SCAN_DONT_KILL_APP = 1<<17; 401 static final int SCAN_IGNORE_FROZEN = 1<<18; 402 403 static final int REMOVE_CHATTY = 1<<16; 404 405 private static final int[] EMPTY_INT_ARRAY = new int[0]; 406 407 /** 408 * Timeout (in milliseconds) after which the watchdog should declare that 409 * our handler thread is wedged. The usual default for such things is one 410 * minute but we sometimes do very lengthy I/O operations on this thread, 411 * such as installing multi-gigabyte applications, so ours needs to be longer. 412 */ 413 private static final long WATCHDOG_TIMEOUT = 1000*60*10; // ten minutes 414 415 /** 416 * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim 417 * be run on this device. We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL 418 * settings entry if available, otherwise we use the hardcoded default. If it's been 419 * more than this long since the last fstrim, we force one during the boot sequence. 420 * 421 * This backstops other fstrim scheduling: if the device is alive at midnight+idle, 422 * one gets run at the next available charging+idle time. This final mandatory 423 * no-fstrim check kicks in only of the other scheduling criteria is never met. 424 */ 425 private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS; 426 427 /** 428 * Whether verification is enabled by default. 429 */ 430 private static final boolean DEFAULT_VERIFY_ENABLE = true; 431 432 /** 433 * The default maximum time to wait for the verification agent to return in 434 * milliseconds. 435 */ 436 private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000; 437 438 /** 439 * The default response for package verification timeout. 440 * 441 * This can be either PackageManager.VERIFICATION_ALLOW or 442 * PackageManager.VERIFICATION_REJECT. 443 */ 444 private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW; 445 446 static final String PLATFORM_PACKAGE_NAME = "android"; 447 448 static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer"; 449 450 static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName( 451 DEFAULT_CONTAINER_PACKAGE, 452 "com.android.defcontainer.DefaultContainerService"); 453 454 private static final String KILL_APP_REASON_GIDS_CHANGED = 455 "permission grant or revoke changed gids"; 456 457 private static final String KILL_APP_REASON_PERMISSIONS_REVOKED = 458 "permissions revoked"; 459 460 private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive"; 461 462 private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay"; 463 464 private static int DEFAULT_EPHEMERAL_HASH_PREFIX_MASK = 0xFFFFF000; 465 private static int DEFAULT_EPHEMERAL_HASH_PREFIX_COUNT = 5; 466 467 /** Permission grant: not grant the permission. */ 468 private static final int GRANT_DENIED = 1; 469 470 /** Permission grant: grant the permission as an install permission. */ 471 private static final int GRANT_INSTALL = 2; 472 473 /** Permission grant: grant the permission as a runtime one. */ 474 private static final int GRANT_RUNTIME = 3; 475 476 /** Permission grant: grant as runtime a permission that was granted as an install time one. */ 477 private static final int GRANT_UPGRADE = 4; 478 479 /** Canonical intent used to identify what counts as a "web browser" app */ 480 private static final Intent sBrowserIntent; 481 static { 482 sBrowserIntent = new Intent(); 483 sBrowserIntent.setAction(Intent.ACTION_VIEW); 484 sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE); 485 sBrowserIntent.setData(Uri.parse("http:")); 486 } 487 488 /** 489 * The set of all protected actions [i.e. those actions for which a high priority 490 * intent filter is disallowed]. 491 */ 492 private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>(); 493 static { 494 PROTECTED_ACTIONS.add(Intent.ACTION_SEND); 495 PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO); 496 PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE); 497 PROTECTED_ACTIONS.add(Intent.ACTION_VIEW); 498 } 499 500 // Compilation reasons. 501 public static final int REASON_FIRST_BOOT = 0; 502 public static final int REASON_BOOT = 1; 503 public static final int REASON_INSTALL = 2; 504 public static final int REASON_BACKGROUND_DEXOPT = 3; 505 public static final int REASON_AB_OTA = 4; 506 public static final int REASON_NON_SYSTEM_LIBRARY = 5; 507 public static final int REASON_SHARED_APK = 6; 508 public static final int REASON_FORCED_DEXOPT = 7; 509 public static final int REASON_CORE_APP = 8; 510 511 public static final int REASON_LAST = REASON_CORE_APP; 512 513 /** Special library name that skips shared libraries check during compilation. */ 514 private static final String SKIP_SHARED_LIBRARY_CHECK = "&"; 515 516 final ServiceThread mHandlerThread; 517 518 final PackageHandler mHandler; 519 520 private final ProcessLoggingHandler mProcessLoggingHandler; 521 522 /** 523 * Messages for {@link #mHandler} that need to wait for system ready before 524 * being dispatched. 525 */ 526 private ArrayList<Message> mPostSystemReadyMessages; 527 528 final int mSdkVersion = Build.VERSION.SDK_INT; 529 530 final Context mContext; 531 final boolean mFactoryTest; 532 final boolean mOnlyCore; 533 final DisplayMetrics mMetrics; 534 final int mDefParseFlags; 535 final String[] mSeparateProcesses; 536 final boolean mIsUpgrade; 537 final boolean mIsPreNUpgrade; 538 539 /** The location for ASEC container files on internal storage. */ 540 final String mAsecInternalPath; 541 542 // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages 543 // LOCK HELD. Can be called with mInstallLock held. 544 @GuardedBy("mInstallLock") 545 final Installer mInstaller; 546 547 /** Directory where installed third-party apps stored */ 548 final File mAppInstallDir; 549 final File mEphemeralInstallDir; 550 551 /** 552 * Directory to which applications installed internally have their 553 * 32 bit native libraries copied. 554 */ 555 private File mAppLib32InstallDir; 556 557 // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked 558 // apps. 559 final File mDrmAppPrivateInstallDir; 560 561 // ---------------------------------------------------------------- 562 563 // Lock for state used when installing and doing other long running 564 // operations. Methods that must be called with this lock held have 565 // the suffix "LI". 566 final Object mInstallLock = new Object(); 567 568 // ---------------------------------------------------------------- 569 570 // Keys are String (package name), values are Package. This also serves 571 // as the lock for the global state. Methods that must be called with 572 // this lock held have the prefix "LP". 573 @GuardedBy("mPackages") 574 final ArrayMap<String, PackageParser.Package> mPackages = 575 new ArrayMap<String, PackageParser.Package>(); 576 577 final ArrayMap<String, Set<String>> mKnownCodebase = 578 new ArrayMap<String, Set<String>>(); 579 580 // Tracks available target package names -> overlay package paths. 581 final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays = 582 new ArrayMap<String, ArrayMap<String, PackageParser.Package>>(); 583 584 /** 585 * Tracks new system packages [received in an OTA] that we expect to 586 * find updated user-installed versions. Keys are package name, values 587 * are package location. 588 */ 589 final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>(); 590 /** 591 * Tracks high priority intent filters for protected actions. During boot, certain 592 * filter actions are protected and should never be allowed to have a high priority 593 * intent filter for them. However, there is one, and only one exception -- the 594 * setup wizard. It must be able to define a high priority intent filter for these 595 * actions to ensure there are no escapes from the wizard. We need to delay processing 596 * of these during boot as we need to look at all of the system packages in order 597 * to know which component is the setup wizard. 598 */ 599 private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>(); 600 /** 601 * Whether or not processing protected filters should be deferred. 602 */ 603 private boolean mDeferProtectedFilters = true; 604 605 /** 606 * Tracks existing system packages prior to receiving an OTA. Keys are package name. 607 */ 608 final private ArraySet<String> mExistingSystemPackages = new ArraySet<>(); 609 /** 610 * Whether or not system app permissions should be promoted from install to runtime. 611 */ 612 boolean mPromoteSystemApps; 613 614 @GuardedBy("mPackages") 615 final Settings mSettings; 616 617 /** 618 * Set of package names that are currently "frozen", which means active 619 * surgery is being done on the code/data for that package. The platform 620 * will refuse to launch frozen packages to avoid race conditions. 621 * 622 * @see PackageFreezer 623 */ 624 @GuardedBy("mPackages") 625 final ArraySet<String> mFrozenPackages = new ArraySet<>(); 626 627 final ProtectedPackages mProtectedPackages; 628 629 boolean mFirstBoot; 630 631 // System configuration read by SystemConfig. 632 final int[] mGlobalGids; 633 final SparseArray<ArraySet<String>> mSystemPermissions; 634 final ArrayMap<String, FeatureInfo> mAvailableFeatures; 635 636 // If mac_permissions.xml was found for seinfo labeling. 637 boolean mFoundPolicyFile; 638 639 private final EphemeralApplicationRegistry mEphemeralApplicationRegistry; 640 641 public static final class SharedLibraryEntry { 642 public final String path; 643 public final String apk; 644 645 SharedLibraryEntry(String _path, String _apk) { 646 path = _path; 647 apk = _apk; 648 } 649 } 650 651 // Currently known shared libraries. 652 final ArrayMap<String, SharedLibraryEntry> mSharedLibraries = 653 new ArrayMap<String, SharedLibraryEntry>(); 654 655 // All available activities, for your resolving pleasure. 656 final ActivityIntentResolver mActivities = 657 new ActivityIntentResolver(); 658 659 // All available receivers, for your resolving pleasure. 660 final ActivityIntentResolver mReceivers = 661 new ActivityIntentResolver(); 662 663 // All available services, for your resolving pleasure. 664 final ServiceIntentResolver mServices = new ServiceIntentResolver(); 665 666 // All available providers, for your resolving pleasure. 667 final ProviderIntentResolver mProviders = new ProviderIntentResolver(); 668 669 // Mapping from provider base names (first directory in content URI codePath) 670 // to the provider information. 671 final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority = 672 new ArrayMap<String, PackageParser.Provider>(); 673 674 // Mapping from instrumentation class names to info about them. 675 final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation = 676 new ArrayMap<ComponentName, PackageParser.Instrumentation>(); 677 678 // Mapping from permission names to info about them. 679 final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups = 680 new ArrayMap<String, PackageParser.PermissionGroup>(); 681 682 // Packages whose data we have transfered into another package, thus 683 // should no longer exist. 684 final ArraySet<String> mTransferedPackages = new ArraySet<String>(); 685 686 // Broadcast actions that are only available to the system. 687 final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>(); 688 689 /** List of packages waiting for verification. */ 690 final SparseArray<PackageVerificationState> mPendingVerification 691 = new SparseArray<PackageVerificationState>(); 692 693 /** Set of packages associated with each app op permission. */ 694 final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>(); 695 696 final PackageInstallerService mInstallerService; 697 698 private final PackageDexOptimizer mPackageDexOptimizer; 699 700 private AtomicInteger mNextMoveId = new AtomicInteger(); 701 private final MoveCallbacks mMoveCallbacks; 702 703 private final OnPermissionChangeListeners mOnPermissionChangeListeners; 704 705 // Cache of users who need badging. 706 SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray(); 707 708 /** Token for keys in mPendingVerification. */ 709 private int mPendingVerificationToken = 0; 710 711 volatile boolean mSystemReady; 712 volatile boolean mSafeMode; 713 volatile boolean mHasSystemUidErrors; 714 715 ApplicationInfo mAndroidApplication; 716 final ActivityInfo mResolveActivity = new ActivityInfo(); 717 final ResolveInfo mResolveInfo = new ResolveInfo(); 718 ComponentName mResolveComponentName; 719 PackageParser.Package mPlatformPackage; 720 ComponentName mCustomResolverComponentName; 721 722 boolean mResolverReplaced = false; 723 724 private final @Nullable ComponentName mIntentFilterVerifierComponent; 725 private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier; 726 727 private int mIntentFilterVerificationToken = 0; 728 729 /** Component that knows whether or not an ephemeral application exists */ 730 final ComponentName mEphemeralResolverComponent; 731 /** The service connection to the ephemeral resolver */ 732 final EphemeralResolverConnection mEphemeralResolverConnection; 733 734 /** Component used to install ephemeral applications */ 735 final ComponentName mEphemeralInstallerComponent; 736 final ActivityInfo mEphemeralInstallerActivity = new ActivityInfo(); 737 final ResolveInfo mEphemeralInstallerInfo = new ResolveInfo(); 738 739 final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates 740 = new SparseArray<IntentFilterVerificationState>(); 741 742 final DefaultPermissionGrantPolicy mDefaultPermissionPolicy = 743 new DefaultPermissionGrantPolicy(this); 744 745 // List of packages names to keep cached, even if they are uninstalled for all users 746 private List<String> mKeepUninstalledPackages; 747 748 private UserManagerInternal mUserManagerInternal; 749 750 private static class IFVerificationParams { 751 PackageParser.Package pkg; 752 boolean replacing; 753 int userId; 754 int verifierUid; 755 756 public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing, 757 int _userId, int _verifierUid) { 758 pkg = _pkg; 759 replacing = _replacing; 760 userId = _userId; 761 replacing = _replacing; 762 verifierUid = _verifierUid; 763 } 764 } 765 766 private interface IntentFilterVerifier<T extends IntentFilter> { 767 boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId, 768 T filter, String packageName); 769 void startVerifications(int userId); 770 void receiveVerificationResponse(int verificationId); 771 } 772 773 private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> { 774 private Context mContext; 775 private ComponentName mIntentFilterVerifierComponent; 776 private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>(); 777 778 public IntentVerifierProxy(Context context, ComponentName verifierComponent) { 779 mContext = context; 780 mIntentFilterVerifierComponent = verifierComponent; 781 } 782 783 private String getDefaultScheme() { 784 return IntentFilter.SCHEME_HTTPS; 785 } 786 787 @Override 788 public void startVerifications(int userId) { 789 // Launch verifications requests 790 int count = mCurrentIntentFilterVerifications.size(); 791 for (int n=0; n<count; n++) { 792 int verificationId = mCurrentIntentFilterVerifications.get(n); 793 final IntentFilterVerificationState ivs = 794 mIntentFilterVerificationStates.get(verificationId); 795 796 String packageName = ivs.getPackageName(); 797 798 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 799 final int filterCount = filters.size(); 800 ArraySet<String> domainsSet = new ArraySet<>(); 801 for (int m=0; m<filterCount; m++) { 802 PackageParser.ActivityIntentInfo filter = filters.get(m); 803 domainsSet.addAll(filter.getHostsList()); 804 } 805 synchronized (mPackages) { 806 if (mSettings.createIntentFilterVerificationIfNeededLPw( 807 packageName, domainsSet) != null) { 808 scheduleWriteSettingsLocked(); 809 } 810 } 811 sendVerificationRequest(userId, verificationId, ivs); 812 } 813 mCurrentIntentFilterVerifications.clear(); 814 } 815 816 private void sendVerificationRequest(int userId, int verificationId, 817 IntentFilterVerificationState ivs) { 818 819 Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 820 verificationIntent.putExtra( 821 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID, 822 verificationId); 823 verificationIntent.putExtra( 824 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME, 825 getDefaultScheme()); 826 verificationIntent.putExtra( 827 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS, 828 ivs.getHostsString()); 829 verificationIntent.putExtra( 830 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME, 831 ivs.getPackageName()); 832 verificationIntent.setComponent(mIntentFilterVerifierComponent); 833 verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 834 835 UserHandle user = new UserHandle(userId); 836 mContext.sendBroadcastAsUser(verificationIntent, user); 837 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 838 "Sending IntentFilter verification broadcast"); 839 } 840 841 public void receiveVerificationResponse(int verificationId) { 842 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 843 844 final boolean verified = ivs.isVerified(); 845 846 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 847 final int count = filters.size(); 848 if (DEBUG_DOMAIN_VERIFICATION) { 849 Slog.i(TAG, "Received verification response " + verificationId 850 + " for " + count + " filters, verified=" + verified); 851 } 852 for (int n=0; n<count; n++) { 853 PackageParser.ActivityIntentInfo filter = filters.get(n); 854 filter.setVerified(verified); 855 856 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString() 857 + " verified with result:" + verified + " and hosts:" 858 + ivs.getHostsString()); 859 } 860 861 mIntentFilterVerificationStates.remove(verificationId); 862 863 final String packageName = ivs.getPackageName(); 864 IntentFilterVerificationInfo ivi = null; 865 866 synchronized (mPackages) { 867 ivi = mSettings.getIntentFilterVerificationLPr(packageName); 868 } 869 if (ivi == null) { 870 Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:" 871 + verificationId + " packageName:" + packageName); 872 return; 873 } 874 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 875 "Updating IntentFilterVerificationInfo for package " + packageName 876 +" verificationId:" + verificationId); 877 878 synchronized (mPackages) { 879 if (verified) { 880 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS); 881 } else { 882 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK); 883 } 884 scheduleWriteSettingsLocked(); 885 886 final int userId = ivs.getUserId(); 887 if (userId != UserHandle.USER_ALL) { 888 final int userStatus = 889 mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 890 891 int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 892 boolean needUpdate = false; 893 894 // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have 895 // already been set by the User thru the Disambiguation dialog 896 switch (userStatus) { 897 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 898 if (verified) { 899 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 900 } else { 901 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 902 } 903 needUpdate = true; 904 break; 905 906 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 907 if (verified) { 908 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 909 needUpdate = true; 910 } 911 break; 912 913 default: 914 // Nothing to do 915 } 916 917 if (needUpdate) { 918 mSettings.updateIntentFilterVerificationStatusLPw( 919 packageName, updatedStatus, userId); 920 scheduleWritePackageRestrictionsLocked(userId); 921 } 922 } 923 } 924 } 925 926 @Override 927 public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId, 928 ActivityIntentInfo filter, String packageName) { 929 if (!hasValidDomains(filter)) { 930 return false; 931 } 932 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 933 if (ivs == null) { 934 ivs = createDomainVerificationState(verifierUid, userId, verificationId, 935 packageName); 936 } 937 if (DEBUG_DOMAIN_VERIFICATION) { 938 Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter); 939 } 940 ivs.addFilter(filter); 941 return true; 942 } 943 944 private IntentFilterVerificationState createDomainVerificationState(int verifierUid, 945 int userId, int verificationId, String packageName) { 946 IntentFilterVerificationState ivs = new IntentFilterVerificationState( 947 verifierUid, userId, packageName); 948 ivs.setPendingState(); 949 synchronized (mPackages) { 950 mIntentFilterVerificationStates.append(verificationId, ivs); 951 mCurrentIntentFilterVerifications.add(verificationId); 952 } 953 return ivs; 954 } 955 } 956 957 private static boolean hasValidDomains(ActivityIntentInfo filter) { 958 return filter.hasCategory(Intent.CATEGORY_BROWSABLE) 959 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 960 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS)); 961 } 962 963 // Set of pending broadcasts for aggregating enable/disable of components. 964 static class PendingPackageBroadcasts { 965 // for each user id, a map of <package name -> components within that package> 966 final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap; 967 968 public PendingPackageBroadcasts() { 969 mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2); 970 } 971 972 public ArrayList<String> get(int userId, String packageName) { 973 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 974 return packages.get(packageName); 975 } 976 977 public void put(int userId, String packageName, ArrayList<String> components) { 978 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 979 packages.put(packageName, components); 980 } 981 982 public void remove(int userId, String packageName) { 983 ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId); 984 if (packages != null) { 985 packages.remove(packageName); 986 } 987 } 988 989 public void remove(int userId) { 990 mUidMap.remove(userId); 991 } 992 993 public int userIdCount() { 994 return mUidMap.size(); 995 } 996 997 public int userIdAt(int n) { 998 return mUidMap.keyAt(n); 999 } 1000 1001 public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) { 1002 return mUidMap.get(userId); 1003 } 1004 1005 public int size() { 1006 // total number of pending broadcast entries across all userIds 1007 int num = 0; 1008 for (int i = 0; i< mUidMap.size(); i++) { 1009 num += mUidMap.valueAt(i).size(); 1010 } 1011 return num; 1012 } 1013 1014 public void clear() { 1015 mUidMap.clear(); 1016 } 1017 1018 private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) { 1019 ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId); 1020 if (map == null) { 1021 map = new ArrayMap<String, ArrayList<String>>(); 1022 mUidMap.put(userId, map); 1023 } 1024 return map; 1025 } 1026 } 1027 final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts(); 1028 1029 // Service Connection to remote media container service to copy 1030 // package uri's from external media onto secure containers 1031 // or internal storage. 1032 private IMediaContainerService mContainerService = null; 1033 1034 static final int SEND_PENDING_BROADCAST = 1; 1035 static final int MCS_BOUND = 3; 1036 static final int END_COPY = 4; 1037 static final int INIT_COPY = 5; 1038 static final int MCS_UNBIND = 6; 1039 static final int START_CLEANING_PACKAGE = 7; 1040 static final int FIND_INSTALL_LOC = 8; 1041 static final int POST_INSTALL = 9; 1042 static final int MCS_RECONNECT = 10; 1043 static final int MCS_GIVE_UP = 11; 1044 static final int UPDATED_MEDIA_STATUS = 12; 1045 static final int WRITE_SETTINGS = 13; 1046 static final int WRITE_PACKAGE_RESTRICTIONS = 14; 1047 static final int PACKAGE_VERIFIED = 15; 1048 static final int CHECK_PENDING_VERIFICATION = 16; 1049 static final int START_INTENT_FILTER_VERIFICATIONS = 17; 1050 static final int INTENT_FILTER_VERIFIED = 18; 1051 static final int WRITE_PACKAGE_LIST = 19; 1052 1053 static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds 1054 1055 // Delay time in millisecs 1056 static final int BROADCAST_DELAY = 10 * 1000; 1057 1058 static UserManagerService sUserManager; 1059 1060 // Stores a list of users whose package restrictions file needs to be updated 1061 private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>(); 1062 1063 final private DefaultContainerConnection mDefContainerConn = 1064 new DefaultContainerConnection(); 1065 class DefaultContainerConnection implements ServiceConnection { 1066 public void onServiceConnected(ComponentName name, IBinder service) { 1067 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected"); 1068 IMediaContainerService imcs = 1069 IMediaContainerService.Stub.asInterface(service); 1070 mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs)); 1071 } 1072 1073 public void onServiceDisconnected(ComponentName name) { 1074 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected"); 1075 } 1076 } 1077 1078 // Recordkeeping of restore-after-install operations that are currently in flight 1079 // between the Package Manager and the Backup Manager 1080 static class PostInstallData { 1081 public InstallArgs args; 1082 public PackageInstalledInfo res; 1083 1084 PostInstallData(InstallArgs _a, PackageInstalledInfo _r) { 1085 args = _a; 1086 res = _r; 1087 } 1088 } 1089 1090 final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>(); 1091 int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows 1092 1093 // XML tags for backup/restore of various bits of state 1094 private static final String TAG_PREFERRED_BACKUP = "pa"; 1095 private static final String TAG_DEFAULT_APPS = "da"; 1096 private static final String TAG_INTENT_FILTER_VERIFICATION = "iv"; 1097 1098 private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup"; 1099 private static final String TAG_ALL_GRANTS = "rt-grants"; 1100 private static final String TAG_GRANT = "grant"; 1101 private static final String ATTR_PACKAGE_NAME = "pkg"; 1102 1103 private static final String TAG_PERMISSION = "perm"; 1104 private static final String ATTR_PERMISSION_NAME = "name"; 1105 private static final String ATTR_IS_GRANTED = "g"; 1106 private static final String ATTR_USER_SET = "set"; 1107 private static final String ATTR_USER_FIXED = "fixed"; 1108 private static final String ATTR_REVOKE_ON_UPGRADE = "rou"; 1109 1110 // System/policy permission grants are not backed up 1111 private static final int SYSTEM_RUNTIME_GRANT_MASK = 1112 FLAG_PERMISSION_POLICY_FIXED 1113 | FLAG_PERMISSION_SYSTEM_FIXED 1114 | FLAG_PERMISSION_GRANTED_BY_DEFAULT; 1115 1116 // And we back up these user-adjusted states 1117 private static final int USER_RUNTIME_GRANT_MASK = 1118 FLAG_PERMISSION_USER_SET 1119 | FLAG_PERMISSION_USER_FIXED 1120 | FLAG_PERMISSION_REVOKE_ON_UPGRADE; 1121 1122 final @Nullable String mRequiredVerifierPackage; 1123 final @NonNull String mRequiredInstallerPackage; 1124 final @Nullable String mSetupWizardPackage; 1125 final @NonNull String mServicesSystemSharedLibraryPackageName; 1126 final @NonNull String mSharedSystemSharedLibraryPackageName; 1127 1128 final boolean mPermissionReviewRequired; 1129 1130 private final PackageUsage mPackageUsage = new PackageUsage(); 1131 private final CompilerStats mCompilerStats = new CompilerStats(); 1132 1133 class PackageHandler extends Handler { 1134 private boolean mBound = false; 1135 final ArrayList<HandlerParams> mPendingInstalls = 1136 new ArrayList<HandlerParams>(); 1137 1138 private boolean connectToService() { 1139 if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" + 1140 " DefaultContainerService"); 1141 Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 1142 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1143 if (mContext.bindServiceAsUser(service, mDefContainerConn, 1144 Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) { 1145 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1146 mBound = true; 1147 return true; 1148 } 1149 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1150 return false; 1151 } 1152 1153 private void disconnectService() { 1154 mContainerService = null; 1155 mBound = false; 1156 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1157 mContext.unbindService(mDefContainerConn); 1158 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1159 } 1160 1161 PackageHandler(Looper looper) { 1162 super(looper); 1163 } 1164 1165 public void handleMessage(Message msg) { 1166 try { 1167 doHandleMessage(msg); 1168 } finally { 1169 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1170 } 1171 } 1172 1173 void doHandleMessage(Message msg) { 1174 switch (msg.what) { 1175 case INIT_COPY: { 1176 HandlerParams params = (HandlerParams) msg.obj; 1177 int idx = mPendingInstalls.size(); 1178 if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params); 1179 // If a bind was already initiated we dont really 1180 // need to do anything. The pending install 1181 // will be processed later on. 1182 if (!mBound) { 1183 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1184 System.identityHashCode(mHandler)); 1185 // If this is the only one pending we might 1186 // have to bind to the service again. 1187 if (!connectToService()) { 1188 Slog.e(TAG, "Failed to bind to media container service"); 1189 params.serviceError(); 1190 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1191 System.identityHashCode(mHandler)); 1192 if (params.traceMethod != null) { 1193 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod, 1194 params.traceCookie); 1195 } 1196 return; 1197 } else { 1198 // Once we bind to the service, the first 1199 // pending request will be processed. 1200 mPendingInstalls.add(idx, params); 1201 } 1202 } else { 1203 mPendingInstalls.add(idx, params); 1204 // Already bound to the service. Just make 1205 // sure we trigger off processing the first request. 1206 if (idx == 0) { 1207 mHandler.sendEmptyMessage(MCS_BOUND); 1208 } 1209 } 1210 break; 1211 } 1212 case MCS_BOUND: { 1213 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound"); 1214 if (msg.obj != null) { 1215 mContainerService = (IMediaContainerService) msg.obj; 1216 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1217 System.identityHashCode(mHandler)); 1218 } 1219 if (mContainerService == null) { 1220 if (!mBound) { 1221 // Something seriously wrong since we are not bound and we are not 1222 // waiting for connection. Bail out. 1223 Slog.e(TAG, "Cannot bind to media container service"); 1224 for (HandlerParams params : mPendingInstalls) { 1225 // Indicate service bind error 1226 params.serviceError(); 1227 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1228 System.identityHashCode(params)); 1229 if (params.traceMethod != null) { 1230 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, 1231 params.traceMethod, params.traceCookie); 1232 } 1233 return; 1234 } 1235 mPendingInstalls.clear(); 1236 } else { 1237 Slog.w(TAG, "Waiting to connect to media container service"); 1238 } 1239 } else if (mPendingInstalls.size() > 0) { 1240 HandlerParams params = mPendingInstalls.get(0); 1241 if (params != null) { 1242 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1243 System.identityHashCode(params)); 1244 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy"); 1245 if (params.startCopy()) { 1246 // We are done... look for more work or to 1247 // go idle. 1248 if (DEBUG_SD_INSTALL) Log.i(TAG, 1249 "Checking for more work or unbind..."); 1250 // Delete pending install 1251 if (mPendingInstalls.size() > 0) { 1252 mPendingInstalls.remove(0); 1253 } 1254 if (mPendingInstalls.size() == 0) { 1255 if (mBound) { 1256 if (DEBUG_SD_INSTALL) Log.i(TAG, 1257 "Posting delayed MCS_UNBIND"); 1258 removeMessages(MCS_UNBIND); 1259 Message ubmsg = obtainMessage(MCS_UNBIND); 1260 // Unbind after a little delay, to avoid 1261 // continual thrashing. 1262 sendMessageDelayed(ubmsg, 10000); 1263 } 1264 } else { 1265 // There are more pending requests in queue. 1266 // Just post MCS_BOUND message to trigger processing 1267 // of next pending install. 1268 if (DEBUG_SD_INSTALL) Log.i(TAG, 1269 "Posting MCS_BOUND for next work"); 1270 mHandler.sendEmptyMessage(MCS_BOUND); 1271 } 1272 } 1273 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 1274 } 1275 } else { 1276 // Should never happen ideally. 1277 Slog.w(TAG, "Empty queue"); 1278 } 1279 break; 1280 } 1281 case MCS_RECONNECT: { 1282 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect"); 1283 if (mPendingInstalls.size() > 0) { 1284 if (mBound) { 1285 disconnectService(); 1286 } 1287 if (!connectToService()) { 1288 Slog.e(TAG, "Failed to bind to media container service"); 1289 for (HandlerParams params : mPendingInstalls) { 1290 // Indicate service bind error 1291 params.serviceError(); 1292 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1293 System.identityHashCode(params)); 1294 } 1295 mPendingInstalls.clear(); 1296 } 1297 } 1298 break; 1299 } 1300 case MCS_UNBIND: { 1301 // If there is no actual work left, then time to unbind. 1302 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind"); 1303 1304 if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) { 1305 if (mBound) { 1306 if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()"); 1307 1308 disconnectService(); 1309 } 1310 } else if (mPendingInstalls.size() > 0) { 1311 // There are more pending requests in queue. 1312 // Just post MCS_BOUND message to trigger processing 1313 // of next pending install. 1314 mHandler.sendEmptyMessage(MCS_BOUND); 1315 } 1316 1317 break; 1318 } 1319 case MCS_GIVE_UP: { 1320 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries"); 1321 HandlerParams params = mPendingInstalls.remove(0); 1322 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1323 System.identityHashCode(params)); 1324 break; 1325 } 1326 case SEND_PENDING_BROADCAST: { 1327 String packages[]; 1328 ArrayList<String> components[]; 1329 int size = 0; 1330 int uids[]; 1331 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1332 synchronized (mPackages) { 1333 if (mPendingBroadcasts == null) { 1334 return; 1335 } 1336 size = mPendingBroadcasts.size(); 1337 if (size <= 0) { 1338 // Nothing to be done. Just return 1339 return; 1340 } 1341 packages = new String[size]; 1342 components = new ArrayList[size]; 1343 uids = new int[size]; 1344 int i = 0; // filling out the above arrays 1345 1346 for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) { 1347 int packageUserId = mPendingBroadcasts.userIdAt(n); 1348 Iterator<Map.Entry<String, ArrayList<String>>> it 1349 = mPendingBroadcasts.packagesForUserId(packageUserId) 1350 .entrySet().iterator(); 1351 while (it.hasNext() && i < size) { 1352 Map.Entry<String, ArrayList<String>> ent = it.next(); 1353 packages[i] = ent.getKey(); 1354 components[i] = ent.getValue(); 1355 PackageSetting ps = mSettings.mPackages.get(ent.getKey()); 1356 uids[i] = (ps != null) 1357 ? UserHandle.getUid(packageUserId, ps.appId) 1358 : -1; 1359 i++; 1360 } 1361 } 1362 size = i; 1363 mPendingBroadcasts.clear(); 1364 } 1365 // Send broadcasts 1366 for (int i = 0; i < size; i++) { 1367 sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]); 1368 } 1369 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1370 break; 1371 } 1372 case START_CLEANING_PACKAGE: { 1373 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1374 final String packageName = (String)msg.obj; 1375 final int userId = msg.arg1; 1376 final boolean andCode = msg.arg2 != 0; 1377 synchronized (mPackages) { 1378 if (userId == UserHandle.USER_ALL) { 1379 int[] users = sUserManager.getUserIds(); 1380 for (int user : users) { 1381 mSettings.addPackageToCleanLPw( 1382 new PackageCleanItem(user, packageName, andCode)); 1383 } 1384 } else { 1385 mSettings.addPackageToCleanLPw( 1386 new PackageCleanItem(userId, packageName, andCode)); 1387 } 1388 } 1389 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1390 startCleaningPackages(); 1391 } break; 1392 case POST_INSTALL: { 1393 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1); 1394 1395 PostInstallData data = mRunningInstalls.get(msg.arg1); 1396 final boolean didRestore = (msg.arg2 != 0); 1397 mRunningInstalls.delete(msg.arg1); 1398 1399 if (data != null) { 1400 InstallArgs args = data.args; 1401 PackageInstalledInfo parentRes = data.res; 1402 1403 final boolean grantPermissions = (args.installFlags 1404 & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0; 1405 final boolean killApp = (args.installFlags 1406 & PackageManager.INSTALL_DONT_KILL_APP) == 0; 1407 final String[] grantedPermissions = args.installGrantPermissions; 1408 1409 // Handle the parent package 1410 handlePackagePostInstall(parentRes, grantPermissions, killApp, 1411 grantedPermissions, didRestore, args.installerPackageName, 1412 args.observer); 1413 1414 // Handle the child packages 1415 final int childCount = (parentRes.addedChildPackages != null) 1416 ? parentRes.addedChildPackages.size() : 0; 1417 for (int i = 0; i < childCount; i++) { 1418 PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i); 1419 handlePackagePostInstall(childRes, grantPermissions, killApp, 1420 grantedPermissions, false, args.installerPackageName, 1421 args.observer); 1422 } 1423 1424 // Log tracing if needed 1425 if (args.traceMethod != null) { 1426 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod, 1427 args.traceCookie); 1428 } 1429 } else { 1430 Slog.e(TAG, "Bogus post-install token " + msg.arg1); 1431 } 1432 1433 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1); 1434 } break; 1435 case UPDATED_MEDIA_STATUS: { 1436 if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS"); 1437 boolean reportStatus = msg.arg1 == 1; 1438 boolean doGc = msg.arg2 == 1; 1439 if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc); 1440 if (doGc) { 1441 // Force a gc to clear up stale containers. 1442 Runtime.getRuntime().gc(); 1443 } 1444 if (msg.obj != null) { 1445 @SuppressWarnings("unchecked") 1446 Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj; 1447 if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers"); 1448 // Unload containers 1449 unloadAllContainers(args); 1450 } 1451 if (reportStatus) { 1452 try { 1453 if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back"); 1454 PackageHelper.getMountService().finishMediaUpdate(); 1455 } catch (RemoteException e) { 1456 Log.e(TAG, "MountService not running?"); 1457 } 1458 } 1459 } break; 1460 case WRITE_SETTINGS: { 1461 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1462 synchronized (mPackages) { 1463 removeMessages(WRITE_SETTINGS); 1464 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1465 mSettings.writeLPr(); 1466 mDirtyUsers.clear(); 1467 } 1468 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1469 } break; 1470 case WRITE_PACKAGE_RESTRICTIONS: { 1471 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1472 synchronized (mPackages) { 1473 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1474 for (int userId : mDirtyUsers) { 1475 mSettings.writePackageRestrictionsLPr(userId); 1476 } 1477 mDirtyUsers.clear(); 1478 } 1479 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1480 } break; 1481 case WRITE_PACKAGE_LIST: { 1482 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1483 synchronized (mPackages) { 1484 removeMessages(WRITE_PACKAGE_LIST); 1485 mSettings.writePackageListLPr(msg.arg1); 1486 } 1487 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1488 } break; 1489 case CHECK_PENDING_VERIFICATION: { 1490 final int verificationId = msg.arg1; 1491 final PackageVerificationState state = mPendingVerification.get(verificationId); 1492 1493 if ((state != null) && !state.timeoutExtended()) { 1494 final InstallArgs args = state.getInstallArgs(); 1495 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1496 1497 Slog.i(TAG, "Verification timed out for " + originUri); 1498 mPendingVerification.remove(verificationId); 1499 1500 int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1501 1502 if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) { 1503 Slog.i(TAG, "Continuing with installation of " + originUri); 1504 state.setVerifierResponse(Binder.getCallingUid(), 1505 PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT); 1506 broadcastPackageVerified(verificationId, originUri, 1507 PackageManager.VERIFICATION_ALLOW, 1508 state.getInstallArgs().getUser()); 1509 try { 1510 ret = args.copyApk(mContainerService, true); 1511 } catch (RemoteException e) { 1512 Slog.e(TAG, "Could not contact the ContainerService"); 1513 } 1514 } else { 1515 broadcastPackageVerified(verificationId, originUri, 1516 PackageManager.VERIFICATION_REJECT, 1517 state.getInstallArgs().getUser()); 1518 } 1519 1520 Trace.asyncTraceEnd( 1521 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 1522 1523 processPendingInstall(args, ret); 1524 mHandler.sendEmptyMessage(MCS_UNBIND); 1525 } 1526 break; 1527 } 1528 case PACKAGE_VERIFIED: { 1529 final int verificationId = msg.arg1; 1530 1531 final PackageVerificationState state = mPendingVerification.get(verificationId); 1532 if (state == null) { 1533 Slog.w(TAG, "Invalid verification token " + verificationId + " received"); 1534 break; 1535 } 1536 1537 final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj; 1538 1539 state.setVerifierResponse(response.callerUid, response.code); 1540 1541 if (state.isVerificationComplete()) { 1542 mPendingVerification.remove(verificationId); 1543 1544 final InstallArgs args = state.getInstallArgs(); 1545 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1546 1547 int ret; 1548 if (state.isInstallAllowed()) { 1549 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 1550 broadcastPackageVerified(verificationId, originUri, 1551 response.code, state.getInstallArgs().getUser()); 1552 try { 1553 ret = args.copyApk(mContainerService, true); 1554 } catch (RemoteException e) { 1555 Slog.e(TAG, "Could not contact the ContainerService"); 1556 } 1557 } else { 1558 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1559 } 1560 1561 Trace.asyncTraceEnd( 1562 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 1563 1564 processPendingInstall(args, ret); 1565 mHandler.sendEmptyMessage(MCS_UNBIND); 1566 } 1567 1568 break; 1569 } 1570 case START_INTENT_FILTER_VERIFICATIONS: { 1571 IFVerificationParams params = (IFVerificationParams) msg.obj; 1572 verifyIntentFiltersIfNeeded(params.userId, params.verifierUid, 1573 params.replacing, params.pkg); 1574 break; 1575 } 1576 case INTENT_FILTER_VERIFIED: { 1577 final int verificationId = msg.arg1; 1578 1579 final IntentFilterVerificationState state = mIntentFilterVerificationStates.get( 1580 verificationId); 1581 if (state == null) { 1582 Slog.w(TAG, "Invalid IntentFilter verification token " 1583 + verificationId + " received"); 1584 break; 1585 } 1586 1587 final int userId = state.getUserId(); 1588 1589 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1590 "Processing IntentFilter verification with token:" 1591 + verificationId + " and userId:" + userId); 1592 1593 final IntentFilterVerificationResponse response = 1594 (IntentFilterVerificationResponse) msg.obj; 1595 1596 state.setVerifierResponse(response.callerUid, response.code); 1597 1598 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1599 "IntentFilter verification with token:" + verificationId 1600 + " and userId:" + userId 1601 + " is settings verifier response with response code:" 1602 + response.code); 1603 1604 if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) { 1605 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: " 1606 + response.getFailedDomainsString()); 1607 } 1608 1609 if (state.isVerificationComplete()) { 1610 mIntentFilterVerifier.receiveVerificationResponse(verificationId); 1611 } else { 1612 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1613 "IntentFilter verification with token:" + verificationId 1614 + " was not said to be complete"); 1615 } 1616 1617 break; 1618 } 1619 } 1620 } 1621 } 1622 1623 private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions, 1624 boolean killApp, String[] grantedPermissions, 1625 boolean launchedForRestore, String installerPackage, 1626 IPackageInstallObserver2 installObserver) { 1627 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 1628 // Send the removed broadcasts 1629 if (res.removedInfo != null) { 1630 res.removedInfo.sendPackageRemovedBroadcasts(killApp); 1631 } 1632 1633 // Now that we successfully installed the package, grant runtime 1634 // permissions if requested before broadcasting the install. 1635 if (grantPermissions && res.pkg.applicationInfo.targetSdkVersion 1636 >= Build.VERSION_CODES.M) { 1637 grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions); 1638 } 1639 1640 final boolean update = res.removedInfo != null 1641 && res.removedInfo.removedPackage != null; 1642 1643 // If this is the first time we have child packages for a disabled privileged 1644 // app that had no children, we grant requested runtime permissions to the new 1645 // children if the parent on the system image had them already granted. 1646 if (res.pkg.parentPackage != null) { 1647 synchronized (mPackages) { 1648 grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg); 1649 } 1650 } 1651 1652 synchronized (mPackages) { 1653 mEphemeralApplicationRegistry.onPackageInstalledLPw(res.pkg); 1654 } 1655 1656 final String packageName = res.pkg.applicationInfo.packageName; 1657 Bundle extras = new Bundle(1); 1658 extras.putInt(Intent.EXTRA_UID, res.uid); 1659 1660 // Determine the set of users who are adding this package for 1661 // the first time vs. those who are seeing an update. 1662 int[] firstUsers = EMPTY_INT_ARRAY; 1663 int[] updateUsers = EMPTY_INT_ARRAY; 1664 if (res.origUsers == null || res.origUsers.length == 0) { 1665 firstUsers = res.newUsers; 1666 } else { 1667 for (int newUser : res.newUsers) { 1668 boolean isNew = true; 1669 for (int origUser : res.origUsers) { 1670 if (origUser == newUser) { 1671 isNew = false; 1672 break; 1673 } 1674 } 1675 if (isNew) { 1676 firstUsers = ArrayUtils.appendInt(firstUsers, newUser); 1677 } else { 1678 updateUsers = ArrayUtils.appendInt(updateUsers, newUser); 1679 } 1680 } 1681 } 1682 1683 // Send installed broadcasts if the install/update is not ephemeral 1684 if (!isEphemeral(res.pkg)) { 1685 mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath); 1686 1687 // Send added for users that see the package for the first time 1688 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, 1689 extras, 0 /*flags*/, null /*targetPackage*/, 1690 null /*finishedReceiver*/, firstUsers); 1691 1692 // Send added for users that don't see the package for the first time 1693 if (update) { 1694 extras.putBoolean(Intent.EXTRA_REPLACING, true); 1695 } 1696 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, 1697 extras, 0 /*flags*/, null /*targetPackage*/, 1698 null /*finishedReceiver*/, updateUsers); 1699 1700 // Send replaced for users that don't see the package for the first time 1701 if (update) { 1702 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, 1703 packageName, extras, 0 /*flags*/, 1704 null /*targetPackage*/, null /*finishedReceiver*/, 1705 updateUsers); 1706 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, 1707 null /*package*/, null /*extras*/, 0 /*flags*/, 1708 packageName /*targetPackage*/, 1709 null /*finishedReceiver*/, updateUsers); 1710 } else if (launchedForRestore && !isSystemApp(res.pkg)) { 1711 // First-install and we did a restore, so we're responsible for the 1712 // first-launch broadcast. 1713 if (DEBUG_BACKUP) { 1714 Slog.i(TAG, "Post-restore of " + packageName 1715 + " sending FIRST_LAUNCH in " + Arrays.toString(firstUsers)); 1716 } 1717 sendFirstLaunchBroadcast(packageName, installerPackage, firstUsers); 1718 } 1719 1720 // Send broadcast package appeared if forward locked/external for all users 1721 // treat asec-hosted packages like removable media on upgrade 1722 if (res.pkg.isForwardLocked() || isExternal(res.pkg)) { 1723 if (DEBUG_INSTALL) { 1724 Slog.i(TAG, "upgrading pkg " + res.pkg 1725 + " is ASEC-hosted -> AVAILABLE"); 1726 } 1727 final int[] uidArray = new int[]{res.pkg.applicationInfo.uid}; 1728 ArrayList<String> pkgList = new ArrayList<>(1); 1729 pkgList.add(packageName); 1730 sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null); 1731 } 1732 } 1733 1734 // Work that needs to happen on first install within each user 1735 if (firstUsers != null && firstUsers.length > 0) { 1736 synchronized (mPackages) { 1737 for (int userId : firstUsers) { 1738 // If this app is a browser and it's newly-installed for some 1739 // users, clear any default-browser state in those users. The 1740 // app's nature doesn't depend on the user, so we can just check 1741 // its browser nature in any user and generalize. 1742 if (packageIsBrowser(packageName, userId)) { 1743 mSettings.setDefaultBrowserPackageNameLPw(null, userId); 1744 } 1745 1746 // We may also need to apply pending (restored) runtime 1747 // permission grants within these users. 1748 mSettings.applyPendingPermissionGrantsLPw(packageName, userId); 1749 } 1750 } 1751 } 1752 1753 // Log current value of "unknown sources" setting 1754 EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED, 1755 getUnknownSourcesSettings()); 1756 1757 // Force a gc to clear up things 1758 Runtime.getRuntime().gc(); 1759 1760 // Remove the replaced package's older resources safely now 1761 // We delete after a gc for applications on sdcard. 1762 if (res.removedInfo != null && res.removedInfo.args != null) { 1763 synchronized (mInstallLock) { 1764 res.removedInfo.args.doPostDeleteLI(true); 1765 } 1766 } 1767 } 1768 1769 // If someone is watching installs - notify them 1770 if (installObserver != null) { 1771 try { 1772 Bundle extras = extrasForInstallResult(res); 1773 installObserver.onPackageInstalled(res.name, res.returnCode, 1774 res.returnMsg, extras); 1775 } catch (RemoteException e) { 1776 Slog.i(TAG, "Observer no longer exists."); 1777 } 1778 } 1779 } 1780 1781 private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw( 1782 PackageParser.Package pkg) { 1783 if (pkg.parentPackage == null) { 1784 return; 1785 } 1786 if (pkg.requestedPermissions == null) { 1787 return; 1788 } 1789 final PackageSetting disabledSysParentPs = mSettings 1790 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName); 1791 if (disabledSysParentPs == null || disabledSysParentPs.pkg == null 1792 || !disabledSysParentPs.isPrivileged() 1793 || (disabledSysParentPs.childPackageNames != null 1794 && !disabledSysParentPs.childPackageNames.isEmpty())) { 1795 return; 1796 } 1797 final int[] allUserIds = sUserManager.getUserIds(); 1798 final int permCount = pkg.requestedPermissions.size(); 1799 for (int i = 0; i < permCount; i++) { 1800 String permission = pkg.requestedPermissions.get(i); 1801 BasePermission bp = mSettings.mPermissions.get(permission); 1802 if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) { 1803 continue; 1804 } 1805 for (int userId : allUserIds) { 1806 if (disabledSysParentPs.getPermissionsState().hasRuntimePermission( 1807 permission, userId)) { 1808 grantRuntimePermission(pkg.packageName, permission, userId); 1809 } 1810 } 1811 } 1812 } 1813 1814 private StorageEventListener mStorageListener = new StorageEventListener() { 1815 @Override 1816 public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) { 1817 if (vol.type == VolumeInfo.TYPE_PRIVATE) { 1818 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1819 final String volumeUuid = vol.getFsUuid(); 1820 1821 // Clean up any users or apps that were removed or recreated 1822 // while this volume was missing 1823 reconcileUsers(volumeUuid); 1824 reconcileApps(volumeUuid); 1825 1826 // Clean up any install sessions that expired or were 1827 // cancelled while this volume was missing 1828 mInstallerService.onPrivateVolumeMounted(volumeUuid); 1829 1830 loadPrivatePackages(vol); 1831 1832 } else if (vol.state == VolumeInfo.STATE_EJECTING) { 1833 unloadPrivatePackages(vol); 1834 } 1835 } 1836 1837 if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) { 1838 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1839 updateExternalMediaStatus(true, false); 1840 } else if (vol.state == VolumeInfo.STATE_EJECTING) { 1841 updateExternalMediaStatus(false, false); 1842 } 1843 } 1844 } 1845 1846 @Override 1847 public void onVolumeForgotten(String fsUuid) { 1848 if (TextUtils.isEmpty(fsUuid)) { 1849 Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring"); 1850 return; 1851 } 1852 1853 // Remove any apps installed on the forgotten volume 1854 synchronized (mPackages) { 1855 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid); 1856 for (PackageSetting ps : packages) { 1857 Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten"); 1858 deletePackage(ps.name, new LegacyPackageDeleteObserver(null).getBinder(), 1859 UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS); 1860 } 1861 1862 mSettings.onVolumeForgotten(fsUuid); 1863 mSettings.writeLPr(); 1864 } 1865 } 1866 }; 1867 1868 private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds, 1869 String[] grantedPermissions) { 1870 for (int userId : userIds) { 1871 grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions); 1872 } 1873 1874 // We could have touched GID membership, so flush out packages.list 1875 synchronized (mPackages) { 1876 mSettings.writePackageListLPr(); 1877 } 1878 } 1879 1880 private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId, 1881 String[] grantedPermissions) { 1882 SettingBase sb = (SettingBase) pkg.mExtras; 1883 if (sb == null) { 1884 return; 1885 } 1886 1887 PermissionsState permissionsState = sb.getPermissionsState(); 1888 1889 final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 1890 | PackageManager.FLAG_PERMISSION_POLICY_FIXED; 1891 1892 for (String permission : pkg.requestedPermissions) { 1893 final BasePermission bp; 1894 synchronized (mPackages) { 1895 bp = mSettings.mPermissions.get(permission); 1896 } 1897 if (bp != null && (bp.isRuntime() || bp.isDevelopment()) 1898 && (grantedPermissions == null 1899 || ArrayUtils.contains(grantedPermissions, permission))) { 1900 final int flags = permissionsState.getPermissionFlags(permission, userId); 1901 // Installer cannot change immutable permissions. 1902 if ((flags & immutableFlags) == 0) { 1903 grantRuntimePermission(pkg.packageName, permission, userId); 1904 } 1905 } 1906 } 1907 } 1908 1909 Bundle extrasForInstallResult(PackageInstalledInfo res) { 1910 Bundle extras = null; 1911 switch (res.returnCode) { 1912 case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: { 1913 extras = new Bundle(); 1914 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION, 1915 res.origPermission); 1916 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE, 1917 res.origPackage); 1918 break; 1919 } 1920 case PackageManager.INSTALL_SUCCEEDED: { 1921 extras = new Bundle(); 1922 extras.putBoolean(Intent.EXTRA_REPLACING, 1923 res.removedInfo != null && res.removedInfo.removedPackage != null); 1924 break; 1925 } 1926 } 1927 return extras; 1928 } 1929 1930 void scheduleWriteSettingsLocked() { 1931 if (!mHandler.hasMessages(WRITE_SETTINGS)) { 1932 mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY); 1933 } 1934 } 1935 1936 void scheduleWritePackageListLocked(int userId) { 1937 if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) { 1938 Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST); 1939 msg.arg1 = userId; 1940 mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY); 1941 } 1942 } 1943 1944 void scheduleWritePackageRestrictionsLocked(UserHandle user) { 1945 final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier(); 1946 scheduleWritePackageRestrictionsLocked(userId); 1947 } 1948 1949 void scheduleWritePackageRestrictionsLocked(int userId) { 1950 final int[] userIds = (userId == UserHandle.USER_ALL) 1951 ? sUserManager.getUserIds() : new int[]{userId}; 1952 for (int nextUserId : userIds) { 1953 if (!sUserManager.exists(nextUserId)) return; 1954 mDirtyUsers.add(nextUserId); 1955 if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) { 1956 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY); 1957 } 1958 } 1959 } 1960 1961 public static PackageManagerService main(Context context, Installer installer, 1962 boolean factoryTest, boolean onlyCore) { 1963 // Self-check for initial settings. 1964 PackageManagerServiceCompilerMapping.checkProperties(); 1965 1966 PackageManagerService m = new PackageManagerService(context, installer, 1967 factoryTest, onlyCore); 1968 m.enableSystemUserPackages(); 1969 ServiceManager.addService("package", m); 1970 return m; 1971 } 1972 1973 private void enableSystemUserPackages() { 1974 if (!UserManager.isSplitSystemUser()) { 1975 return; 1976 } 1977 // For system user, enable apps based on the following conditions: 1978 // - app is whitelisted or belong to one of these groups: 1979 // -- system app which has no launcher icons 1980 // -- system app which has INTERACT_ACROSS_USERS permission 1981 // -- system IME app 1982 // - app is not in the blacklist 1983 AppsQueryHelper queryHelper = new AppsQueryHelper(this); 1984 Set<String> enableApps = new ArraySet<>(); 1985 enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS 1986 | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM 1987 | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM)); 1988 ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps(); 1989 enableApps.addAll(wlApps); 1990 enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER, 1991 /* systemAppsOnly */ false, UserHandle.SYSTEM)); 1992 ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps(); 1993 enableApps.removeAll(blApps); 1994 Log.i(TAG, "Applications installed for system user: " + enableApps); 1995 List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false, 1996 UserHandle.SYSTEM); 1997 final int allAppsSize = allAps.size(); 1998 synchronized (mPackages) { 1999 for (int i = 0; i < allAppsSize; i++) { 2000 String pName = allAps.get(i); 2001 PackageSetting pkgSetting = mSettings.mPackages.get(pName); 2002 // Should not happen, but we shouldn't be failing if it does 2003 if (pkgSetting == null) { 2004 continue; 2005 } 2006 boolean install = enableApps.contains(pName); 2007 if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) { 2008 Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName 2009 + " for system user"); 2010 pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM); 2011 } 2012 } 2013 } 2014 } 2015 2016 private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) { 2017 DisplayManager displayManager = (DisplayManager) context.getSystemService( 2018 Context.DISPLAY_SERVICE); 2019 displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics); 2020 } 2021 2022 /** 2023 * Requests that files preopted on a secondary system partition be copied to the data partition 2024 * if possible. Note that the actual copying of the files is accomplished by init for security 2025 * reasons. This simply requests that the copy takes place and awaits confirmation of its 2026 * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy. 2027 */ 2028 private static void requestCopyPreoptedFiles() { 2029 final int WAIT_TIME_MS = 100; 2030 final String CP_PREOPT_PROPERTY = "sys.cppreopt"; 2031 if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) { 2032 SystemProperties.set(CP_PREOPT_PROPERTY, "requested"); 2033 // We will wait for up to 100 seconds. 2034 final long timeEnd = SystemClock.uptimeMillis() + 100 * 1000; 2035 while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) { 2036 try { 2037 Thread.sleep(WAIT_TIME_MS); 2038 } catch (InterruptedException e) { 2039 // Do nothing 2040 } 2041 if (SystemClock.uptimeMillis() > timeEnd) { 2042 SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out"); 2043 Slog.wtf(TAG, "cppreopt did not finish!"); 2044 break; 2045 } 2046 } 2047 } 2048 } 2049 2050 public PackageManagerService(Context context, Installer installer, 2051 boolean factoryTest, boolean onlyCore) { 2052 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager"); 2053 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START, 2054 SystemClock.uptimeMillis()); 2055 2056 if (mSdkVersion <= 0) { 2057 Slog.w(TAG, "**** ro.build.version.sdk not set!"); 2058 } 2059 2060 mContext = context; 2061 2062 mPermissionReviewRequired = context.getResources().getBoolean( 2063 R.bool.config_permissionReviewRequired); 2064 2065 mFactoryTest = factoryTest; 2066 mOnlyCore = onlyCore; 2067 mMetrics = new DisplayMetrics(); 2068 mSettings = new Settings(mPackages); 2069 mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID, 2070 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2071 mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, 2072 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2073 mSettings.addSharedUserLPw("android.uid.log", LOG_UID, 2074 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2075 mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, 2076 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2077 mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID, 2078 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2079 mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID, 2080 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2081 2082 String separateProcesses = SystemProperties.get("debug.separate_processes"); 2083 if (separateProcesses != null && separateProcesses.length() > 0) { 2084 if ("*".equals(separateProcesses)) { 2085 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES; 2086 mSeparateProcesses = null; 2087 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)"); 2088 } else { 2089 mDefParseFlags = 0; 2090 mSeparateProcesses = separateProcesses.split(","); 2091 Slog.w(TAG, "Running with debug.separate_processes: " 2092 + separateProcesses); 2093 } 2094 } else { 2095 mDefParseFlags = 0; 2096 mSeparateProcesses = null; 2097 } 2098 2099 mInstaller = installer; 2100 mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context, 2101 "*dexopt*"); 2102 mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper()); 2103 2104 mOnPermissionChangeListeners = new OnPermissionChangeListeners( 2105 FgThread.get().getLooper()); 2106 2107 getDefaultDisplayMetrics(context, mMetrics); 2108 2109 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config"); 2110 SystemConfig systemConfig = SystemConfig.getInstance(); 2111 mGlobalGids = systemConfig.getGlobalGids(); 2112 mSystemPermissions = systemConfig.getSystemPermissions(); 2113 mAvailableFeatures = systemConfig.getAvailableFeatures(); 2114 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2115 2116 mProtectedPackages = new ProtectedPackages(mContext); 2117 2118 synchronized (mInstallLock) { 2119 // writer 2120 synchronized (mPackages) { 2121 mHandlerThread = new ServiceThread(TAG, 2122 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/); 2123 mHandlerThread.start(); 2124 mHandler = new PackageHandler(mHandlerThread.getLooper()); 2125 mProcessLoggingHandler = new ProcessLoggingHandler(); 2126 Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT); 2127 2128 File dataDir = Environment.getDataDirectory(); 2129 mAppInstallDir = new File(dataDir, "app"); 2130 mAppLib32InstallDir = new File(dataDir, "app-lib"); 2131 mEphemeralInstallDir = new File(dataDir, "app-ephemeral"); 2132 mAsecInternalPath = new File(dataDir, "app-asec").getPath(); 2133 mDrmAppPrivateInstallDir = new File(dataDir, "app-private"); 2134 2135 sUserManager = new UserManagerService(context, this, mPackages); 2136 2137 // Propagate permission configuration in to package manager. 2138 ArrayMap<String, SystemConfig.PermissionEntry> permConfig 2139 = systemConfig.getPermissions(); 2140 for (int i=0; i<permConfig.size(); i++) { 2141 SystemConfig.PermissionEntry perm = permConfig.valueAt(i); 2142 BasePermission bp = mSettings.mPermissions.get(perm.name); 2143 if (bp == null) { 2144 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN); 2145 mSettings.mPermissions.put(perm.name, bp); 2146 } 2147 if (perm.gids != null) { 2148 bp.setGids(perm.gids, perm.perUser); 2149 } 2150 } 2151 2152 ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries(); 2153 for (int i=0; i<libConfig.size(); i++) { 2154 mSharedLibraries.put(libConfig.keyAt(i), 2155 new SharedLibraryEntry(libConfig.valueAt(i), null)); 2156 } 2157 2158 mFoundPolicyFile = SELinuxMMAC.readInstallPolicy(); 2159 2160 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings"); 2161 mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false)); 2162 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2163 2164 if (mFirstBoot) { 2165 requestCopyPreoptedFiles(); 2166 } 2167 2168 String customResolverActivity = Resources.getSystem().getString( 2169 R.string.config_customResolverActivity); 2170 if (TextUtils.isEmpty(customResolverActivity)) { 2171 customResolverActivity = null; 2172 } else { 2173 mCustomResolverComponentName = ComponentName.unflattenFromString( 2174 customResolverActivity); 2175 } 2176 2177 long startTime = SystemClock.uptimeMillis(); 2178 2179 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START, 2180 startTime); 2181 2182 // Set flag to monitor and not change apk file paths when 2183 // scanning install directories. 2184 final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING | SCAN_INITIAL; 2185 2186 final String bootClassPath = System.getenv("BOOTCLASSPATH"); 2187 final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH"); 2188 2189 if (bootClassPath == null) { 2190 Slog.w(TAG, "No BOOTCLASSPATH found!"); 2191 } 2192 2193 if (systemServerClassPath == null) { 2194 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!"); 2195 } 2196 2197 final List<String> allInstructionSets = InstructionSets.getAllInstructionSets(); 2198 final String[] dexCodeInstructionSets = 2199 getDexCodeInstructionSets( 2200 allInstructionSets.toArray(new String[allInstructionSets.size()])); 2201 2202 /** 2203 * Ensure all external libraries have had dexopt run on them. 2204 */ 2205 if (mSharedLibraries.size() > 0) { 2206 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 2207 // NOTE: For now, we're compiling these system "shared libraries" 2208 // (and framework jars) into all available architectures. It's possible 2209 // to compile them only when we come across an app that uses them (there's 2210 // already logic for that in scanPackageLI) but that adds some complexity. 2211 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 2212 for (SharedLibraryEntry libEntry : mSharedLibraries.values()) { 2213 final String lib = libEntry.path; 2214 if (lib == null) { 2215 continue; 2216 } 2217 2218 try { 2219 // Shared libraries do not have profiles so we perform a full 2220 // AOT compilation (if needed). 2221 int dexoptNeeded = DexFile.getDexOptNeeded( 2222 lib, dexCodeInstructionSet, 2223 getCompilerFilterForReason(REASON_SHARED_APK), 2224 false /* newProfile */); 2225 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { 2226 mInstaller.dexopt(lib, Process.SYSTEM_UID, dexCodeInstructionSet, 2227 dexoptNeeded, DEXOPT_PUBLIC /*dexFlags*/, 2228 getCompilerFilterForReason(REASON_SHARED_APK), 2229 StorageManager.UUID_PRIVATE_INTERNAL, 2230 SKIP_SHARED_LIBRARY_CHECK); 2231 } 2232 } catch (FileNotFoundException e) { 2233 Slog.w(TAG, "Library not found: " + lib); 2234 } catch (IOException | InstallerException e) { 2235 Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? " 2236 + e.getMessage()); 2237 } 2238 } 2239 } 2240 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2241 } 2242 2243 File frameworkDir = new File(Environment.getRootDirectory(), "framework"); 2244 2245 final VersionInfo ver = mSettings.getInternalVersion(); 2246 mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint); 2247 2248 // when upgrading from pre-M, promote system app permissions from install to runtime 2249 mPromoteSystemApps = 2250 mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1; 2251 2252 // When upgrading from pre-N, we need to handle package extraction like first boot, 2253 // as there is no profiling data available. 2254 mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N; 2255 2256 // save off the names of pre-existing system packages prior to scanning; we don't 2257 // want to automatically grant runtime permissions for new system apps 2258 if (mPromoteSystemApps) { 2259 Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator(); 2260 while (pkgSettingIter.hasNext()) { 2261 PackageSetting ps = pkgSettingIter.next(); 2262 if (isSystemApp(ps)) { 2263 mExistingSystemPackages.add(ps.name); 2264 } 2265 } 2266 } 2267 2268 // Collect vendor overlay packages. 2269 // (Do this before scanning any apps.) 2270 // For security and version matching reason, only consider 2271 // overlay packages if they reside in VENDOR_OVERLAY_DIR. 2272 File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR); 2273 scanDirTracedLI(vendorOverlayDir, mDefParseFlags 2274 | PackageParser.PARSE_IS_SYSTEM 2275 | PackageParser.PARSE_IS_SYSTEM_DIR 2276 | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0); 2277 2278 // Find base frameworks (resource packages without code). 2279 scanDirTracedLI(frameworkDir, mDefParseFlags 2280 | PackageParser.PARSE_IS_SYSTEM 2281 | PackageParser.PARSE_IS_SYSTEM_DIR 2282 | PackageParser.PARSE_IS_PRIVILEGED, 2283 scanFlags | SCAN_NO_DEX, 0); 2284 2285 // Collected privileged system packages. 2286 final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app"); 2287 scanDirTracedLI(privilegedAppDir, mDefParseFlags 2288 | PackageParser.PARSE_IS_SYSTEM 2289 | PackageParser.PARSE_IS_SYSTEM_DIR 2290 | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0); 2291 2292 // Collect ordinary system packages. 2293 final File systemAppDir = new File(Environment.getRootDirectory(), "app"); 2294 scanDirTracedLI(systemAppDir, mDefParseFlags 2295 | PackageParser.PARSE_IS_SYSTEM 2296 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2297 2298 // Collect all vendor packages. 2299 File vendorAppDir = new File("/vendor/app"); 2300 try { 2301 vendorAppDir = vendorAppDir.getCanonicalFile(); 2302 } catch (IOException e) { 2303 // failed to look up canonical path, continue with original one 2304 } 2305 scanDirTracedLI(vendorAppDir, mDefParseFlags 2306 | PackageParser.PARSE_IS_SYSTEM 2307 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2308 2309 // Collect all OEM packages. 2310 final File oemAppDir = new File(Environment.getOemDirectory(), "app"); 2311 scanDirTracedLI(oemAppDir, mDefParseFlags 2312 | PackageParser.PARSE_IS_SYSTEM 2313 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2314 2315 // Prune any system packages that no longer exist. 2316 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>(); 2317 if (!mOnlyCore) { 2318 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 2319 while (psit.hasNext()) { 2320 PackageSetting ps = psit.next(); 2321 2322 /* 2323 * If this is not a system app, it can't be a 2324 * disable system app. 2325 */ 2326 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) { 2327 continue; 2328 } 2329 2330 /* 2331 * If the package is scanned, it's not erased. 2332 */ 2333 final PackageParser.Package scannedPkg = mPackages.get(ps.name); 2334 if (scannedPkg != null) { 2335 /* 2336 * If the system app is both scanned and in the 2337 * disabled packages list, then it must have been 2338 * added via OTA. Remove it from the currently 2339 * scanned package so the previously user-installed 2340 * application can be scanned. 2341 */ 2342 if (mSettings.isDisabledSystemPackageLPr(ps.name)) { 2343 logCriticalInfo(Log.WARN, "Expecting better updated system app for " 2344 + ps.name + "; removing system app. Last known codePath=" 2345 + ps.codePathString + ", installStatus=" + ps.installStatus 2346 + ", versionCode=" + ps.versionCode + "; scanned versionCode=" 2347 + scannedPkg.mVersionCode); 2348 removePackageLI(scannedPkg, true); 2349 mExpectingBetter.put(ps.name, ps.codePath); 2350 } 2351 2352 continue; 2353 } 2354 2355 if (!mSettings.isDisabledSystemPackageLPr(ps.name)) { 2356 psit.remove(); 2357 logCriticalInfo(Log.WARN, "System package " + ps.name 2358 + " no longer exists; it's data will be wiped"); 2359 // Actual deletion of code and data will be handled by later 2360 // reconciliation step 2361 } else { 2362 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name); 2363 if (disabledPs.codePath == null || !disabledPs.codePath.exists()) { 2364 possiblyDeletedUpdatedSystemApps.add(ps.name); 2365 } 2366 } 2367 } 2368 } 2369 2370 //look for any incomplete package installations 2371 ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr(); 2372 for (int i = 0; i < deletePkgsList.size(); i++) { 2373 // Actual deletion of code and data will be handled by later 2374 // reconciliation step 2375 final String packageName = deletePkgsList.get(i).name; 2376 logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName); 2377 synchronized (mPackages) { 2378 mSettings.removePackageLPw(packageName); 2379 } 2380 } 2381 2382 //delete tmp files 2383 deleteTempPackageFiles(); 2384 2385 // Remove any shared userIDs that have no associated packages 2386 mSettings.pruneSharedUsersLPw(); 2387 2388 if (!mOnlyCore) { 2389 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START, 2390 SystemClock.uptimeMillis()); 2391 scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0); 2392 2393 scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags 2394 | PackageParser.PARSE_FORWARD_LOCK, 2395 scanFlags | SCAN_REQUIRE_KNOWN, 0); 2396 2397 scanDirLI(mEphemeralInstallDir, mDefParseFlags 2398 | PackageParser.PARSE_IS_EPHEMERAL, 2399 scanFlags | SCAN_REQUIRE_KNOWN, 0); 2400 2401 /** 2402 * Remove disable package settings for any updated system 2403 * apps that were removed via an OTA. If they're not a 2404 * previously-updated app, remove them completely. 2405 * Otherwise, just revoke their system-level permissions. 2406 */ 2407 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) { 2408 PackageParser.Package deletedPkg = mPackages.get(deletedAppName); 2409 mSettings.removeDisabledSystemPackageLPw(deletedAppName); 2410 2411 String msg; 2412 if (deletedPkg == null) { 2413 msg = "Updated system package " + deletedAppName 2414 + " no longer exists; it's data will be wiped"; 2415 // Actual deletion of code and data will be handled by later 2416 // reconciliation step 2417 } else { 2418 msg = "Updated system app + " + deletedAppName 2419 + " no longer present; removing system privileges for " 2420 + deletedAppName; 2421 2422 deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM; 2423 2424 PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName); 2425 deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM; 2426 } 2427 logCriticalInfo(Log.WARN, msg); 2428 } 2429 2430 /** 2431 * Make sure all system apps that we expected to appear on 2432 * the userdata partition actually showed up. If they never 2433 * appeared, crawl back and revive the system version. 2434 */ 2435 for (int i = 0; i < mExpectingBetter.size(); i++) { 2436 final String packageName = mExpectingBetter.keyAt(i); 2437 if (!mPackages.containsKey(packageName)) { 2438 final File scanFile = mExpectingBetter.valueAt(i); 2439 2440 logCriticalInfo(Log.WARN, "Expected better " + packageName 2441 + " but never showed up; reverting to system"); 2442 2443 int reparseFlags = mDefParseFlags; 2444 if (FileUtils.contains(privilegedAppDir, scanFile)) { 2445 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2446 | PackageParser.PARSE_IS_SYSTEM_DIR 2447 | PackageParser.PARSE_IS_PRIVILEGED; 2448 } else if (FileUtils.contains(systemAppDir, scanFile)) { 2449 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2450 | PackageParser.PARSE_IS_SYSTEM_DIR; 2451 } else if (FileUtils.contains(vendorAppDir, scanFile)) { 2452 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2453 | PackageParser.PARSE_IS_SYSTEM_DIR; 2454 } else if (FileUtils.contains(oemAppDir, scanFile)) { 2455 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2456 | PackageParser.PARSE_IS_SYSTEM_DIR; 2457 } else { 2458 Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile); 2459 continue; 2460 } 2461 2462 mSettings.enableSystemPackageLPw(packageName); 2463 2464 try { 2465 scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null); 2466 } catch (PackageManagerException e) { 2467 Slog.e(TAG, "Failed to parse original system package: " 2468 + e.getMessage()); 2469 } 2470 } 2471 } 2472 } 2473 mExpectingBetter.clear(); 2474 2475 // Resolve protected action filters. Only the setup wizard is allowed to 2476 // have a high priority filter for these actions. 2477 mSetupWizardPackage = getSetupWizardPackageName(); 2478 if (mProtectedFilters.size() > 0) { 2479 if (DEBUG_FILTERS && mSetupWizardPackage == null) { 2480 Slog.i(TAG, "No setup wizard;" 2481 + " All protected intents capped to priority 0"); 2482 } 2483 for (ActivityIntentInfo filter : mProtectedFilters) { 2484 if (filter.activity.info.packageName.equals(mSetupWizardPackage)) { 2485 if (DEBUG_FILTERS) { 2486 Slog.i(TAG, "Found setup wizard;" 2487 + " allow priority " + filter.getPriority() + ";" 2488 + " package: " + filter.activity.info.packageName 2489 + " activity: " + filter.activity.className 2490 + " priority: " + filter.getPriority()); 2491 } 2492 // skip setup wizard; allow it to keep the high priority filter 2493 continue; 2494 } 2495 Slog.w(TAG, "Protected action; cap priority to 0;" 2496 + " package: " + filter.activity.info.packageName 2497 + " activity: " + filter.activity.className 2498 + " origPrio: " + filter.getPriority()); 2499 filter.setPriority(0); 2500 } 2501 } 2502 mDeferProtectedFilters = false; 2503 mProtectedFilters.clear(); 2504 2505 // Now that we know all of the shared libraries, update all clients to have 2506 // the correct library paths. 2507 updateAllSharedLibrariesLPw(); 2508 2509 for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) { 2510 // NOTE: We ignore potential failures here during a system scan (like 2511 // the rest of the commands above) because there's precious little we 2512 // can do about it. A settings error is reported, though. 2513 adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */, 2514 false /* boot complete */); 2515 } 2516 2517 // Now that we know all the packages we are keeping, 2518 // read and update their last usage times. 2519 mPackageUsage.read(mPackages); 2520 mCompilerStats.read(); 2521 2522 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END, 2523 SystemClock.uptimeMillis()); 2524 Slog.i(TAG, "Time to scan packages: " 2525 + ((SystemClock.uptimeMillis()-startTime)/1000f) 2526 + " seconds"); 2527 2528 // If the platform SDK has changed since the last time we booted, 2529 // we need to re-grant app permission to catch any new ones that 2530 // appear. This is really a hack, and means that apps can in some 2531 // cases get permissions that the user didn't initially explicitly 2532 // allow... it would be nice to have some better way to handle 2533 // this situation. 2534 int updateFlags = UPDATE_PERMISSIONS_ALL; 2535 if (ver.sdkVersion != mSdkVersion) { 2536 Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to " 2537 + mSdkVersion + "; regranting permissions for internal storage"); 2538 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 2539 } 2540 updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags); 2541 ver.sdkVersion = mSdkVersion; 2542 2543 // If this is the first boot or an update from pre-M, and it is a normal 2544 // boot, then we need to initialize the default preferred apps across 2545 // all defined users. 2546 if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) { 2547 for (UserInfo user : sUserManager.getUsers(true)) { 2548 mSettings.applyDefaultPreferredAppsLPw(this, user.id); 2549 applyFactoryDefaultBrowserLPw(user.id); 2550 primeDomainVerificationsLPw(user.id); 2551 } 2552 } 2553 2554 // Prepare storage for system user really early during boot, 2555 // since core system apps like SettingsProvider and SystemUI 2556 // can't wait for user to start 2557 final int storageFlags; 2558 if (StorageManager.isFileEncryptedNativeOrEmulated()) { 2559 storageFlags = StorageManager.FLAG_STORAGE_DE; 2560 } else { 2561 storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 2562 } 2563 reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL, UserHandle.USER_SYSTEM, 2564 storageFlags, true /* migrateAppData */); 2565 2566 // If this is first boot after an OTA, and a normal boot, then 2567 // we need to clear code cache directories. 2568 // Note that we do *not* clear the application profiles. These remain valid 2569 // across OTAs and are used to drive profile verification (post OTA) and 2570 // profile compilation (without waiting to collect a fresh set of profiles). 2571 if (mIsUpgrade && !onlyCore) { 2572 Slog.i(TAG, "Build fingerprint changed; clearing code caches"); 2573 for (int i = 0; i < mSettings.mPackages.size(); i++) { 2574 final PackageSetting ps = mSettings.mPackages.valueAt(i); 2575 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) { 2576 // No apps are running this early, so no need to freeze 2577 clearAppDataLIF(ps.pkg, UserHandle.USER_ALL, 2578 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE 2579 | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 2580 } 2581 } 2582 ver.fingerprint = Build.FINGERPRINT; 2583 } 2584 2585 checkDefaultBrowser(); 2586 2587 // clear only after permissions and other defaults have been updated 2588 mExistingSystemPackages.clear(); 2589 mPromoteSystemApps = false; 2590 2591 // All the changes are done during package scanning. 2592 ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION; 2593 2594 // can downgrade to reader 2595 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings"); 2596 mSettings.writeLPr(); 2597 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2598 2599 // Perform dexopt on all apps that mark themselves as coreApps. We do this pretty 2600 // early on (before the package manager declares itself as early) because other 2601 // components in the system server might ask for package contexts for these apps. 2602 // 2603 // Note that "onlyCore" in this context means the system is encrypted or encrypting 2604 // (i.e, that the data partition is unavailable). 2605 if ((isFirstBoot() || isUpgrade() || VMRuntime.didPruneDalvikCache()) && !onlyCore) { 2606 long start = System.nanoTime(); 2607 List<PackageParser.Package> coreApps = new ArrayList<>(); 2608 for (PackageParser.Package pkg : mPackages.values()) { 2609 if (pkg.coreApp) { 2610 coreApps.add(pkg); 2611 } 2612 } 2613 2614 int[] stats = performDexOptUpgrade(coreApps, false, 2615 getCompilerFilterForReason(REASON_CORE_APP)); 2616 2617 final int elapsedTimeSeconds = 2618 (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start); 2619 MetricsLogger.histogram(mContext, "opt_coreapps_time_s", elapsedTimeSeconds); 2620 2621 if (DEBUG_DEXOPT) { 2622 Slog.i(TAG, "Dex-opt core apps took : " + elapsedTimeSeconds + " seconds (" + 2623 stats[0] + ", " + stats[1] + ", " + stats[2] + ")"); 2624 } 2625 2626 2627 // TODO: Should we log these stats to tron too ? 2628 // MetricsLogger.histogram(mContext, "opt_coreapps_num_dexopted", stats[0]); 2629 // MetricsLogger.histogram(mContext, "opt_coreapps_num_skipped", stats[1]); 2630 // MetricsLogger.histogram(mContext, "opt_coreapps_num_failed", stats[2]); 2631 // MetricsLogger.histogram(mContext, "opt_coreapps_num_total", coreApps.size()); 2632 } 2633 2634 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY, 2635 SystemClock.uptimeMillis()); 2636 2637 if (!mOnlyCore) { 2638 mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr(); 2639 mRequiredInstallerPackage = getRequiredInstallerLPr(); 2640 mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr(); 2641 mIntentFilterVerifier = new IntentVerifierProxy(mContext, 2642 mIntentFilterVerifierComponent); 2643 mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr( 2644 PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES); 2645 mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr( 2646 PackageManager.SYSTEM_SHARED_LIBRARY_SHARED); 2647 } else { 2648 mRequiredVerifierPackage = null; 2649 mRequiredInstallerPackage = null; 2650 mIntentFilterVerifierComponent = null; 2651 mIntentFilterVerifier = null; 2652 mServicesSystemSharedLibraryPackageName = null; 2653 mSharedSystemSharedLibraryPackageName = null; 2654 } 2655 2656 mInstallerService = new PackageInstallerService(context, this); 2657 2658 final ComponentName ephemeralResolverComponent = getEphemeralResolverLPr(); 2659 final ComponentName ephemeralInstallerComponent = getEphemeralInstallerLPr(); 2660 // both the installer and resolver must be present to enable ephemeral 2661 if (ephemeralInstallerComponent != null && ephemeralResolverComponent != null) { 2662 if (DEBUG_EPHEMERAL) { 2663 Slog.i(TAG, "Ephemeral activated; resolver: " + ephemeralResolverComponent 2664 + " installer:" + ephemeralInstallerComponent); 2665 } 2666 mEphemeralResolverComponent = ephemeralResolverComponent; 2667 mEphemeralInstallerComponent = ephemeralInstallerComponent; 2668 setUpEphemeralInstallerActivityLP(mEphemeralInstallerComponent); 2669 mEphemeralResolverConnection = 2670 new EphemeralResolverConnection(mContext, mEphemeralResolverComponent); 2671 } else { 2672 if (DEBUG_EPHEMERAL) { 2673 final String missingComponent = 2674 (ephemeralResolverComponent == null) 2675 ? (ephemeralInstallerComponent == null) 2676 ? "resolver and installer" 2677 : "resolver" 2678 : "installer"; 2679 Slog.i(TAG, "Ephemeral deactivated; missing " + missingComponent); 2680 } 2681 mEphemeralResolverComponent = null; 2682 mEphemeralInstallerComponent = null; 2683 mEphemeralResolverConnection = null; 2684 } 2685 2686 mEphemeralApplicationRegistry = new EphemeralApplicationRegistry(this); 2687 } // synchronized (mPackages) 2688 } // synchronized (mInstallLock) 2689 2690 // Now after opening every single application zip, make sure they 2691 // are all flushed. Not really needed, but keeps things nice and 2692 // tidy. 2693 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC"); 2694 Runtime.getRuntime().gc(); 2695 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2696 2697 // The initial scanning above does many calls into installd while 2698 // holding the mPackages lock, but we're mostly interested in yelling 2699 // once we have a booted system. 2700 mInstaller.setWarnIfHeld(mPackages); 2701 2702 // Expose private service for system components to use. 2703 LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl()); 2704 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2705 } 2706 2707 @Override 2708 public boolean isFirstBoot() { 2709 return mFirstBoot; 2710 } 2711 2712 @Override 2713 public boolean isOnlyCoreApps() { 2714 return mOnlyCore; 2715 } 2716 2717 @Override 2718 public boolean isUpgrade() { 2719 return mIsUpgrade; 2720 } 2721 2722 private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() { 2723 final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 2724 2725 final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE, 2726 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 2727 UserHandle.USER_SYSTEM); 2728 if (matches.size() == 1) { 2729 return matches.get(0).getComponentInfo().packageName; 2730 } else { 2731 Log.e(TAG, "There should probably be exactly one verifier; found " + matches); 2732 return null; 2733 } 2734 } 2735 2736 private @NonNull String getRequiredSharedLibraryLPr(String libraryName) { 2737 synchronized (mPackages) { 2738 SharedLibraryEntry libraryEntry = mSharedLibraries.get(libraryName); 2739 if (libraryEntry == null) { 2740 throw new IllegalStateException("Missing required shared library:" + libraryName); 2741 } 2742 return libraryEntry.apk; 2743 } 2744 } 2745 2746 private @NonNull String getRequiredInstallerLPr() { 2747 final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE); 2748 intent.addCategory(Intent.CATEGORY_DEFAULT); 2749 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE); 2750 2751 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE, 2752 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 2753 UserHandle.USER_SYSTEM); 2754 if (matches.size() == 1) { 2755 ResolveInfo resolveInfo = matches.get(0); 2756 if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) { 2757 throw new RuntimeException("The installer must be a privileged app"); 2758 } 2759 return matches.get(0).getComponentInfo().packageName; 2760 } else { 2761 throw new RuntimeException("There must be exactly one installer; found " + matches); 2762 } 2763 } 2764 2765 private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() { 2766 final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 2767 2768 final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE, 2769 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 2770 UserHandle.USER_SYSTEM); 2771 ResolveInfo best = null; 2772 final int N = matches.size(); 2773 for (int i = 0; i < N; i++) { 2774 final ResolveInfo cur = matches.get(i); 2775 final String packageName = cur.getComponentInfo().packageName; 2776 if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 2777 packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) { 2778 continue; 2779 } 2780 2781 if (best == null || cur.priority > best.priority) { 2782 best = cur; 2783 } 2784 } 2785 2786 if (best != null) { 2787 return best.getComponentInfo().getComponentName(); 2788 } else { 2789 throw new RuntimeException("There must be at least one intent filter verifier"); 2790 } 2791 } 2792 2793 private @Nullable ComponentName getEphemeralResolverLPr() { 2794 final String[] packageArray = 2795 mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage); 2796 if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) { 2797 if (DEBUG_EPHEMERAL) { 2798 Slog.d(TAG, "Ephemeral resolver NOT found; empty package list"); 2799 } 2800 return null; 2801 } 2802 2803 final int resolveFlags = 2804 MATCH_DIRECT_BOOT_AWARE 2805 | MATCH_DIRECT_BOOT_UNAWARE 2806 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0); 2807 final Intent resolverIntent = new Intent(Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE); 2808 final List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null, 2809 resolveFlags, UserHandle.USER_SYSTEM); 2810 2811 final int N = resolvers.size(); 2812 if (N == 0) { 2813 if (DEBUG_EPHEMERAL) { 2814 Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters"); 2815 } 2816 return null; 2817 } 2818 2819 final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray)); 2820 for (int i = 0; i < N; i++) { 2821 final ResolveInfo info = resolvers.get(i); 2822 2823 if (info.serviceInfo == null) { 2824 continue; 2825 } 2826 2827 final String packageName = info.serviceInfo.packageName; 2828 if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) { 2829 if (DEBUG_EPHEMERAL) { 2830 Slog.d(TAG, "Ephemeral resolver not in allowed package list;" 2831 + " pkg: " + packageName + ", info:" + info); 2832 } 2833 continue; 2834 } 2835 2836 if (DEBUG_EPHEMERAL) { 2837 Slog.v(TAG, "Ephemeral resolver found;" 2838 + " pkg: " + packageName + ", info:" + info); 2839 } 2840 return new ComponentName(packageName, info.serviceInfo.name); 2841 } 2842 if (DEBUG_EPHEMERAL) { 2843 Slog.v(TAG, "Ephemeral resolver NOT found"); 2844 } 2845 return null; 2846 } 2847 2848 private @Nullable ComponentName getEphemeralInstallerLPr() { 2849 final Intent intent = new Intent(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE); 2850 intent.addCategory(Intent.CATEGORY_DEFAULT); 2851 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE); 2852 2853 final int resolveFlags = 2854 MATCH_DIRECT_BOOT_AWARE 2855 | MATCH_DIRECT_BOOT_UNAWARE 2856 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0); 2857 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE, 2858 resolveFlags, UserHandle.USER_SYSTEM); 2859 if (matches.size() == 0) { 2860 return null; 2861 } else if (matches.size() == 1) { 2862 return matches.get(0).getComponentInfo().getComponentName(); 2863 } else { 2864 throw new RuntimeException( 2865 "There must be at most one ephemeral installer; found " + matches); 2866 } 2867 } 2868 2869 private void primeDomainVerificationsLPw(int userId) { 2870 if (DEBUG_DOMAIN_VERIFICATION) { 2871 Slog.d(TAG, "Priming domain verifications in user " + userId); 2872 } 2873 2874 SystemConfig systemConfig = SystemConfig.getInstance(); 2875 ArraySet<String> packages = systemConfig.getLinkedApps(); 2876 2877 for (String packageName : packages) { 2878 PackageParser.Package pkg = mPackages.get(packageName); 2879 if (pkg != null) { 2880 if (!pkg.isSystemApp()) { 2881 Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>"); 2882 continue; 2883 } 2884 2885 ArraySet<String> domains = null; 2886 for (PackageParser.Activity a : pkg.activities) { 2887 for (ActivityIntentInfo filter : a.intents) { 2888 if (hasValidDomains(filter)) { 2889 if (domains == null) { 2890 domains = new ArraySet<String>(); 2891 } 2892 domains.addAll(filter.getHostsList()); 2893 } 2894 } 2895 } 2896 2897 if (domains != null && domains.size() > 0) { 2898 if (DEBUG_DOMAIN_VERIFICATION) { 2899 Slog.v(TAG, " + " + packageName); 2900 } 2901 // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual 2902 // state w.r.t. the formal app-linkage "no verification attempted" state; 2903 // and then 'always' in the per-user state actually used for intent resolution. 2904 final IntentFilterVerificationInfo ivi; 2905 ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains); 2906 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED); 2907 mSettings.updateIntentFilterVerificationStatusLPw(packageName, 2908 INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId); 2909 } else { 2910 Slog.w(TAG, "Sysconfig <app-link> package '" + packageName 2911 + "' does not handle web links"); 2912 } 2913 } else { 2914 Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>"); 2915 } 2916 } 2917 2918 scheduleWritePackageRestrictionsLocked(userId); 2919 scheduleWriteSettingsLocked(); 2920 } 2921 2922 private void applyFactoryDefaultBrowserLPw(int userId) { 2923 // The default browser app's package name is stored in a string resource, 2924 // with a product-specific overlay used for vendor customization. 2925 String browserPkg = mContext.getResources().getString( 2926 com.android.internal.R.string.default_browser); 2927 if (!TextUtils.isEmpty(browserPkg)) { 2928 // non-empty string => required to be a known package 2929 PackageSetting ps = mSettings.mPackages.get(browserPkg); 2930 if (ps == null) { 2931 Slog.e(TAG, "Product default browser app does not exist: " + browserPkg); 2932 browserPkg = null; 2933 } else { 2934 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId); 2935 } 2936 } 2937 2938 // Nothing valid explicitly set? Make the factory-installed browser the explicit 2939 // default. If there's more than one, just leave everything alone. 2940 if (browserPkg == null) { 2941 calculateDefaultBrowserLPw(userId); 2942 } 2943 } 2944 2945 private void calculateDefaultBrowserLPw(int userId) { 2946 List<String> allBrowsers = resolveAllBrowserApps(userId); 2947 final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null; 2948 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId); 2949 } 2950 2951 private List<String> resolveAllBrowserApps(int userId) { 2952 // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set 2953 List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null, 2954 PackageManager.MATCH_ALL, userId); 2955 2956 final int count = list.size(); 2957 List<String> result = new ArrayList<String>(count); 2958 for (int i=0; i<count; i++) { 2959 ResolveInfo info = list.get(i); 2960 if (info.activityInfo == null 2961 || !info.handleAllWebDataURI 2962 || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0 2963 || result.contains(info.activityInfo.packageName)) { 2964 continue; 2965 } 2966 result.add(info.activityInfo.packageName); 2967 } 2968 2969 return result; 2970 } 2971 2972 private boolean packageIsBrowser(String packageName, int userId) { 2973 List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null, 2974 PackageManager.MATCH_ALL, userId); 2975 final int N = list.size(); 2976 for (int i = 0; i < N; i++) { 2977 ResolveInfo info = list.get(i); 2978 if (packageName.equals(info.activityInfo.packageName)) { 2979 return true; 2980 } 2981 } 2982 return false; 2983 } 2984 2985 private void checkDefaultBrowser() { 2986 final int myUserId = UserHandle.myUserId(); 2987 final String packageName = getDefaultBrowserPackageName(myUserId); 2988 if (packageName != null) { 2989 PackageInfo info = getPackageInfo(packageName, 0, myUserId); 2990 if (info == null) { 2991 Slog.w(TAG, "Default browser no longer installed: " + packageName); 2992 synchronized (mPackages) { 2993 applyFactoryDefaultBrowserLPw(myUserId); // leaves ambiguous when > 1 2994 } 2995 } 2996 } 2997 } 2998 2999 @Override 3000 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 3001 throws RemoteException { 3002 try { 3003 return super.onTransact(code, data, reply, flags); 3004 } catch (RuntimeException e) { 3005 if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) { 3006 Slog.wtf(TAG, "Package Manager Crash", e); 3007 } 3008 throw e; 3009 } 3010 } 3011 3012 static int[] appendInts(int[] cur, int[] add) { 3013 if (add == null) return cur; 3014 if (cur == null) return add; 3015 final int N = add.length; 3016 for (int i=0; i<N; i++) { 3017 cur = appendInt(cur, add[i]); 3018 } 3019 return cur; 3020 } 3021 3022 private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) { 3023 if (!sUserManager.exists(userId)) return null; 3024 if (ps == null) { 3025 return null; 3026 } 3027 final PackageParser.Package p = ps.pkg; 3028 if (p == null) { 3029 return null; 3030 } 3031 3032 final PermissionsState permissionsState = ps.getPermissionsState(); 3033 3034 // Compute GIDs only if requested 3035 final int[] gids = (flags & PackageManager.GET_GIDS) == 0 3036 ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId); 3037 // Compute granted permissions only if package has requested permissions 3038 final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions) 3039 ? Collections.<String>emptySet() : permissionsState.getPermissions(userId); 3040 final PackageUserState state = ps.readUserState(userId); 3041 3042 return PackageParser.generatePackageInfo(p, gids, flags, 3043 ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId); 3044 } 3045 3046 @Override 3047 public void checkPackageStartable(String packageName, int userId) { 3048 final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId); 3049 3050 synchronized (mPackages) { 3051 final PackageSetting ps = mSettings.mPackages.get(packageName); 3052 if (ps == null) { 3053 throw new SecurityException("Package " + packageName + " was not found!"); 3054 } 3055 3056 if (!ps.getInstalled(userId)) { 3057 throw new SecurityException( 3058 "Package " + packageName + " was not installed for user " + userId + "!"); 3059 } 3060 3061 if (mSafeMode && !ps.isSystem()) { 3062 throw new SecurityException("Package " + packageName + " not a system app!"); 3063 } 3064 3065 if (mFrozenPackages.contains(packageName)) { 3066 throw new SecurityException("Package " + packageName + " is currently frozen!"); 3067 } 3068 3069 if (!userKeyUnlocked && !(ps.pkg.applicationInfo.isDirectBootAware() 3070 || ps.pkg.applicationInfo.isPartiallyDirectBootAware())) { 3071 throw new SecurityException("Package " + packageName + " is not encryption aware!"); 3072 } 3073 } 3074 } 3075 3076 @Override 3077 public boolean isPackageAvailable(String packageName, int userId) { 3078 if (!sUserManager.exists(userId)) return false; 3079 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3080 false /* requireFullPermission */, false /* checkShell */, "is package available"); 3081 synchronized (mPackages) { 3082 PackageParser.Package p = mPackages.get(packageName); 3083 if (p != null) { 3084 final PackageSetting ps = (PackageSetting) p.mExtras; 3085 if (ps != null) { 3086 final PackageUserState state = ps.readUserState(userId); 3087 if (state != null) { 3088 return PackageParser.isAvailable(state); 3089 } 3090 } 3091 } 3092 } 3093 return false; 3094 } 3095 3096 @Override 3097 public PackageInfo getPackageInfo(String packageName, int flags, int userId) { 3098 if (!sUserManager.exists(userId)) return null; 3099 flags = updateFlagsForPackage(flags, userId, packageName); 3100 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3101 false /* requireFullPermission */, false /* checkShell */, "get package info"); 3102 // reader 3103 synchronized (mPackages) { 3104 final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0; 3105 PackageParser.Package p = null; 3106 if (matchFactoryOnly) { 3107 final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName); 3108 if (ps != null) { 3109 return generatePackageInfo(ps, flags, userId); 3110 } 3111 } 3112 if (p == null) { 3113 p = mPackages.get(packageName); 3114 if (matchFactoryOnly && p != null && !isSystemApp(p)) { 3115 return null; 3116 } 3117 } 3118 if (DEBUG_PACKAGE_INFO) 3119 Log.v(TAG, "getPackageInfo " + packageName + ": " + p); 3120 if (p != null) { 3121 return generatePackageInfo((PackageSetting)p.mExtras, flags, userId); 3122 } 3123 if (!matchFactoryOnly && (flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 3124 final PackageSetting ps = mSettings.mPackages.get(packageName); 3125 return generatePackageInfo(ps, flags, userId); 3126 } 3127 } 3128 return null; 3129 } 3130 3131 @Override 3132 public String[] currentToCanonicalPackageNames(String[] names) { 3133 String[] out = new String[names.length]; 3134 // reader 3135 synchronized (mPackages) { 3136 for (int i=names.length-1; i>=0; i--) { 3137 PackageSetting ps = mSettings.mPackages.get(names[i]); 3138 out[i] = ps != null && ps.realName != null ? ps.realName : names[i]; 3139 } 3140 } 3141 return out; 3142 } 3143 3144 @Override 3145 public String[] canonicalToCurrentPackageNames(String[] names) { 3146 String[] out = new String[names.length]; 3147 // reader 3148 synchronized (mPackages) { 3149 for (int i=names.length-1; i>=0; i--) { 3150 String cur = mSettings.getRenamedPackage(names[i]); 3151 out[i] = cur != null ? cur : names[i]; 3152 } 3153 } 3154 return out; 3155 } 3156 3157 @Override 3158 public int getPackageUid(String packageName, int flags, int userId) { 3159 if (!sUserManager.exists(userId)) return -1; 3160 flags = updateFlagsForPackage(flags, userId, packageName); 3161 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3162 false /* requireFullPermission */, false /* checkShell */, "get package uid"); 3163 3164 // reader 3165 synchronized (mPackages) { 3166 final PackageParser.Package p = mPackages.get(packageName); 3167 if (p != null && p.isMatch(flags)) { 3168 return UserHandle.getUid(userId, p.applicationInfo.uid); 3169 } 3170 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 3171 final PackageSetting ps = mSettings.mPackages.get(packageName); 3172 if (ps != null && ps.isMatch(flags)) { 3173 return UserHandle.getUid(userId, ps.appId); 3174 } 3175 } 3176 } 3177 3178 return -1; 3179 } 3180 3181 @Override 3182 public int[] getPackageGids(String packageName, int flags, int userId) { 3183 if (!sUserManager.exists(userId)) return null; 3184 flags = updateFlagsForPackage(flags, userId, packageName); 3185 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3186 false /* requireFullPermission */, false /* checkShell */, 3187 "getPackageGids"); 3188 3189 // reader 3190 synchronized (mPackages) { 3191 final PackageParser.Package p = mPackages.get(packageName); 3192 if (p != null && p.isMatch(flags)) { 3193 PackageSetting ps = (PackageSetting) p.mExtras; 3194 return ps.getPermissionsState().computeGids(userId); 3195 } 3196 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 3197 final PackageSetting ps = mSettings.mPackages.get(packageName); 3198 if (ps != null && ps.isMatch(flags)) { 3199 return ps.getPermissionsState().computeGids(userId); 3200 } 3201 } 3202 } 3203 3204 return null; 3205 } 3206 3207 static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) { 3208 if (bp.perm != null) { 3209 return PackageParser.generatePermissionInfo(bp.perm, flags); 3210 } 3211 PermissionInfo pi = new PermissionInfo(); 3212 pi.name = bp.name; 3213 pi.packageName = bp.sourcePackage; 3214 pi.nonLocalizedLabel = bp.name; 3215 pi.protectionLevel = bp.protectionLevel; 3216 return pi; 3217 } 3218 3219 @Override 3220 public PermissionInfo getPermissionInfo(String name, int flags) { 3221 // reader 3222 synchronized (mPackages) { 3223 final BasePermission p = mSettings.mPermissions.get(name); 3224 if (p != null) { 3225 return generatePermissionInfo(p, flags); 3226 } 3227 return null; 3228 } 3229 } 3230 3231 @Override 3232 public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group, 3233 int flags) { 3234 // reader 3235 synchronized (mPackages) { 3236 if (group != null && !mPermissionGroups.containsKey(group)) { 3237 // This is thrown as NameNotFoundException 3238 return null; 3239 } 3240 3241 ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10); 3242 for (BasePermission p : mSettings.mPermissions.values()) { 3243 if (group == null) { 3244 if (p.perm == null || p.perm.info.group == null) { 3245 out.add(generatePermissionInfo(p, flags)); 3246 } 3247 } else { 3248 if (p.perm != null && group.equals(p.perm.info.group)) { 3249 out.add(PackageParser.generatePermissionInfo(p.perm, flags)); 3250 } 3251 } 3252 } 3253 return new ParceledListSlice<>(out); 3254 } 3255 } 3256 3257 @Override 3258 public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) { 3259 // reader 3260 synchronized (mPackages) { 3261 return PackageParser.generatePermissionGroupInfo( 3262 mPermissionGroups.get(name), flags); 3263 } 3264 } 3265 3266 @Override 3267 public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) { 3268 // reader 3269 synchronized (mPackages) { 3270 final int N = mPermissionGroups.size(); 3271 ArrayList<PermissionGroupInfo> out 3272 = new ArrayList<PermissionGroupInfo>(N); 3273 for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) { 3274 out.add(PackageParser.generatePermissionGroupInfo(pg, flags)); 3275 } 3276 return new ParceledListSlice<>(out); 3277 } 3278 } 3279 3280 private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags, 3281 int userId) { 3282 if (!sUserManager.exists(userId)) return null; 3283 PackageSetting ps = mSettings.mPackages.get(packageName); 3284 if (ps != null) { 3285 if (ps.pkg == null) { 3286 final PackageInfo pInfo = generatePackageInfo(ps, flags, userId); 3287 if (pInfo != null) { 3288 return pInfo.applicationInfo; 3289 } 3290 return null; 3291 } 3292 return PackageParser.generateApplicationInfo(ps.pkg, flags, 3293 ps.readUserState(userId), userId); 3294 } 3295 return null; 3296 } 3297 3298 @Override 3299 public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) { 3300 if (!sUserManager.exists(userId)) return null; 3301 flags = updateFlagsForApplication(flags, userId, packageName); 3302 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3303 false /* requireFullPermission */, false /* checkShell */, "get application info"); 3304 // writer 3305 synchronized (mPackages) { 3306 PackageParser.Package p = mPackages.get(packageName); 3307 if (DEBUG_PACKAGE_INFO) Log.v( 3308 TAG, "getApplicationInfo " + packageName 3309 + ": " + p); 3310 if (p != null) { 3311 PackageSetting ps = mSettings.mPackages.get(packageName); 3312 if (ps == null) return null; 3313 // Note: isEnabledLP() does not apply here - always return info 3314 return PackageParser.generateApplicationInfo( 3315 p, flags, ps.readUserState(userId), userId); 3316 } 3317 if ("android".equals(packageName)||"system".equals(packageName)) { 3318 return mAndroidApplication; 3319 } 3320 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 3321 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId); 3322 } 3323 } 3324 return null; 3325 } 3326 3327 @Override 3328 public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize, 3329 final IPackageDataObserver observer) { 3330 mContext.enforceCallingOrSelfPermission( 3331 android.Manifest.permission.CLEAR_APP_CACHE, null); 3332 // Queue up an async operation since clearing cache may take a little while. 3333 mHandler.post(new Runnable() { 3334 public void run() { 3335 mHandler.removeCallbacks(this); 3336 boolean success = true; 3337 synchronized (mInstallLock) { 3338 try { 3339 mInstaller.freeCache(volumeUuid, freeStorageSize); 3340 } catch (InstallerException e) { 3341 Slog.w(TAG, "Couldn't clear application caches: " + e); 3342 success = false; 3343 } 3344 } 3345 if (observer != null) { 3346 try { 3347 observer.onRemoveCompleted(null, success); 3348 } catch (RemoteException e) { 3349 Slog.w(TAG, "RemoveException when invoking call back"); 3350 } 3351 } 3352 } 3353 }); 3354 } 3355 3356 @Override 3357 public void freeStorage(final String volumeUuid, final long freeStorageSize, 3358 final IntentSender pi) { 3359 mContext.enforceCallingOrSelfPermission( 3360 android.Manifest.permission.CLEAR_APP_CACHE, null); 3361 // Queue up an async operation since clearing cache may take a little while. 3362 mHandler.post(new Runnable() { 3363 public void run() { 3364 mHandler.removeCallbacks(this); 3365 boolean success = true; 3366 synchronized (mInstallLock) { 3367 try { 3368 mInstaller.freeCache(volumeUuid, freeStorageSize); 3369 } catch (InstallerException e) { 3370 Slog.w(TAG, "Couldn't clear application caches: " + e); 3371 success = false; 3372 } 3373 } 3374 if(pi != null) { 3375 try { 3376 // Callback via pending intent 3377 int code = success ? 1 : 0; 3378 pi.sendIntent(null, code, null, 3379 null, null); 3380 } catch (SendIntentException e1) { 3381 Slog.i(TAG, "Failed to send pending intent"); 3382 } 3383 } 3384 } 3385 }); 3386 } 3387 3388 void freeStorage(String volumeUuid, long freeStorageSize) throws IOException { 3389 synchronized (mInstallLock) { 3390 try { 3391 mInstaller.freeCache(volumeUuid, freeStorageSize); 3392 } catch (InstallerException e) { 3393 throw new IOException("Failed to free enough space", e); 3394 } 3395 } 3396 } 3397 3398 /** 3399 * Update given flags based on encryption status of current user. 3400 */ 3401 private int updateFlags(int flags, int userId) { 3402 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE 3403 | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) { 3404 // Caller expressed an explicit opinion about what encryption 3405 // aware/unaware components they want to see, so fall through and 3406 // give them what they want 3407 } else { 3408 // Caller expressed no opinion, so match based on user state 3409 if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) { 3410 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE; 3411 } else { 3412 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE; 3413 } 3414 } 3415 return flags; 3416 } 3417 3418 private UserManagerInternal getUserManagerInternal() { 3419 if (mUserManagerInternal == null) { 3420 mUserManagerInternal = LocalServices.getService(UserManagerInternal.class); 3421 } 3422 return mUserManagerInternal; 3423 } 3424 3425 /** 3426 * Update given flags when being used to request {@link PackageInfo}. 3427 */ 3428 private int updateFlagsForPackage(int flags, int userId, Object cookie) { 3429 boolean triaged = true; 3430 if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS 3431 | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) { 3432 // Caller is asking for component details, so they'd better be 3433 // asking for specific encryption matching behavior, or be triaged 3434 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE 3435 | PackageManager.MATCH_DIRECT_BOOT_AWARE 3436 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3437 triaged = false; 3438 } 3439 } 3440 if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES 3441 | PackageManager.MATCH_SYSTEM_ONLY 3442 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3443 triaged = false; 3444 } 3445 if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) { 3446 Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie 3447 + " with flags 0x" + Integer.toHexString(flags), new Throwable()); 3448 } 3449 return updateFlags(flags, userId); 3450 } 3451 3452 /** 3453 * Update given flags when being used to request {@link ApplicationInfo}. 3454 */ 3455 private int updateFlagsForApplication(int flags, int userId, Object cookie) { 3456 return updateFlagsForPackage(flags, userId, cookie); 3457 } 3458 3459 /** 3460 * Update given flags when being used to request {@link ComponentInfo}. 3461 */ 3462 private int updateFlagsForComponent(int flags, int userId, Object cookie) { 3463 if (cookie instanceof Intent) { 3464 if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) { 3465 flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING; 3466 } 3467 } 3468 3469 boolean triaged = true; 3470 // Caller is asking for component details, so they'd better be 3471 // asking for specific encryption matching behavior, or be triaged 3472 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE 3473 | PackageManager.MATCH_DIRECT_BOOT_AWARE 3474 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3475 triaged = false; 3476 } 3477 if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) { 3478 Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie 3479 + " with flags 0x" + Integer.toHexString(flags), new Throwable()); 3480 } 3481 3482 return updateFlags(flags, userId); 3483 } 3484 3485 /** 3486 * Update given flags when being used to request {@link ResolveInfo}. 3487 */ 3488 int updateFlagsForResolve(int flags, int userId, Object cookie) { 3489 // Safe mode means we shouldn't match any third-party components 3490 if (mSafeMode) { 3491 flags |= PackageManager.MATCH_SYSTEM_ONLY; 3492 } 3493 3494 return updateFlagsForComponent(flags, userId, cookie); 3495 } 3496 3497 @Override 3498 public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) { 3499 if (!sUserManager.exists(userId)) return null; 3500 flags = updateFlagsForComponent(flags, userId, component); 3501 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3502 false /* requireFullPermission */, false /* checkShell */, "get activity info"); 3503 synchronized (mPackages) { 3504 PackageParser.Activity a = mActivities.mActivities.get(component); 3505 3506 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a); 3507 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) { 3508 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3509 if (ps == null) return null; 3510 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 3511 userId); 3512 } 3513 if (mResolveComponentName.equals(component)) { 3514 return PackageParser.generateActivityInfo(mResolveActivity, flags, 3515 new PackageUserState(), userId); 3516 } 3517 } 3518 return null; 3519 } 3520 3521 @Override 3522 public boolean activitySupportsIntent(ComponentName component, Intent intent, 3523 String resolvedType) { 3524 synchronized (mPackages) { 3525 if (component.equals(mResolveComponentName)) { 3526 // The resolver supports EVERYTHING! 3527 return true; 3528 } 3529 PackageParser.Activity a = mActivities.mActivities.get(component); 3530 if (a == null) { 3531 return false; 3532 } 3533 for (int i=0; i<a.intents.size(); i++) { 3534 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(), 3535 intent.getData(), intent.getCategories(), TAG) >= 0) { 3536 return true; 3537 } 3538 } 3539 return false; 3540 } 3541 } 3542 3543 @Override 3544 public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) { 3545 if (!sUserManager.exists(userId)) return null; 3546 flags = updateFlagsForComponent(flags, userId, component); 3547 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3548 false /* requireFullPermission */, false /* checkShell */, "get receiver info"); 3549 synchronized (mPackages) { 3550 PackageParser.Activity a = mReceivers.mActivities.get(component); 3551 if (DEBUG_PACKAGE_INFO) Log.v( 3552 TAG, "getReceiverInfo " + component + ": " + a); 3553 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) { 3554 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3555 if (ps == null) return null; 3556 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 3557 userId); 3558 } 3559 } 3560 return null; 3561 } 3562 3563 @Override 3564 public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) { 3565 if (!sUserManager.exists(userId)) return null; 3566 flags = updateFlagsForComponent(flags, userId, component); 3567 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3568 false /* requireFullPermission */, false /* checkShell */, "get service info"); 3569 synchronized (mPackages) { 3570 PackageParser.Service s = mServices.mServices.get(component); 3571 if (DEBUG_PACKAGE_INFO) Log.v( 3572 TAG, "getServiceInfo " + component + ": " + s); 3573 if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) { 3574 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3575 if (ps == null) return null; 3576 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId), 3577 userId); 3578 } 3579 } 3580 return null; 3581 } 3582 3583 @Override 3584 public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) { 3585 if (!sUserManager.exists(userId)) return null; 3586 flags = updateFlagsForComponent(flags, userId, component); 3587 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3588 false /* requireFullPermission */, false /* checkShell */, "get provider info"); 3589 synchronized (mPackages) { 3590 PackageParser.Provider p = mProviders.mProviders.get(component); 3591 if (DEBUG_PACKAGE_INFO) Log.v( 3592 TAG, "getProviderInfo " + component + ": " + p); 3593 if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) { 3594 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3595 if (ps == null) return null; 3596 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId), 3597 userId); 3598 } 3599 } 3600 return null; 3601 } 3602 3603 @Override 3604 public String[] getSystemSharedLibraryNames() { 3605 Set<String> libSet; 3606 synchronized (mPackages) { 3607 libSet = mSharedLibraries.keySet(); 3608 int size = libSet.size(); 3609 if (size > 0) { 3610 String[] libs = new String[size]; 3611 libSet.toArray(libs); 3612 return libs; 3613 } 3614 } 3615 return null; 3616 } 3617 3618 @Override 3619 public @NonNull String getServicesSystemSharedLibraryPackageName() { 3620 synchronized (mPackages) { 3621 return mServicesSystemSharedLibraryPackageName; 3622 } 3623 } 3624 3625 @Override 3626 public @NonNull String getSharedSystemSharedLibraryPackageName() { 3627 synchronized (mPackages) { 3628 return mSharedSystemSharedLibraryPackageName; 3629 } 3630 } 3631 3632 @Override 3633 public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() { 3634 synchronized (mPackages) { 3635 final ArrayList<FeatureInfo> res = new ArrayList<>(mAvailableFeatures.values()); 3636 3637 final FeatureInfo fi = new FeatureInfo(); 3638 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version", 3639 FeatureInfo.GL_ES_VERSION_UNDEFINED); 3640 res.add(fi); 3641 3642 return new ParceledListSlice<>(res); 3643 } 3644 } 3645 3646 @Override 3647 public boolean hasSystemFeature(String name, int version) { 3648 synchronized (mPackages) { 3649 final FeatureInfo feat = mAvailableFeatures.get(name); 3650 if (feat == null) { 3651 return false; 3652 } else { 3653 return feat.version >= version; 3654 } 3655 } 3656 } 3657 3658 @Override 3659 public int checkPermission(String permName, String pkgName, int userId) { 3660 if (!sUserManager.exists(userId)) { 3661 return PackageManager.PERMISSION_DENIED; 3662 } 3663 3664 synchronized (mPackages) { 3665 final PackageParser.Package p = mPackages.get(pkgName); 3666 if (p != null && p.mExtras != null) { 3667 final PackageSetting ps = (PackageSetting) p.mExtras; 3668 final PermissionsState permissionsState = ps.getPermissionsState(); 3669 if (permissionsState.hasPermission(permName, userId)) { 3670 return PackageManager.PERMISSION_GRANTED; 3671 } 3672 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION 3673 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState 3674 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { 3675 return PackageManager.PERMISSION_GRANTED; 3676 } 3677 } 3678 } 3679 3680 return PackageManager.PERMISSION_DENIED; 3681 } 3682 3683 @Override 3684 public int checkUidPermission(String permName, int uid) { 3685 final int userId = UserHandle.getUserId(uid); 3686 3687 if (!sUserManager.exists(userId)) { 3688 return PackageManager.PERMISSION_DENIED; 3689 } 3690 3691 synchronized (mPackages) { 3692 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 3693 if (obj != null) { 3694 final SettingBase ps = (SettingBase) obj; 3695 final PermissionsState permissionsState = ps.getPermissionsState(); 3696 if (permissionsState.hasPermission(permName, userId)) { 3697 return PackageManager.PERMISSION_GRANTED; 3698 } 3699 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION 3700 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState 3701 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { 3702 return PackageManager.PERMISSION_GRANTED; 3703 } 3704 } else { 3705 ArraySet<String> perms = mSystemPermissions.get(uid); 3706 if (perms != null) { 3707 if (perms.contains(permName)) { 3708 return PackageManager.PERMISSION_GRANTED; 3709 } 3710 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms 3711 .contains(Manifest.permission.ACCESS_FINE_LOCATION)) { 3712 return PackageManager.PERMISSION_GRANTED; 3713 } 3714 } 3715 } 3716 } 3717 3718 return PackageManager.PERMISSION_DENIED; 3719 } 3720 3721 @Override 3722 public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) { 3723 if (UserHandle.getCallingUserId() != userId) { 3724 mContext.enforceCallingPermission( 3725 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 3726 "isPermissionRevokedByPolicy for user " + userId); 3727 } 3728 3729 if (checkPermission(permission, packageName, userId) 3730 == PackageManager.PERMISSION_GRANTED) { 3731 return false; 3732 } 3733 3734 final long identity = Binder.clearCallingIdentity(); 3735 try { 3736 final int flags = getPermissionFlags(permission, packageName, userId); 3737 return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0; 3738 } finally { 3739 Binder.restoreCallingIdentity(identity); 3740 } 3741 } 3742 3743 @Override 3744 public String getPermissionControllerPackageName() { 3745 synchronized (mPackages) { 3746 return mRequiredInstallerPackage; 3747 } 3748 } 3749 3750 /** 3751 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS 3752 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller. 3753 * @param checkShell whether to prevent shell from access if there's a debugging restriction 3754 * @param message the message to log on security exception 3755 */ 3756 void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, 3757 boolean checkShell, String message) { 3758 if (userId < 0) { 3759 throw new IllegalArgumentException("Invalid userId " + userId); 3760 } 3761 if (checkShell) { 3762 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); 3763 } 3764 if (userId == UserHandle.getUserId(callingUid)) return; 3765 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 3766 if (requireFullPermission) { 3767 mContext.enforceCallingOrSelfPermission( 3768 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 3769 } else { 3770 try { 3771 mContext.enforceCallingOrSelfPermission( 3772 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 3773 } catch (SecurityException se) { 3774 mContext.enforceCallingOrSelfPermission( 3775 android.Manifest.permission.INTERACT_ACROSS_USERS, message); 3776 } 3777 } 3778 } 3779 } 3780 3781 void enforceShellRestriction(String restriction, int callingUid, int userHandle) { 3782 if (callingUid == Process.SHELL_UID) { 3783 if (userHandle >= 0 3784 && sUserManager.hasUserRestriction(restriction, userHandle)) { 3785 throw new SecurityException("Shell does not have permission to access user " 3786 + userHandle); 3787 } else if (userHandle < 0) { 3788 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t" 3789 + Debug.getCallers(3)); 3790 } 3791 } 3792 } 3793 3794 private BasePermission findPermissionTreeLP(String permName) { 3795 for(BasePermission bp : mSettings.mPermissionTrees.values()) { 3796 if (permName.startsWith(bp.name) && 3797 permName.length() > bp.name.length() && 3798 permName.charAt(bp.name.length()) == '.') { 3799 return bp; 3800 } 3801 } 3802 return null; 3803 } 3804 3805 private BasePermission checkPermissionTreeLP(String permName) { 3806 if (permName != null) { 3807 BasePermission bp = findPermissionTreeLP(permName); 3808 if (bp != null) { 3809 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) { 3810 return bp; 3811 } 3812 throw new SecurityException("Calling uid " 3813 + Binder.getCallingUid() 3814 + " is not allowed to add to permission tree " 3815 + bp.name + " owned by uid " + bp.uid); 3816 } 3817 } 3818 throw new SecurityException("No permission tree found for " + permName); 3819 } 3820 3821 static boolean compareStrings(CharSequence s1, CharSequence s2) { 3822 if (s1 == null) { 3823 return s2 == null; 3824 } 3825 if (s2 == null) { 3826 return false; 3827 } 3828 if (s1.getClass() != s2.getClass()) { 3829 return false; 3830 } 3831 return s1.equals(s2); 3832 } 3833 3834 static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) { 3835 if (pi1.icon != pi2.icon) return false; 3836 if (pi1.logo != pi2.logo) return false; 3837 if (pi1.protectionLevel != pi2.protectionLevel) return false; 3838 if (!compareStrings(pi1.name, pi2.name)) return false; 3839 if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false; 3840 // We'll take care of setting this one. 3841 if (!compareStrings(pi1.packageName, pi2.packageName)) return false; 3842 // These are not currently stored in settings. 3843 //if (!compareStrings(pi1.group, pi2.group)) return false; 3844 //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false; 3845 //if (pi1.labelRes != pi2.labelRes) return false; 3846 //if (pi1.descriptionRes != pi2.descriptionRes) return false; 3847 return true; 3848 } 3849 3850 int permissionInfoFootprint(PermissionInfo info) { 3851 int size = info.name.length(); 3852 if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length(); 3853 if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length(); 3854 return size; 3855 } 3856 3857 int calculateCurrentPermissionFootprintLocked(BasePermission tree) { 3858 int size = 0; 3859 for (BasePermission perm : mSettings.mPermissions.values()) { 3860 if (perm.uid == tree.uid) { 3861 size += perm.name.length() + permissionInfoFootprint(perm.perm.info); 3862 } 3863 } 3864 return size; 3865 } 3866 3867 void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) { 3868 // We calculate the max size of permissions defined by this uid and throw 3869 // if that plus the size of 'info' would exceed our stated maximum. 3870 if (tree.uid != Process.SYSTEM_UID) { 3871 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree); 3872 if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) { 3873 throw new SecurityException("Permission tree size cap exceeded"); 3874 } 3875 } 3876 } 3877 3878 boolean addPermissionLocked(PermissionInfo info, boolean async) { 3879 if (info.labelRes == 0 && info.nonLocalizedLabel == null) { 3880 throw new SecurityException("Label must be specified in permission"); 3881 } 3882 BasePermission tree = checkPermissionTreeLP(info.name); 3883 BasePermission bp = mSettings.mPermissions.get(info.name); 3884 boolean added = bp == null; 3885 boolean changed = true; 3886 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel); 3887 if (added) { 3888 enforcePermissionCapLocked(info, tree); 3889 bp = new BasePermission(info.name, tree.sourcePackage, 3890 BasePermission.TYPE_DYNAMIC); 3891 } else if (bp.type != BasePermission.TYPE_DYNAMIC) { 3892 throw new SecurityException( 3893 "Not allowed to modify non-dynamic permission " 3894 + info.name); 3895 } else { 3896 if (bp.protectionLevel == fixedLevel 3897 && bp.perm.owner.equals(tree.perm.owner) 3898 && bp.uid == tree.uid 3899 && comparePermissionInfos(bp.perm.info, info)) { 3900 changed = false; 3901 } 3902 } 3903 bp.protectionLevel = fixedLevel; 3904 info = new PermissionInfo(info); 3905 info.protectionLevel = fixedLevel; 3906 bp.perm = new PackageParser.Permission(tree.perm.owner, info); 3907 bp.perm.info.packageName = tree.perm.info.packageName; 3908 bp.uid = tree.uid; 3909 if (added) { 3910 mSettings.mPermissions.put(info.name, bp); 3911 } 3912 if (changed) { 3913 if (!async) { 3914 mSettings.writeLPr(); 3915 } else { 3916 scheduleWriteSettingsLocked(); 3917 } 3918 } 3919 return added; 3920 } 3921 3922 @Override 3923 public boolean addPermission(PermissionInfo info) { 3924 synchronized (mPackages) { 3925 return addPermissionLocked(info, false); 3926 } 3927 } 3928 3929 @Override 3930 public boolean addPermissionAsync(PermissionInfo info) { 3931 synchronized (mPackages) { 3932 return addPermissionLocked(info, true); 3933 } 3934 } 3935 3936 @Override 3937 public void removePermission(String name) { 3938 synchronized (mPackages) { 3939 checkPermissionTreeLP(name); 3940 BasePermission bp = mSettings.mPermissions.get(name); 3941 if (bp != null) { 3942 if (bp.type != BasePermission.TYPE_DYNAMIC) { 3943 throw new SecurityException( 3944 "Not allowed to modify non-dynamic permission " 3945 + name); 3946 } 3947 mSettings.mPermissions.remove(name); 3948 mSettings.writeLPr(); 3949 } 3950 } 3951 } 3952 3953 private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg, 3954 BasePermission bp) { 3955 int index = pkg.requestedPermissions.indexOf(bp.name); 3956 if (index == -1) { 3957 throw new SecurityException("Package " + pkg.packageName 3958 + " has not requested permission " + bp.name); 3959 } 3960 if (!bp.isRuntime() && !bp.isDevelopment()) { 3961 throw new SecurityException("Permission " + bp.name 3962 + " is not a changeable permission type"); 3963 } 3964 } 3965 3966 @Override 3967 public void grantRuntimePermission(String packageName, String name, final int userId) { 3968 if (!sUserManager.exists(userId)) { 3969 Log.e(TAG, "No such user:" + userId); 3970 return; 3971 } 3972 3973 mContext.enforceCallingOrSelfPermission( 3974 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 3975 "grantRuntimePermission"); 3976 3977 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3978 true /* requireFullPermission */, true /* checkShell */, 3979 "grantRuntimePermission"); 3980 3981 final int uid; 3982 final SettingBase sb; 3983 3984 synchronized (mPackages) { 3985 final PackageParser.Package pkg = mPackages.get(packageName); 3986 if (pkg == null) { 3987 throw new IllegalArgumentException("Unknown package: " + packageName); 3988 } 3989 3990 final BasePermission bp = mSettings.mPermissions.get(name); 3991 if (bp == null) { 3992 throw new IllegalArgumentException("Unknown permission: " + name); 3993 } 3994 3995 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp); 3996 3997 // If a permission review is required for legacy apps we represent 3998 // their permissions as always granted runtime ones since we need 3999 // to keep the review required permission flag per user while an 4000 // install permission's state is shared across all users. 4001 if ((mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED) 4002 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M 4003 && bp.isRuntime()) { 4004 return; 4005 } 4006 4007 uid = UserHandle.getUid(userId, pkg.applicationInfo.uid); 4008 sb = (SettingBase) pkg.mExtras; 4009 if (sb == null) { 4010 throw new IllegalArgumentException("Unknown package: " + packageName); 4011 } 4012 4013 final PermissionsState permissionsState = sb.getPermissionsState(); 4014 4015 final int flags = permissionsState.getPermissionFlags(name, userId); 4016 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 4017 throw new SecurityException("Cannot grant system fixed permission " 4018 + name + " for package " + packageName); 4019 } 4020 4021 if (bp.isDevelopment()) { 4022 // Development permissions must be handled specially, since they are not 4023 // normal runtime permissions. For now they apply to all users. 4024 if (permissionsState.grantInstallPermission(bp) != 4025 PermissionsState.PERMISSION_OPERATION_FAILURE) { 4026 scheduleWriteSettingsLocked(); 4027 } 4028 return; 4029 } 4030 4031 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 4032 Slog.w(TAG, "Cannot grant runtime permission to a legacy app"); 4033 return; 4034 } 4035 4036 final int result = permissionsState.grantRuntimePermission(bp, userId); 4037 switch (result) { 4038 case PermissionsState.PERMISSION_OPERATION_FAILURE: { 4039 return; 4040 } 4041 4042 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 4043 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); 4044 mHandler.post(new Runnable() { 4045 @Override 4046 public void run() { 4047 killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED); 4048 } 4049 }); 4050 } 4051 break; 4052 } 4053 4054 mOnPermissionChangeListeners.onPermissionsChanged(uid); 4055 4056 // Not critical if that is lost - app has to request again. 4057 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 4058 } 4059 4060 // Only need to do this if user is initialized. Otherwise it's a new user 4061 // and there are no processes running as the user yet and there's no need 4062 // to make an expensive call to remount processes for the changed permissions. 4063 if (READ_EXTERNAL_STORAGE.equals(name) 4064 || WRITE_EXTERNAL_STORAGE.equals(name)) { 4065 final long token = Binder.clearCallingIdentity(); 4066 try { 4067 if (sUserManager.isInitialized(userId)) { 4068 MountServiceInternal mountServiceInternal = LocalServices.getService( 4069 MountServiceInternal.class); 4070 mountServiceInternal.onExternalStoragePolicyChanged(uid, packageName); 4071 } 4072 } finally { 4073 Binder.restoreCallingIdentity(token); 4074 } 4075 } 4076 } 4077 4078 @Override 4079 public void revokeRuntimePermission(String packageName, String name, int userId) { 4080 if (!sUserManager.exists(userId)) { 4081 Log.e(TAG, "No such user:" + userId); 4082 return; 4083 } 4084 4085 mContext.enforceCallingOrSelfPermission( 4086 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 4087 "revokeRuntimePermission"); 4088 4089 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4090 true /* requireFullPermission */, true /* checkShell */, 4091 "revokeRuntimePermission"); 4092 4093 final int appId; 4094 4095 synchronized (mPackages) { 4096 final PackageParser.Package pkg = mPackages.get(packageName); 4097 if (pkg == null) { 4098 throw new IllegalArgumentException("Unknown package: " + packageName); 4099 } 4100 4101 final BasePermission bp = mSettings.mPermissions.get(name); 4102 if (bp == null) { 4103 throw new IllegalArgumentException("Unknown permission: " + name); 4104 } 4105 4106 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp); 4107 4108 // If a permission review is required for legacy apps we represent 4109 // their permissions as always granted runtime ones since we need 4110 // to keep the review required permission flag per user while an 4111 // install permission's state is shared across all users. 4112 if ((mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED) 4113 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M 4114 && bp.isRuntime()) { 4115 return; 4116 } 4117 4118 SettingBase sb = (SettingBase) pkg.mExtras; 4119 if (sb == null) { 4120 throw new IllegalArgumentException("Unknown package: " + packageName); 4121 } 4122 4123 final PermissionsState permissionsState = sb.getPermissionsState(); 4124 4125 final int flags = permissionsState.getPermissionFlags(name, userId); 4126 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 4127 throw new SecurityException("Cannot revoke system fixed permission " 4128 + name + " for package " + packageName); 4129 } 4130 4131 if (bp.isDevelopment()) { 4132 // Development permissions must be handled specially, since they are not 4133 // normal runtime permissions. For now they apply to all users. 4134 if (permissionsState.revokeInstallPermission(bp) != 4135 PermissionsState.PERMISSION_OPERATION_FAILURE) { 4136 scheduleWriteSettingsLocked(); 4137 } 4138 return; 4139 } 4140 4141 if (permissionsState.revokeRuntimePermission(bp, userId) == 4142 PermissionsState.PERMISSION_OPERATION_FAILURE) { 4143 return; 4144 } 4145 4146 mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid); 4147 4148 // Critical, after this call app should never have the permission. 4149 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 4150 4151 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 4152 } 4153 4154 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED); 4155 } 4156 4157 @Override 4158 public void resetRuntimePermissions() { 4159 mContext.enforceCallingOrSelfPermission( 4160 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 4161 "revokeRuntimePermission"); 4162 4163 int callingUid = Binder.getCallingUid(); 4164 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 4165 mContext.enforceCallingOrSelfPermission( 4166 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 4167 "resetRuntimePermissions"); 4168 } 4169 4170 synchronized (mPackages) { 4171 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL); 4172 for (int userId : UserManagerService.getInstance().getUserIds()) { 4173 final int packageCount = mPackages.size(); 4174 for (int i = 0; i < packageCount; i++) { 4175 PackageParser.Package pkg = mPackages.valueAt(i); 4176 if (!(pkg.mExtras instanceof PackageSetting)) { 4177 continue; 4178 } 4179 PackageSetting ps = (PackageSetting) pkg.mExtras; 4180 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 4181 } 4182 } 4183 } 4184 } 4185 4186 @Override 4187 public int getPermissionFlags(String name, String packageName, int userId) { 4188 if (!sUserManager.exists(userId)) { 4189 return 0; 4190 } 4191 4192 enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags"); 4193 4194 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4195 true /* requireFullPermission */, false /* checkShell */, 4196 "getPermissionFlags"); 4197 4198 synchronized (mPackages) { 4199 final PackageParser.Package pkg = mPackages.get(packageName); 4200 if (pkg == null) { 4201 return 0; 4202 } 4203 4204 final BasePermission bp = mSettings.mPermissions.get(name); 4205 if (bp == null) { 4206 return 0; 4207 } 4208 4209 SettingBase sb = (SettingBase) pkg.mExtras; 4210 if (sb == null) { 4211 return 0; 4212 } 4213 4214 PermissionsState permissionsState = sb.getPermissionsState(); 4215 return permissionsState.getPermissionFlags(name, userId); 4216 } 4217 } 4218 4219 @Override 4220 public void updatePermissionFlags(String name, String packageName, int flagMask, 4221 int flagValues, int userId) { 4222 if (!sUserManager.exists(userId)) { 4223 return; 4224 } 4225 4226 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags"); 4227 4228 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4229 true /* requireFullPermission */, true /* checkShell */, 4230 "updatePermissionFlags"); 4231 4232 // Only the system can change these flags and nothing else. 4233 if (getCallingUid() != Process.SYSTEM_UID) { 4234 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4235 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4236 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 4237 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 4238 flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 4239 } 4240 4241 synchronized (mPackages) { 4242 final PackageParser.Package pkg = mPackages.get(packageName); 4243 if (pkg == null) { 4244 throw new IllegalArgumentException("Unknown package: " + packageName); 4245 } 4246 4247 final BasePermission bp = mSettings.mPermissions.get(name); 4248 if (bp == null) { 4249 throw new IllegalArgumentException("Unknown permission: " + name); 4250 } 4251 4252 SettingBase sb = (SettingBase) pkg.mExtras; 4253 if (sb == null) { 4254 throw new IllegalArgumentException("Unknown package: " + packageName); 4255 } 4256 4257 PermissionsState permissionsState = sb.getPermissionsState(); 4258 4259 boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null; 4260 4261 if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) { 4262 // Install and runtime permissions are stored in different places, 4263 // so figure out what permission changed and persist the change. 4264 if (permissionsState.getInstallPermissionState(name) != null) { 4265 scheduleWriteSettingsLocked(); 4266 } else if (permissionsState.getRuntimePermissionState(name, userId) != null 4267 || hadState) { 4268 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 4269 } 4270 } 4271 } 4272 } 4273 4274 /** 4275 * Update the permission flags for all packages and runtime permissions of a user in order 4276 * to allow device or profile owner to remove POLICY_FIXED. 4277 */ 4278 @Override 4279 public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) { 4280 if (!sUserManager.exists(userId)) { 4281 return; 4282 } 4283 4284 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps"); 4285 4286 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4287 true /* requireFullPermission */, true /* checkShell */, 4288 "updatePermissionFlagsForAllApps"); 4289 4290 // Only the system can change system fixed flags. 4291 if (getCallingUid() != Process.SYSTEM_UID) { 4292 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4293 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4294 } 4295 4296 synchronized (mPackages) { 4297 boolean changed = false; 4298 final int packageCount = mPackages.size(); 4299 for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) { 4300 final PackageParser.Package pkg = mPackages.valueAt(pkgIndex); 4301 SettingBase sb = (SettingBase) pkg.mExtras; 4302 if (sb == null) { 4303 continue; 4304 } 4305 PermissionsState permissionsState = sb.getPermissionsState(); 4306 changed |= permissionsState.updatePermissionFlagsForAllPermissions( 4307 userId, flagMask, flagValues); 4308 } 4309 if (changed) { 4310 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 4311 } 4312 } 4313 } 4314 4315 private void enforceGrantRevokeRuntimePermissionPermissions(String message) { 4316 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS) 4317 != PackageManager.PERMISSION_GRANTED 4318 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) 4319 != PackageManager.PERMISSION_GRANTED) { 4320 throw new SecurityException(message + " requires " 4321 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or " 4322 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS); 4323 } 4324 } 4325 4326 @Override 4327 public boolean shouldShowRequestPermissionRationale(String permissionName, 4328 String packageName, int userId) { 4329 if (UserHandle.getCallingUserId() != userId) { 4330 mContext.enforceCallingPermission( 4331 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 4332 "canShowRequestPermissionRationale for user " + userId); 4333 } 4334 4335 final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId); 4336 if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) { 4337 return false; 4338 } 4339 4340 if (checkPermission(permissionName, packageName, userId) 4341 == PackageManager.PERMISSION_GRANTED) { 4342 return false; 4343 } 4344 4345 final int flags; 4346 4347 final long identity = Binder.clearCallingIdentity(); 4348 try { 4349 flags = getPermissionFlags(permissionName, 4350 packageName, userId); 4351 } finally { 4352 Binder.restoreCallingIdentity(identity); 4353 } 4354 4355 final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 4356 | PackageManager.FLAG_PERMISSION_POLICY_FIXED 4357 | PackageManager.FLAG_PERMISSION_USER_FIXED; 4358 4359 if ((flags & fixedFlags) != 0) { 4360 return false; 4361 } 4362 4363 return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0; 4364 } 4365 4366 @Override 4367 public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 4368 mContext.enforceCallingOrSelfPermission( 4369 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS, 4370 "addOnPermissionsChangeListener"); 4371 4372 synchronized (mPackages) { 4373 mOnPermissionChangeListeners.addListenerLocked(listener); 4374 } 4375 } 4376 4377 @Override 4378 public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 4379 synchronized (mPackages) { 4380 mOnPermissionChangeListeners.removeListenerLocked(listener); 4381 } 4382 } 4383 4384 @Override 4385 public boolean isProtectedBroadcast(String actionName) { 4386 synchronized (mPackages) { 4387 if (mProtectedBroadcasts.contains(actionName)) { 4388 return true; 4389 } else if (actionName != null) { 4390 // TODO: remove these terrible hacks 4391 if (actionName.startsWith("android.net.netmon.lingerExpired") 4392 || actionName.startsWith("com.android.server.sip.SipWakeupTimer") 4393 || actionName.startsWith("com.android.internal.telephony.data-reconnect") 4394 || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) { 4395 return true; 4396 } 4397 } 4398 } 4399 return false; 4400 } 4401 4402 @Override 4403 public int checkSignatures(String pkg1, String pkg2) { 4404 synchronized (mPackages) { 4405 final PackageParser.Package p1 = mPackages.get(pkg1); 4406 final PackageParser.Package p2 = mPackages.get(pkg2); 4407 if (p1 == null || p1.mExtras == null 4408 || p2 == null || p2.mExtras == null) { 4409 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4410 } 4411 return compareSignatures(p1.mSignatures, p2.mSignatures); 4412 } 4413 } 4414 4415 @Override 4416 public int checkUidSignatures(int uid1, int uid2) { 4417 // Map to base uids. 4418 uid1 = UserHandle.getAppId(uid1); 4419 uid2 = UserHandle.getAppId(uid2); 4420 // reader 4421 synchronized (mPackages) { 4422 Signature[] s1; 4423 Signature[] s2; 4424 Object obj = mSettings.getUserIdLPr(uid1); 4425 if (obj != null) { 4426 if (obj instanceof SharedUserSetting) { 4427 s1 = ((SharedUserSetting)obj).signatures.mSignatures; 4428 } else if (obj instanceof PackageSetting) { 4429 s1 = ((PackageSetting)obj).signatures.mSignatures; 4430 } else { 4431 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4432 } 4433 } else { 4434 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4435 } 4436 obj = mSettings.getUserIdLPr(uid2); 4437 if (obj != null) { 4438 if (obj instanceof SharedUserSetting) { 4439 s2 = ((SharedUserSetting)obj).signatures.mSignatures; 4440 } else if (obj instanceof PackageSetting) { 4441 s2 = ((PackageSetting)obj).signatures.mSignatures; 4442 } else { 4443 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4444 } 4445 } else { 4446 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4447 } 4448 return compareSignatures(s1, s2); 4449 } 4450 } 4451 4452 /** 4453 * This method should typically only be used when granting or revoking 4454 * permissions, since the app may immediately restart after this call. 4455 * <p> 4456 * If you're doing surgery on app code/data, use {@link PackageFreezer} to 4457 * guard your work against the app being relaunched. 4458 */ 4459 private void killUid(int appId, int userId, String reason) { 4460 final long identity = Binder.clearCallingIdentity(); 4461 try { 4462 IActivityManager am = ActivityManagerNative.getDefault(); 4463 if (am != null) { 4464 try { 4465 am.killUid(appId, userId, reason); 4466 } catch (RemoteException e) { 4467 /* ignore - same process */ 4468 } 4469 } 4470 } finally { 4471 Binder.restoreCallingIdentity(identity); 4472 } 4473 } 4474 4475 /** 4476 * Compares two sets of signatures. Returns: 4477 * <br /> 4478 * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null, 4479 * <br /> 4480 * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null, 4481 * <br /> 4482 * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null, 4483 * <br /> 4484 * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical, 4485 * <br /> 4486 * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ. 4487 */ 4488 static int compareSignatures(Signature[] s1, Signature[] s2) { 4489 if (s1 == null) { 4490 return s2 == null 4491 ? PackageManager.SIGNATURE_NEITHER_SIGNED 4492 : PackageManager.SIGNATURE_FIRST_NOT_SIGNED; 4493 } 4494 4495 if (s2 == null) { 4496 return PackageManager.SIGNATURE_SECOND_NOT_SIGNED; 4497 } 4498 4499 if (s1.length != s2.length) { 4500 return PackageManager.SIGNATURE_NO_MATCH; 4501 } 4502 4503 // Since both signature sets are of size 1, we can compare without HashSets. 4504 if (s1.length == 1) { 4505 return s1[0].equals(s2[0]) ? 4506 PackageManager.SIGNATURE_MATCH : 4507 PackageManager.SIGNATURE_NO_MATCH; 4508 } 4509 4510 ArraySet<Signature> set1 = new ArraySet<Signature>(); 4511 for (Signature sig : s1) { 4512 set1.add(sig); 4513 } 4514 ArraySet<Signature> set2 = new ArraySet<Signature>(); 4515 for (Signature sig : s2) { 4516 set2.add(sig); 4517 } 4518 // Make sure s2 contains all signatures in s1. 4519 if (set1.equals(set2)) { 4520 return PackageManager.SIGNATURE_MATCH; 4521 } 4522 return PackageManager.SIGNATURE_NO_MATCH; 4523 } 4524 4525 /** 4526 * If the database version for this type of package (internal storage or 4527 * external storage) is less than the version where package signatures 4528 * were updated, return true. 4529 */ 4530 private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 4531 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); 4532 return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY; 4533 } 4534 4535 /** 4536 * Used for backward compatibility to make sure any packages with 4537 * certificate chains get upgraded to the new style. {@code existingSigs} 4538 * will be in the old format (since they were stored on disk from before the 4539 * system upgrade) and {@code scannedSigs} will be in the newer format. 4540 */ 4541 private int compareSignaturesCompat(PackageSignatures existingSigs, 4542 PackageParser.Package scannedPkg) { 4543 if (!isCompatSignatureUpdateNeeded(scannedPkg)) { 4544 return PackageManager.SIGNATURE_NO_MATCH; 4545 } 4546 4547 ArraySet<Signature> existingSet = new ArraySet<Signature>(); 4548 for (Signature sig : existingSigs.mSignatures) { 4549 existingSet.add(sig); 4550 } 4551 ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>(); 4552 for (Signature sig : scannedPkg.mSignatures) { 4553 try { 4554 Signature[] chainSignatures = sig.getChainSignatures(); 4555 for (Signature chainSig : chainSignatures) { 4556 scannedCompatSet.add(chainSig); 4557 } 4558 } catch (CertificateEncodingException e) { 4559 scannedCompatSet.add(sig); 4560 } 4561 } 4562 /* 4563 * Make sure the expanded scanned set contains all signatures in the 4564 * existing one. 4565 */ 4566 if (scannedCompatSet.equals(existingSet)) { 4567 // Migrate the old signatures to the new scheme. 4568 existingSigs.assignSignatures(scannedPkg.mSignatures); 4569 // The new KeySets will be re-added later in the scanning process. 4570 synchronized (mPackages) { 4571 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName); 4572 } 4573 return PackageManager.SIGNATURE_MATCH; 4574 } 4575 return PackageManager.SIGNATURE_NO_MATCH; 4576 } 4577 4578 private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 4579 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); 4580 return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER; 4581 } 4582 4583 private int compareSignaturesRecover(PackageSignatures existingSigs, 4584 PackageParser.Package scannedPkg) { 4585 if (!isRecoverSignatureUpdateNeeded(scannedPkg)) { 4586 return PackageManager.SIGNATURE_NO_MATCH; 4587 } 4588 4589 String msg = null; 4590 try { 4591 if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) { 4592 logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for " 4593 + scannedPkg.packageName); 4594 return PackageManager.SIGNATURE_MATCH; 4595 } 4596 } catch (CertificateException e) { 4597 msg = e.getMessage(); 4598 } 4599 4600 logCriticalInfo(Log.INFO, 4601 "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg); 4602 return PackageManager.SIGNATURE_NO_MATCH; 4603 } 4604 4605 @Override 4606 public List<String> getAllPackages() { 4607 synchronized (mPackages) { 4608 return new ArrayList<String>(mPackages.keySet()); 4609 } 4610 } 4611 4612 @Override 4613 public String[] getPackagesForUid(int uid) { 4614 uid = UserHandle.getAppId(uid); 4615 // reader 4616 synchronized (mPackages) { 4617 Object obj = mSettings.getUserIdLPr(uid); 4618 if (obj instanceof SharedUserSetting) { 4619 final SharedUserSetting sus = (SharedUserSetting) obj; 4620 final int N = sus.packages.size(); 4621 final String[] res = new String[N]; 4622 for (int i = 0; i < N; i++) { 4623 res[i] = sus.packages.valueAt(i).name; 4624 } 4625 return res; 4626 } else if (obj instanceof PackageSetting) { 4627 final PackageSetting ps = (PackageSetting) obj; 4628 return new String[] { ps.name }; 4629 } 4630 } 4631 return null; 4632 } 4633 4634 @Override 4635 public String getNameForUid(int uid) { 4636 // reader 4637 synchronized (mPackages) { 4638 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4639 if (obj instanceof SharedUserSetting) { 4640 final SharedUserSetting sus = (SharedUserSetting) obj; 4641 return sus.name + ":" + sus.userId; 4642 } else if (obj instanceof PackageSetting) { 4643 final PackageSetting ps = (PackageSetting) obj; 4644 return ps.name; 4645 } 4646 } 4647 return null; 4648 } 4649 4650 @Override 4651 public int getUidForSharedUser(String sharedUserName) { 4652 if(sharedUserName == null) { 4653 return -1; 4654 } 4655 // reader 4656 synchronized (mPackages) { 4657 final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false); 4658 if (suid == null) { 4659 return -1; 4660 } 4661 return suid.userId; 4662 } 4663 } 4664 4665 @Override 4666 public int getFlagsForUid(int uid) { 4667 synchronized (mPackages) { 4668 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4669 if (obj instanceof SharedUserSetting) { 4670 final SharedUserSetting sus = (SharedUserSetting) obj; 4671 return sus.pkgFlags; 4672 } else if (obj instanceof PackageSetting) { 4673 final PackageSetting ps = (PackageSetting) obj; 4674 return ps.pkgFlags; 4675 } 4676 } 4677 return 0; 4678 } 4679 4680 @Override 4681 public int getPrivateFlagsForUid(int uid) { 4682 synchronized (mPackages) { 4683 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4684 if (obj instanceof SharedUserSetting) { 4685 final SharedUserSetting sus = (SharedUserSetting) obj; 4686 return sus.pkgPrivateFlags; 4687 } else if (obj instanceof PackageSetting) { 4688 final PackageSetting ps = (PackageSetting) obj; 4689 return ps.pkgPrivateFlags; 4690 } 4691 } 4692 return 0; 4693 } 4694 4695 @Override 4696 public boolean isUidPrivileged(int uid) { 4697 uid = UserHandle.getAppId(uid); 4698 // reader 4699 synchronized (mPackages) { 4700 Object obj = mSettings.getUserIdLPr(uid); 4701 if (obj instanceof SharedUserSetting) { 4702 final SharedUserSetting sus = (SharedUserSetting) obj; 4703 final Iterator<PackageSetting> it = sus.packages.iterator(); 4704 while (it.hasNext()) { 4705 if (it.next().isPrivileged()) { 4706 return true; 4707 } 4708 } 4709 } else if (obj instanceof PackageSetting) { 4710 final PackageSetting ps = (PackageSetting) obj; 4711 return ps.isPrivileged(); 4712 } 4713 } 4714 return false; 4715 } 4716 4717 @Override 4718 public String[] getAppOpPermissionPackages(String permissionName) { 4719 synchronized (mPackages) { 4720 ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName); 4721 if (pkgs == null) { 4722 return null; 4723 } 4724 return pkgs.toArray(new String[pkgs.size()]); 4725 } 4726 } 4727 4728 @Override 4729 public ResolveInfo resolveIntent(Intent intent, String resolvedType, 4730 int flags, int userId) { 4731 try { 4732 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent"); 4733 4734 if (!sUserManager.exists(userId)) return null; 4735 flags = updateFlagsForResolve(flags, userId, intent); 4736 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4737 false /*requireFullPermission*/, false /*checkShell*/, "resolve intent"); 4738 4739 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities"); 4740 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, 4741 flags, userId); 4742 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 4743 4744 final ResolveInfo bestChoice = 4745 chooseBestActivity(intent, resolvedType, flags, query, userId); 4746 return bestChoice; 4747 } finally { 4748 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 4749 } 4750 } 4751 4752 @Override 4753 public void setLastChosenActivity(Intent intent, String resolvedType, int flags, 4754 IntentFilter filter, int match, ComponentName activity) { 4755 final int userId = UserHandle.getCallingUserId(); 4756 if (DEBUG_PREFERRED) { 4757 Log.v(TAG, "setLastChosenActivity intent=" + intent 4758 + " resolvedType=" + resolvedType 4759 + " flags=" + flags 4760 + " filter=" + filter 4761 + " match=" + match 4762 + " activity=" + activity); 4763 filter.dump(new PrintStreamPrinter(System.out), " "); 4764 } 4765 intent.setComponent(null); 4766 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags, 4767 userId); 4768 // Find any earlier preferred or last chosen entries and nuke them 4769 findPreferredActivity(intent, resolvedType, 4770 flags, query, 0, false, true, false, userId); 4771 // Add the new activity as the last chosen for this filter 4772 addPreferredActivityInternal(filter, match, null, activity, false, userId, 4773 "Setting last chosen"); 4774 } 4775 4776 @Override 4777 public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) { 4778 final int userId = UserHandle.getCallingUserId(); 4779 if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent); 4780 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags, 4781 userId); 4782 return findPreferredActivity(intent, resolvedType, flags, query, 0, 4783 false, false, false, userId); 4784 } 4785 4786 private boolean isEphemeralAllowed( 4787 Intent intent, List<ResolveInfo> resolvedActivities, int userId, 4788 boolean skipPackageCheck) { 4789 // Short circuit and return early if possible. 4790 if (DISABLE_EPHEMERAL_APPS) { 4791 return false; 4792 } 4793 final int callingUser = UserHandle.getCallingUserId(); 4794 if (callingUser != UserHandle.USER_SYSTEM) { 4795 return false; 4796 } 4797 if (mEphemeralResolverConnection == null) { 4798 return false; 4799 } 4800 if (intent.getComponent() != null) { 4801 return false; 4802 } 4803 if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) { 4804 return false; 4805 } 4806 if (!skipPackageCheck && intent.getPackage() != null) { 4807 return false; 4808 } 4809 final boolean isWebUri = hasWebURI(intent); 4810 if (!isWebUri || intent.getData().getHost() == null) { 4811 return false; 4812 } 4813 // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution. 4814 synchronized (mPackages) { 4815 final int count = (resolvedActivities == null ? 0 : resolvedActivities.size()); 4816 for (int n = 0; n < count; n++) { 4817 ResolveInfo info = resolvedActivities.get(n); 4818 String packageName = info.activityInfo.packageName; 4819 PackageSetting ps = mSettings.mPackages.get(packageName); 4820 if (ps != null) { 4821 // Try to get the status from User settings first 4822 long packedStatus = getDomainVerificationStatusLPr(ps, userId); 4823 int status = (int) (packedStatus >> 32); 4824 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS 4825 || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) { 4826 if (DEBUG_EPHEMERAL) { 4827 Slog.v(TAG, "DENY ephemeral apps;" 4828 + " pkg: " + packageName + ", status: " + status); 4829 } 4830 return false; 4831 } 4832 } 4833 } 4834 } 4835 // We've exhausted all ways to deny ephemeral application; let the system look for them. 4836 return true; 4837 } 4838 4839 private static EphemeralResolveInfo getEphemeralResolveInfo( 4840 Context context, EphemeralResolverConnection resolverConnection, Intent intent, 4841 String resolvedType, int userId, String packageName) { 4842 final int ephemeralPrefixMask = Global.getInt(context.getContentResolver(), 4843 Global.EPHEMERAL_HASH_PREFIX_MASK, DEFAULT_EPHEMERAL_HASH_PREFIX_MASK); 4844 final int ephemeralPrefixCount = Global.getInt(context.getContentResolver(), 4845 Global.EPHEMERAL_HASH_PREFIX_COUNT, DEFAULT_EPHEMERAL_HASH_PREFIX_COUNT); 4846 final EphemeralDigest digest = new EphemeralDigest(intent.getData(), ephemeralPrefixMask, 4847 ephemeralPrefixCount); 4848 final int[] shaPrefix = digest.getDigestPrefix(); 4849 final byte[][] digestBytes = digest.getDigestBytes(); 4850 final List<EphemeralResolveInfo> ephemeralResolveInfoList = 4851 resolverConnection.getEphemeralResolveInfoList(shaPrefix, ephemeralPrefixMask); 4852 if (ephemeralResolveInfoList == null || ephemeralResolveInfoList.size() == 0) { 4853 // No hash prefix match; there are no ephemeral apps for this domain. 4854 return null; 4855 } 4856 4857 // Go in reverse order so we match the narrowest scope first. 4858 for (int i = shaPrefix.length - 1; i >= 0 ; --i) { 4859 for (EphemeralResolveInfo ephemeralApplication : ephemeralResolveInfoList) { 4860 if (!Arrays.equals(digestBytes[i], ephemeralApplication.getDigestBytes())) { 4861 continue; 4862 } 4863 final List<IntentFilter> filters = ephemeralApplication.getFilters(); 4864 // No filters; this should never happen. 4865 if (filters.isEmpty()) { 4866 continue; 4867 } 4868 if (packageName != null 4869 && !packageName.equals(ephemeralApplication.getPackageName())) { 4870 continue; 4871 } 4872 // We have a domain match; resolve the filters to see if anything matches. 4873 final EphemeralIntentResolver ephemeralResolver = new EphemeralIntentResolver(); 4874 for (int j = filters.size() - 1; j >= 0; --j) { 4875 final EphemeralResolveIntentInfo intentInfo = 4876 new EphemeralResolveIntentInfo(filters.get(j), ephemeralApplication); 4877 ephemeralResolver.addFilter(intentInfo); 4878 } 4879 List<EphemeralResolveInfo> matchedResolveInfoList = ephemeralResolver.queryIntent( 4880 intent, resolvedType, false /*defaultOnly*/, userId); 4881 if (!matchedResolveInfoList.isEmpty()) { 4882 return matchedResolveInfoList.get(0); 4883 } 4884 } 4885 } 4886 // Hash or filter mis-match; no ephemeral apps for this domain. 4887 return null; 4888 } 4889 4890 private ResolveInfo chooseBestActivity(Intent intent, String resolvedType, 4891 int flags, List<ResolveInfo> query, int userId) { 4892 if (query != null) { 4893 final int N = query.size(); 4894 if (N == 1) { 4895 return query.get(0); 4896 } else if (N > 1) { 4897 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 4898 // If there is more than one activity with the same priority, 4899 // then let the user decide between them. 4900 ResolveInfo r0 = query.get(0); 4901 ResolveInfo r1 = query.get(1); 4902 if (DEBUG_INTENT_MATCHING || debug) { 4903 Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs " 4904 + r1.activityInfo.name + "=" + r1.priority); 4905 } 4906 // If the first activity has a higher priority, or a different 4907 // default, then it is always desirable to pick it. 4908 if (r0.priority != r1.priority 4909 || r0.preferredOrder != r1.preferredOrder 4910 || r0.isDefault != r1.isDefault) { 4911 return query.get(0); 4912 } 4913 // If we have saved a preference for a preferred activity for 4914 // this Intent, use that. 4915 ResolveInfo ri = findPreferredActivity(intent, resolvedType, 4916 flags, query, r0.priority, true, false, debug, userId); 4917 if (ri != null) { 4918 return ri; 4919 } 4920 ri = new ResolveInfo(mResolveInfo); 4921 ri.activityInfo = new ActivityInfo(ri.activityInfo); 4922 ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction()); 4923 // If all of the options come from the same package, show the application's 4924 // label and icon instead of the generic resolver's. 4925 // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here 4926 // and then throw away the ResolveInfo itself, meaning that the caller loses 4927 // the resolvePackageName. Therefore the activityInfo.labelRes above provides 4928 // a fallback for this case; we only set the target package's resources on 4929 // the ResolveInfo, not the ActivityInfo. 4930 final String intentPackage = intent.getPackage(); 4931 if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) { 4932 final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo; 4933 ri.resolvePackageName = intentPackage; 4934 if (userNeedsBadging(userId)) { 4935 ri.noResourceId = true; 4936 } else { 4937 ri.icon = appi.icon; 4938 } 4939 ri.iconResourceId = appi.icon; 4940 ri.labelRes = appi.labelRes; 4941 } 4942 ri.activityInfo.applicationInfo = new ApplicationInfo( 4943 ri.activityInfo.applicationInfo); 4944 if (userId != 0) { 4945 ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId, 4946 UserHandle.getAppId(ri.activityInfo.applicationInfo.uid)); 4947 } 4948 // Make sure that the resolver is displayable in car mode 4949 if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle(); 4950 ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true); 4951 return ri; 4952 } 4953 } 4954 return null; 4955 } 4956 4957 /** 4958 * Return true if the given list is not empty and all of its contents have 4959 * an activityInfo with the given package name. 4960 */ 4961 private boolean allHavePackage(List<ResolveInfo> list, String packageName) { 4962 if (ArrayUtils.isEmpty(list)) { 4963 return false; 4964 } 4965 for (int i = 0, N = list.size(); i < N; i++) { 4966 final ResolveInfo ri = list.get(i); 4967 final ActivityInfo ai = ri != null ? ri.activityInfo : null; 4968 if (ai == null || !packageName.equals(ai.packageName)) { 4969 return false; 4970 } 4971 } 4972 return true; 4973 } 4974 4975 private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType, 4976 int flags, List<ResolveInfo> query, boolean debug, int userId) { 4977 final int N = query.size(); 4978 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 4979 .get(userId); 4980 // Get the list of persistent preferred activities that handle the intent 4981 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities..."); 4982 List<PersistentPreferredActivity> pprefs = ppir != null 4983 ? ppir.queryIntent(intent, resolvedType, 4984 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 4985 : null; 4986 if (pprefs != null && pprefs.size() > 0) { 4987 final int M = pprefs.size(); 4988 for (int i=0; i<M; i++) { 4989 final PersistentPreferredActivity ppa = pprefs.get(i); 4990 if (DEBUG_PREFERRED || debug) { 4991 Slog.v(TAG, "Checking PersistentPreferredActivity ds=" 4992 + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>") 4993 + "\n component=" + ppa.mComponent); 4994 ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4995 } 4996 final ActivityInfo ai = getActivityInfo(ppa.mComponent, 4997 flags | MATCH_DISABLED_COMPONENTS, userId); 4998 if (DEBUG_PREFERRED || debug) { 4999 Slog.v(TAG, "Found persistent preferred activity:"); 5000 if (ai != null) { 5001 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 5002 } else { 5003 Slog.v(TAG, " null"); 5004 } 5005 } 5006 if (ai == null) { 5007 // This previously registered persistent preferred activity 5008 // component is no longer known. Ignore it and do NOT remove it. 5009 continue; 5010 } 5011 for (int j=0; j<N; j++) { 5012 final ResolveInfo ri = query.get(j); 5013 if (!ri.activityInfo.applicationInfo.packageName 5014 .equals(ai.applicationInfo.packageName)) { 5015 continue; 5016 } 5017 if (!ri.activityInfo.name.equals(ai.name)) { 5018 continue; 5019 } 5020 // Found a persistent preference that can handle the intent. 5021 if (DEBUG_PREFERRED || debug) { 5022 Slog.v(TAG, "Returning persistent preferred activity: " + 5023 ri.activityInfo.packageName + "/" + ri.activityInfo.name); 5024 } 5025 return ri; 5026 } 5027 } 5028 } 5029 return null; 5030 } 5031 5032 // TODO: handle preferred activities missing while user has amnesia 5033 ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags, 5034 List<ResolveInfo> query, int priority, boolean always, 5035 boolean removeMatches, boolean debug, int userId) { 5036 if (!sUserManager.exists(userId)) return null; 5037 flags = updateFlagsForResolve(flags, userId, intent); 5038 // writer 5039 synchronized (mPackages) { 5040 if (intent.getSelector() != null) { 5041 intent = intent.getSelector(); 5042 } 5043 if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION); 5044 5045 // Try to find a matching persistent preferred activity. 5046 ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query, 5047 debug, userId); 5048 5049 // If a persistent preferred activity matched, use it. 5050 if (pri != null) { 5051 return pri; 5052 } 5053 5054 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 5055 // Get the list of preferred activities that handle the intent 5056 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities..."); 5057 List<PreferredActivity> prefs = pir != null 5058 ? pir.queryIntent(intent, resolvedType, 5059 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 5060 : null; 5061 if (prefs != null && prefs.size() > 0) { 5062 boolean changed = false; 5063 try { 5064 // First figure out how good the original match set is. 5065 // We will only allow preferred activities that came 5066 // from the same match quality. 5067 int match = 0; 5068 5069 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match..."); 5070 5071 final int N = query.size(); 5072 for (int j=0; j<N; j++) { 5073 final ResolveInfo ri = query.get(j); 5074 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo 5075 + ": 0x" + Integer.toHexString(match)); 5076 if (ri.match > match) { 5077 match = ri.match; 5078 } 5079 } 5080 5081 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x" 5082 + Integer.toHexString(match)); 5083 5084 match &= IntentFilter.MATCH_CATEGORY_MASK; 5085 final int M = prefs.size(); 5086 for (int i=0; i<M; i++) { 5087 final PreferredActivity pa = prefs.get(i); 5088 if (DEBUG_PREFERRED || debug) { 5089 Slog.v(TAG, "Checking PreferredActivity ds=" 5090 + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>") 5091 + "\n component=" + pa.mPref.mComponent); 5092 pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 5093 } 5094 if (pa.mPref.mMatch != match) { 5095 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match " 5096 + Integer.toHexString(pa.mPref.mMatch)); 5097 continue; 5098 } 5099 // If it's not an "always" type preferred activity and that's what we're 5100 // looking for, skip it. 5101 if (always && !pa.mPref.mAlways) { 5102 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry"); 5103 continue; 5104 } 5105 final ActivityInfo ai = getActivityInfo( 5106 pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS 5107 | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 5108 userId); 5109 if (DEBUG_PREFERRED || debug) { 5110 Slog.v(TAG, "Found preferred activity:"); 5111 if (ai != null) { 5112 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 5113 } else { 5114 Slog.v(TAG, " null"); 5115 } 5116 } 5117 if (ai == null) { 5118 // This previously registered preferred activity 5119 // component is no longer known. Most likely an update 5120 // to the app was installed and in the new version this 5121 // component no longer exists. Clean it up by removing 5122 // it from the preferred activities list, and skip it. 5123 Slog.w(TAG, "Removing dangling preferred activity: " 5124 + pa.mPref.mComponent); 5125 pir.removeFilter(pa); 5126 changed = true; 5127 continue; 5128 } 5129 for (int j=0; j<N; j++) { 5130 final ResolveInfo ri = query.get(j); 5131 if (!ri.activityInfo.applicationInfo.packageName 5132 .equals(ai.applicationInfo.packageName)) { 5133 continue; 5134 } 5135 if (!ri.activityInfo.name.equals(ai.name)) { 5136 continue; 5137 } 5138 5139 if (removeMatches) { 5140 pir.removeFilter(pa); 5141 changed = true; 5142 if (DEBUG_PREFERRED) { 5143 Slog.v(TAG, "Removing match " + pa.mPref.mComponent); 5144 } 5145 break; 5146 } 5147 5148 // Okay we found a previously set preferred or last chosen app. 5149 // If the result set is different from when this 5150 // was created, we need to clear it and re-ask the 5151 // user their preference, if we're looking for an "always" type entry. 5152 if (always && !pa.mPref.sameSet(query)) { 5153 Slog.i(TAG, "Result set changed, dropping preferred activity for " 5154 + intent + " type " + resolvedType); 5155 if (DEBUG_PREFERRED) { 5156 Slog.v(TAG, "Removing preferred activity since set changed " 5157 + pa.mPref.mComponent); 5158 } 5159 pir.removeFilter(pa); 5160 // Re-add the filter as a "last chosen" entry (!always) 5161 PreferredActivity lastChosen = new PreferredActivity( 5162 pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false); 5163 pir.addFilter(lastChosen); 5164 changed = true; 5165 return null; 5166 } 5167 5168 // Yay! Either the set matched or we're looking for the last chosen 5169 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: " 5170 + ri.activityInfo.packageName + "/" + ri.activityInfo.name); 5171 return ri; 5172 } 5173 } 5174 } finally { 5175 if (changed) { 5176 if (DEBUG_PREFERRED) { 5177 Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions"); 5178 } 5179 scheduleWritePackageRestrictionsLocked(userId); 5180 } 5181 } 5182 } 5183 } 5184 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return"); 5185 return null; 5186 } 5187 5188 /* 5189 * Returns if intent can be forwarded from the sourceUserId to the targetUserId 5190 */ 5191 @Override 5192 public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId, 5193 int targetUserId) { 5194 mContext.enforceCallingOrSelfPermission( 5195 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 5196 List<CrossProfileIntentFilter> matches = 5197 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId); 5198 if (matches != null) { 5199 int size = matches.size(); 5200 for (int i = 0; i < size; i++) { 5201 if (matches.get(i).getTargetUserId() == targetUserId) return true; 5202 } 5203 } 5204 if (hasWebURI(intent)) { 5205 // cross-profile app linking works only towards the parent. 5206 final UserInfo parent = getProfileParent(sourceUserId); 5207 synchronized(mPackages) { 5208 int flags = updateFlagsForResolve(0, parent.id, intent); 5209 CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr( 5210 intent, resolvedType, flags, sourceUserId, parent.id); 5211 return xpDomainInfo != null; 5212 } 5213 } 5214 return false; 5215 } 5216 5217 private UserInfo getProfileParent(int userId) { 5218 final long identity = Binder.clearCallingIdentity(); 5219 try { 5220 return sUserManager.getProfileParent(userId); 5221 } finally { 5222 Binder.restoreCallingIdentity(identity); 5223 } 5224 } 5225 5226 private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent, 5227 String resolvedType, int userId) { 5228 CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId); 5229 if (resolver != null) { 5230 return resolver.queryIntent(intent, resolvedType, false, userId); 5231 } 5232 return null; 5233 } 5234 5235 @Override 5236 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent, 5237 String resolvedType, int flags, int userId) { 5238 try { 5239 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities"); 5240 5241 return new ParceledListSlice<>( 5242 queryIntentActivitiesInternal(intent, resolvedType, flags, userId)); 5243 } finally { 5244 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 5245 } 5246 } 5247 5248 private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, 5249 String resolvedType, int flags, int userId) { 5250 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5251 flags = updateFlagsForResolve(flags, userId, intent); 5252 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5253 false /* requireFullPermission */, false /* checkShell */, 5254 "query intent activities"); 5255 ComponentName comp = intent.getComponent(); 5256 if (comp == null) { 5257 if (intent.getSelector() != null) { 5258 intent = intent.getSelector(); 5259 comp = intent.getComponent(); 5260 } 5261 } 5262 5263 if (comp != null) { 5264 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5265 final ActivityInfo ai = getActivityInfo(comp, flags, userId); 5266 if (ai != null) { 5267 final ResolveInfo ri = new ResolveInfo(); 5268 ri.activityInfo = ai; 5269 list.add(ri); 5270 } 5271 return list; 5272 } 5273 5274 // reader 5275 boolean sortResult = false; 5276 boolean addEphemeral = false; 5277 boolean matchEphemeralPackage = false; 5278 List<ResolveInfo> result; 5279 final String pkgName = intent.getPackage(); 5280 synchronized (mPackages) { 5281 if (pkgName == null) { 5282 List<CrossProfileIntentFilter> matchingFilters = 5283 getMatchingCrossProfileIntentFilters(intent, resolvedType, userId); 5284 // Check for results that need to skip the current profile. 5285 ResolveInfo xpResolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent, 5286 resolvedType, flags, userId); 5287 if (xpResolveInfo != null) { 5288 List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1); 5289 xpResult.add(xpResolveInfo); 5290 return filterIfNotSystemUser(xpResult, userId); 5291 } 5292 5293 // Check for results in the current profile. 5294 result = filterIfNotSystemUser(mActivities.queryIntent( 5295 intent, resolvedType, flags, userId), userId); 5296 addEphemeral = 5297 isEphemeralAllowed(intent, result, userId, false /*skipPackageCheck*/); 5298 5299 // Check for cross profile results. 5300 boolean hasNonNegativePriorityResult = hasNonNegativePriority(result); 5301 xpResolveInfo = queryCrossProfileIntents( 5302 matchingFilters, intent, resolvedType, flags, userId, 5303 hasNonNegativePriorityResult); 5304 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) { 5305 boolean isVisibleToUser = filterIfNotSystemUser( 5306 Collections.singletonList(xpResolveInfo), userId).size() > 0; 5307 if (isVisibleToUser) { 5308 result.add(xpResolveInfo); 5309 sortResult = true; 5310 } 5311 } 5312 if (hasWebURI(intent)) { 5313 CrossProfileDomainInfo xpDomainInfo = null; 5314 final UserInfo parent = getProfileParent(userId); 5315 if (parent != null) { 5316 xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType, 5317 flags, userId, parent.id); 5318 } 5319 if (xpDomainInfo != null) { 5320 if (xpResolveInfo != null) { 5321 // If we didn't remove it, the cross-profile ResolveInfo would be twice 5322 // in the result. 5323 result.remove(xpResolveInfo); 5324 } 5325 if (result.size() == 0 && !addEphemeral) { 5326 result.add(xpDomainInfo.resolveInfo); 5327 return result; 5328 } 5329 } 5330 if (result.size() > 1 || addEphemeral) { 5331 result = filterCandidatesWithDomainPreferredActivitiesLPr( 5332 intent, flags, result, xpDomainInfo, userId); 5333 sortResult = true; 5334 } 5335 } 5336 } else { 5337 final PackageParser.Package pkg = mPackages.get(pkgName); 5338 if (pkg != null) { 5339 result = filterIfNotSystemUser( 5340 mActivities.queryIntentForPackage( 5341 intent, resolvedType, flags, pkg.activities, userId), 5342 userId); 5343 } else { 5344 // the caller wants to resolve for a particular package; however, there 5345 // were no installed results, so, try to find an ephemeral result 5346 addEphemeral = isEphemeralAllowed( 5347 intent, null /*result*/, userId, true /*skipPackageCheck*/); 5348 matchEphemeralPackage = true; 5349 result = new ArrayList<ResolveInfo>(); 5350 } 5351 } 5352 } 5353 if (addEphemeral) { 5354 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral"); 5355 final EphemeralResolveInfo ai = getEphemeralResolveInfo( 5356 mContext, mEphemeralResolverConnection, intent, resolvedType, userId, 5357 matchEphemeralPackage ? pkgName : null); 5358 if (ai != null) { 5359 if (DEBUG_EPHEMERAL) { 5360 Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list"); 5361 } 5362 final ResolveInfo ephemeralInstaller = new ResolveInfo(mEphemeralInstallerInfo); 5363 ephemeralInstaller.ephemeralResolveInfo = ai; 5364 // make sure this resolver is the default 5365 ephemeralInstaller.isDefault = true; 5366 ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART 5367 | IntentFilter.MATCH_ADJUSTMENT_NORMAL; 5368 // add a non-generic filter 5369 ephemeralInstaller.filter = new IntentFilter(intent.getAction()); 5370 ephemeralInstaller.filter.addDataPath( 5371 intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL); 5372 result.add(ephemeralInstaller); 5373 } 5374 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 5375 } 5376 if (sortResult) { 5377 Collections.sort(result, mResolvePrioritySorter); 5378 } 5379 return result; 5380 } 5381 5382 private static class CrossProfileDomainInfo { 5383 /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */ 5384 ResolveInfo resolveInfo; 5385 /* Best domain verification status of the activities found in the other profile */ 5386 int bestDomainVerificationStatus; 5387 } 5388 5389 private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent, 5390 String resolvedType, int flags, int sourceUserId, int parentUserId) { 5391 if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING, 5392 sourceUserId)) { 5393 return null; 5394 } 5395 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 5396 resolvedType, flags, parentUserId); 5397 5398 if (resultTargetUser == null || resultTargetUser.isEmpty()) { 5399 return null; 5400 } 5401 CrossProfileDomainInfo result = null; 5402 int size = resultTargetUser.size(); 5403 for (int i = 0; i < size; i++) { 5404 ResolveInfo riTargetUser = resultTargetUser.get(i); 5405 // Intent filter verification is only for filters that specify a host. So don't return 5406 // those that handle all web uris. 5407 if (riTargetUser.handleAllWebDataURI) { 5408 continue; 5409 } 5410 String packageName = riTargetUser.activityInfo.packageName; 5411 PackageSetting ps = mSettings.mPackages.get(packageName); 5412 if (ps == null) { 5413 continue; 5414 } 5415 long verificationState = getDomainVerificationStatusLPr(ps, parentUserId); 5416 int status = (int)(verificationState >> 32); 5417 if (result == null) { 5418 result = new CrossProfileDomainInfo(); 5419 result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(), 5420 sourceUserId, parentUserId); 5421 result.bestDomainVerificationStatus = status; 5422 } else { 5423 result.bestDomainVerificationStatus = bestDomainVerificationStatus(status, 5424 result.bestDomainVerificationStatus); 5425 } 5426 } 5427 // Don't consider matches with status NEVER across profiles. 5428 if (result != null && result.bestDomainVerificationStatus 5429 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5430 return null; 5431 } 5432 return result; 5433 } 5434 5435 /** 5436 * Verification statuses are ordered from the worse to the best, except for 5437 * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse. 5438 */ 5439 private int bestDomainVerificationStatus(int status1, int status2) { 5440 if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5441 return status2; 5442 } 5443 if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5444 return status1; 5445 } 5446 return (int) MathUtils.max(status1, status2); 5447 } 5448 5449 private boolean isUserEnabled(int userId) { 5450 long callingId = Binder.clearCallingIdentity(); 5451 try { 5452 UserInfo userInfo = sUserManager.getUserInfo(userId); 5453 return userInfo != null && userInfo.isEnabled(); 5454 } finally { 5455 Binder.restoreCallingIdentity(callingId); 5456 } 5457 } 5458 5459 /** 5460 * Filter out activities with systemUserOnly flag set, when current user is not System. 5461 * 5462 * @return filtered list 5463 */ 5464 private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) { 5465 if (userId == UserHandle.USER_SYSTEM) { 5466 return resolveInfos; 5467 } 5468 for (int i = resolveInfos.size() - 1; i >= 0; i--) { 5469 ResolveInfo info = resolveInfos.get(i); 5470 if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) { 5471 resolveInfos.remove(i); 5472 } 5473 } 5474 return resolveInfos; 5475 } 5476 5477 /** 5478 * @param resolveInfos list of resolve infos in descending priority order 5479 * @return if the list contains a resolve info with non-negative priority 5480 */ 5481 private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) { 5482 return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0; 5483 } 5484 5485 private static boolean hasWebURI(Intent intent) { 5486 if (intent.getData() == null) { 5487 return false; 5488 } 5489 final String scheme = intent.getScheme(); 5490 if (TextUtils.isEmpty(scheme)) { 5491 return false; 5492 } 5493 return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS); 5494 } 5495 5496 private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent, 5497 int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo, 5498 int userId) { 5499 final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0; 5500 5501 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) { 5502 Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " + 5503 candidates.size()); 5504 } 5505 5506 ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>(); 5507 ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>(); 5508 ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>(); 5509 ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>(); 5510 ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>(); 5511 ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>(); 5512 5513 synchronized (mPackages) { 5514 final int count = candidates.size(); 5515 // First, try to use linked apps. Partition the candidates into four lists: 5516 // one for the final results, one for the "do not use ever", one for "undefined status" 5517 // and finally one for "browser app type". 5518 for (int n=0; n<count; n++) { 5519 ResolveInfo info = candidates.get(n); 5520 String packageName = info.activityInfo.packageName; 5521 PackageSetting ps = mSettings.mPackages.get(packageName); 5522 if (ps != null) { 5523 // Add to the special match all list (Browser use case) 5524 if (info.handleAllWebDataURI) { 5525 matchAllList.add(info); 5526 continue; 5527 } 5528 // Try to get the status from User settings first 5529 long packedStatus = getDomainVerificationStatusLPr(ps, userId); 5530 int status = (int)(packedStatus >> 32); 5531 int linkGeneration = (int)(packedStatus & 0xFFFFFFFF); 5532 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) { 5533 if (DEBUG_DOMAIN_VERIFICATION) { 5534 Slog.i(TAG, " + always: " + info.activityInfo.packageName 5535 + " : linkgen=" + linkGeneration); 5536 } 5537 // Use link-enabled generation as preferredOrder, i.e. 5538 // prefer newly-enabled over earlier-enabled. 5539 info.preferredOrder = linkGeneration; 5540 alwaysList.add(info); 5541 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5542 if (DEBUG_DOMAIN_VERIFICATION) { 5543 Slog.i(TAG, " + never: " + info.activityInfo.packageName); 5544 } 5545 neverList.add(info); 5546 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) { 5547 if (DEBUG_DOMAIN_VERIFICATION) { 5548 Slog.i(TAG, " + always-ask: " + info.activityInfo.packageName); 5549 } 5550 alwaysAskList.add(info); 5551 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED || 5552 status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) { 5553 if (DEBUG_DOMAIN_VERIFICATION) { 5554 Slog.i(TAG, " + ask: " + info.activityInfo.packageName); 5555 } 5556 undefinedList.add(info); 5557 } 5558 } 5559 } 5560 5561 // We'll want to include browser possibilities in a few cases 5562 boolean includeBrowser = false; 5563 5564 // First try to add the "always" resolution(s) for the current user, if any 5565 if (alwaysList.size() > 0) { 5566 result.addAll(alwaysList); 5567 } else { 5568 // Add all undefined apps as we want them to appear in the disambiguation dialog. 5569 result.addAll(undefinedList); 5570 // Maybe add one for the other profile. 5571 if (xpDomainInfo != null && ( 5572 xpDomainInfo.bestDomainVerificationStatus 5573 != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) { 5574 result.add(xpDomainInfo.resolveInfo); 5575 } 5576 includeBrowser = true; 5577 } 5578 5579 // The presence of any 'always ask' alternatives means we'll also offer browsers. 5580 // If there were 'always' entries their preferred order has been set, so we also 5581 // back that off to make the alternatives equivalent 5582 if (alwaysAskList.size() > 0) { 5583 for (ResolveInfo i : result) { 5584 i.preferredOrder = 0; 5585 } 5586 result.addAll(alwaysAskList); 5587 includeBrowser = true; 5588 } 5589 5590 if (includeBrowser) { 5591 // Also add browsers (all of them or only the default one) 5592 if (DEBUG_DOMAIN_VERIFICATION) { 5593 Slog.v(TAG, " ...including browsers in candidate set"); 5594 } 5595 if ((matchFlags & MATCH_ALL) != 0) { 5596 result.addAll(matchAllList); 5597 } else { 5598 // Browser/generic handling case. If there's a default browser, go straight 5599 // to that (but only if there is no other higher-priority match). 5600 final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId); 5601 int maxMatchPrio = 0; 5602 ResolveInfo defaultBrowserMatch = null; 5603 final int numCandidates = matchAllList.size(); 5604 for (int n = 0; n < numCandidates; n++) { 5605 ResolveInfo info = matchAllList.get(n); 5606 // track the highest overall match priority... 5607 if (info.priority > maxMatchPrio) { 5608 maxMatchPrio = info.priority; 5609 } 5610 // ...and the highest-priority default browser match 5611 if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) { 5612 if (defaultBrowserMatch == null 5613 || (defaultBrowserMatch.priority < info.priority)) { 5614 if (debug) { 5615 Slog.v(TAG, "Considering default browser match " + info); 5616 } 5617 defaultBrowserMatch = info; 5618 } 5619 } 5620 } 5621 if (defaultBrowserMatch != null 5622 && defaultBrowserMatch.priority >= maxMatchPrio 5623 && !TextUtils.isEmpty(defaultBrowserPackageName)) 5624 { 5625 if (debug) { 5626 Slog.v(TAG, "Default browser match " + defaultBrowserMatch); 5627 } 5628 result.add(defaultBrowserMatch); 5629 } else { 5630 result.addAll(matchAllList); 5631 } 5632 } 5633 5634 // If there is nothing selected, add all candidates and remove the ones that the user 5635 // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state 5636 if (result.size() == 0) { 5637 result.addAll(candidates); 5638 result.removeAll(neverList); 5639 } 5640 } 5641 } 5642 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) { 5643 Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " + 5644 result.size()); 5645 for (ResolveInfo info : result) { 5646 Slog.v(TAG, " + " + info.activityInfo); 5647 } 5648 } 5649 return result; 5650 } 5651 5652 // Returns a packed value as a long: 5653 // 5654 // high 'int'-sized word: link status: undefined/ask/never/always. 5655 // low 'int'-sized word: relative priority among 'always' results. 5656 private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) { 5657 long result = ps.getDomainVerificationStatusForUser(userId); 5658 // if none available, get the master status 5659 if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 5660 if (ps.getIntentFilterVerificationInfo() != null) { 5661 result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32; 5662 } 5663 } 5664 return result; 5665 } 5666 5667 private ResolveInfo querySkipCurrentProfileIntents( 5668 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 5669 int flags, int sourceUserId) { 5670 if (matchingFilters != null) { 5671 int size = matchingFilters.size(); 5672 for (int i = 0; i < size; i ++) { 5673 CrossProfileIntentFilter filter = matchingFilters.get(i); 5674 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) { 5675 // Checking if there are activities in the target user that can handle the 5676 // intent. 5677 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent, 5678 resolvedType, flags, sourceUserId); 5679 if (resolveInfo != null) { 5680 return resolveInfo; 5681 } 5682 } 5683 } 5684 } 5685 return null; 5686 } 5687 5688 // Return matching ResolveInfo in target user if any. 5689 private ResolveInfo queryCrossProfileIntents( 5690 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 5691 int flags, int sourceUserId, boolean matchInCurrentProfile) { 5692 if (matchingFilters != null) { 5693 // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and 5694 // match the same intent. For performance reasons, it is better not to 5695 // run queryIntent twice for the same userId 5696 SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray(); 5697 int size = matchingFilters.size(); 5698 for (int i = 0; i < size; i++) { 5699 CrossProfileIntentFilter filter = matchingFilters.get(i); 5700 int targetUserId = filter.getTargetUserId(); 5701 boolean skipCurrentProfile = 5702 (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0; 5703 boolean skipCurrentProfileIfNoMatchFound = 5704 (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0; 5705 if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId) 5706 && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) { 5707 // Checking if there are activities in the target user that can handle the 5708 // intent. 5709 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent, 5710 resolvedType, flags, sourceUserId); 5711 if (resolveInfo != null) return resolveInfo; 5712 alreadyTriedUserIds.put(targetUserId, true); 5713 } 5714 } 5715 } 5716 return null; 5717 } 5718 5719 /** 5720 * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that 5721 * will forward the intent to the filter's target user. 5722 * Otherwise, returns null. 5723 */ 5724 private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent, 5725 String resolvedType, int flags, int sourceUserId) { 5726 int targetUserId = filter.getTargetUserId(); 5727 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 5728 resolvedType, flags, targetUserId); 5729 if (resultTargetUser != null && isUserEnabled(targetUserId)) { 5730 // If all the matches in the target profile are suspended, return null. 5731 for (int i = resultTargetUser.size() - 1; i >= 0; i--) { 5732 if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags 5733 & ApplicationInfo.FLAG_SUSPENDED) == 0) { 5734 return createForwardingResolveInfoUnchecked(filter, sourceUserId, 5735 targetUserId); 5736 } 5737 } 5738 } 5739 return null; 5740 } 5741 5742 private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter, 5743 int sourceUserId, int targetUserId) { 5744 ResolveInfo forwardingResolveInfo = new ResolveInfo(); 5745 long ident = Binder.clearCallingIdentity(); 5746 boolean targetIsProfile; 5747 try { 5748 targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile(); 5749 } finally { 5750 Binder.restoreCallingIdentity(ident); 5751 } 5752 String className; 5753 if (targetIsProfile) { 5754 className = FORWARD_INTENT_TO_MANAGED_PROFILE; 5755 } else { 5756 className = FORWARD_INTENT_TO_PARENT; 5757 } 5758 ComponentName forwardingActivityComponentName = new ComponentName( 5759 mAndroidApplication.packageName, className); 5760 ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0, 5761 sourceUserId); 5762 if (!targetIsProfile) { 5763 forwardingActivityInfo.showUserIcon = targetUserId; 5764 forwardingResolveInfo.noResourceId = true; 5765 } 5766 forwardingResolveInfo.activityInfo = forwardingActivityInfo; 5767 forwardingResolveInfo.priority = 0; 5768 forwardingResolveInfo.preferredOrder = 0; 5769 forwardingResolveInfo.match = 0; 5770 forwardingResolveInfo.isDefault = true; 5771 forwardingResolveInfo.filter = filter; 5772 forwardingResolveInfo.targetUserId = targetUserId; 5773 return forwardingResolveInfo; 5774 } 5775 5776 @Override 5777 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller, 5778 Intent[] specifics, String[] specificTypes, Intent intent, 5779 String resolvedType, int flags, int userId) { 5780 return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics, 5781 specificTypes, intent, resolvedType, flags, userId)); 5782 } 5783 5784 private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller, 5785 Intent[] specifics, String[] specificTypes, Intent intent, 5786 String resolvedType, int flags, int userId) { 5787 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5788 flags = updateFlagsForResolve(flags, userId, intent); 5789 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5790 false /* requireFullPermission */, false /* checkShell */, 5791 "query intent activity options"); 5792 final String resultsAction = intent.getAction(); 5793 5794 final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags 5795 | PackageManager.GET_RESOLVED_FILTER, userId); 5796 5797 if (DEBUG_INTENT_MATCHING) { 5798 Log.v(TAG, "Query " + intent + ": " + results); 5799 } 5800 5801 int specificsPos = 0; 5802 int N; 5803 5804 // todo: note that the algorithm used here is O(N^2). This 5805 // isn't a problem in our current environment, but if we start running 5806 // into situations where we have more than 5 or 10 matches then this 5807 // should probably be changed to something smarter... 5808 5809 // First we go through and resolve each of the specific items 5810 // that were supplied, taking care of removing any corresponding 5811 // duplicate items in the generic resolve list. 5812 if (specifics != null) { 5813 for (int i=0; i<specifics.length; i++) { 5814 final Intent sintent = specifics[i]; 5815 if (sintent == null) { 5816 continue; 5817 } 5818 5819 if (DEBUG_INTENT_MATCHING) { 5820 Log.v(TAG, "Specific #" + i + ": " + sintent); 5821 } 5822 5823 String action = sintent.getAction(); 5824 if (resultsAction != null && resultsAction.equals(action)) { 5825 // If this action was explicitly requested, then don't 5826 // remove things that have it. 5827 action = null; 5828 } 5829 5830 ResolveInfo ri = null; 5831 ActivityInfo ai = null; 5832 5833 ComponentName comp = sintent.getComponent(); 5834 if (comp == null) { 5835 ri = resolveIntent( 5836 sintent, 5837 specificTypes != null ? specificTypes[i] : null, 5838 flags, userId); 5839 if (ri == null) { 5840 continue; 5841 } 5842 if (ri == mResolveInfo) { 5843 // ACK! Must do something better with this. 5844 } 5845 ai = ri.activityInfo; 5846 comp = new ComponentName(ai.applicationInfo.packageName, 5847 ai.name); 5848 } else { 5849 ai = getActivityInfo(comp, flags, userId); 5850 if (ai == null) { 5851 continue; 5852 } 5853 } 5854 5855 // Look for any generic query activities that are duplicates 5856 // of this specific one, and remove them from the results. 5857 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai); 5858 N = results.size(); 5859 int j; 5860 for (j=specificsPos; j<N; j++) { 5861 ResolveInfo sri = results.get(j); 5862 if ((sri.activityInfo.name.equals(comp.getClassName()) 5863 && sri.activityInfo.applicationInfo.packageName.equals( 5864 comp.getPackageName())) 5865 || (action != null && sri.filter.matchAction(action))) { 5866 results.remove(j); 5867 if (DEBUG_INTENT_MATCHING) Log.v( 5868 TAG, "Removing duplicate item from " + j 5869 + " due to specific " + specificsPos); 5870 if (ri == null) { 5871 ri = sri; 5872 } 5873 j--; 5874 N--; 5875 } 5876 } 5877 5878 // Add this specific item to its proper place. 5879 if (ri == null) { 5880 ri = new ResolveInfo(); 5881 ri.activityInfo = ai; 5882 } 5883 results.add(specificsPos, ri); 5884 ri.specificIndex = i; 5885 specificsPos++; 5886 } 5887 } 5888 5889 // Now we go through the remaining generic results and remove any 5890 // duplicate actions that are found here. 5891 N = results.size(); 5892 for (int i=specificsPos; i<N-1; i++) { 5893 final ResolveInfo rii = results.get(i); 5894 if (rii.filter == null) { 5895 continue; 5896 } 5897 5898 // Iterate over all of the actions of this result's intent 5899 // filter... typically this should be just one. 5900 final Iterator<String> it = rii.filter.actionsIterator(); 5901 if (it == null) { 5902 continue; 5903 } 5904 while (it.hasNext()) { 5905 final String action = it.next(); 5906 if (resultsAction != null && resultsAction.equals(action)) { 5907 // If this action was explicitly requested, then don't 5908 // remove things that have it. 5909 continue; 5910 } 5911 for (int j=i+1; j<N; j++) { 5912 final ResolveInfo rij = results.get(j); 5913 if (rij.filter != null && rij.filter.hasAction(action)) { 5914 results.remove(j); 5915 if (DEBUG_INTENT_MATCHING) Log.v( 5916 TAG, "Removing duplicate item from " + j 5917 + " due to action " + action + " at " + i); 5918 j--; 5919 N--; 5920 } 5921 } 5922 } 5923 5924 // If the caller didn't request filter information, drop it now 5925 // so we don't have to marshall/unmarshall it. 5926 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 5927 rii.filter = null; 5928 } 5929 } 5930 5931 // Filter out the caller activity if so requested. 5932 if (caller != null) { 5933 N = results.size(); 5934 for (int i=0; i<N; i++) { 5935 ActivityInfo ainfo = results.get(i).activityInfo; 5936 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName) 5937 && caller.getClassName().equals(ainfo.name)) { 5938 results.remove(i); 5939 break; 5940 } 5941 } 5942 } 5943 5944 // If the caller didn't request filter information, 5945 // drop them now so we don't have to 5946 // marshall/unmarshall it. 5947 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 5948 N = results.size(); 5949 for (int i=0; i<N; i++) { 5950 results.get(i).filter = null; 5951 } 5952 } 5953 5954 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results); 5955 return results; 5956 } 5957 5958 @Override 5959 public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent, 5960 String resolvedType, int flags, int userId) { 5961 return new ParceledListSlice<>( 5962 queryIntentReceiversInternal(intent, resolvedType, flags, userId)); 5963 } 5964 5965 private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent, 5966 String resolvedType, int flags, int userId) { 5967 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5968 flags = updateFlagsForResolve(flags, userId, intent); 5969 ComponentName comp = intent.getComponent(); 5970 if (comp == null) { 5971 if (intent.getSelector() != null) { 5972 intent = intent.getSelector(); 5973 comp = intent.getComponent(); 5974 } 5975 } 5976 if (comp != null) { 5977 List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5978 ActivityInfo ai = getReceiverInfo(comp, flags, userId); 5979 if (ai != null) { 5980 ResolveInfo ri = new ResolveInfo(); 5981 ri.activityInfo = ai; 5982 list.add(ri); 5983 } 5984 return list; 5985 } 5986 5987 // reader 5988 synchronized (mPackages) { 5989 String pkgName = intent.getPackage(); 5990 if (pkgName == null) { 5991 return mReceivers.queryIntent(intent, resolvedType, flags, userId); 5992 } 5993 final PackageParser.Package pkg = mPackages.get(pkgName); 5994 if (pkg != null) { 5995 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers, 5996 userId); 5997 } 5998 return Collections.emptyList(); 5999 } 6000 } 6001 6002 @Override 6003 public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) { 6004 if (!sUserManager.exists(userId)) return null; 6005 flags = updateFlagsForResolve(flags, userId, intent); 6006 List<ResolveInfo> query = queryIntentServicesInternal(intent, resolvedType, flags, userId); 6007 if (query != null) { 6008 if (query.size() >= 1) { 6009 // If there is more than one service with the same priority, 6010 // just arbitrarily pick the first one. 6011 return query.get(0); 6012 } 6013 } 6014 return null; 6015 } 6016 6017 @Override 6018 public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent, 6019 String resolvedType, int flags, int userId) { 6020 return new ParceledListSlice<>( 6021 queryIntentServicesInternal(intent, resolvedType, flags, userId)); 6022 } 6023 6024 private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent, 6025 String resolvedType, int flags, int userId) { 6026 if (!sUserManager.exists(userId)) return Collections.emptyList(); 6027 flags = updateFlagsForResolve(flags, userId, intent); 6028 ComponentName comp = intent.getComponent(); 6029 if (comp == null) { 6030 if (intent.getSelector() != null) { 6031 intent = intent.getSelector(); 6032 comp = intent.getComponent(); 6033 } 6034 } 6035 if (comp != null) { 6036 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 6037 final ServiceInfo si = getServiceInfo(comp, flags, userId); 6038 if (si != null) { 6039 final ResolveInfo ri = new ResolveInfo(); 6040 ri.serviceInfo = si; 6041 list.add(ri); 6042 } 6043 return list; 6044 } 6045 6046 // reader 6047 synchronized (mPackages) { 6048 String pkgName = intent.getPackage(); 6049 if (pkgName == null) { 6050 return mServices.queryIntent(intent, resolvedType, flags, userId); 6051 } 6052 final PackageParser.Package pkg = mPackages.get(pkgName); 6053 if (pkg != null) { 6054 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services, 6055 userId); 6056 } 6057 return Collections.emptyList(); 6058 } 6059 } 6060 6061 @Override 6062 public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent, 6063 String resolvedType, int flags, int userId) { 6064 return new ParceledListSlice<>( 6065 queryIntentContentProvidersInternal(intent, resolvedType, flags, userId)); 6066 } 6067 6068 private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal( 6069 Intent intent, String resolvedType, int flags, int userId) { 6070 if (!sUserManager.exists(userId)) return Collections.emptyList(); 6071 flags = updateFlagsForResolve(flags, userId, intent); 6072 ComponentName comp = intent.getComponent(); 6073 if (comp == null) { 6074 if (intent.getSelector() != null) { 6075 intent = intent.getSelector(); 6076 comp = intent.getComponent(); 6077 } 6078 } 6079 if (comp != null) { 6080 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 6081 final ProviderInfo pi = getProviderInfo(comp, flags, userId); 6082 if (pi != null) { 6083 final ResolveInfo ri = new ResolveInfo(); 6084 ri.providerInfo = pi; 6085 list.add(ri); 6086 } 6087 return list; 6088 } 6089 6090 // reader 6091 synchronized (mPackages) { 6092 String pkgName = intent.getPackage(); 6093 if (pkgName == null) { 6094 return mProviders.queryIntent(intent, resolvedType, flags, userId); 6095 } 6096 final PackageParser.Package pkg = mPackages.get(pkgName); 6097 if (pkg != null) { 6098 return mProviders.queryIntentForPackage( 6099 intent, resolvedType, flags, pkg.providers, userId); 6100 } 6101 return Collections.emptyList(); 6102 } 6103 } 6104 6105 @Override 6106 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) { 6107 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 6108 flags = updateFlagsForPackage(flags, userId, null); 6109 final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0; 6110 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6111 true /* requireFullPermission */, false /* checkShell */, 6112 "get installed packages"); 6113 6114 // writer 6115 synchronized (mPackages) { 6116 ArrayList<PackageInfo> list; 6117 if (listUninstalled) { 6118 list = new ArrayList<PackageInfo>(mSettings.mPackages.size()); 6119 for (PackageSetting ps : mSettings.mPackages.values()) { 6120 final PackageInfo pi; 6121 if (ps.pkg != null) { 6122 pi = generatePackageInfo(ps, flags, userId); 6123 } else { 6124 pi = generatePackageInfo(ps, flags, userId); 6125 } 6126 if (pi != null) { 6127 list.add(pi); 6128 } 6129 } 6130 } else { 6131 list = new ArrayList<PackageInfo>(mPackages.size()); 6132 for (PackageParser.Package p : mPackages.values()) { 6133 final PackageInfo pi = 6134 generatePackageInfo((PackageSetting)p.mExtras, flags, userId); 6135 if (pi != null) { 6136 list.add(pi); 6137 } 6138 } 6139 } 6140 6141 return new ParceledListSlice<PackageInfo>(list); 6142 } 6143 } 6144 6145 private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps, 6146 String[] permissions, boolean[] tmp, int flags, int userId) { 6147 int numMatch = 0; 6148 final PermissionsState permissionsState = ps.getPermissionsState(); 6149 for (int i=0; i<permissions.length; i++) { 6150 final String permission = permissions[i]; 6151 if (permissionsState.hasPermission(permission, userId)) { 6152 tmp[i] = true; 6153 numMatch++; 6154 } else { 6155 tmp[i] = false; 6156 } 6157 } 6158 if (numMatch == 0) { 6159 return; 6160 } 6161 final PackageInfo pi; 6162 if (ps.pkg != null) { 6163 pi = generatePackageInfo(ps, flags, userId); 6164 } else { 6165 pi = generatePackageInfo(ps, flags, userId); 6166 } 6167 // The above might return null in cases of uninstalled apps or install-state 6168 // skew across users/profiles. 6169 if (pi != null) { 6170 if ((flags&PackageManager.GET_PERMISSIONS) == 0) { 6171 if (numMatch == permissions.length) { 6172 pi.requestedPermissions = permissions; 6173 } else { 6174 pi.requestedPermissions = new String[numMatch]; 6175 numMatch = 0; 6176 for (int i=0; i<permissions.length; i++) { 6177 if (tmp[i]) { 6178 pi.requestedPermissions[numMatch] = permissions[i]; 6179 numMatch++; 6180 } 6181 } 6182 } 6183 } 6184 list.add(pi); 6185 } 6186 } 6187 6188 @Override 6189 public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions( 6190 String[] permissions, int flags, int userId) { 6191 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 6192 flags = updateFlagsForPackage(flags, userId, permissions); 6193 final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0; 6194 6195 // writer 6196 synchronized (mPackages) { 6197 ArrayList<PackageInfo> list = new ArrayList<PackageInfo>(); 6198 boolean[] tmpBools = new boolean[permissions.length]; 6199 if (listUninstalled) { 6200 for (PackageSetting ps : mSettings.mPackages.values()) { 6201 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId); 6202 } 6203 } else { 6204 for (PackageParser.Package pkg : mPackages.values()) { 6205 PackageSetting ps = (PackageSetting)pkg.mExtras; 6206 if (ps != null) { 6207 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, 6208 userId); 6209 } 6210 } 6211 } 6212 6213 return new ParceledListSlice<PackageInfo>(list); 6214 } 6215 } 6216 6217 @Override 6218 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) { 6219 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 6220 flags = updateFlagsForApplication(flags, userId, null); 6221 final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0; 6222 6223 // writer 6224 synchronized (mPackages) { 6225 ArrayList<ApplicationInfo> list; 6226 if (listUninstalled) { 6227 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size()); 6228 for (PackageSetting ps : mSettings.mPackages.values()) { 6229 ApplicationInfo ai; 6230 if (ps.pkg != null) { 6231 ai = PackageParser.generateApplicationInfo(ps.pkg, flags, 6232 ps.readUserState(userId), userId); 6233 } else { 6234 ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId); 6235 } 6236 if (ai != null) { 6237 list.add(ai); 6238 } 6239 } 6240 } else { 6241 list = new ArrayList<ApplicationInfo>(mPackages.size()); 6242 for (PackageParser.Package p : mPackages.values()) { 6243 if (p.mExtras != null) { 6244 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 6245 ((PackageSetting)p.mExtras).readUserState(userId), userId); 6246 if (ai != null) { 6247 list.add(ai); 6248 } 6249 } 6250 } 6251 } 6252 6253 return new ParceledListSlice<ApplicationInfo>(list); 6254 } 6255 } 6256 6257 @Override 6258 public ParceledListSlice<EphemeralApplicationInfo> getEphemeralApplications(int userId) { 6259 if (DISABLE_EPHEMERAL_APPS) { 6260 return null; 6261 } 6262 6263 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS, 6264 "getEphemeralApplications"); 6265 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6266 true /* requireFullPermission */, false /* checkShell */, 6267 "getEphemeralApplications"); 6268 synchronized (mPackages) { 6269 List<EphemeralApplicationInfo> ephemeralApps = mEphemeralApplicationRegistry 6270 .getEphemeralApplicationsLPw(userId); 6271 if (ephemeralApps != null) { 6272 return new ParceledListSlice<>(ephemeralApps); 6273 } 6274 } 6275 return null; 6276 } 6277 6278 @Override 6279 public boolean isEphemeralApplication(String packageName, int userId) { 6280 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6281 true /* requireFullPermission */, false /* checkShell */, 6282 "isEphemeral"); 6283 if (DISABLE_EPHEMERAL_APPS) { 6284 return false; 6285 } 6286 6287 if (!isCallerSameApp(packageName)) { 6288 return false; 6289 } 6290 synchronized (mPackages) { 6291 PackageParser.Package pkg = mPackages.get(packageName); 6292 if (pkg != null) { 6293 return pkg.applicationInfo.isEphemeralApp(); 6294 } 6295 } 6296 return false; 6297 } 6298 6299 @Override 6300 public byte[] getEphemeralApplicationCookie(String packageName, int userId) { 6301 if (DISABLE_EPHEMERAL_APPS) { 6302 return null; 6303 } 6304 6305 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6306 true /* requireFullPermission */, false /* checkShell */, 6307 "getCookie"); 6308 if (!isCallerSameApp(packageName)) { 6309 return null; 6310 } 6311 synchronized (mPackages) { 6312 return mEphemeralApplicationRegistry.getEphemeralApplicationCookieLPw( 6313 packageName, userId); 6314 } 6315 } 6316 6317 @Override 6318 public boolean setEphemeralApplicationCookie(String packageName, byte[] cookie, int userId) { 6319 if (DISABLE_EPHEMERAL_APPS) { 6320 return true; 6321 } 6322 6323 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6324 true /* requireFullPermission */, true /* checkShell */, 6325 "setCookie"); 6326 if (!isCallerSameApp(packageName)) { 6327 return false; 6328 } 6329 synchronized (mPackages) { 6330 return mEphemeralApplicationRegistry.setEphemeralApplicationCookieLPw( 6331 packageName, cookie, userId); 6332 } 6333 } 6334 6335 @Override 6336 public Bitmap getEphemeralApplicationIcon(String packageName, int userId) { 6337 if (DISABLE_EPHEMERAL_APPS) { 6338 return null; 6339 } 6340 6341 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS, 6342 "getEphemeralApplicationIcon"); 6343 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6344 true /* requireFullPermission */, false /* checkShell */, 6345 "getEphemeralApplicationIcon"); 6346 synchronized (mPackages) { 6347 return mEphemeralApplicationRegistry.getEphemeralApplicationIconLPw( 6348 packageName, userId); 6349 } 6350 } 6351 6352 private boolean isCallerSameApp(String packageName) { 6353 PackageParser.Package pkg = mPackages.get(packageName); 6354 return pkg != null 6355 && UserHandle.getAppId(Binder.getCallingUid()) == pkg.applicationInfo.uid; 6356 } 6357 6358 @Override 6359 public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) { 6360 return new ParceledListSlice<>(getPersistentApplicationsInternal(flags)); 6361 } 6362 6363 private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) { 6364 final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>(); 6365 6366 // reader 6367 synchronized (mPackages) { 6368 final Iterator<PackageParser.Package> i = mPackages.values().iterator(); 6369 final int userId = UserHandle.getCallingUserId(); 6370 while (i.hasNext()) { 6371 final PackageParser.Package p = i.next(); 6372 if (p.applicationInfo == null) continue; 6373 6374 final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0) 6375 && !p.applicationInfo.isDirectBootAware(); 6376 final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0) 6377 && p.applicationInfo.isDirectBootAware(); 6378 6379 if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0 6380 && (!mSafeMode || isSystemApp(p)) 6381 && (matchesUnaware || matchesAware)) { 6382 PackageSetting ps = mSettings.mPackages.get(p.packageName); 6383 if (ps != null) { 6384 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 6385 ps.readUserState(userId), userId); 6386 if (ai != null) { 6387 finalList.add(ai); 6388 } 6389 } 6390 } 6391 } 6392 } 6393 6394 return finalList; 6395 } 6396 6397 @Override 6398 public ProviderInfo resolveContentProvider(String name, int flags, int userId) { 6399 if (!sUserManager.exists(userId)) return null; 6400 flags = updateFlagsForComponent(flags, userId, name); 6401 // reader 6402 synchronized (mPackages) { 6403 final PackageParser.Provider provider = mProvidersByAuthority.get(name); 6404 PackageSetting ps = provider != null 6405 ? mSettings.mPackages.get(provider.owner.packageName) 6406 : null; 6407 return ps != null 6408 && mSettings.isEnabledAndMatchLPr(provider.info, flags, userId) 6409 ? PackageParser.generateProviderInfo(provider, flags, 6410 ps.readUserState(userId), userId) 6411 : null; 6412 } 6413 } 6414 6415 /** 6416 * @deprecated 6417 */ 6418 @Deprecated 6419 public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) { 6420 // reader 6421 synchronized (mPackages) { 6422 final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority 6423 .entrySet().iterator(); 6424 final int userId = UserHandle.getCallingUserId(); 6425 while (i.hasNext()) { 6426 Map.Entry<String, PackageParser.Provider> entry = i.next(); 6427 PackageParser.Provider p = entry.getValue(); 6428 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 6429 6430 if (ps != null && p.syncable 6431 && (!mSafeMode || (p.info.applicationInfo.flags 6432 &ApplicationInfo.FLAG_SYSTEM) != 0)) { 6433 ProviderInfo info = PackageParser.generateProviderInfo(p, 0, 6434 ps.readUserState(userId), userId); 6435 if (info != null) { 6436 outNames.add(entry.getKey()); 6437 outInfo.add(info); 6438 } 6439 } 6440 } 6441 } 6442 } 6443 6444 @Override 6445 public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName, 6446 int uid, int flags) { 6447 final int userId = processName != null ? UserHandle.getUserId(uid) 6448 : UserHandle.getCallingUserId(); 6449 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 6450 flags = updateFlagsForComponent(flags, userId, processName); 6451 6452 ArrayList<ProviderInfo> finalList = null; 6453 // reader 6454 synchronized (mPackages) { 6455 final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator(); 6456 while (i.hasNext()) { 6457 final PackageParser.Provider p = i.next(); 6458 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 6459 if (ps != null && p.info.authority != null 6460 && (processName == null 6461 || (p.info.processName.equals(processName) 6462 && UserHandle.isSameApp(p.info.applicationInfo.uid, uid))) 6463 && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) { 6464 if (finalList == null) { 6465 finalList = new ArrayList<ProviderInfo>(3); 6466 } 6467 ProviderInfo info = PackageParser.generateProviderInfo(p, flags, 6468 ps.readUserState(userId), userId); 6469 if (info != null) { 6470 finalList.add(info); 6471 } 6472 } 6473 } 6474 } 6475 6476 if (finalList != null) { 6477 Collections.sort(finalList, mProviderInitOrderSorter); 6478 return new ParceledListSlice<ProviderInfo>(finalList); 6479 } 6480 6481 return ParceledListSlice.emptyList(); 6482 } 6483 6484 @Override 6485 public InstrumentationInfo getInstrumentationInfo(ComponentName name, int flags) { 6486 // reader 6487 synchronized (mPackages) { 6488 final PackageParser.Instrumentation i = mInstrumentation.get(name); 6489 return PackageParser.generateInstrumentationInfo(i, flags); 6490 } 6491 } 6492 6493 @Override 6494 public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation( 6495 String targetPackage, int flags) { 6496 return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags)); 6497 } 6498 6499 private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage, 6500 int flags) { 6501 ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>(); 6502 6503 // reader 6504 synchronized (mPackages) { 6505 final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator(); 6506 while (i.hasNext()) { 6507 final PackageParser.Instrumentation p = i.next(); 6508 if (targetPackage == null 6509 || targetPackage.equals(p.info.targetPackage)) { 6510 InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p, 6511 flags); 6512 if (ii != null) { 6513 finalList.add(ii); 6514 } 6515 } 6516 } 6517 } 6518 6519 return finalList; 6520 } 6521 6522 private void createIdmapsForPackageLI(PackageParser.Package pkg) { 6523 ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName); 6524 if (overlays == null) { 6525 Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages"); 6526 return; 6527 } 6528 for (PackageParser.Package opkg : overlays.values()) { 6529 // Not much to do if idmap fails: we already logged the error 6530 // and we certainly don't want to abort installation of pkg simply 6531 // because an overlay didn't fit properly. For these reasons, 6532 // ignore the return value of createIdmapForPackagePairLI. 6533 createIdmapForPackagePairLI(pkg, opkg); 6534 } 6535 } 6536 6537 private boolean createIdmapForPackagePairLI(PackageParser.Package pkg, 6538 PackageParser.Package opkg) { 6539 if (!opkg.mTrustedOverlay) { 6540 Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " + 6541 opkg.baseCodePath + ": overlay not trusted"); 6542 return false; 6543 } 6544 ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName); 6545 if (overlaySet == null) { 6546 Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " + 6547 opkg.baseCodePath + " but target package has no known overlays"); 6548 return false; 6549 } 6550 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 6551 // TODO: generate idmap for split APKs 6552 try { 6553 mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid); 6554 } catch (InstallerException e) { 6555 Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and " 6556 + opkg.baseCodePath); 6557 return false; 6558 } 6559 PackageParser.Package[] overlayArray = 6560 overlaySet.values().toArray(new PackageParser.Package[0]); 6561 Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() { 6562 public int compare(PackageParser.Package p1, PackageParser.Package p2) { 6563 return p1.mOverlayPriority - p2.mOverlayPriority; 6564 } 6565 }; 6566 Arrays.sort(overlayArray, cmp); 6567 6568 pkg.applicationInfo.resourceDirs = new String[overlayArray.length]; 6569 int i = 0; 6570 for (PackageParser.Package p : overlayArray) { 6571 pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath; 6572 } 6573 return true; 6574 } 6575 6576 private void scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime) { 6577 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + dir.getAbsolutePath() + "]"); 6578 try { 6579 scanDirLI(dir, parseFlags, scanFlags, currentTime); 6580 } finally { 6581 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6582 } 6583 } 6584 6585 private void scanDirLI(File dir, final int parseFlags, int scanFlags, long currentTime) { 6586 final File[] files = dir.listFiles(); 6587 if (ArrayUtils.isEmpty(files)) { 6588 Log.d(TAG, "No files in app dir " + dir); 6589 return; 6590 } 6591 6592 if (DEBUG_PACKAGE_SCANNING) { 6593 Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags 6594 + " flags=0x" + Integer.toHexString(parseFlags)); 6595 } 6596 6597 for (File file : files) { 6598 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 6599 && !PackageInstallerService.isStageName(file.getName()); 6600 if (!isPackage) { 6601 // Ignore entries which are not packages 6602 continue; 6603 } 6604 try { 6605 scanPackageTracedLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK, 6606 scanFlags, currentTime, null); 6607 } catch (PackageManagerException e) { 6608 Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage()); 6609 6610 // Delete invalid userdata apps 6611 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 && 6612 e.error == PackageManager.INSTALL_FAILED_INVALID_APK) { 6613 logCriticalInfo(Log.WARN, "Deleting invalid package at " + file); 6614 removeCodePathLI(file); 6615 } 6616 } 6617 } 6618 } 6619 6620 private static File getSettingsProblemFile() { 6621 File dataDir = Environment.getDataDirectory(); 6622 File systemDir = new File(dataDir, "system"); 6623 File fname = new File(systemDir, "uiderrors.txt"); 6624 return fname; 6625 } 6626 6627 static void reportSettingsProblem(int priority, String msg) { 6628 logCriticalInfo(priority, msg); 6629 } 6630 6631 static void logCriticalInfo(int priority, String msg) { 6632 Slog.println(priority, TAG, msg); 6633 EventLogTags.writePmCriticalInfo(msg); 6634 try { 6635 File fname = getSettingsProblemFile(); 6636 FileOutputStream out = new FileOutputStream(fname, true); 6637 PrintWriter pw = new FastPrintWriter(out); 6638 SimpleDateFormat formatter = new SimpleDateFormat(); 6639 String dateString = formatter.format(new Date(System.currentTimeMillis())); 6640 pw.println(dateString + ": " + msg); 6641 pw.close(); 6642 FileUtils.setPermissions( 6643 fname.toString(), 6644 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH, 6645 -1, -1); 6646 } catch (java.io.IOException e) { 6647 } 6648 } 6649 6650 private long getLastModifiedTime(PackageParser.Package pkg, File srcFile) { 6651 if (srcFile.isDirectory()) { 6652 final File baseFile = new File(pkg.baseCodePath); 6653 long maxModifiedTime = baseFile.lastModified(); 6654 if (pkg.splitCodePaths != null) { 6655 for (int i = pkg.splitCodePaths.length - 1; i >=0; --i) { 6656 final File splitFile = new File(pkg.splitCodePaths[i]); 6657 maxModifiedTime = Math.max(maxModifiedTime, splitFile.lastModified()); 6658 } 6659 } 6660 return maxModifiedTime; 6661 } 6662 return srcFile.lastModified(); 6663 } 6664 6665 private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile, 6666 final int policyFlags) throws PackageManagerException { 6667 if (ps != null 6668 && ps.codePath.equals(srcFile) 6669 && ps.timeStamp == getLastModifiedTime(pkg, srcFile) 6670 && !isCompatSignatureUpdateNeeded(pkg) 6671 && !isRecoverSignatureUpdateNeeded(pkg)) { 6672 long mSigningKeySetId = ps.keySetData.getProperSigningKeySet(); 6673 KeySetManagerService ksms = mSettings.mKeySetManagerService; 6674 ArraySet<PublicKey> signingKs; 6675 synchronized (mPackages) { 6676 signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId); 6677 } 6678 if (ps.signatures.mSignatures != null 6679 && ps.signatures.mSignatures.length != 0 6680 && signingKs != null) { 6681 // Optimization: reuse the existing cached certificates 6682 // if the package appears to be unchanged. 6683 pkg.mSignatures = ps.signatures.mSignatures; 6684 pkg.mSigningKeys = signingKs; 6685 return; 6686 } 6687 6688 Slog.w(TAG, "PackageSetting for " + ps.name 6689 + " is missing signatures. Collecting certs again to recover them."); 6690 } else { 6691 Log.i(TAG, srcFile.toString() + " changed; collecting certs"); 6692 } 6693 6694 try { 6695 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates"); 6696 PackageParser.collectCertificates(pkg, policyFlags); 6697 } catch (PackageParserException e) { 6698 throw PackageManagerException.from(e); 6699 } finally { 6700 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6701 } 6702 } 6703 6704 /** 6705 * Traces a package scan. 6706 * @see #scanPackageLI(File, int, int, long, UserHandle) 6707 */ 6708 private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags, 6709 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 6710 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]"); 6711 try { 6712 return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user); 6713 } finally { 6714 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6715 } 6716 } 6717 6718 /** 6719 * Scans a package and returns the newly parsed package. 6720 * Returns {@code null} in case of errors and the error code is stored in mLastScanError 6721 */ 6722 private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags, 6723 long currentTime, UserHandle user) throws PackageManagerException { 6724 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile); 6725 PackageParser pp = new PackageParser(); 6726 pp.setSeparateProcesses(mSeparateProcesses); 6727 pp.setOnlyCoreApps(mOnlyCore); 6728 pp.setDisplayMetrics(mMetrics); 6729 6730 if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) { 6731 parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY; 6732 } 6733 6734 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage"); 6735 final PackageParser.Package pkg; 6736 try { 6737 pkg = pp.parsePackage(scanFile, parseFlags); 6738 } catch (PackageParserException e) { 6739 throw PackageManagerException.from(e); 6740 } finally { 6741 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6742 } 6743 6744 return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user); 6745 } 6746 6747 /** 6748 * Scans a package and returns the newly parsed package. 6749 * @throws PackageManagerException on a parse error. 6750 */ 6751 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile, 6752 final int policyFlags, int scanFlags, long currentTime, UserHandle user) 6753 throws PackageManagerException { 6754 // If the package has children and this is the first dive in the function 6755 // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all 6756 // packages (parent and children) would be successfully scanned before the 6757 // actual scan since scanning mutates internal state and we want to atomically 6758 // install the package and its children. 6759 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 6760 if (pkg.childPackages != null && pkg.childPackages.size() > 0) { 6761 scanFlags |= SCAN_CHECK_ONLY; 6762 } 6763 } else { 6764 scanFlags &= ~SCAN_CHECK_ONLY; 6765 } 6766 6767 // Scan the parent 6768 PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, policyFlags, 6769 scanFlags, currentTime, user); 6770 6771 // Scan the children 6772 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 6773 for (int i = 0; i < childCount; i++) { 6774 PackageParser.Package childPackage = pkg.childPackages.get(i); 6775 scanPackageInternalLI(childPackage, scanFile, policyFlags, scanFlags, 6776 currentTime, user); 6777 } 6778 6779 6780 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 6781 return scanPackageLI(pkg, scanFile, policyFlags, scanFlags, currentTime, user); 6782 } 6783 6784 return scannedPkg; 6785 } 6786 6787 /** 6788 * Scans a package and returns the newly parsed package. 6789 * @throws PackageManagerException on a parse error. 6790 */ 6791 private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile, 6792 int policyFlags, int scanFlags, long currentTime, UserHandle user) 6793 throws PackageManagerException { 6794 PackageSetting ps = null; 6795 PackageSetting updatedPkg; 6796 // reader 6797 synchronized (mPackages) { 6798 // Look to see if we already know about this package. 6799 String oldName = mSettings.getRenamedPackage(pkg.packageName); 6800 if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) { 6801 // This package has been renamed to its original name. Let's 6802 // use that. 6803 ps = mSettings.peekPackageLPr(oldName); 6804 } 6805 // If there was no original package, see one for the real package name. 6806 if (ps == null) { 6807 ps = mSettings.peekPackageLPr(pkg.packageName); 6808 } 6809 // Check to see if this package could be hiding/updating a system 6810 // package. Must look for it either under the original or real 6811 // package name depending on our state. 6812 updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName); 6813 if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg); 6814 6815 // If this is a package we don't know about on the system partition, we 6816 // may need to remove disabled child packages on the system partition 6817 // or may need to not add child packages if the parent apk is updated 6818 // on the data partition and no longer defines this child package. 6819 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) { 6820 // If this is a parent package for an updated system app and this system 6821 // app got an OTA update which no longer defines some of the child packages 6822 // we have to prune them from the disabled system packages. 6823 PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName); 6824 if (disabledPs != null) { 6825 final int scannedChildCount = (pkg.childPackages != null) 6826 ? pkg.childPackages.size() : 0; 6827 final int disabledChildCount = disabledPs.childPackageNames != null 6828 ? disabledPs.childPackageNames.size() : 0; 6829 for (int i = 0; i < disabledChildCount; i++) { 6830 String disabledChildPackageName = disabledPs.childPackageNames.get(i); 6831 boolean disabledPackageAvailable = false; 6832 for (int j = 0; j < scannedChildCount; j++) { 6833 PackageParser.Package childPkg = pkg.childPackages.get(j); 6834 if (childPkg.packageName.equals(disabledChildPackageName)) { 6835 disabledPackageAvailable = true; 6836 break; 6837 } 6838 } 6839 if (!disabledPackageAvailable) { 6840 mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName); 6841 } 6842 } 6843 } 6844 } 6845 } 6846 6847 boolean updatedPkgBetter = false; 6848 // First check if this is a system package that may involve an update 6849 if (updatedPkg != null && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) { 6850 // If new package is not located in "/system/priv-app" (e.g. due to an OTA), 6851 // it needs to drop FLAG_PRIVILEGED. 6852 if (locationIsPrivileged(scanFile)) { 6853 updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 6854 } else { 6855 updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 6856 } 6857 6858 if (ps != null && !ps.codePath.equals(scanFile)) { 6859 // The path has changed from what was last scanned... check the 6860 // version of the new path against what we have stored to determine 6861 // what to do. 6862 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath); 6863 if (pkg.mVersionCode <= ps.versionCode) { 6864 // The system package has been updated and the code path does not match 6865 // Ignore entry. Skip it. 6866 if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile 6867 + " ignored: updated version " + ps.versionCode 6868 + " better than this " + pkg.mVersionCode); 6869 if (!updatedPkg.codePath.equals(scanFile)) { 6870 Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg " 6871 + ps.name + " changing from " + updatedPkg.codePathString 6872 + " to " + scanFile); 6873 updatedPkg.codePath = scanFile; 6874 updatedPkg.codePathString = scanFile.toString(); 6875 updatedPkg.resourcePath = scanFile; 6876 updatedPkg.resourcePathString = scanFile.toString(); 6877 } 6878 updatedPkg.pkg = pkg; 6879 updatedPkg.versionCode = pkg.mVersionCode; 6880 6881 // Update the disabled system child packages to point to the package too. 6882 final int childCount = updatedPkg.childPackageNames != null 6883 ? updatedPkg.childPackageNames.size() : 0; 6884 for (int i = 0; i < childCount; i++) { 6885 String childPackageName = updatedPkg.childPackageNames.get(i); 6886 PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr( 6887 childPackageName); 6888 if (updatedChildPkg != null) { 6889 updatedChildPkg.pkg = pkg; 6890 updatedChildPkg.versionCode = pkg.mVersionCode; 6891 } 6892 } 6893 6894 throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at " 6895 + scanFile + " ignored: updated version " + ps.versionCode 6896 + " better than this " + pkg.mVersionCode); 6897 } else { 6898 // The current app on the system partition is better than 6899 // what we have updated to on the data partition; switch 6900 // back to the system partition version. 6901 // At this point, its safely assumed that package installation for 6902 // apps in system partition will go through. If not there won't be a working 6903 // version of the app 6904 // writer 6905 synchronized (mPackages) { 6906 // Just remove the loaded entries from package lists. 6907 mPackages.remove(ps.name); 6908 } 6909 6910 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 6911 + " reverting from " + ps.codePathString 6912 + ": new version " + pkg.mVersionCode 6913 + " better than installed " + ps.versionCode); 6914 6915 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 6916 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 6917 synchronized (mInstallLock) { 6918 args.cleanUpResourcesLI(); 6919 } 6920 synchronized (mPackages) { 6921 mSettings.enableSystemPackageLPw(ps.name); 6922 } 6923 updatedPkgBetter = true; 6924 } 6925 } 6926 } 6927 6928 if (updatedPkg != null) { 6929 // An updated system app will not have the PARSE_IS_SYSTEM flag set 6930 // initially 6931 policyFlags |= PackageParser.PARSE_IS_SYSTEM; 6932 6933 // An updated privileged app will not have the PARSE_IS_PRIVILEGED 6934 // flag set initially 6935 if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) { 6936 policyFlags |= PackageParser.PARSE_IS_PRIVILEGED; 6937 } 6938 } 6939 6940 // Verify certificates against what was last scanned 6941 collectCertificatesLI(ps, pkg, scanFile, policyFlags); 6942 6943 /* 6944 * A new system app appeared, but we already had a non-system one of the 6945 * same name installed earlier. 6946 */ 6947 boolean shouldHideSystemApp = false; 6948 if (updatedPkg == null && ps != null 6949 && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) { 6950 /* 6951 * Check to make sure the signatures match first. If they don't, 6952 * wipe the installed application and its data. 6953 */ 6954 if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures) 6955 != PackageManager.SIGNATURE_MATCH) { 6956 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but" 6957 + " signatures don't match existing userdata copy; removing"); 6958 try (PackageFreezer freezer = freezePackage(pkg.packageName, 6959 "scanPackageInternalLI")) { 6960 deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null); 6961 } 6962 ps = null; 6963 } else { 6964 /* 6965 * If the newly-added system app is an older version than the 6966 * already installed version, hide it. It will be scanned later 6967 * and re-added like an update. 6968 */ 6969 if (pkg.mVersionCode <= ps.versionCode) { 6970 shouldHideSystemApp = true; 6971 logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile 6972 + " but new version " + pkg.mVersionCode + " better than installed " 6973 + ps.versionCode + "; hiding system"); 6974 } else { 6975 /* 6976 * The newly found system app is a newer version that the 6977 * one previously installed. Simply remove the 6978 * already-installed application and replace it with our own 6979 * while keeping the application data. 6980 */ 6981 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 6982 + " reverting from " + ps.codePathString + ": new version " 6983 + pkg.mVersionCode + " better than installed " + ps.versionCode); 6984 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 6985 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 6986 synchronized (mInstallLock) { 6987 args.cleanUpResourcesLI(); 6988 } 6989 } 6990 } 6991 } 6992 6993 // The apk is forward locked (not public) if its code and resources 6994 // are kept in different files. (except for app in either system or 6995 // vendor path). 6996 // TODO grab this value from PackageSettings 6997 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 6998 if (ps != null && !ps.codePath.equals(ps.resourcePath)) { 6999 policyFlags |= PackageParser.PARSE_FORWARD_LOCK; 7000 } 7001 } 7002 7003 // TODO: extend to support forward-locked splits 7004 String resourcePath = null; 7005 String baseResourcePath = null; 7006 if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) { 7007 if (ps != null && ps.resourcePathString != null) { 7008 resourcePath = ps.resourcePathString; 7009 baseResourcePath = ps.resourcePathString; 7010 } else { 7011 // Should not happen at all. Just log an error. 7012 Slog.e(TAG, "Resource path not set for package " + pkg.packageName); 7013 } 7014 } else { 7015 resourcePath = pkg.codePath; 7016 baseResourcePath = pkg.baseCodePath; 7017 } 7018 7019 // Set application objects path explicitly. 7020 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 7021 pkg.setApplicationInfoCodePath(pkg.codePath); 7022 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 7023 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 7024 pkg.setApplicationInfoResourcePath(resourcePath); 7025 pkg.setApplicationInfoBaseResourcePath(baseResourcePath); 7026 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 7027 7028 // Note that we invoke the following method only if we are about to unpack an application 7029 PackageParser.Package scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags 7030 | SCAN_UPDATE_SIGNATURE, currentTime, user); 7031 7032 /* 7033 * If the system app should be overridden by a previously installed 7034 * data, hide the system app now and let the /data/app scan pick it up 7035 * again. 7036 */ 7037 if (shouldHideSystemApp) { 7038 synchronized (mPackages) { 7039 mSettings.disableSystemPackageLPw(pkg.packageName, true); 7040 } 7041 } 7042 7043 return scannedPkg; 7044 } 7045 7046 private static String fixProcessName(String defProcessName, 7047 String processName, int uid) { 7048 if (processName == null) { 7049 return defProcessName; 7050 } 7051 return processName; 7052 } 7053 7054 private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg) 7055 throws PackageManagerException { 7056 if (pkgSetting.signatures.mSignatures != null) { 7057 // Already existing package. Make sure signatures match 7058 boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures) 7059 == PackageManager.SIGNATURE_MATCH; 7060 if (!match) { 7061 match = compareSignaturesCompat(pkgSetting.signatures, pkg) 7062 == PackageManager.SIGNATURE_MATCH; 7063 } 7064 if (!match) { 7065 match = compareSignaturesRecover(pkgSetting.signatures, pkg) 7066 == PackageManager.SIGNATURE_MATCH; 7067 } 7068 if (!match) { 7069 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 7070 + pkg.packageName + " signatures do not match the " 7071 + "previously installed version; ignoring!"); 7072 } 7073 } 7074 7075 // Check for shared user signatures 7076 if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) { 7077 // Already existing package. Make sure signatures match 7078 boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 7079 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 7080 if (!match) { 7081 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg) 7082 == PackageManager.SIGNATURE_MATCH; 7083 } 7084 if (!match) { 7085 match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg) 7086 == PackageManager.SIGNATURE_MATCH; 7087 } 7088 if (!match) { 7089 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 7090 "Package " + pkg.packageName 7091 + " has no signatures that match those in shared user " 7092 + pkgSetting.sharedUser.name + "; ignoring!"); 7093 } 7094 } 7095 } 7096 7097 /** 7098 * Enforces that only the system UID or root's UID can call a method exposed 7099 * via Binder. 7100 * 7101 * @param message used as message if SecurityException is thrown 7102 * @throws SecurityException if the caller is not system or root 7103 */ 7104 private static final void enforceSystemOrRoot(String message) { 7105 final int uid = Binder.getCallingUid(); 7106 if (uid != Process.SYSTEM_UID && uid != 0) { 7107 throw new SecurityException(message); 7108 } 7109 } 7110 7111 @Override 7112 public void performFstrimIfNeeded() { 7113 enforceSystemOrRoot("Only the system can request fstrim"); 7114 7115 // Before everything else, see whether we need to fstrim. 7116 try { 7117 IMountService ms = PackageHelper.getMountService(); 7118 if (ms != null) { 7119 boolean doTrim = false; 7120 final long interval = android.provider.Settings.Global.getLong( 7121 mContext.getContentResolver(), 7122 android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL, 7123 DEFAULT_MANDATORY_FSTRIM_INTERVAL); 7124 if (interval > 0) { 7125 final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance(); 7126 if (timeSinceLast > interval) { 7127 doTrim = true; 7128 Slog.w(TAG, "No disk maintenance in " + timeSinceLast 7129 + "; running immediately"); 7130 } 7131 } 7132 if (doTrim) { 7133 if (!isFirstBoot()) { 7134 try { 7135 ActivityManagerNative.getDefault().showBootMessage( 7136 mContext.getResources().getString( 7137 R.string.android_upgrading_fstrim), true); 7138 } catch (RemoteException e) { 7139 } 7140 } 7141 ms.runMaintenance(); 7142 } 7143 } else { 7144 Slog.e(TAG, "Mount service unavailable!"); 7145 } 7146 } catch (RemoteException e) { 7147 // Can't happen; MountService is local 7148 } 7149 } 7150 7151 @Override 7152 public void updatePackagesIfNeeded() { 7153 enforceSystemOrRoot("Only the system can request package update"); 7154 7155 // We need to re-extract after an OTA. 7156 boolean causeUpgrade = isUpgrade(); 7157 7158 // First boot or factory reset. 7159 // Note: we also handle devices that are upgrading to N right now as if it is their 7160 // first boot, as they do not have profile data. 7161 boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade; 7162 7163 // We need to re-extract after a pruned cache, as AoT-ed files will be out of date. 7164 boolean causePrunedCache = VMRuntime.didPruneDalvikCache(); 7165 7166 if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) { 7167 return; 7168 } 7169 7170 List<PackageParser.Package> pkgs; 7171 synchronized (mPackages) { 7172 pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this); 7173 } 7174 7175 final long startTime = System.nanoTime(); 7176 final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */, 7177 getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT)); 7178 7179 final int elapsedTimeSeconds = 7180 (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime); 7181 7182 MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]); 7183 MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]); 7184 MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]); 7185 MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size()); 7186 MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds); 7187 } 7188 7189 /** 7190 * Performs dexopt on the set of packages in {@code packages} and returns an int array 7191 * containing statistics about the invocation. The array consists of three elements, 7192 * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped} 7193 * and {@code numberOfPackagesFailed}. 7194 */ 7195 private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog, 7196 String compilerFilter) { 7197 7198 int numberOfPackagesVisited = 0; 7199 int numberOfPackagesOptimized = 0; 7200 int numberOfPackagesSkipped = 0; 7201 int numberOfPackagesFailed = 0; 7202 final int numberOfPackagesToDexopt = pkgs.size(); 7203 7204 for (PackageParser.Package pkg : pkgs) { 7205 numberOfPackagesVisited++; 7206 7207 if (!PackageDexOptimizer.canOptimizePackage(pkg)) { 7208 if (DEBUG_DEXOPT) { 7209 Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName); 7210 } 7211 numberOfPackagesSkipped++; 7212 continue; 7213 } 7214 7215 if (DEBUG_DEXOPT) { 7216 Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " + 7217 numberOfPackagesToDexopt + ": " + pkg.packageName); 7218 } 7219 7220 if (showDialog) { 7221 try { 7222 ActivityManagerNative.getDefault().showBootMessage( 7223 mContext.getResources().getString(R.string.android_upgrading_apk, 7224 numberOfPackagesVisited, numberOfPackagesToDexopt), true); 7225 } catch (RemoteException e) { 7226 } 7227 } 7228 7229 // If the OTA updates a system app which was previously preopted to a non-preopted state 7230 // the app might end up being verified at runtime. That's because by default the apps 7231 // are verify-profile but for preopted apps there's no profile. 7232 // Do a hacky check to ensure that if we have no profiles (a reasonable indication 7233 // that before the OTA the app was preopted) the app gets compiled with a non-profile 7234 // filter (by default interpret-only). 7235 // Note that at this stage unused apps are already filtered. 7236 if (isSystemApp(pkg) && 7237 DexFile.isProfileGuidedCompilerFilter(compilerFilter) && 7238 !Environment.getReferenceProfile(pkg.packageName).exists()) { 7239 compilerFilter = getNonProfileGuidedCompilerFilter(compilerFilter); 7240 } 7241 7242 // checkProfiles is false to avoid merging profiles during boot which 7243 // might interfere with background compilation (b/28612421). 7244 // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will 7245 // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a 7246 // trade-off worth doing to save boot time work. 7247 int dexOptStatus = performDexOptTraced(pkg.packageName, 7248 false /* checkProfiles */, 7249 compilerFilter, 7250 false /* force */); 7251 switch (dexOptStatus) { 7252 case PackageDexOptimizer.DEX_OPT_PERFORMED: 7253 numberOfPackagesOptimized++; 7254 break; 7255 case PackageDexOptimizer.DEX_OPT_SKIPPED: 7256 numberOfPackagesSkipped++; 7257 break; 7258 case PackageDexOptimizer.DEX_OPT_FAILED: 7259 numberOfPackagesFailed++; 7260 break; 7261 default: 7262 Log.e(TAG, "Unexpected dexopt return code " + dexOptStatus); 7263 break; 7264 } 7265 } 7266 7267 return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped, 7268 numberOfPackagesFailed }; 7269 } 7270 7271 @Override 7272 public void notifyPackageUse(String packageName, int reason) { 7273 synchronized (mPackages) { 7274 PackageParser.Package p = mPackages.get(packageName); 7275 if (p == null) { 7276 return; 7277 } 7278 p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis(); 7279 } 7280 } 7281 7282 // TODO: this is not used nor needed. Delete it. 7283 @Override 7284 public boolean performDexOptIfNeeded(String packageName) { 7285 int dexOptStatus = performDexOptTraced(packageName, 7286 false /* checkProfiles */, getFullCompilerFilter(), false /* force */); 7287 return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED; 7288 } 7289 7290 @Override 7291 public boolean performDexOpt(String packageName, 7292 boolean checkProfiles, int compileReason, boolean force) { 7293 int dexOptStatus = performDexOptTraced(packageName, checkProfiles, 7294 getCompilerFilterForReason(compileReason), force); 7295 return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED; 7296 } 7297 7298 @Override 7299 public boolean performDexOptMode(String packageName, 7300 boolean checkProfiles, String targetCompilerFilter, boolean force) { 7301 int dexOptStatus = performDexOptTraced(packageName, checkProfiles, 7302 targetCompilerFilter, force); 7303 return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED; 7304 } 7305 7306 private int performDexOptTraced(String packageName, 7307 boolean checkProfiles, String targetCompilerFilter, boolean force) { 7308 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 7309 try { 7310 return performDexOptInternal(packageName, checkProfiles, 7311 targetCompilerFilter, force); 7312 } finally { 7313 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7314 } 7315 } 7316 7317 // Run dexopt on a given package. Returns true if dexopt did not fail, i.e. 7318 // if the package can now be considered up to date for the given filter. 7319 private int performDexOptInternal(String packageName, 7320 boolean checkProfiles, String targetCompilerFilter, boolean force) { 7321 PackageParser.Package p; 7322 synchronized (mPackages) { 7323 p = mPackages.get(packageName); 7324 if (p == null) { 7325 // Package could not be found. Report failure. 7326 return PackageDexOptimizer.DEX_OPT_FAILED; 7327 } 7328 mPackageUsage.maybeWriteAsync(mPackages); 7329 mCompilerStats.maybeWriteAsync(); 7330 } 7331 long callingId = Binder.clearCallingIdentity(); 7332 try { 7333 synchronized (mInstallLock) { 7334 return performDexOptInternalWithDependenciesLI(p, checkProfiles, 7335 targetCompilerFilter, force); 7336 } 7337 } finally { 7338 Binder.restoreCallingIdentity(callingId); 7339 } 7340 } 7341 7342 public ArraySet<String> getOptimizablePackages() { 7343 ArraySet<String> pkgs = new ArraySet<String>(); 7344 synchronized (mPackages) { 7345 for (PackageParser.Package p : mPackages.values()) { 7346 if (PackageDexOptimizer.canOptimizePackage(p)) { 7347 pkgs.add(p.packageName); 7348 } 7349 } 7350 } 7351 return pkgs; 7352 } 7353 7354 private int performDexOptInternalWithDependenciesLI(PackageParser.Package p, 7355 boolean checkProfiles, String targetCompilerFilter, 7356 boolean force) { 7357 // Select the dex optimizer based on the force parameter. 7358 // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to 7359 // allocate an object here. 7360 PackageDexOptimizer pdo = force 7361 ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer) 7362 : mPackageDexOptimizer; 7363 7364 // Optimize all dependencies first. Note: we ignore the return value and march on 7365 // on errors. 7366 Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p); 7367 final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo); 7368 if (!deps.isEmpty()) { 7369 for (PackageParser.Package depPackage : deps) { 7370 // TODO: Analyze and investigate if we (should) profile libraries. 7371 // Currently this will do a full compilation of the library by default. 7372 pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets, 7373 false /* checkProfiles */, 7374 getCompilerFilterForReason(REASON_NON_SYSTEM_LIBRARY), 7375 getOrCreateCompilerPackageStats(depPackage)); 7376 } 7377 } 7378 return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles, 7379 targetCompilerFilter, getOrCreateCompilerPackageStats(p)); 7380 } 7381 7382 Collection<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) { 7383 if (p.usesLibraries != null || p.usesOptionalLibraries != null) { 7384 ArrayList<PackageParser.Package> retValue = new ArrayList<>(); 7385 Set<String> collectedNames = new HashSet<>(); 7386 findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames); 7387 7388 retValue.remove(p); 7389 7390 return retValue; 7391 } else { 7392 return Collections.emptyList(); 7393 } 7394 } 7395 7396 private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p, 7397 Collection<PackageParser.Package> collected, Set<String> collectedNames) { 7398 if (!collectedNames.contains(p.packageName)) { 7399 collectedNames.add(p.packageName); 7400 collected.add(p); 7401 7402 if (p.usesLibraries != null) { 7403 findSharedNonSystemLibrariesRecursive(p.usesLibraries, collected, collectedNames); 7404 } 7405 if (p.usesOptionalLibraries != null) { 7406 findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries, collected, 7407 collectedNames); 7408 } 7409 } 7410 } 7411 7412 private void findSharedNonSystemLibrariesRecursive(Collection<String> libs, 7413 Collection<PackageParser.Package> collected, Set<String> collectedNames) { 7414 for (String libName : libs) { 7415 PackageParser.Package libPkg = findSharedNonSystemLibrary(libName); 7416 if (libPkg != null) { 7417 findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames); 7418 } 7419 } 7420 } 7421 7422 private PackageParser.Package findSharedNonSystemLibrary(String libName) { 7423 synchronized (mPackages) { 7424 PackageManagerService.SharedLibraryEntry lib = mSharedLibraries.get(libName); 7425 if (lib != null && lib.apk != null) { 7426 return mPackages.get(lib.apk); 7427 } 7428 } 7429 return null; 7430 } 7431 7432 public void shutdown() { 7433 mPackageUsage.writeNow(mPackages); 7434 mCompilerStats.writeNow(); 7435 } 7436 7437 @Override 7438 public void dumpProfiles(String packageName) { 7439 PackageParser.Package pkg; 7440 synchronized (mPackages) { 7441 pkg = mPackages.get(packageName); 7442 if (pkg == null) { 7443 throw new IllegalArgumentException("Unknown package: " + packageName); 7444 } 7445 } 7446 /* Only the shell, root, or the app user should be able to dump profiles. */ 7447 int callingUid = Binder.getCallingUid(); 7448 if (callingUid != Process.SHELL_UID && 7449 callingUid != Process.ROOT_UID && 7450 callingUid != pkg.applicationInfo.uid) { 7451 throw new SecurityException("dumpProfiles"); 7452 } 7453 7454 synchronized (mInstallLock) { 7455 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles"); 7456 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 7457 try { 7458 List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly(); 7459 String gid = Integer.toString(sharedGid); 7460 String codePaths = TextUtils.join(";", allCodePaths); 7461 mInstaller.dumpProfiles(gid, packageName, codePaths); 7462 } catch (InstallerException e) { 7463 Slog.w(TAG, "Failed to dump profiles", e); 7464 } 7465 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7466 } 7467 } 7468 7469 @Override 7470 public void forceDexOpt(String packageName) { 7471 enforceSystemOrRoot("forceDexOpt"); 7472 7473 PackageParser.Package pkg; 7474 synchronized (mPackages) { 7475 pkg = mPackages.get(packageName); 7476 if (pkg == null) { 7477 throw new IllegalArgumentException("Unknown package: " + packageName); 7478 } 7479 } 7480 7481 synchronized (mInstallLock) { 7482 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 7483 7484 // Whoever is calling forceDexOpt wants a fully compiled package. 7485 // Don't use profiles since that may cause compilation to be skipped. 7486 final int res = performDexOptInternalWithDependenciesLI(pkg, 7487 false /* checkProfiles */, getCompilerFilterForReason(REASON_FORCED_DEXOPT), 7488 true /* force */); 7489 7490 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7491 if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) { 7492 throw new IllegalStateException("Failed to dexopt: " + res); 7493 } 7494 } 7495 } 7496 7497 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) { 7498 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) { 7499 Slog.w(TAG, "Unable to update from " + oldPkg.name 7500 + " to " + newPkg.packageName 7501 + ": old package not in system partition"); 7502 return false; 7503 } else if (mPackages.get(oldPkg.name) != null) { 7504 Slog.w(TAG, "Unable to update from " + oldPkg.name 7505 + " to " + newPkg.packageName 7506 + ": old package still exists"); 7507 return false; 7508 } 7509 return true; 7510 } 7511 7512 void removeCodePathLI(File codePath) { 7513 if (codePath.isDirectory()) { 7514 try { 7515 mInstaller.rmPackageDir(codePath.getAbsolutePath()); 7516 } catch (InstallerException e) { 7517 Slog.w(TAG, "Failed to remove code path", e); 7518 } 7519 } else { 7520 codePath.delete(); 7521 } 7522 } 7523 7524 private int[] resolveUserIds(int userId) { 7525 return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId }; 7526 } 7527 7528 private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) { 7529 if (pkg == null) { 7530 Slog.wtf(TAG, "Package was null!", new Throwable()); 7531 return; 7532 } 7533 clearAppDataLeafLIF(pkg, userId, flags); 7534 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7535 for (int i = 0; i < childCount; i++) { 7536 clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags); 7537 } 7538 } 7539 7540 private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) { 7541 final PackageSetting ps; 7542 synchronized (mPackages) { 7543 ps = mSettings.mPackages.get(pkg.packageName); 7544 } 7545 for (int realUserId : resolveUserIds(userId)) { 7546 final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0; 7547 try { 7548 mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags, 7549 ceDataInode); 7550 } catch (InstallerException e) { 7551 Slog.w(TAG, String.valueOf(e)); 7552 } 7553 } 7554 } 7555 7556 private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) { 7557 if (pkg == null) { 7558 Slog.wtf(TAG, "Package was null!", new Throwable()); 7559 return; 7560 } 7561 destroyAppDataLeafLIF(pkg, userId, flags); 7562 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7563 for (int i = 0; i < childCount; i++) { 7564 destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags); 7565 } 7566 } 7567 7568 private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) { 7569 final PackageSetting ps; 7570 synchronized (mPackages) { 7571 ps = mSettings.mPackages.get(pkg.packageName); 7572 } 7573 for (int realUserId : resolveUserIds(userId)) { 7574 final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0; 7575 try { 7576 mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags, 7577 ceDataInode); 7578 } catch (InstallerException e) { 7579 Slog.w(TAG, String.valueOf(e)); 7580 } 7581 } 7582 } 7583 7584 private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) { 7585 if (pkg == null) { 7586 Slog.wtf(TAG, "Package was null!", new Throwable()); 7587 return; 7588 } 7589 destroyAppProfilesLeafLIF(pkg); 7590 destroyAppReferenceProfileLeafLIF(pkg, userId, true /* removeBaseMarker */); 7591 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7592 for (int i = 0; i < childCount; i++) { 7593 destroyAppProfilesLeafLIF(pkg.childPackages.get(i)); 7594 destroyAppReferenceProfileLeafLIF(pkg.childPackages.get(i), userId, 7595 true /* removeBaseMarker */); 7596 } 7597 } 7598 7599 private void destroyAppReferenceProfileLeafLIF(PackageParser.Package pkg, int userId, 7600 boolean removeBaseMarker) { 7601 if (pkg.isForwardLocked()) { 7602 return; 7603 } 7604 7605 for (String path : pkg.getAllCodePathsExcludingResourceOnly()) { 7606 try { 7607 path = PackageManagerServiceUtils.realpath(new File(path)); 7608 } catch (IOException e) { 7609 // TODO: Should we return early here ? 7610 Slog.w(TAG, "Failed to get canonical path", e); 7611 continue; 7612 } 7613 7614 final String useMarker = path.replace('/', '@'); 7615 for (int realUserId : resolveUserIds(userId)) { 7616 File profileDir = Environment.getDataProfilesDeForeignDexDirectory(realUserId); 7617 if (removeBaseMarker) { 7618 File foreignUseMark = new File(profileDir, useMarker); 7619 if (foreignUseMark.exists()) { 7620 if (!foreignUseMark.delete()) { 7621 Slog.w(TAG, "Unable to delete foreign user mark for package: " 7622 + pkg.packageName); 7623 } 7624 } 7625 } 7626 7627 File[] markers = profileDir.listFiles(); 7628 if (markers != null) { 7629 final String searchString = "@" + pkg.packageName + "@"; 7630 // We also delete all markers that contain the package name we're 7631 // uninstalling. These are associated with secondary dex-files belonging 7632 // to the package. Reconstructing the path of these dex files is messy 7633 // in general. 7634 for (File marker : markers) { 7635 if (marker.getName().indexOf(searchString) > 0) { 7636 if (!marker.delete()) { 7637 Slog.w(TAG, "Unable to delete foreign user mark for package: " 7638 + pkg.packageName); 7639 } 7640 } 7641 } 7642 } 7643 } 7644 } 7645 } 7646 7647 private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) { 7648 try { 7649 mInstaller.destroyAppProfiles(pkg.packageName); 7650 } catch (InstallerException e) { 7651 Slog.w(TAG, String.valueOf(e)); 7652 } 7653 } 7654 7655 private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) { 7656 if (pkg == null) { 7657 Slog.wtf(TAG, "Package was null!", new Throwable()); 7658 return; 7659 } 7660 clearAppProfilesLeafLIF(pkg); 7661 // We don't remove the base foreign use marker when clearing profiles because 7662 // we will rename it when the app is updated. Unlike the actual profile contents, 7663 // the foreign use marker is good across installs. 7664 destroyAppReferenceProfileLeafLIF(pkg, userId, false /* removeBaseMarker */); 7665 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7666 for (int i = 0; i < childCount; i++) { 7667 clearAppProfilesLeafLIF(pkg.childPackages.get(i)); 7668 } 7669 } 7670 7671 private void clearAppProfilesLeafLIF(PackageParser.Package pkg) { 7672 try { 7673 mInstaller.clearAppProfiles(pkg.packageName); 7674 } catch (InstallerException e) { 7675 Slog.w(TAG, String.valueOf(e)); 7676 } 7677 } 7678 7679 private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime, 7680 long lastUpdateTime) { 7681 // Set parent install/update time 7682 PackageSetting ps = (PackageSetting) pkg.mExtras; 7683 if (ps != null) { 7684 ps.firstInstallTime = firstInstallTime; 7685 ps.lastUpdateTime = lastUpdateTime; 7686 } 7687 // Set children install/update time 7688 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7689 for (int i = 0; i < childCount; i++) { 7690 PackageParser.Package childPkg = pkg.childPackages.get(i); 7691 ps = (PackageSetting) childPkg.mExtras; 7692 if (ps != null) { 7693 ps.firstInstallTime = firstInstallTime; 7694 ps.lastUpdateTime = lastUpdateTime; 7695 } 7696 } 7697 } 7698 7699 private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file, 7700 PackageParser.Package changingLib) { 7701 if (file.path != null) { 7702 usesLibraryFiles.add(file.path); 7703 return; 7704 } 7705 PackageParser.Package p = mPackages.get(file.apk); 7706 if (changingLib != null && changingLib.packageName.equals(file.apk)) { 7707 // If we are doing this while in the middle of updating a library apk, 7708 // then we need to make sure to use that new apk for determining the 7709 // dependencies here. (We haven't yet finished committing the new apk 7710 // to the package manager state.) 7711 if (p == null || p.packageName.equals(changingLib.packageName)) { 7712 p = changingLib; 7713 } 7714 } 7715 if (p != null) { 7716 usesLibraryFiles.addAll(p.getAllCodePaths()); 7717 } 7718 } 7719 7720 private void updateSharedLibrariesLPw(PackageParser.Package pkg, 7721 PackageParser.Package changingLib) throws PackageManagerException { 7722 if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) { 7723 final ArraySet<String> usesLibraryFiles = new ArraySet<>(); 7724 int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0; 7725 for (int i=0; i<N; i++) { 7726 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i)); 7727 if (file == null) { 7728 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, 7729 "Package " + pkg.packageName + " requires unavailable shared library " 7730 + pkg.usesLibraries.get(i) + "; failing!"); 7731 } 7732 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 7733 } 7734 N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0; 7735 for (int i=0; i<N; i++) { 7736 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i)); 7737 if (file == null) { 7738 Slog.w(TAG, "Package " + pkg.packageName 7739 + " desires unavailable shared library " 7740 + pkg.usesOptionalLibraries.get(i) + "; ignoring!"); 7741 } else { 7742 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 7743 } 7744 } 7745 N = usesLibraryFiles.size(); 7746 if (N > 0) { 7747 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]); 7748 } else { 7749 pkg.usesLibraryFiles = null; 7750 } 7751 } 7752 } 7753 7754 private static boolean hasString(List<String> list, List<String> which) { 7755 if (list == null) { 7756 return false; 7757 } 7758 for (int i=list.size()-1; i>=0; i--) { 7759 for (int j=which.size()-1; j>=0; j--) { 7760 if (which.get(j).equals(list.get(i))) { 7761 return true; 7762 } 7763 } 7764 } 7765 return false; 7766 } 7767 7768 private void updateAllSharedLibrariesLPw() { 7769 for (PackageParser.Package pkg : mPackages.values()) { 7770 try { 7771 updateSharedLibrariesLPw(pkg, null); 7772 } catch (PackageManagerException e) { 7773 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 7774 } 7775 } 7776 } 7777 7778 private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw( 7779 PackageParser.Package changingPkg) { 7780 ArrayList<PackageParser.Package> res = null; 7781 for (PackageParser.Package pkg : mPackages.values()) { 7782 if (hasString(pkg.usesLibraries, changingPkg.libraryNames) 7783 || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) { 7784 if (res == null) { 7785 res = new ArrayList<PackageParser.Package>(); 7786 } 7787 res.add(pkg); 7788 try { 7789 updateSharedLibrariesLPw(pkg, changingPkg); 7790 } catch (PackageManagerException e) { 7791 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 7792 } 7793 } 7794 } 7795 return res; 7796 } 7797 7798 /** 7799 * Derive the value of the {@code cpuAbiOverride} based on the provided 7800 * value and an optional stored value from the package settings. 7801 */ 7802 private static String deriveAbiOverride(String abiOverride, PackageSetting settings) { 7803 String cpuAbiOverride = null; 7804 7805 if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) { 7806 cpuAbiOverride = null; 7807 } else if (abiOverride != null) { 7808 cpuAbiOverride = abiOverride; 7809 } else if (settings != null) { 7810 cpuAbiOverride = settings.cpuAbiOverrideString; 7811 } 7812 7813 return cpuAbiOverride; 7814 } 7815 7816 private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg, 7817 final int policyFlags, int scanFlags, long currentTime, UserHandle user) 7818 throws PackageManagerException { 7819 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage"); 7820 // If the package has children and this is the first dive in the function 7821 // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see 7822 // whether all packages (parent and children) would be successfully scanned 7823 // before the actual scan since scanning mutates internal state and we want 7824 // to atomically install the package and its children. 7825 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 7826 if (pkg.childPackages != null && pkg.childPackages.size() > 0) { 7827 scanFlags |= SCAN_CHECK_ONLY; 7828 } 7829 } else { 7830 scanFlags &= ~SCAN_CHECK_ONLY; 7831 } 7832 7833 final PackageParser.Package scannedPkg; 7834 try { 7835 // Scan the parent 7836 scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags, currentTime, user); 7837 // Scan the children 7838 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7839 for (int i = 0; i < childCount; i++) { 7840 PackageParser.Package childPkg = pkg.childPackages.get(i); 7841 scanPackageLI(childPkg, policyFlags, 7842 scanFlags, currentTime, user); 7843 } 7844 } finally { 7845 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7846 } 7847 7848 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 7849 return scanPackageTracedLI(pkg, policyFlags, scanFlags, currentTime, user); 7850 } 7851 7852 return scannedPkg; 7853 } 7854 7855 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags, 7856 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 7857 boolean success = false; 7858 try { 7859 final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags, 7860 currentTime, user); 7861 success = true; 7862 return res; 7863 } finally { 7864 if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) { 7865 // DELETE_DATA_ON_FAILURES is only used by frozen paths 7866 destroyAppDataLIF(pkg, UserHandle.USER_ALL, 7867 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 7868 destroyAppProfilesLIF(pkg, UserHandle.USER_ALL); 7869 } 7870 } 7871 } 7872 7873 /** 7874 * Returns {@code true} if the given file contains code. Otherwise {@code false}. 7875 */ 7876 private static boolean apkHasCode(String fileName) { 7877 StrictJarFile jarFile = null; 7878 try { 7879 jarFile = new StrictJarFile(fileName, 7880 false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/); 7881 return jarFile.findEntry("classes.dex") != null; 7882 } catch (IOException ignore) { 7883 } finally { 7884 try { 7885 if (jarFile != null) { 7886 jarFile.close(); 7887 } 7888 } catch (IOException ignore) {} 7889 } 7890 return false; 7891 } 7892 7893 /** 7894 * Enforces code policy for the package. This ensures that if an APK has 7895 * declared hasCode="true" in its manifest that the APK actually contains 7896 * code. 7897 * 7898 * @throws PackageManagerException If bytecode could not be found when it should exist 7899 */ 7900 private static void enforceCodePolicy(PackageParser.Package pkg) 7901 throws PackageManagerException { 7902 final boolean shouldHaveCode = 7903 (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0; 7904 if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) { 7905 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 7906 "Package " + pkg.baseCodePath + " code is missing"); 7907 } 7908 7909 if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) { 7910 for (int i = 0; i < pkg.splitCodePaths.length; i++) { 7911 final boolean splitShouldHaveCode = 7912 (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0; 7913 if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) { 7914 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 7915 "Package " + pkg.splitCodePaths[i] + " code is missing"); 7916 } 7917 } 7918 } 7919 } 7920 7921 private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, 7922 final int policyFlags, final int scanFlags, long currentTime, UserHandle user) 7923 throws PackageManagerException { 7924 final File scanFile = new File(pkg.codePath); 7925 if (pkg.applicationInfo.getCodePath() == null || 7926 pkg.applicationInfo.getResourcePath() == null) { 7927 // Bail out. The resource and code paths haven't been set. 7928 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 7929 "Code and resource paths haven't been set correctly"); 7930 } 7931 7932 // Apply policy 7933 if ((policyFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 7934 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; 7935 if (pkg.applicationInfo.isDirectBootAware()) { 7936 // we're direct boot aware; set for all components 7937 for (PackageParser.Service s : pkg.services) { 7938 s.info.encryptionAware = s.info.directBootAware = true; 7939 } 7940 for (PackageParser.Provider p : pkg.providers) { 7941 p.info.encryptionAware = p.info.directBootAware = true; 7942 } 7943 for (PackageParser.Activity a : pkg.activities) { 7944 a.info.encryptionAware = a.info.directBootAware = true; 7945 } 7946 for (PackageParser.Activity r : pkg.receivers) { 7947 r.info.encryptionAware = r.info.directBootAware = true; 7948 } 7949 } 7950 } else { 7951 // Only allow system apps to be flagged as core apps. 7952 pkg.coreApp = false; 7953 // clear flags not applicable to regular apps 7954 pkg.applicationInfo.privateFlags &= 7955 ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE; 7956 pkg.applicationInfo.privateFlags &= 7957 ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE; 7958 } 7959 pkg.mTrustedOverlay = (policyFlags&PackageParser.PARSE_TRUSTED_OVERLAY) != 0; 7960 7961 if ((policyFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) { 7962 pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 7963 } 7964 7965 if ((policyFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) { 7966 enforceCodePolicy(pkg); 7967 } 7968 7969 if (mCustomResolverComponentName != null && 7970 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) { 7971 setUpCustomResolverActivity(pkg); 7972 } 7973 7974 if (pkg.packageName.equals("android")) { 7975 synchronized (mPackages) { 7976 if (mAndroidApplication != null) { 7977 Slog.w(TAG, "*************************************************"); 7978 Slog.w(TAG, "Core android package being redefined. Skipping."); 7979 Slog.w(TAG, " file=" + scanFile); 7980 Slog.w(TAG, "*************************************************"); 7981 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 7982 "Core android package being redefined. Skipping."); 7983 } 7984 7985 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 7986 // Set up information for our fall-back user intent resolution activity. 7987 mPlatformPackage = pkg; 7988 pkg.mVersionCode = mSdkVersion; 7989 mAndroidApplication = pkg.applicationInfo; 7990 7991 if (!mResolverReplaced) { 7992 mResolveActivity.applicationInfo = mAndroidApplication; 7993 mResolveActivity.name = ResolverActivity.class.getName(); 7994 mResolveActivity.packageName = mAndroidApplication.packageName; 7995 mResolveActivity.processName = "system:ui"; 7996 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 7997 mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER; 7998 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS; 7999 mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert; 8000 mResolveActivity.exported = true; 8001 mResolveActivity.enabled = true; 8002 mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE; 8003 mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE 8004 | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE 8005 | ActivityInfo.CONFIG_SCREEN_LAYOUT 8006 | ActivityInfo.CONFIG_ORIENTATION 8007 | ActivityInfo.CONFIG_KEYBOARD 8008 | ActivityInfo.CONFIG_KEYBOARD_HIDDEN; 8009 mResolveInfo.activityInfo = mResolveActivity; 8010 mResolveInfo.priority = 0; 8011 mResolveInfo.preferredOrder = 0; 8012 mResolveInfo.match = 0; 8013 mResolveComponentName = new ComponentName( 8014 mAndroidApplication.packageName, mResolveActivity.name); 8015 } 8016 } 8017 } 8018 } 8019 8020 if (DEBUG_PACKAGE_SCANNING) { 8021 if ((policyFlags & PackageParser.PARSE_CHATTY) != 0) 8022 Log.d(TAG, "Scanning package " + pkg.packageName); 8023 } 8024 8025 synchronized (mPackages) { 8026 if (mPackages.containsKey(pkg.packageName) 8027 || mSharedLibraries.containsKey(pkg.packageName)) { 8028 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 8029 "Application package " + pkg.packageName 8030 + " already installed. Skipping duplicate."); 8031 } 8032 8033 // If we're only installing presumed-existing packages, require that the 8034 // scanned APK is both already known and at the path previously established 8035 // for it. Previously unknown packages we pick up normally, but if we have an 8036 // a priori expectation about this package's install presence, enforce it. 8037 // With a singular exception for new system packages. When an OTA contains 8038 // a new system package, we allow the codepath to change from a system location 8039 // to the user-installed location. If we don't allow this change, any newer, 8040 // user-installed version of the application will be ignored. 8041 if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) { 8042 if (mExpectingBetter.containsKey(pkg.packageName)) { 8043 logCriticalInfo(Log.WARN, 8044 "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName); 8045 } else { 8046 PackageSetting known = mSettings.peekPackageLPr(pkg.packageName); 8047 if (known != null) { 8048 if (DEBUG_PACKAGE_SCANNING) { 8049 Log.d(TAG, "Examining " + pkg.codePath 8050 + " and requiring known paths " + known.codePathString 8051 + " & " + known.resourcePathString); 8052 } 8053 if (!pkg.applicationInfo.getCodePath().equals(known.codePathString) 8054 || !pkg.applicationInfo.getResourcePath().equals( 8055 known.resourcePathString)) { 8056 throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED, 8057 "Application package " + pkg.packageName 8058 + " found at " + pkg.applicationInfo.getCodePath() 8059 + " but expected at " + known.codePathString 8060 + "; ignoring."); 8061 } 8062 } 8063 } 8064 } 8065 } 8066 8067 // Initialize package source and resource directories 8068 File destCodeFile = new File(pkg.applicationInfo.getCodePath()); 8069 File destResourceFile = new File(pkg.applicationInfo.getResourcePath()); 8070 8071 SharedUserSetting suid = null; 8072 PackageSetting pkgSetting = null; 8073 8074 if (!isSystemApp(pkg)) { 8075 // Only system apps can use these features. 8076 pkg.mOriginalPackages = null; 8077 pkg.mRealPackage = null; 8078 pkg.mAdoptPermissions = null; 8079 } 8080 8081 // Getting the package setting may have a side-effect, so if we 8082 // are only checking if scan would succeed, stash a copy of the 8083 // old setting to restore at the end. 8084 PackageSetting nonMutatedPs = null; 8085 8086 // writer 8087 synchronized (mPackages) { 8088 if (pkg.mSharedUserId != null) { 8089 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, true); 8090 if (suid == null) { 8091 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 8092 "Creating application package " + pkg.packageName 8093 + " for shared user failed"); 8094 } 8095 if (DEBUG_PACKAGE_SCANNING) { 8096 if ((policyFlags & PackageParser.PARSE_CHATTY) != 0) 8097 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId 8098 + "): packages=" + suid.packages); 8099 } 8100 } 8101 8102 // Check if we are renaming from an original package name. 8103 PackageSetting origPackage = null; 8104 String realName = null; 8105 if (pkg.mOriginalPackages != null) { 8106 // This package may need to be renamed to a previously 8107 // installed name. Let's check on that... 8108 final String renamed = mSettings.getRenamedPackage(pkg.mRealPackage); 8109 if (pkg.mOriginalPackages.contains(renamed)) { 8110 // This package had originally been installed as the 8111 // original name, and we have already taken care of 8112 // transitioning to the new one. Just update the new 8113 // one to continue using the old name. 8114 realName = pkg.mRealPackage; 8115 if (!pkg.packageName.equals(renamed)) { 8116 // Callers into this function may have already taken 8117 // care of renaming the package; only do it here if 8118 // it is not already done. 8119 pkg.setPackageName(renamed); 8120 } 8121 8122 } else { 8123 for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) { 8124 if ((origPackage = mSettings.peekPackageLPr( 8125 pkg.mOriginalPackages.get(i))) != null) { 8126 // We do have the package already installed under its 8127 // original name... should we use it? 8128 if (!verifyPackageUpdateLPr(origPackage, pkg)) { 8129 // New package is not compatible with original. 8130 origPackage = null; 8131 continue; 8132 } else if (origPackage.sharedUser != null) { 8133 // Make sure uid is compatible between packages. 8134 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) { 8135 Slog.w(TAG, "Unable to migrate data from " + origPackage.name 8136 + " to " + pkg.packageName + ": old uid " 8137 + origPackage.sharedUser.name 8138 + " differs from " + pkg.mSharedUserId); 8139 origPackage = null; 8140 continue; 8141 } 8142 // TODO: Add case when shared user id is added [b/28144775] 8143 } else { 8144 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package " 8145 + pkg.packageName + " to old name " + origPackage.name); 8146 } 8147 break; 8148 } 8149 } 8150 } 8151 } 8152 8153 if (mTransferedPackages.contains(pkg.packageName)) { 8154 Slog.w(TAG, "Package " + pkg.packageName 8155 + " was transferred to another, but its .apk remains"); 8156 } 8157 8158 // See comments in nonMutatedPs declaration 8159 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 8160 PackageSetting foundPs = mSettings.peekPackageLPr(pkg.packageName); 8161 if (foundPs != null) { 8162 nonMutatedPs = new PackageSetting(foundPs); 8163 } 8164 } 8165 8166 // Just create the setting, don't add it yet. For already existing packages 8167 // the PkgSetting exists already and doesn't have to be created. 8168 pkgSetting = mSettings.getPackageWithBenefitsLPw(pkg, origPackage, realName, suid, 8169 destCodeFile, destResourceFile, pkg.applicationInfo.nativeLibraryRootDir, 8170 pkg.applicationInfo.primaryCpuAbi, 8171 pkg.applicationInfo.secondaryCpuAbi, 8172 pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, 8173 user); 8174 if (pkgSetting == null) { 8175 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 8176 "Creating application package " + pkg.packageName + " failed"); 8177 } 8178 8179 if (pkgSetting.origPackage != null) { 8180 // If we are first transitioning from an original package, 8181 // fix up the new package's name now. We need to do this after 8182 // looking up the package under its new name, so getPackageLP 8183 // can take care of fiddling things correctly. 8184 pkg.setPackageName(origPackage.name); 8185 8186 // File a report about this. 8187 String msg = "New package " + pkgSetting.realName 8188 + " renamed to replace old package " + pkgSetting.name; 8189 reportSettingsProblem(Log.WARN, msg); 8190 8191 // Make a note of it. 8192 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 8193 mTransferedPackages.add(origPackage.name); 8194 } 8195 8196 // No longer need to retain this. 8197 pkgSetting.origPackage = null; 8198 } 8199 8200 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) { 8201 // Make a note of it. 8202 mTransferedPackages.add(pkg.packageName); 8203 } 8204 8205 if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) { 8206 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 8207 } 8208 8209 if ((policyFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 8210 // Check all shared libraries and map to their actual file path. 8211 // We only do this here for apps not on a system dir, because those 8212 // are the only ones that can fail an install due to this. We 8213 // will take care of the system apps by updating all of their 8214 // library paths after the scan is done. 8215 updateSharedLibrariesLPw(pkg, null); 8216 } 8217 8218 if (mFoundPolicyFile) { 8219 SELinuxMMAC.assignSeinfoValue(pkg); 8220 } 8221 8222 pkg.applicationInfo.uid = pkgSetting.appId; 8223 pkg.mExtras = pkgSetting; 8224 if (shouldCheckUpgradeKeySetLP(pkgSetting, scanFlags)) { 8225 if (checkUpgradeKeySetLP(pkgSetting, pkg)) { 8226 // We just determined the app is signed correctly, so bring 8227 // over the latest parsed certs. 8228 pkgSetting.signatures.mSignatures = pkg.mSignatures; 8229 } else { 8230 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 8231 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 8232 "Package " + pkg.packageName + " upgrade keys do not match the " 8233 + "previously installed version"); 8234 } else { 8235 pkgSetting.signatures.mSignatures = pkg.mSignatures; 8236 String msg = "System package " + pkg.packageName 8237 + " signature changed; retaining data."; 8238 reportSettingsProblem(Log.WARN, msg); 8239 } 8240 } 8241 } else { 8242 try { 8243 verifySignaturesLP(pkgSetting, pkg); 8244 // We just determined the app is signed correctly, so bring 8245 // over the latest parsed certs. 8246 pkgSetting.signatures.mSignatures = pkg.mSignatures; 8247 } catch (PackageManagerException e) { 8248 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 8249 throw e; 8250 } 8251 // The signature has changed, but this package is in the system 8252 // image... let's recover! 8253 pkgSetting.signatures.mSignatures = pkg.mSignatures; 8254 // However... if this package is part of a shared user, but it 8255 // doesn't match the signature of the shared user, let's fail. 8256 // What this means is that you can't change the signatures 8257 // associated with an overall shared user, which doesn't seem all 8258 // that unreasonable. 8259 if (pkgSetting.sharedUser != null) { 8260 if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 8261 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { 8262 throw new PackageManagerException( 8263 INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES, 8264 "Signature mismatch for shared user: " 8265 + pkgSetting.sharedUser); 8266 } 8267 } 8268 // File a report about this. 8269 String msg = "System package " + pkg.packageName 8270 + " signature changed; retaining data."; 8271 reportSettingsProblem(Log.WARN, msg); 8272 } 8273 } 8274 // Verify that this new package doesn't have any content providers 8275 // that conflict with existing packages. Only do this if the 8276 // package isn't already installed, since we don't want to break 8277 // things that are installed. 8278 if ((scanFlags & SCAN_NEW_INSTALL) != 0) { 8279 final int N = pkg.providers.size(); 8280 int i; 8281 for (i=0; i<N; i++) { 8282 PackageParser.Provider p = pkg.providers.get(i); 8283 if (p.info.authority != null) { 8284 String names[] = p.info.authority.split(";"); 8285 for (int j = 0; j < names.length; j++) { 8286 if (mProvidersByAuthority.containsKey(names[j])) { 8287 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 8288 final String otherPackageName = 8289 ((other != null && other.getComponentName() != null) ? 8290 other.getComponentName().getPackageName() : "?"); 8291 throw new PackageManagerException( 8292 INSTALL_FAILED_CONFLICTING_PROVIDER, 8293 "Can't install because provider name " + names[j] 8294 + " (in package " + pkg.applicationInfo.packageName 8295 + ") is already used by " + otherPackageName); 8296 } 8297 } 8298 } 8299 } 8300 } 8301 8302 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) { 8303 // This package wants to adopt ownership of permissions from 8304 // another package. 8305 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) { 8306 final String origName = pkg.mAdoptPermissions.get(i); 8307 final PackageSetting orig = mSettings.peekPackageLPr(origName); 8308 if (orig != null) { 8309 if (verifyPackageUpdateLPr(orig, pkg)) { 8310 Slog.i(TAG, "Adopting permissions from " + origName + " to " 8311 + pkg.packageName); 8312 mSettings.transferPermissionsLPw(origName, pkg.packageName); 8313 } 8314 } 8315 } 8316 } 8317 } 8318 8319 final String pkgName = pkg.packageName; 8320 8321 final long scanFileTime = getLastModifiedTime(pkg, scanFile); 8322 final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0; 8323 pkg.applicationInfo.processName = fixProcessName( 8324 pkg.applicationInfo.packageName, 8325 pkg.applicationInfo.processName, 8326 pkg.applicationInfo.uid); 8327 8328 if (pkg != mPlatformPackage) { 8329 // Get all of our default paths setup 8330 pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM); 8331 } 8332 8333 final String path = scanFile.getPath(); 8334 final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting); 8335 8336 if ((scanFlags & SCAN_NEW_INSTALL) == 0) { 8337 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi"); 8338 derivePackageAbi(pkg, scanFile, cpuAbiOverride, true /*extractLibs*/); 8339 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 8340 8341 // Some system apps still use directory structure for native libraries 8342 // in which case we might end up not detecting abi solely based on apk 8343 // structure. Try to detect abi based on directory structure. 8344 if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() && 8345 pkg.applicationInfo.primaryCpuAbi == null) { 8346 setBundledAppAbisAndRoots(pkg, pkgSetting); 8347 setNativeLibraryPaths(pkg); 8348 } 8349 8350 } else { 8351 if ((scanFlags & SCAN_MOVE) != 0) { 8352 // We haven't run dex-opt for this move (since we've moved the compiled output too) 8353 // but we already have this packages package info in the PackageSetting. We just 8354 // use that and derive the native library path based on the new codepath. 8355 pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString; 8356 pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString; 8357 } 8358 8359 // Set native library paths again. For moves, the path will be updated based on the 8360 // ABIs we've determined above. For non-moves, the path will be updated based on the 8361 // ABIs we determined during compilation, but the path will depend on the final 8362 // package path (after the rename away from the stage path). 8363 setNativeLibraryPaths(pkg); 8364 } 8365 8366 // This is a special case for the "system" package, where the ABI is 8367 // dictated by the zygote configuration (and init.rc). We should keep track 8368 // of this ABI so that we can deal with "normal" applications that run under 8369 // the same UID correctly. 8370 if (mPlatformPackage == pkg) { 8371 pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ? 8372 Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]; 8373 } 8374 8375 // If there's a mismatch between the abi-override in the package setting 8376 // and the abiOverride specified for the install. Warn about this because we 8377 // would've already compiled the app without taking the package setting into 8378 // account. 8379 if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) { 8380 if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) { 8381 Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride + 8382 " for package " + pkg.packageName); 8383 } 8384 } 8385 8386 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 8387 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 8388 pkgSetting.cpuAbiOverrideString = cpuAbiOverride; 8389 8390 // Copy the derived override back to the parsed package, so that we can 8391 // update the package settings accordingly. 8392 pkg.cpuAbiOverride = cpuAbiOverride; 8393 8394 if (DEBUG_ABI_SELECTION) { 8395 Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName 8396 + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa=" 8397 + pkg.applicationInfo.nativeLibraryRootRequiresIsa); 8398 } 8399 8400 // Push the derived path down into PackageSettings so we know what to 8401 // clean up at uninstall time. 8402 pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir; 8403 8404 if (DEBUG_ABI_SELECTION) { 8405 Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" + 8406 " primary=" + pkg.applicationInfo.primaryCpuAbi + 8407 " secondary=" + pkg.applicationInfo.secondaryCpuAbi); 8408 } 8409 8410 if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) { 8411 // We don't do this here during boot because we can do it all 8412 // at once after scanning all existing packages. 8413 // 8414 // We also do this *before* we perform dexopt on this package, so that 8415 // we can avoid redundant dexopts, and also to make sure we've got the 8416 // code and package path correct. 8417 adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, 8418 pkg, true /* boot complete */); 8419 } 8420 8421 if (mFactoryTest && pkg.requestedPermissions.contains( 8422 android.Manifest.permission.FACTORY_TEST)) { 8423 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST; 8424 } 8425 8426 ArrayList<PackageParser.Package> clientLibPkgs = null; 8427 8428 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 8429 if (nonMutatedPs != null) { 8430 synchronized (mPackages) { 8431 mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs); 8432 } 8433 } 8434 return pkg; 8435 } 8436 8437 // Only privileged apps and updated privileged apps can add child packages. 8438 if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) { 8439 if ((policyFlags & PARSE_IS_PRIVILEGED) == 0) { 8440 throw new PackageManagerException("Only privileged apps and updated " 8441 + "privileged apps can add child packages. Ignoring package " 8442 + pkg.packageName); 8443 } 8444 final int childCount = pkg.childPackages.size(); 8445 for (int i = 0; i < childCount; i++) { 8446 PackageParser.Package childPkg = pkg.childPackages.get(i); 8447 if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName, 8448 childPkg.packageName)) { 8449 throw new PackageManagerException("Cannot override a child package of " 8450 + "another disabled system app. Ignoring package " + pkg.packageName); 8451 } 8452 } 8453 } 8454 8455 // writer 8456 synchronized (mPackages) { 8457 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 8458 // Only system apps can add new shared libraries. 8459 if (pkg.libraryNames != null) { 8460 for (int i=0; i<pkg.libraryNames.size(); i++) { 8461 String name = pkg.libraryNames.get(i); 8462 boolean allowed = false; 8463 if (pkg.isUpdatedSystemApp()) { 8464 // New library entries can only be added through the 8465 // system image. This is important to get rid of a lot 8466 // of nasty edge cases: for example if we allowed a non- 8467 // system update of the app to add a library, then uninstalling 8468 // the update would make the library go away, and assumptions 8469 // we made such as through app install filtering would now 8470 // have allowed apps on the device which aren't compatible 8471 // with it. Better to just have the restriction here, be 8472 // conservative, and create many fewer cases that can negatively 8473 // impact the user experience. 8474 final PackageSetting sysPs = mSettings 8475 .getDisabledSystemPkgLPr(pkg.packageName); 8476 if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) { 8477 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) { 8478 if (name.equals(sysPs.pkg.libraryNames.get(j))) { 8479 allowed = true; 8480 break; 8481 } 8482 } 8483 } 8484 } else { 8485 allowed = true; 8486 } 8487 if (allowed) { 8488 if (!mSharedLibraries.containsKey(name)) { 8489 mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName)); 8490 } else if (!name.equals(pkg.packageName)) { 8491 Slog.w(TAG, "Package " + pkg.packageName + " library " 8492 + name + " already exists; skipping"); 8493 } 8494 } else { 8495 Slog.w(TAG, "Package " + pkg.packageName + " declares lib " 8496 + name + " that is not declared on system image; skipping"); 8497 } 8498 } 8499 if ((scanFlags & SCAN_BOOTING) == 0) { 8500 // If we are not booting, we need to update any applications 8501 // that are clients of our shared library. If we are booting, 8502 // this will all be done once the scan is complete. 8503 clientLibPkgs = updateAllSharedLibrariesLPw(pkg); 8504 } 8505 } 8506 } 8507 } 8508 8509 if ((scanFlags & SCAN_BOOTING) != 0) { 8510 // No apps can run during boot scan, so they don't need to be frozen 8511 } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) { 8512 // Caller asked to not kill app, so it's probably not frozen 8513 } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) { 8514 // Caller asked us to ignore frozen check for some reason; they 8515 // probably didn't know the package name 8516 } else { 8517 // We're doing major surgery on this package, so it better be frozen 8518 // right now to keep it from launching 8519 checkPackageFrozen(pkgName); 8520 } 8521 8522 // Also need to kill any apps that are dependent on the library. 8523 if (clientLibPkgs != null) { 8524 for (int i=0; i<clientLibPkgs.size(); i++) { 8525 PackageParser.Package clientPkg = clientLibPkgs.get(i); 8526 killApplication(clientPkg.applicationInfo.packageName, 8527 clientPkg.applicationInfo.uid, "update lib"); 8528 } 8529 } 8530 8531 // Make sure we're not adding any bogus keyset info 8532 KeySetManagerService ksms = mSettings.mKeySetManagerService; 8533 ksms.assertScannedPackageValid(pkg); 8534 8535 // writer 8536 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 8537 8538 boolean createIdmapFailed = false; 8539 synchronized (mPackages) { 8540 // We don't expect installation to fail beyond this point 8541 8542 if (pkgSetting.pkg != null) { 8543 // Note that |user| might be null during the initial boot scan. If a codePath 8544 // for an app has changed during a boot scan, it's due to an app update that's 8545 // part of the system partition and marker changes must be applied to all users. 8546 maybeRenameForeignDexMarkers(pkgSetting.pkg, pkg, 8547 (user != null) ? user : UserHandle.ALL); 8548 } 8549 8550 // Add the new setting to mSettings 8551 mSettings.insertPackageSettingLPw(pkgSetting, pkg); 8552 // Add the new setting to mPackages 8553 mPackages.put(pkg.applicationInfo.packageName, pkg); 8554 // Make sure we don't accidentally delete its data. 8555 final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator(); 8556 while (iter.hasNext()) { 8557 PackageCleanItem item = iter.next(); 8558 if (pkgName.equals(item.packageName)) { 8559 iter.remove(); 8560 } 8561 } 8562 8563 // Take care of first install / last update times. 8564 if (currentTime != 0) { 8565 if (pkgSetting.firstInstallTime == 0) { 8566 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime; 8567 } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) { 8568 pkgSetting.lastUpdateTime = currentTime; 8569 } 8570 } else if (pkgSetting.firstInstallTime == 0) { 8571 // We need *something*. Take time time stamp of the file. 8572 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime; 8573 } else if ((policyFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) { 8574 if (scanFileTime != pkgSetting.timeStamp) { 8575 // A package on the system image has changed; consider this 8576 // to be an update. 8577 pkgSetting.lastUpdateTime = scanFileTime; 8578 } 8579 } 8580 8581 // Add the package's KeySets to the global KeySetManagerService 8582 ksms.addScannedPackageLPw(pkg); 8583 8584 int N = pkg.providers.size(); 8585 StringBuilder r = null; 8586 int i; 8587 for (i=0; i<N; i++) { 8588 PackageParser.Provider p = pkg.providers.get(i); 8589 p.info.processName = fixProcessName(pkg.applicationInfo.processName, 8590 p.info.processName, pkg.applicationInfo.uid); 8591 mProviders.addProvider(p); 8592 p.syncable = p.info.isSyncable; 8593 if (p.info.authority != null) { 8594 String names[] = p.info.authority.split(";"); 8595 p.info.authority = null; 8596 for (int j = 0; j < names.length; j++) { 8597 if (j == 1 && p.syncable) { 8598 // We only want the first authority for a provider to possibly be 8599 // syncable, so if we already added this provider using a different 8600 // authority clear the syncable flag. We copy the provider before 8601 // changing it because the mProviders object contains a reference 8602 // to a provider that we don't want to change. 8603 // Only do this for the second authority since the resulting provider 8604 // object can be the same for all future authorities for this provider. 8605 p = new PackageParser.Provider(p); 8606 p.syncable = false; 8607 } 8608 if (!mProvidersByAuthority.containsKey(names[j])) { 8609 mProvidersByAuthority.put(names[j], p); 8610 if (p.info.authority == null) { 8611 p.info.authority = names[j]; 8612 } else { 8613 p.info.authority = p.info.authority + ";" + names[j]; 8614 } 8615 if (DEBUG_PACKAGE_SCANNING) { 8616 if ((policyFlags & PackageParser.PARSE_CHATTY) != 0) 8617 Log.d(TAG, "Registered content provider: " + names[j] 8618 + ", className = " + p.info.name + ", isSyncable = " 8619 + p.info.isSyncable); 8620 } 8621 } else { 8622 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 8623 Slog.w(TAG, "Skipping provider name " + names[j] + 8624 " (in package " + pkg.applicationInfo.packageName + 8625 "): name already used by " 8626 + ((other != null && other.getComponentName() != null) 8627 ? other.getComponentName().getPackageName() : "?")); 8628 } 8629 } 8630 } 8631 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) { 8632 if (r == null) { 8633 r = new StringBuilder(256); 8634 } else { 8635 r.append(' '); 8636 } 8637 r.append(p.info.name); 8638 } 8639 } 8640 if (r != null) { 8641 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r); 8642 } 8643 8644 N = pkg.services.size(); 8645 r = null; 8646 for (i=0; i<N; i++) { 8647 PackageParser.Service s = pkg.services.get(i); 8648 s.info.processName = fixProcessName(pkg.applicationInfo.processName, 8649 s.info.processName, pkg.applicationInfo.uid); 8650 mServices.addService(s); 8651 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) { 8652 if (r == null) { 8653 r = new StringBuilder(256); 8654 } else { 8655 r.append(' '); 8656 } 8657 r.append(s.info.name); 8658 } 8659 } 8660 if (r != null) { 8661 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r); 8662 } 8663 8664 N = pkg.receivers.size(); 8665 r = null; 8666 for (i=0; i<N; i++) { 8667 PackageParser.Activity a = pkg.receivers.get(i); 8668 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 8669 a.info.processName, pkg.applicationInfo.uid); 8670 mReceivers.addActivity(a, "receiver"); 8671 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) { 8672 if (r == null) { 8673 r = new StringBuilder(256); 8674 } else { 8675 r.append(' '); 8676 } 8677 r.append(a.info.name); 8678 } 8679 } 8680 if (r != null) { 8681 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r); 8682 } 8683 8684 N = pkg.activities.size(); 8685 r = null; 8686 for (i=0; i<N; i++) { 8687 PackageParser.Activity a = pkg.activities.get(i); 8688 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 8689 a.info.processName, pkg.applicationInfo.uid); 8690 mActivities.addActivity(a, "activity"); 8691 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) { 8692 if (r == null) { 8693 r = new StringBuilder(256); 8694 } else { 8695 r.append(' '); 8696 } 8697 r.append(a.info.name); 8698 } 8699 } 8700 if (r != null) { 8701 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r); 8702 } 8703 8704 N = pkg.permissionGroups.size(); 8705 r = null; 8706 for (i=0; i<N; i++) { 8707 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i); 8708 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name); 8709 if (cur == null) { 8710 mPermissionGroups.put(pg.info.name, pg); 8711 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) { 8712 if (r == null) { 8713 r = new StringBuilder(256); 8714 } else { 8715 r.append(' '); 8716 } 8717 r.append(pg.info.name); 8718 } 8719 } else { 8720 Slog.w(TAG, "Permission group " + pg.info.name + " from package " 8721 + pg.info.packageName + " ignored: original from " 8722 + cur.info.packageName); 8723 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) { 8724 if (r == null) { 8725 r = new StringBuilder(256); 8726 } else { 8727 r.append(' '); 8728 } 8729 r.append("DUP:"); 8730 r.append(pg.info.name); 8731 } 8732 } 8733 } 8734 if (r != null) { 8735 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permission Groups: " + r); 8736 } 8737 8738 N = pkg.permissions.size(); 8739 r = null; 8740 for (i=0; i<N; i++) { 8741 PackageParser.Permission p = pkg.permissions.get(i); 8742 8743 // Assume by default that we did not install this permission into the system. 8744 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED; 8745 8746 // Now that permission groups have a special meaning, we ignore permission 8747 // groups for legacy apps to prevent unexpected behavior. In particular, 8748 // permissions for one app being granted to someone just becase they happen 8749 // to be in a group defined by another app (before this had no implications). 8750 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) { 8751 p.group = mPermissionGroups.get(p.info.group); 8752 // Warn for a permission in an unknown group. 8753 if (p.info.group != null && p.group == null) { 8754 Slog.w(TAG, "Permission " + p.info.name + " from package " 8755 + p.info.packageName + " in an unknown group " + p.info.group); 8756 } 8757 } 8758 8759 ArrayMap<String, BasePermission> permissionMap = 8760 p.tree ? mSettings.mPermissionTrees 8761 : mSettings.mPermissions; 8762 BasePermission bp = permissionMap.get(p.info.name); 8763 8764 // Allow system apps to redefine non-system permissions 8765 if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) { 8766 final boolean currentOwnerIsSystem = (bp.perm != null 8767 && isSystemApp(bp.perm.owner)); 8768 if (isSystemApp(p.owner)) { 8769 if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) { 8770 // It's a built-in permission and no owner, take ownership now 8771 bp.packageSetting = pkgSetting; 8772 bp.perm = p; 8773 bp.uid = pkg.applicationInfo.uid; 8774 bp.sourcePackage = p.info.packageName; 8775 p.info.flags |= PermissionInfo.FLAG_INSTALLED; 8776 } else if (!currentOwnerIsSystem) { 8777 String msg = "New decl " + p.owner + " of permission " 8778 + p.info.name + " is system; overriding " + bp.sourcePackage; 8779 reportSettingsProblem(Log.WARN, msg); 8780 bp = null; 8781 } 8782 } 8783 } 8784 8785 if (bp == null) { 8786 bp = new BasePermission(p.info.name, p.info.packageName, 8787 BasePermission.TYPE_NORMAL); 8788 permissionMap.put(p.info.name, bp); 8789 } 8790 8791 if (bp.perm == null) { 8792 if (bp.sourcePackage == null 8793 || bp.sourcePackage.equals(p.info.packageName)) { 8794 BasePermission tree = findPermissionTreeLP(p.info.name); 8795 if (tree == null 8796 || tree.sourcePackage.equals(p.info.packageName)) { 8797 bp.packageSetting = pkgSetting; 8798 bp.perm = p; 8799 bp.uid = pkg.applicationInfo.uid; 8800 bp.sourcePackage = p.info.packageName; 8801 p.info.flags |= PermissionInfo.FLAG_INSTALLED; 8802 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) { 8803 if (r == null) { 8804 r = new StringBuilder(256); 8805 } else { 8806 r.append(' '); 8807 } 8808 r.append(p.info.name); 8809 } 8810 } else { 8811 Slog.w(TAG, "Permission " + p.info.name + " from package " 8812 + p.info.packageName + " ignored: base tree " 8813 + tree.name + " is from package " 8814 + tree.sourcePackage); 8815 } 8816 } else { 8817 Slog.w(TAG, "Permission " + p.info.name + " from package " 8818 + p.info.packageName + " ignored: original from " 8819 + bp.sourcePackage); 8820 } 8821 } else if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) { 8822 if (r == null) { 8823 r = new StringBuilder(256); 8824 } else { 8825 r.append(' '); 8826 } 8827 r.append("DUP:"); 8828 r.append(p.info.name); 8829 } 8830 if (bp.perm == p) { 8831 bp.protectionLevel = p.info.protectionLevel; 8832 } 8833 } 8834 8835 if (r != null) { 8836 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permissions: " + r); 8837 } 8838 8839 N = pkg.instrumentation.size(); 8840 r = null; 8841 for (i=0; i<N; i++) { 8842 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 8843 a.info.packageName = pkg.applicationInfo.packageName; 8844 a.info.sourceDir = pkg.applicationInfo.sourceDir; 8845 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir; 8846 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs; 8847 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs; 8848 a.info.dataDir = pkg.applicationInfo.dataDir; 8849 a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir; 8850 a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir; 8851 8852 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir; 8853 a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir; 8854 mInstrumentation.put(a.getComponentName(), a); 8855 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) { 8856 if (r == null) { 8857 r = new StringBuilder(256); 8858 } else { 8859 r.append(' '); 8860 } 8861 r.append(a.info.name); 8862 } 8863 } 8864 if (r != null) { 8865 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r); 8866 } 8867 8868 if (pkg.protectedBroadcasts != null) { 8869 N = pkg.protectedBroadcasts.size(); 8870 for (i=0; i<N; i++) { 8871 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i)); 8872 } 8873 } 8874 8875 pkgSetting.setTimeStamp(scanFileTime); 8876 8877 // Create idmap files for pairs of (packages, overlay packages). 8878 // Note: "android", ie framework-res.apk, is handled by native layers. 8879 if (pkg.mOverlayTarget != null) { 8880 // This is an overlay package. 8881 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) { 8882 if (!mOverlays.containsKey(pkg.mOverlayTarget)) { 8883 mOverlays.put(pkg.mOverlayTarget, 8884 new ArrayMap<String, PackageParser.Package>()); 8885 } 8886 ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget); 8887 map.put(pkg.packageName, pkg); 8888 PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget); 8889 if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) { 8890 createIdmapFailed = true; 8891 } 8892 } 8893 } else if (mOverlays.containsKey(pkg.packageName) && 8894 !pkg.packageName.equals("android")) { 8895 // This is a regular package, with one or more known overlay packages. 8896 createIdmapsForPackageLI(pkg); 8897 } 8898 } 8899 8900 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 8901 8902 if (createIdmapFailed) { 8903 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 8904 "scanPackageLI failed to createIdmap"); 8905 } 8906 return pkg; 8907 } 8908 8909 private void maybeRenameForeignDexMarkers(PackageParser.Package existing, 8910 PackageParser.Package update, UserHandle user) { 8911 if (existing.applicationInfo == null || update.applicationInfo == null) { 8912 // This isn't due to an app installation. 8913 return; 8914 } 8915 8916 final File oldCodePath = new File(existing.applicationInfo.getCodePath()); 8917 final File newCodePath = new File(update.applicationInfo.getCodePath()); 8918 8919 // The codePath hasn't changed, so there's nothing for us to do. 8920 if (Objects.equals(oldCodePath, newCodePath)) { 8921 return; 8922 } 8923 8924 File canonicalNewCodePath; 8925 try { 8926 canonicalNewCodePath = new File(PackageManagerServiceUtils.realpath(newCodePath)); 8927 } catch (IOException e) { 8928 Slog.w(TAG, "Failed to get canonical path.", e); 8929 return; 8930 } 8931 8932 // This is a bit of a hack. The oldCodePath doesn't exist at this point (because 8933 // we've already renamed / deleted it) so we cannot call realpath on it. Here we assume 8934 // that the last component of the path (i.e, the name) doesn't need canonicalization 8935 // (i.e, that it isn't ".", ".." or a symbolic link). This is a valid assumption for now 8936 // but may change in the future. Hopefully this function won't exist at that point. 8937 final File canonicalOldCodePath = new File(canonicalNewCodePath.getParentFile(), 8938 oldCodePath.getName()); 8939 8940 // Calculate the prefixes of the markers. These are just the paths with "/" replaced 8941 // with "@". 8942 String oldMarkerPrefix = canonicalOldCodePath.getAbsolutePath().replace('/', '@'); 8943 if (!oldMarkerPrefix.endsWith("@")) { 8944 oldMarkerPrefix += "@"; 8945 } 8946 String newMarkerPrefix = canonicalNewCodePath.getAbsolutePath().replace('/', '@'); 8947 if (!newMarkerPrefix.endsWith("@")) { 8948 newMarkerPrefix += "@"; 8949 } 8950 8951 List<String> updatedPaths = update.getAllCodePathsExcludingResourceOnly(); 8952 List<String> markerSuffixes = new ArrayList<String>(updatedPaths.size()); 8953 for (String updatedPath : updatedPaths) { 8954 String updatedPathName = new File(updatedPath).getName(); 8955 markerSuffixes.add(updatedPathName.replace('/', '@')); 8956 } 8957 8958 for (int userId : resolveUserIds(user.getIdentifier())) { 8959 File profileDir = Environment.getDataProfilesDeForeignDexDirectory(userId); 8960 8961 for (String markerSuffix : markerSuffixes) { 8962 File oldForeignUseMark = new File(profileDir, oldMarkerPrefix + markerSuffix); 8963 File newForeignUseMark = new File(profileDir, newMarkerPrefix + markerSuffix); 8964 if (oldForeignUseMark.exists()) { 8965 try { 8966 Os.rename(oldForeignUseMark.getAbsolutePath(), 8967 newForeignUseMark.getAbsolutePath()); 8968 } catch (ErrnoException e) { 8969 Slog.w(TAG, "Failed to rename foreign use marker", e); 8970 oldForeignUseMark.delete(); 8971 } 8972 } 8973 } 8974 } 8975 } 8976 8977 /** 8978 * Derive the ABI of a non-system package located at {@code scanFile}. This information 8979 * is derived purely on the basis of the contents of {@code scanFile} and 8980 * {@code cpuAbiOverride}. 8981 * 8982 * If {@code extractLibs} is true, native libraries are extracted from the app if required. 8983 */ 8984 private void derivePackageAbi(PackageParser.Package pkg, File scanFile, 8985 String cpuAbiOverride, boolean extractLibs) 8986 throws PackageManagerException { 8987 // TODO: We can probably be smarter about this stuff. For installed apps, 8988 // we can calculate this information at install time once and for all. For 8989 // system apps, we can probably assume that this information doesn't change 8990 // after the first boot scan. As things stand, we do lots of unnecessary work. 8991 8992 // Give ourselves some initial paths; we'll come back for another 8993 // pass once we've determined ABI below. 8994 setNativeLibraryPaths(pkg); 8995 8996 // We would never need to extract libs for forward-locked and external packages, 8997 // since the container service will do it for us. We shouldn't attempt to 8998 // extract libs from system app when it was not updated. 8999 if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() || 9000 (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) { 9001 extractLibs = false; 9002 } 9003 9004 final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir; 9005 final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa; 9006 9007 NativeLibraryHelper.Handle handle = null; 9008 try { 9009 handle = NativeLibraryHelper.Handle.create(pkg); 9010 // TODO(multiArch): This can be null for apps that didn't go through the 9011 // usual installation process. We can calculate it again, like we 9012 // do during install time. 9013 // 9014 // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally 9015 // unnecessary. 9016 final File nativeLibraryRoot = new File(nativeLibraryRootStr); 9017 9018 // Null out the abis so that they can be recalculated. 9019 pkg.applicationInfo.primaryCpuAbi = null; 9020 pkg.applicationInfo.secondaryCpuAbi = null; 9021 if (isMultiArch(pkg.applicationInfo)) { 9022 // Warn if we've set an abiOverride for multi-lib packages.. 9023 // By definition, we need to copy both 32 and 64 bit libraries for 9024 // such packages. 9025 if (pkg.cpuAbiOverride != null 9026 && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) { 9027 Slog.w(TAG, "Ignoring abiOverride for multi arch application."); 9028 } 9029 9030 int abi32 = PackageManager.NO_NATIVE_LIBRARIES; 9031 int abi64 = PackageManager.NO_NATIVE_LIBRARIES; 9032 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) { 9033 if (extractLibs) { 9034 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries"); 9035 abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 9036 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS, 9037 useIsaSpecificSubdirs); 9038 } else { 9039 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi"); 9040 abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS); 9041 } 9042 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 9043 } 9044 9045 maybeThrowExceptionForMultiArchCopy( 9046 "Error unpackaging 32 bit native libs for multiarch app.", abi32); 9047 9048 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) { 9049 if (extractLibs) { 9050 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries"); 9051 abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 9052 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS, 9053 useIsaSpecificSubdirs); 9054 } else { 9055 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi"); 9056 abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS); 9057 } 9058 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 9059 } 9060 9061 maybeThrowExceptionForMultiArchCopy( 9062 "Error unpackaging 64 bit native libs for multiarch app.", abi64); 9063 9064 if (abi64 >= 0) { 9065 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64]; 9066 } 9067 9068 if (abi32 >= 0) { 9069 final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32]; 9070 if (abi64 >= 0) { 9071 if (pkg.use32bitAbi) { 9072 pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi; 9073 pkg.applicationInfo.primaryCpuAbi = abi; 9074 } else { 9075 pkg.applicationInfo.secondaryCpuAbi = abi; 9076 } 9077 } else { 9078 pkg.applicationInfo.primaryCpuAbi = abi; 9079 } 9080 } 9081 9082 } else { 9083 String[] abiList = (cpuAbiOverride != null) ? 9084 new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS; 9085 9086 // Enable gross and lame hacks for apps that are built with old 9087 // SDK tools. We must scan their APKs for renderscript bitcode and 9088 // not launch them if it's present. Don't bother checking on devices 9089 // that don't have 64 bit support. 9090 boolean needsRenderScriptOverride = false; 9091 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null && 9092 NativeLibraryHelper.hasRenderscriptBitcode(handle)) { 9093 abiList = Build.SUPPORTED_32_BIT_ABIS; 9094 needsRenderScriptOverride = true; 9095 } 9096 9097 final int copyRet; 9098 if (extractLibs) { 9099 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries"); 9100 copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 9101 nativeLibraryRoot, abiList, useIsaSpecificSubdirs); 9102 } else { 9103 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi"); 9104 copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList); 9105 } 9106 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 9107 9108 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { 9109 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, 9110 "Error unpackaging native libs for app, errorCode=" + copyRet); 9111 } 9112 9113 if (copyRet >= 0) { 9114 pkg.applicationInfo.primaryCpuAbi = abiList[copyRet]; 9115 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) { 9116 pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride; 9117 } else if (needsRenderScriptOverride) { 9118 pkg.applicationInfo.primaryCpuAbi = abiList[0]; 9119 } 9120 } 9121 } catch (IOException ioe) { 9122 Slog.e(TAG, "Unable to get canonical file " + ioe.toString()); 9123 } finally { 9124 IoUtils.closeQuietly(handle); 9125 } 9126 9127 // Now that we've calculated the ABIs and determined if it's an internal app, 9128 // we will go ahead and populate the nativeLibraryPath. 9129 setNativeLibraryPaths(pkg); 9130 } 9131 9132 /** 9133 * Adjusts ABIs for a set of packages belonging to a shared user so that they all match. 9134 * i.e, so that all packages can be run inside a single process if required. 9135 * 9136 * Optionally, callers can pass in a parsed package via {@code newPackage} in which case 9137 * this function will either try and make the ABI for all packages in {@code packagesForUser} 9138 * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match 9139 * the ABI selected for {@code packagesForUser}. This variant is used when installing or 9140 * updating a package that belongs to a shared user. 9141 * 9142 * NOTE: We currently only match for the primary CPU abi string. Matching the secondary 9143 * adds unnecessary complexity. 9144 */ 9145 private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser, 9146 PackageParser.Package scannedPackage, boolean bootComplete) { 9147 String requiredInstructionSet = null; 9148 if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) { 9149 requiredInstructionSet = VMRuntime.getInstructionSet( 9150 scannedPackage.applicationInfo.primaryCpuAbi); 9151 } 9152 9153 PackageSetting requirer = null; 9154 for (PackageSetting ps : packagesForUser) { 9155 // If packagesForUser contains scannedPackage, we skip it. This will happen 9156 // when scannedPackage is an update of an existing package. Without this check, 9157 // we will never be able to change the ABI of any package belonging to a shared 9158 // user, even if it's compatible with other packages. 9159 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 9160 if (ps.primaryCpuAbiString == null) { 9161 continue; 9162 } 9163 9164 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString); 9165 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) { 9166 // We have a mismatch between instruction sets (say arm vs arm64) warn about 9167 // this but there's not much we can do. 9168 String errorMessage = "Instruction set mismatch, " 9169 + ((requirer == null) ? "[caller]" : requirer) 9170 + " requires " + requiredInstructionSet + " whereas " + ps 9171 + " requires " + instructionSet; 9172 Slog.w(TAG, errorMessage); 9173 } 9174 9175 if (requiredInstructionSet == null) { 9176 requiredInstructionSet = instructionSet; 9177 requirer = ps; 9178 } 9179 } 9180 } 9181 9182 if (requiredInstructionSet != null) { 9183 String adjustedAbi; 9184 if (requirer != null) { 9185 // requirer != null implies that either scannedPackage was null or that scannedPackage 9186 // did not require an ABI, in which case we have to adjust scannedPackage to match 9187 // the ABI of the set (which is the same as requirer's ABI) 9188 adjustedAbi = requirer.primaryCpuAbiString; 9189 if (scannedPackage != null) { 9190 scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi; 9191 } 9192 } else { 9193 // requirer == null implies that we're updating all ABIs in the set to 9194 // match scannedPackage. 9195 adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi; 9196 } 9197 9198 for (PackageSetting ps : packagesForUser) { 9199 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 9200 if (ps.primaryCpuAbiString != null) { 9201 continue; 9202 } 9203 9204 ps.primaryCpuAbiString = adjustedAbi; 9205 if (ps.pkg != null && ps.pkg.applicationInfo != null && 9206 !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) { 9207 ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi; 9208 Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi 9209 + " (requirer=" 9210 + (requirer == null ? "null" : requirer.pkg.packageName) 9211 + ", scannedPackage=" 9212 + (scannedPackage != null ? scannedPackage.packageName : "null") 9213 + ")"); 9214 try { 9215 mInstaller.rmdex(ps.codePathString, 9216 getDexCodeInstructionSet(getPreferredInstructionSet())); 9217 } catch (InstallerException ignored) { 9218 } 9219 } 9220 } 9221 } 9222 } 9223 } 9224 9225 private void setUpCustomResolverActivity(PackageParser.Package pkg) { 9226 synchronized (mPackages) { 9227 mResolverReplaced = true; 9228 // Set up information for custom user intent resolution activity. 9229 mResolveActivity.applicationInfo = pkg.applicationInfo; 9230 mResolveActivity.name = mCustomResolverComponentName.getClassName(); 9231 mResolveActivity.packageName = pkg.applicationInfo.packageName; 9232 mResolveActivity.processName = pkg.applicationInfo.packageName; 9233 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 9234 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS | 9235 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 9236 mResolveActivity.theme = 0; 9237 mResolveActivity.exported = true; 9238 mResolveActivity.enabled = true; 9239 mResolveInfo.activityInfo = mResolveActivity; 9240 mResolveInfo.priority = 0; 9241 mResolveInfo.preferredOrder = 0; 9242 mResolveInfo.match = 0; 9243 mResolveComponentName = mCustomResolverComponentName; 9244 Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " + 9245 mResolveComponentName); 9246 } 9247 } 9248 9249 private void setUpEphemeralInstallerActivityLP(ComponentName installerComponent) { 9250 final PackageParser.Package pkg = mPackages.get(installerComponent.getPackageName()); 9251 9252 // Set up information for ephemeral installer activity 9253 mEphemeralInstallerActivity.applicationInfo = pkg.applicationInfo; 9254 mEphemeralInstallerActivity.name = mEphemeralInstallerComponent.getClassName(); 9255 mEphemeralInstallerActivity.packageName = pkg.applicationInfo.packageName; 9256 mEphemeralInstallerActivity.processName = pkg.applicationInfo.packageName; 9257 mEphemeralInstallerActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 9258 mEphemeralInstallerActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS 9259 | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 9260 mEphemeralInstallerActivity.theme = 0; 9261 mEphemeralInstallerActivity.exported = true; 9262 mEphemeralInstallerActivity.enabled = true; 9263 mEphemeralInstallerInfo.activityInfo = mEphemeralInstallerActivity; 9264 mEphemeralInstallerInfo.priority = 0; 9265 mEphemeralInstallerInfo.preferredOrder = 1; 9266 mEphemeralInstallerInfo.isDefault = true; 9267 mEphemeralInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART 9268 | IntentFilter.MATCH_ADJUSTMENT_NORMAL; 9269 9270 if (DEBUG_EPHEMERAL) { 9271 Slog.d(TAG, "Set ephemeral installer activity: " + mEphemeralInstallerComponent); 9272 } 9273 } 9274 9275 private static String calculateBundledApkRoot(final String codePathString) { 9276 final File codePath = new File(codePathString); 9277 final File codeRoot; 9278 if (FileUtils.contains(Environment.getRootDirectory(), codePath)) { 9279 codeRoot = Environment.getRootDirectory(); 9280 } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) { 9281 codeRoot = Environment.getOemDirectory(); 9282 } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) { 9283 codeRoot = Environment.getVendorDirectory(); 9284 } else { 9285 // Unrecognized code path; take its top real segment as the apk root: 9286 // e.g. /something/app/blah.apk => /something 9287 try { 9288 File f = codePath.getCanonicalFile(); 9289 File parent = f.getParentFile(); // non-null because codePath is a file 9290 File tmp; 9291 while ((tmp = parent.getParentFile()) != null) { 9292 f = parent; 9293 parent = tmp; 9294 } 9295 codeRoot = f; 9296 Slog.w(TAG, "Unrecognized code path " 9297 + codePath + " - using " + codeRoot); 9298 } catch (IOException e) { 9299 // Can't canonicalize the code path -- shenanigans? 9300 Slog.w(TAG, "Can't canonicalize code path " + codePath); 9301 return Environment.getRootDirectory().getPath(); 9302 } 9303 } 9304 return codeRoot.getPath(); 9305 } 9306 9307 /** 9308 * Derive and set the location of native libraries for the given package, 9309 * which varies depending on where and how the package was installed. 9310 */ 9311 private void setNativeLibraryPaths(PackageParser.Package pkg) { 9312 final ApplicationInfo info = pkg.applicationInfo; 9313 final String codePath = pkg.codePath; 9314 final File codeFile = new File(codePath); 9315 final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp(); 9316 final boolean asecApp = info.isForwardLocked() || info.isExternalAsec(); 9317 9318 info.nativeLibraryRootDir = null; 9319 info.nativeLibraryRootRequiresIsa = false; 9320 info.nativeLibraryDir = null; 9321 info.secondaryNativeLibraryDir = null; 9322 9323 if (isApkFile(codeFile)) { 9324 // Monolithic install 9325 if (bundledApp) { 9326 // If "/system/lib64/apkname" exists, assume that is the per-package 9327 // native library directory to use; otherwise use "/system/lib/apkname". 9328 final String apkRoot = calculateBundledApkRoot(info.sourceDir); 9329 final boolean is64Bit = VMRuntime.is64BitInstructionSet( 9330 getPrimaryInstructionSet(info)); 9331 9332 // This is a bundled system app so choose the path based on the ABI. 9333 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this 9334 // is just the default path. 9335 final String apkName = deriveCodePathName(codePath); 9336 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME; 9337 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir, 9338 apkName).getAbsolutePath(); 9339 9340 if (info.secondaryCpuAbi != null) { 9341 final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME; 9342 info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot), 9343 secondaryLibDir, apkName).getAbsolutePath(); 9344 } 9345 } else if (asecApp) { 9346 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME) 9347 .getAbsolutePath(); 9348 } else { 9349 final String apkName = deriveCodePathName(codePath); 9350 info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName) 9351 .getAbsolutePath(); 9352 } 9353 9354 info.nativeLibraryRootRequiresIsa = false; 9355 info.nativeLibraryDir = info.nativeLibraryRootDir; 9356 } else { 9357 // Cluster install 9358 info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath(); 9359 info.nativeLibraryRootRequiresIsa = true; 9360 9361 info.nativeLibraryDir = new File(info.nativeLibraryRootDir, 9362 getPrimaryInstructionSet(info)).getAbsolutePath(); 9363 9364 if (info.secondaryCpuAbi != null) { 9365 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir, 9366 VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath(); 9367 } 9368 } 9369 } 9370 9371 /** 9372 * Calculate the abis and roots for a bundled app. These can uniquely 9373 * be determined from the contents of the system partition, i.e whether 9374 * it contains 64 or 32 bit shared libraries etc. We do not validate any 9375 * of this information, and instead assume that the system was built 9376 * sensibly. 9377 */ 9378 private void setBundledAppAbisAndRoots(PackageParser.Package pkg, 9379 PackageSetting pkgSetting) { 9380 final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath()); 9381 9382 // If "/system/lib64/apkname" exists, assume that is the per-package 9383 // native library directory to use; otherwise use "/system/lib/apkname". 9384 final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir); 9385 setBundledAppAbi(pkg, apkRoot, apkName); 9386 // pkgSetting might be null during rescan following uninstall of updates 9387 // to a bundled app, so accommodate that possibility. The settings in 9388 // that case will be established later from the parsed package. 9389 // 9390 // If the settings aren't null, sync them up with what we've just derived. 9391 // note that apkRoot isn't stored in the package settings. 9392 if (pkgSetting != null) { 9393 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 9394 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 9395 } 9396 } 9397 9398 /** 9399 * Deduces the ABI of a bundled app and sets the relevant fields on the 9400 * parsed pkg object. 9401 * 9402 * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem} 9403 * under which system libraries are installed. 9404 * @param apkName the name of the installed package. 9405 */ 9406 private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) { 9407 final File codeFile = new File(pkg.codePath); 9408 9409 final boolean has64BitLibs; 9410 final boolean has32BitLibs; 9411 if (isApkFile(codeFile)) { 9412 // Monolithic install 9413 has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists(); 9414 has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists(); 9415 } else { 9416 // Cluster install 9417 final File rootDir = new File(codeFile, LIB_DIR_NAME); 9418 if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS) 9419 && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) { 9420 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]); 9421 has64BitLibs = (new File(rootDir, isa)).exists(); 9422 } else { 9423 has64BitLibs = false; 9424 } 9425 if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS) 9426 && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) { 9427 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]); 9428 has32BitLibs = (new File(rootDir, isa)).exists(); 9429 } else { 9430 has32BitLibs = false; 9431 } 9432 } 9433 9434 if (has64BitLibs && !has32BitLibs) { 9435 // The package has 64 bit libs, but not 32 bit libs. Its primary 9436 // ABI should be 64 bit. We can safely assume here that the bundled 9437 // native libraries correspond to the most preferred ABI in the list. 9438 9439 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 9440 pkg.applicationInfo.secondaryCpuAbi = null; 9441 } else if (has32BitLibs && !has64BitLibs) { 9442 // The package has 32 bit libs but not 64 bit libs. Its primary 9443 // ABI should be 32 bit. 9444 9445 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 9446 pkg.applicationInfo.secondaryCpuAbi = null; 9447 } else if (has32BitLibs && has64BitLibs) { 9448 // The application has both 64 and 32 bit bundled libraries. We check 9449 // here that the app declares multiArch support, and warn if it doesn't. 9450 // 9451 // We will be lenient here and record both ABIs. The primary will be the 9452 // ABI that's higher on the list, i.e, a device that's configured to prefer 9453 // 64 bit apps will see a 64 bit primary ABI, 9454 9455 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) { 9456 Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch."); 9457 } 9458 9459 if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) { 9460 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 9461 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 9462 } else { 9463 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 9464 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 9465 } 9466 } else { 9467 pkg.applicationInfo.primaryCpuAbi = null; 9468 pkg.applicationInfo.secondaryCpuAbi = null; 9469 } 9470 } 9471 9472 private void killApplication(String pkgName, int appId, String reason) { 9473 killApplication(pkgName, appId, UserHandle.USER_ALL, reason); 9474 } 9475 9476 private void killApplication(String pkgName, int appId, int userId, String reason) { 9477 // Request the ActivityManager to kill the process(only for existing packages) 9478 // so that we do not end up in a confused state while the user is still using the older 9479 // version of the application while the new one gets installed. 9480 final long token = Binder.clearCallingIdentity(); 9481 try { 9482 IActivityManager am = ActivityManagerNative.getDefault(); 9483 if (am != null) { 9484 try { 9485 am.killApplication(pkgName, appId, userId, reason); 9486 } catch (RemoteException e) { 9487 } 9488 } 9489 } finally { 9490 Binder.restoreCallingIdentity(token); 9491 } 9492 } 9493 9494 private void removePackageLI(PackageParser.Package pkg, boolean chatty) { 9495 // Remove the parent package setting 9496 PackageSetting ps = (PackageSetting) pkg.mExtras; 9497 if (ps != null) { 9498 removePackageLI(ps, chatty); 9499 } 9500 // Remove the child package setting 9501 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 9502 for (int i = 0; i < childCount; i++) { 9503 PackageParser.Package childPkg = pkg.childPackages.get(i); 9504 ps = (PackageSetting) childPkg.mExtras; 9505 if (ps != null) { 9506 removePackageLI(ps, chatty); 9507 } 9508 } 9509 } 9510 9511 void removePackageLI(PackageSetting ps, boolean chatty) { 9512 if (DEBUG_INSTALL) { 9513 if (chatty) 9514 Log.d(TAG, "Removing package " + ps.name); 9515 } 9516 9517 // writer 9518 synchronized (mPackages) { 9519 mPackages.remove(ps.name); 9520 final PackageParser.Package pkg = ps.pkg; 9521 if (pkg != null) { 9522 cleanPackageDataStructuresLILPw(pkg, chatty); 9523 } 9524 } 9525 } 9526 9527 void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) { 9528 if (DEBUG_INSTALL) { 9529 if (chatty) 9530 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName); 9531 } 9532 9533 // writer 9534 synchronized (mPackages) { 9535 // Remove the parent package 9536 mPackages.remove(pkg.applicationInfo.packageName); 9537 cleanPackageDataStructuresLILPw(pkg, chatty); 9538 9539 // Remove the child packages 9540 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 9541 for (int i = 0; i < childCount; i++) { 9542 PackageParser.Package childPkg = pkg.childPackages.get(i); 9543 mPackages.remove(childPkg.applicationInfo.packageName); 9544 cleanPackageDataStructuresLILPw(childPkg, chatty); 9545 } 9546 } 9547 } 9548 9549 void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) { 9550 int N = pkg.providers.size(); 9551 StringBuilder r = null; 9552 int i; 9553 for (i=0; i<N; i++) { 9554 PackageParser.Provider p = pkg.providers.get(i); 9555 mProviders.removeProvider(p); 9556 if (p.info.authority == null) { 9557 9558 /* There was another ContentProvider with this authority when 9559 * this app was installed so this authority is null, 9560 * Ignore it as we don't have to unregister the provider. 9561 */ 9562 continue; 9563 } 9564 String names[] = p.info.authority.split(";"); 9565 for (int j = 0; j < names.length; j++) { 9566 if (mProvidersByAuthority.get(names[j]) == p) { 9567 mProvidersByAuthority.remove(names[j]); 9568 if (DEBUG_REMOVE) { 9569 if (chatty) 9570 Log.d(TAG, "Unregistered content provider: " + names[j] 9571 + ", className = " + p.info.name + ", isSyncable = " 9572 + p.info.isSyncable); 9573 } 9574 } 9575 } 9576 if (DEBUG_REMOVE && chatty) { 9577 if (r == null) { 9578 r = new StringBuilder(256); 9579 } else { 9580 r.append(' '); 9581 } 9582 r.append(p.info.name); 9583 } 9584 } 9585 if (r != null) { 9586 if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r); 9587 } 9588 9589 N = pkg.services.size(); 9590 r = null; 9591 for (i=0; i<N; i++) { 9592 PackageParser.Service s = pkg.services.get(i); 9593 mServices.removeService(s); 9594 if (chatty) { 9595 if (r == null) { 9596 r = new StringBuilder(256); 9597 } else { 9598 r.append(' '); 9599 } 9600 r.append(s.info.name); 9601 } 9602 } 9603 if (r != null) { 9604 if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r); 9605 } 9606 9607 N = pkg.receivers.size(); 9608 r = null; 9609 for (i=0; i<N; i++) { 9610 PackageParser.Activity a = pkg.receivers.get(i); 9611 mReceivers.removeActivity(a, "receiver"); 9612 if (DEBUG_REMOVE && chatty) { 9613 if (r == null) { 9614 r = new StringBuilder(256); 9615 } else { 9616 r.append(' '); 9617 } 9618 r.append(a.info.name); 9619 } 9620 } 9621 if (r != null) { 9622 if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r); 9623 } 9624 9625 N = pkg.activities.size(); 9626 r = null; 9627 for (i=0; i<N; i++) { 9628 PackageParser.Activity a = pkg.activities.get(i); 9629 mActivities.removeActivity(a, "activity"); 9630 if (DEBUG_REMOVE && chatty) { 9631 if (r == null) { 9632 r = new StringBuilder(256); 9633 } else { 9634 r.append(' '); 9635 } 9636 r.append(a.info.name); 9637 } 9638 } 9639 if (r != null) { 9640 if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r); 9641 } 9642 9643 N = pkg.permissions.size(); 9644 r = null; 9645 for (i=0; i<N; i++) { 9646 PackageParser.Permission p = pkg.permissions.get(i); 9647 BasePermission bp = mSettings.mPermissions.get(p.info.name); 9648 if (bp == null) { 9649 bp = mSettings.mPermissionTrees.get(p.info.name); 9650 } 9651 if (bp != null && bp.perm == p) { 9652 bp.perm = null; 9653 if (DEBUG_REMOVE && chatty) { 9654 if (r == null) { 9655 r = new StringBuilder(256); 9656 } else { 9657 r.append(' '); 9658 } 9659 r.append(p.info.name); 9660 } 9661 } 9662 if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 9663 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name); 9664 if (appOpPkgs != null) { 9665 appOpPkgs.remove(pkg.packageName); 9666 } 9667 } 9668 } 9669 if (r != null) { 9670 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 9671 } 9672 9673 N = pkg.requestedPermissions.size(); 9674 r = null; 9675 for (i=0; i<N; i++) { 9676 String perm = pkg.requestedPermissions.get(i); 9677 BasePermission bp = mSettings.mPermissions.get(perm); 9678 if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 9679 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm); 9680 if (appOpPkgs != null) { 9681 appOpPkgs.remove(pkg.packageName); 9682 if (appOpPkgs.isEmpty()) { 9683 mAppOpPermissionPackages.remove(perm); 9684 } 9685 } 9686 } 9687 } 9688 if (r != null) { 9689 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 9690 } 9691 9692 N = pkg.instrumentation.size(); 9693 r = null; 9694 for (i=0; i<N; i++) { 9695 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 9696 mInstrumentation.remove(a.getComponentName()); 9697 if (DEBUG_REMOVE && chatty) { 9698 if (r == null) { 9699 r = new StringBuilder(256); 9700 } else { 9701 r.append(' '); 9702 } 9703 r.append(a.info.name); 9704 } 9705 } 9706 if (r != null) { 9707 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r); 9708 } 9709 9710 r = null; 9711 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9712 // Only system apps can hold shared libraries. 9713 if (pkg.libraryNames != null) { 9714 for (i=0; i<pkg.libraryNames.size(); i++) { 9715 String name = pkg.libraryNames.get(i); 9716 SharedLibraryEntry cur = mSharedLibraries.get(name); 9717 if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) { 9718 mSharedLibraries.remove(name); 9719 if (DEBUG_REMOVE && chatty) { 9720 if (r == null) { 9721 r = new StringBuilder(256); 9722 } else { 9723 r.append(' '); 9724 } 9725 r.append(name); 9726 } 9727 } 9728 } 9729 } 9730 } 9731 if (r != null) { 9732 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r); 9733 } 9734 } 9735 9736 private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) { 9737 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) { 9738 if (pkgInfo.permissions.get(i).info.name.equals(perm)) { 9739 return true; 9740 } 9741 } 9742 return false; 9743 } 9744 9745 static final int UPDATE_PERMISSIONS_ALL = 1<<0; 9746 static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1; 9747 static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2; 9748 9749 private void updatePermissionsLPw(PackageParser.Package pkg, int flags) { 9750 // Update the parent permissions 9751 updatePermissionsLPw(pkg.packageName, pkg, flags); 9752 // Update the child permissions 9753 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 9754 for (int i = 0; i < childCount; i++) { 9755 PackageParser.Package childPkg = pkg.childPackages.get(i); 9756 updatePermissionsLPw(childPkg.packageName, childPkg, flags); 9757 } 9758 } 9759 9760 private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo, 9761 int flags) { 9762 final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null; 9763 updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags); 9764 } 9765 9766 private void updatePermissionsLPw(String changingPkg, 9767 PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) { 9768 // Make sure there are no dangling permission trees. 9769 Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator(); 9770 while (it.hasNext()) { 9771 final BasePermission bp = it.next(); 9772 if (bp.packageSetting == null) { 9773 // We may not yet have parsed the package, so just see if 9774 // we still know about its settings. 9775 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 9776 } 9777 if (bp.packageSetting == null) { 9778 Slog.w(TAG, "Removing dangling permission tree: " + bp.name 9779 + " from package " + bp.sourcePackage); 9780 it.remove(); 9781 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 9782 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 9783 Slog.i(TAG, "Removing old permission tree: " + bp.name 9784 + " from package " + bp.sourcePackage); 9785 flags |= UPDATE_PERMISSIONS_ALL; 9786 it.remove(); 9787 } 9788 } 9789 } 9790 9791 // Make sure all dynamic permissions have been assigned to a package, 9792 // and make sure there are no dangling permissions. 9793 it = mSettings.mPermissions.values().iterator(); 9794 while (it.hasNext()) { 9795 final BasePermission bp = it.next(); 9796 if (bp.type == BasePermission.TYPE_DYNAMIC) { 9797 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name=" 9798 + bp.name + " pkg=" + bp.sourcePackage 9799 + " info=" + bp.pendingInfo); 9800 if (bp.packageSetting == null && bp.pendingInfo != null) { 9801 final BasePermission tree = findPermissionTreeLP(bp.name); 9802 if (tree != null && tree.perm != null) { 9803 bp.packageSetting = tree.packageSetting; 9804 bp.perm = new PackageParser.Permission(tree.perm.owner, 9805 new PermissionInfo(bp.pendingInfo)); 9806 bp.perm.info.packageName = tree.perm.info.packageName; 9807 bp.perm.info.name = bp.name; 9808 bp.uid = tree.uid; 9809 } 9810 } 9811 } 9812 if (bp.packageSetting == null) { 9813 // We may not yet have parsed the package, so just see if 9814 // we still know about its settings. 9815 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 9816 } 9817 if (bp.packageSetting == null) { 9818 Slog.w(TAG, "Removing dangling permission: " + bp.name 9819 + " from package " + bp.sourcePackage); 9820 it.remove(); 9821 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 9822 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 9823 Slog.i(TAG, "Removing old permission: " + bp.name 9824 + " from package " + bp.sourcePackage); 9825 flags |= UPDATE_PERMISSIONS_ALL; 9826 it.remove(); 9827 } 9828 } 9829 } 9830 9831 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions"); 9832 // Now update the permissions for all packages, in particular 9833 // replace the granted permissions of the system packages. 9834 if ((flags&UPDATE_PERMISSIONS_ALL) != 0) { 9835 for (PackageParser.Package pkg : mPackages.values()) { 9836 if (pkg != pkgInfo) { 9837 // Only replace for packages on requested volume 9838 final String volumeUuid = getVolumeUuidForPackage(pkg); 9839 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0) 9840 && Objects.equals(replaceVolumeUuid, volumeUuid); 9841 grantPermissionsLPw(pkg, replace, changingPkg); 9842 } 9843 } 9844 } 9845 9846 if (pkgInfo != null) { 9847 // Only replace for packages on requested volume 9848 final String volumeUuid = getVolumeUuidForPackage(pkgInfo); 9849 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0) 9850 && Objects.equals(replaceVolumeUuid, volumeUuid); 9851 grantPermissionsLPw(pkgInfo, replace, changingPkg); 9852 } 9853 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 9854 } 9855 9856 private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace, 9857 String packageOfInterest) { 9858 // IMPORTANT: There are two types of permissions: install and runtime. 9859 // Install time permissions are granted when the app is installed to 9860 // all device users and users added in the future. Runtime permissions 9861 // are granted at runtime explicitly to specific users. Normal and signature 9862 // protected permissions are install time permissions. Dangerous permissions 9863 // are install permissions if the app's target SDK is Lollipop MR1 or older, 9864 // otherwise they are runtime permissions. This function does not manage 9865 // runtime permissions except for the case an app targeting Lollipop MR1 9866 // being upgraded to target a newer SDK, in which case dangerous permissions 9867 // are transformed from install time to runtime ones. 9868 9869 final PackageSetting ps = (PackageSetting) pkg.mExtras; 9870 if (ps == null) { 9871 return; 9872 } 9873 9874 PermissionsState permissionsState = ps.getPermissionsState(); 9875 PermissionsState origPermissions = permissionsState; 9876 9877 final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); 9878 9879 boolean runtimePermissionsRevoked = false; 9880 int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY; 9881 9882 boolean changedInstallPermission = false; 9883 9884 if (replace) { 9885 ps.installPermissionsFixed = false; 9886 if (!ps.isSharedUser()) { 9887 origPermissions = new PermissionsState(permissionsState); 9888 permissionsState.reset(); 9889 } else { 9890 // We need to know only about runtime permission changes since the 9891 // calling code always writes the install permissions state but 9892 // the runtime ones are written only if changed. The only cases of 9893 // changed runtime permissions here are promotion of an install to 9894 // runtime and revocation of a runtime from a shared user. 9895 changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw( 9896 ps.sharedUser, UserManagerService.getInstance().getUserIds()); 9897 if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) { 9898 runtimePermissionsRevoked = true; 9899 } 9900 } 9901 } 9902 9903 permissionsState.setGlobalGids(mGlobalGids); 9904 9905 final int N = pkg.requestedPermissions.size(); 9906 for (int i=0; i<N; i++) { 9907 final String name = pkg.requestedPermissions.get(i); 9908 final BasePermission bp = mSettings.mPermissions.get(name); 9909 9910 if (DEBUG_INSTALL) { 9911 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp); 9912 } 9913 9914 if (bp == null || bp.packageSetting == null) { 9915 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 9916 Slog.w(TAG, "Unknown permission " + name 9917 + " in package " + pkg.packageName); 9918 } 9919 continue; 9920 } 9921 9922 final String perm = bp.name; 9923 boolean allowedSig = false; 9924 int grant = GRANT_DENIED; 9925 9926 // Keep track of app op permissions. 9927 if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 9928 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name); 9929 if (pkgs == null) { 9930 pkgs = new ArraySet<>(); 9931 mAppOpPermissionPackages.put(bp.name, pkgs); 9932 } 9933 pkgs.add(pkg.packageName); 9934 } 9935 9936 final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; 9937 final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion 9938 >= Build.VERSION_CODES.M; 9939 switch (level) { 9940 case PermissionInfo.PROTECTION_NORMAL: { 9941 // For all apps normal permissions are install time ones. 9942 grant = GRANT_INSTALL; 9943 } break; 9944 9945 case PermissionInfo.PROTECTION_DANGEROUS: { 9946 // If a permission review is required for legacy apps we represent 9947 // their permissions as always granted runtime ones since we need 9948 // to keep the review required permission flag per user while an 9949 // install permission's state is shared across all users. 9950 if (!appSupportsRuntimePermissions && !mPermissionReviewRequired 9951 && !Build.PERMISSIONS_REVIEW_REQUIRED) { 9952 // For legacy apps dangerous permissions are install time ones. 9953 grant = GRANT_INSTALL; 9954 } else if (origPermissions.hasInstallPermission(bp.name)) { 9955 // For legacy apps that became modern, install becomes runtime. 9956 grant = GRANT_UPGRADE; 9957 } else if (mPromoteSystemApps 9958 && isSystemApp(ps) 9959 && mExistingSystemPackages.contains(ps.name)) { 9960 // For legacy system apps, install becomes runtime. 9961 // We cannot check hasInstallPermission() for system apps since those 9962 // permissions were granted implicitly and not persisted pre-M. 9963 grant = GRANT_UPGRADE; 9964 } else { 9965 // For modern apps keep runtime permissions unchanged. 9966 grant = GRANT_RUNTIME; 9967 } 9968 } break; 9969 9970 case PermissionInfo.PROTECTION_SIGNATURE: { 9971 // For all apps signature permissions are install time ones. 9972 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions); 9973 if (allowedSig) { 9974 grant = GRANT_INSTALL; 9975 } 9976 } break; 9977 } 9978 9979 if (DEBUG_INSTALL) { 9980 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm); 9981 } 9982 9983 if (grant != GRANT_DENIED) { 9984 if (!isSystemApp(ps) && ps.installPermissionsFixed) { 9985 // If this is an existing, non-system package, then 9986 // we can't add any new permissions to it. 9987 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) { 9988 // Except... if this is a permission that was added 9989 // to the platform (note: need to only do this when 9990 // updating the platform). 9991 if (!isNewPlatformPermissionForPackage(perm, pkg)) { 9992 grant = GRANT_DENIED; 9993 } 9994 } 9995 } 9996 9997 switch (grant) { 9998 case GRANT_INSTALL: { 9999 // Revoke this as runtime permission to handle the case of 10000 // a runtime permission being downgraded to an install one. 10001 // Also in permission review mode we keep dangerous permissions 10002 // for legacy apps 10003 for (int userId : UserManagerService.getInstance().getUserIds()) { 10004 if (origPermissions.getRuntimePermissionState( 10005 bp.name, userId) != null) { 10006 // Revoke the runtime permission and clear the flags. 10007 origPermissions.revokeRuntimePermission(bp, userId); 10008 origPermissions.updatePermissionFlags(bp, userId, 10009 PackageManager.MASK_PERMISSION_FLAGS, 0); 10010 // If we revoked a permission permission, we have to write. 10011 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 10012 changedRuntimePermissionUserIds, userId); 10013 } 10014 } 10015 // Grant an install permission. 10016 if (permissionsState.grantInstallPermission(bp) != 10017 PermissionsState.PERMISSION_OPERATION_FAILURE) { 10018 changedInstallPermission = true; 10019 } 10020 } break; 10021 10022 case GRANT_RUNTIME: { 10023 // Grant previously granted runtime permissions. 10024 for (int userId : UserManagerService.getInstance().getUserIds()) { 10025 PermissionState permissionState = origPermissions 10026 .getRuntimePermissionState(bp.name, userId); 10027 int flags = permissionState != null 10028 ? permissionState.getFlags() : 0; 10029 if (origPermissions.hasRuntimePermission(bp.name, userId)) { 10030 if (permissionsState.grantRuntimePermission(bp, userId) == 10031 PermissionsState.PERMISSION_OPERATION_FAILURE) { 10032 // If we cannot put the permission as it was, we have to write. 10033 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 10034 changedRuntimePermissionUserIds, userId); 10035 } 10036 // If the app supports runtime permissions no need for a review. 10037 if ((mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED) 10038 && appSupportsRuntimePermissions 10039 && (flags & PackageManager 10040 .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) { 10041 flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 10042 // Since we changed the flags, we have to write. 10043 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 10044 changedRuntimePermissionUserIds, userId); 10045 } 10046 } else if ((mPermissionReviewRequired 10047 || Build.PERMISSIONS_REVIEW_REQUIRED) 10048 && !appSupportsRuntimePermissions) { 10049 // For legacy apps that need a permission review, every new 10050 // runtime permission is granted but it is pending a review. 10051 // We also need to review only platform defined runtime 10052 // permissions as these are the only ones the platform knows 10053 // how to disable the API to simulate revocation as legacy 10054 // apps don't expect to run with revoked permissions. 10055 if (PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage)) { 10056 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) { 10057 flags |= FLAG_PERMISSION_REVIEW_REQUIRED; 10058 // We changed the flags, hence have to write. 10059 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 10060 changedRuntimePermissionUserIds, userId); 10061 } 10062 } 10063 if (permissionsState.grantRuntimePermission(bp, userId) 10064 != PermissionsState.PERMISSION_OPERATION_FAILURE) { 10065 // We changed the permission, hence have to write. 10066 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 10067 changedRuntimePermissionUserIds, userId); 10068 } 10069 } 10070 // Propagate the permission flags. 10071 permissionsState.updatePermissionFlags(bp, userId, flags, flags); 10072 } 10073 } break; 10074 10075 case GRANT_UPGRADE: { 10076 // Grant runtime permissions for a previously held install permission. 10077 PermissionState permissionState = origPermissions 10078 .getInstallPermissionState(bp.name); 10079 final int flags = permissionState != null ? permissionState.getFlags() : 0; 10080 10081 if (origPermissions.revokeInstallPermission(bp) 10082 != PermissionsState.PERMISSION_OPERATION_FAILURE) { 10083 // We will be transferring the permission flags, so clear them. 10084 origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL, 10085 PackageManager.MASK_PERMISSION_FLAGS, 0); 10086 changedInstallPermission = true; 10087 } 10088 10089 // If the permission is not to be promoted to runtime we ignore it and 10090 // also its other flags as they are not applicable to install permissions. 10091 if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) { 10092 for (int userId : currentUserIds) { 10093 if (permissionsState.grantRuntimePermission(bp, userId) != 10094 PermissionsState.PERMISSION_OPERATION_FAILURE) { 10095 // Transfer the permission flags. 10096 permissionsState.updatePermissionFlags(bp, userId, 10097 flags, flags); 10098 // If we granted the permission, we have to write. 10099 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 10100 changedRuntimePermissionUserIds, userId); 10101 } 10102 } 10103 } 10104 } break; 10105 10106 default: { 10107 if (packageOfInterest == null 10108 || packageOfInterest.equals(pkg.packageName)) { 10109 Slog.w(TAG, "Not granting permission " + perm 10110 + " to package " + pkg.packageName 10111 + " because it was previously installed without"); 10112 } 10113 } break; 10114 } 10115 } else { 10116 if (permissionsState.revokeInstallPermission(bp) != 10117 PermissionsState.PERMISSION_OPERATION_FAILURE) { 10118 // Also drop the permission flags. 10119 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 10120 PackageManager.MASK_PERMISSION_FLAGS, 0); 10121 changedInstallPermission = true; 10122 Slog.i(TAG, "Un-granting permission " + perm 10123 + " from package " + pkg.packageName 10124 + " (protectionLevel=" + bp.protectionLevel 10125 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 10126 + ")"); 10127 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) { 10128 // Don't print warning for app op permissions, since it is fine for them 10129 // not to be granted, there is a UI for the user to decide. 10130 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 10131 Slog.w(TAG, "Not granting permission " + perm 10132 + " to package " + pkg.packageName 10133 + " (protectionLevel=" + bp.protectionLevel 10134 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 10135 + ")"); 10136 } 10137 } 10138 } 10139 } 10140 10141 if ((changedInstallPermission || replace) && !ps.installPermissionsFixed && 10142 !isSystemApp(ps) || isUpdatedSystemApp(ps)){ 10143 // This is the first that we have heard about this package, so the 10144 // permissions we have now selected are fixed until explicitly 10145 // changed. 10146 ps.installPermissionsFixed = true; 10147 } 10148 10149 // Persist the runtime permissions state for users with changes. If permissions 10150 // were revoked because no app in the shared user declares them we have to 10151 // write synchronously to avoid losing runtime permissions state. 10152 for (int userId : changedRuntimePermissionUserIds) { 10153 mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked); 10154 } 10155 } 10156 10157 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) { 10158 boolean allowed = false; 10159 final int NP = PackageParser.NEW_PERMISSIONS.length; 10160 for (int ip=0; ip<NP; ip++) { 10161 final PackageParser.NewPermissionInfo npi 10162 = PackageParser.NEW_PERMISSIONS[ip]; 10163 if (npi.name.equals(perm) 10164 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) { 10165 allowed = true; 10166 Log.i(TAG, "Auto-granting " + perm + " to old pkg " 10167 + pkg.packageName); 10168 break; 10169 } 10170 } 10171 return allowed; 10172 } 10173 10174 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg, 10175 BasePermission bp, PermissionsState origPermissions) { 10176 boolean allowed; 10177 allowed = (compareSignatures( 10178 bp.packageSetting.signatures.mSignatures, pkg.mSignatures) 10179 == PackageManager.SIGNATURE_MATCH) 10180 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures) 10181 == PackageManager.SIGNATURE_MATCH); 10182 if (!allowed && (bp.protectionLevel 10183 & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) { 10184 if (isSystemApp(pkg)) { 10185 // For updated system applications, a system permission 10186 // is granted only if it had been defined by the original application. 10187 if (pkg.isUpdatedSystemApp()) { 10188 final PackageSetting sysPs = mSettings 10189 .getDisabledSystemPkgLPr(pkg.packageName); 10190 if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) { 10191 // If the original was granted this permission, we take 10192 // that grant decision as read and propagate it to the 10193 // update. 10194 if (sysPs.isPrivileged()) { 10195 allowed = true; 10196 } 10197 } else { 10198 // The system apk may have been updated with an older 10199 // version of the one on the data partition, but which 10200 // granted a new system permission that it didn't have 10201 // before. In this case we do want to allow the app to 10202 // now get the new permission if the ancestral apk is 10203 // privileged to get it. 10204 if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) { 10205 for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) { 10206 if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) { 10207 allowed = true; 10208 break; 10209 } 10210 } 10211 } 10212 // Also if a privileged parent package on the system image or any of 10213 // its children requested a privileged permission, the updated child 10214 // packages can also get the permission. 10215 if (pkg.parentPackage != null) { 10216 final PackageSetting disabledSysParentPs = mSettings 10217 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName); 10218 if (disabledSysParentPs != null && disabledSysParentPs.pkg != null 10219 && disabledSysParentPs.isPrivileged()) { 10220 if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) { 10221 allowed = true; 10222 } else if (disabledSysParentPs.pkg.childPackages != null) { 10223 final int count = disabledSysParentPs.pkg.childPackages.size(); 10224 for (int i = 0; i < count; i++) { 10225 PackageParser.Package disabledSysChildPkg = 10226 disabledSysParentPs.pkg.childPackages.get(i); 10227 if (isPackageRequestingPermission(disabledSysChildPkg, 10228 perm)) { 10229 allowed = true; 10230 break; 10231 } 10232 } 10233 } 10234 } 10235 } 10236 } 10237 } else { 10238 allowed = isPrivilegedApp(pkg); 10239 } 10240 } 10241 } 10242 if (!allowed) { 10243 if (!allowed && (bp.protectionLevel 10244 & PermissionInfo.PROTECTION_FLAG_PRE23) != 0 10245 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 10246 // If this was a previously normal/dangerous permission that got moved 10247 // to a system permission as part of the runtime permission redesign, then 10248 // we still want to blindly grant it to old apps. 10249 allowed = true; 10250 } 10251 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0 10252 && pkg.packageName.equals(mRequiredInstallerPackage)) { 10253 // If this permission is to be granted to the system installer and 10254 // this app is an installer, then it gets the permission. 10255 allowed = true; 10256 } 10257 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0 10258 && pkg.packageName.equals(mRequiredVerifierPackage)) { 10259 // If this permission is to be granted to the system verifier and 10260 // this app is a verifier, then it gets the permission. 10261 allowed = true; 10262 } 10263 if (!allowed && (bp.protectionLevel 10264 & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0 10265 && isSystemApp(pkg)) { 10266 // Any pre-installed system app is allowed to get this permission. 10267 allowed = true; 10268 } 10269 if (!allowed && (bp.protectionLevel 10270 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) { 10271 // For development permissions, a development permission 10272 // is granted only if it was already granted. 10273 allowed = origPermissions.hasInstallPermission(perm); 10274 } 10275 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0 10276 && pkg.packageName.equals(mSetupWizardPackage)) { 10277 // If this permission is to be granted to the system setup wizard and 10278 // this app is a setup wizard, then it gets the permission. 10279 allowed = true; 10280 } 10281 } 10282 return allowed; 10283 } 10284 10285 private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) { 10286 final int permCount = pkg.requestedPermissions.size(); 10287 for (int j = 0; j < permCount; j++) { 10288 String requestedPermission = pkg.requestedPermissions.get(j); 10289 if (permission.equals(requestedPermission)) { 10290 return true; 10291 } 10292 } 10293 return false; 10294 } 10295 10296 final class ActivityIntentResolver 10297 extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> { 10298 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 10299 boolean defaultOnly, int userId) { 10300 if (!sUserManager.exists(userId)) return null; 10301 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 10302 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 10303 } 10304 10305 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 10306 int userId) { 10307 if (!sUserManager.exists(userId)) return null; 10308 mFlags = flags; 10309 return super.queryIntent(intent, resolvedType, 10310 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 10311 } 10312 10313 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 10314 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) { 10315 if (!sUserManager.exists(userId)) return null; 10316 if (packageActivities == null) { 10317 return null; 10318 } 10319 mFlags = flags; 10320 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 10321 final int N = packageActivities.size(); 10322 ArrayList<PackageParser.ActivityIntentInfo[]> listCut = 10323 new ArrayList<PackageParser.ActivityIntentInfo[]>(N); 10324 10325 ArrayList<PackageParser.ActivityIntentInfo> intentFilters; 10326 for (int i = 0; i < N; ++i) { 10327 intentFilters = packageActivities.get(i).intents; 10328 if (intentFilters != null && intentFilters.size() > 0) { 10329 PackageParser.ActivityIntentInfo[] array = 10330 new PackageParser.ActivityIntentInfo[intentFilters.size()]; 10331 intentFilters.toArray(array); 10332 listCut.add(array); 10333 } 10334 } 10335 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 10336 } 10337 10338 /** 10339 * Finds a privileged activity that matches the specified activity names. 10340 */ 10341 private PackageParser.Activity findMatchingActivity( 10342 List<PackageParser.Activity> activityList, ActivityInfo activityInfo) { 10343 for (PackageParser.Activity sysActivity : activityList) { 10344 if (sysActivity.info.name.equals(activityInfo.name)) { 10345 return sysActivity; 10346 } 10347 if (sysActivity.info.name.equals(activityInfo.targetActivity)) { 10348 return sysActivity; 10349 } 10350 if (sysActivity.info.targetActivity != null) { 10351 if (sysActivity.info.targetActivity.equals(activityInfo.name)) { 10352 return sysActivity; 10353 } 10354 if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) { 10355 return sysActivity; 10356 } 10357 } 10358 } 10359 return null; 10360 } 10361 10362 public class IterGenerator<E> { 10363 public Iterator<E> generate(ActivityIntentInfo info) { 10364 return null; 10365 } 10366 } 10367 10368 public class ActionIterGenerator extends IterGenerator<String> { 10369 @Override 10370 public Iterator<String> generate(ActivityIntentInfo info) { 10371 return info.actionsIterator(); 10372 } 10373 } 10374 10375 public class CategoriesIterGenerator extends IterGenerator<String> { 10376 @Override 10377 public Iterator<String> generate(ActivityIntentInfo info) { 10378 return info.categoriesIterator(); 10379 } 10380 } 10381 10382 public class SchemesIterGenerator extends IterGenerator<String> { 10383 @Override 10384 public Iterator<String> generate(ActivityIntentInfo info) { 10385 return info.schemesIterator(); 10386 } 10387 } 10388 10389 public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> { 10390 @Override 10391 public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) { 10392 return info.authoritiesIterator(); 10393 } 10394 } 10395 10396 /** 10397 * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE 10398 * MODIFIED. Do not pass in a list that should not be changed. 10399 */ 10400 private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList, 10401 IterGenerator<T> generator, Iterator<T> searchIterator) { 10402 // loop through the set of actions; every one must be found in the intent filter 10403 while (searchIterator.hasNext()) { 10404 // we must have at least one filter in the list to consider a match 10405 if (intentList.size() == 0) { 10406 break; 10407 } 10408 10409 final T searchAction = searchIterator.next(); 10410 10411 // loop through the set of intent filters 10412 final Iterator<ActivityIntentInfo> intentIter = intentList.iterator(); 10413 while (intentIter.hasNext()) { 10414 final ActivityIntentInfo intentInfo = intentIter.next(); 10415 boolean selectionFound = false; 10416 10417 // loop through the intent filter's selection criteria; at least one 10418 // of them must match the searched criteria 10419 final Iterator<T> intentSelectionIter = generator.generate(intentInfo); 10420 while (intentSelectionIter != null && intentSelectionIter.hasNext()) { 10421 final T intentSelection = intentSelectionIter.next(); 10422 if (intentSelection != null && intentSelection.equals(searchAction)) { 10423 selectionFound = true; 10424 break; 10425 } 10426 } 10427 10428 // the selection criteria wasn't found in this filter's set; this filter 10429 // is not a potential match 10430 if (!selectionFound) { 10431 intentIter.remove(); 10432 } 10433 } 10434 } 10435 } 10436 10437 private boolean isProtectedAction(ActivityIntentInfo filter) { 10438 final Iterator<String> actionsIter = filter.actionsIterator(); 10439 while (actionsIter != null && actionsIter.hasNext()) { 10440 final String filterAction = actionsIter.next(); 10441 if (PROTECTED_ACTIONS.contains(filterAction)) { 10442 return true; 10443 } 10444 } 10445 return false; 10446 } 10447 10448 /** 10449 * Adjusts the priority of the given intent filter according to policy. 10450 * <p> 10451 * <ul> 10452 * <li>The priority for non privileged applications is capped to '0'</li> 10453 * <li>The priority for protected actions on privileged applications is capped to '0'</li> 10454 * <li>The priority for unbundled updates to privileged applications is capped to the 10455 * priority defined on the system partition</li> 10456 * </ul> 10457 * <p> 10458 * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is 10459 * allowed to obtain any priority on any action. 10460 */ 10461 private void adjustPriority( 10462 List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) { 10463 // nothing to do; priority is fine as-is 10464 if (intent.getPriority() <= 0) { 10465 return; 10466 } 10467 10468 final ActivityInfo activityInfo = intent.activity.info; 10469 final ApplicationInfo applicationInfo = activityInfo.applicationInfo; 10470 10471 final boolean privilegedApp = 10472 ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0); 10473 if (!privilegedApp) { 10474 // non-privileged applications can never define a priority >0 10475 Slog.w(TAG, "Non-privileged app; cap priority to 0;" 10476 + " package: " + applicationInfo.packageName 10477 + " activity: " + intent.activity.className 10478 + " origPrio: " + intent.getPriority()); 10479 intent.setPriority(0); 10480 return; 10481 } 10482 10483 if (systemActivities == null) { 10484 // the system package is not disabled; we're parsing the system partition 10485 if (isProtectedAction(intent)) { 10486 if (mDeferProtectedFilters) { 10487 // We can't deal with these just yet. No component should ever obtain a 10488 // >0 priority for a protected actions, with ONE exception -- the setup 10489 // wizard. The setup wizard, however, cannot be known until we're able to 10490 // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do 10491 // until all intent filters have been processed. Chicken, meet egg. 10492 // Let the filter temporarily have a high priority and rectify the 10493 // priorities after all system packages have been scanned. 10494 mProtectedFilters.add(intent); 10495 if (DEBUG_FILTERS) { 10496 Slog.i(TAG, "Protected action; save for later;" 10497 + " package: " + applicationInfo.packageName 10498 + " activity: " + intent.activity.className 10499 + " origPrio: " + intent.getPriority()); 10500 } 10501 return; 10502 } else { 10503 if (DEBUG_FILTERS && mSetupWizardPackage == null) { 10504 Slog.i(TAG, "No setup wizard;" 10505 + " All protected intents capped to priority 0"); 10506 } 10507 if (intent.activity.info.packageName.equals(mSetupWizardPackage)) { 10508 if (DEBUG_FILTERS) { 10509 Slog.i(TAG, "Found setup wizard;" 10510 + " allow priority " + intent.getPriority() + ";" 10511 + " package: " + intent.activity.info.packageName 10512 + " activity: " + intent.activity.className 10513 + " priority: " + intent.getPriority()); 10514 } 10515 // setup wizard gets whatever it wants 10516 return; 10517 } 10518 Slog.w(TAG, "Protected action; cap priority to 0;" 10519 + " package: " + intent.activity.info.packageName 10520 + " activity: " + intent.activity.className 10521 + " origPrio: " + intent.getPriority()); 10522 intent.setPriority(0); 10523 return; 10524 } 10525 } 10526 // privileged apps on the system image get whatever priority they request 10527 return; 10528 } 10529 10530 // privileged app unbundled update ... try to find the same activity 10531 final PackageParser.Activity foundActivity = 10532 findMatchingActivity(systemActivities, activityInfo); 10533 if (foundActivity == null) { 10534 // this is a new activity; it cannot obtain >0 priority 10535 if (DEBUG_FILTERS) { 10536 Slog.i(TAG, "New activity; cap priority to 0;" 10537 + " package: " + applicationInfo.packageName 10538 + " activity: " + intent.activity.className 10539 + " origPrio: " + intent.getPriority()); 10540 } 10541 intent.setPriority(0); 10542 return; 10543 } 10544 10545 // found activity, now check for filter equivalence 10546 10547 // a shallow copy is enough; we modify the list, not its contents 10548 final List<ActivityIntentInfo> intentListCopy = 10549 new ArrayList<>(foundActivity.intents); 10550 final List<ActivityIntentInfo> foundFilters = findFilters(intent); 10551 10552 // find matching action subsets 10553 final Iterator<String> actionsIterator = intent.actionsIterator(); 10554 if (actionsIterator != null) { 10555 getIntentListSubset( 10556 intentListCopy, new ActionIterGenerator(), actionsIterator); 10557 if (intentListCopy.size() == 0) { 10558 // no more intents to match; we're not equivalent 10559 if (DEBUG_FILTERS) { 10560 Slog.i(TAG, "Mismatched action; cap priority to 0;" 10561 + " package: " + applicationInfo.packageName 10562 + " activity: " + intent.activity.className 10563 + " origPrio: " + intent.getPriority()); 10564 } 10565 intent.setPriority(0); 10566 return; 10567 } 10568 } 10569 10570 // find matching category subsets 10571 final Iterator<String> categoriesIterator = intent.categoriesIterator(); 10572 if (categoriesIterator != null) { 10573 getIntentListSubset(intentListCopy, new CategoriesIterGenerator(), 10574 categoriesIterator); 10575 if (intentListCopy.size() == 0) { 10576 // no more intents to match; we're not equivalent 10577 if (DEBUG_FILTERS) { 10578 Slog.i(TAG, "Mismatched category; cap priority to 0;" 10579 + " package: " + applicationInfo.packageName 10580 + " activity: " + intent.activity.className 10581 + " origPrio: " + intent.getPriority()); 10582 } 10583 intent.setPriority(0); 10584 return; 10585 } 10586 } 10587 10588 // find matching schemes subsets 10589 final Iterator<String> schemesIterator = intent.schemesIterator(); 10590 if (schemesIterator != null) { 10591 getIntentListSubset(intentListCopy, new SchemesIterGenerator(), 10592 schemesIterator); 10593 if (intentListCopy.size() == 0) { 10594 // no more intents to match; we're not equivalent 10595 if (DEBUG_FILTERS) { 10596 Slog.i(TAG, "Mismatched scheme; cap priority to 0;" 10597 + " package: " + applicationInfo.packageName 10598 + " activity: " + intent.activity.className 10599 + " origPrio: " + intent.getPriority()); 10600 } 10601 intent.setPriority(0); 10602 return; 10603 } 10604 } 10605 10606 // find matching authorities subsets 10607 final Iterator<IntentFilter.AuthorityEntry> 10608 authoritiesIterator = intent.authoritiesIterator(); 10609 if (authoritiesIterator != null) { 10610 getIntentListSubset(intentListCopy, 10611 new AuthoritiesIterGenerator(), 10612 authoritiesIterator); 10613 if (intentListCopy.size() == 0) { 10614 // no more intents to match; we're not equivalent 10615 if (DEBUG_FILTERS) { 10616 Slog.i(TAG, "Mismatched authority; cap priority to 0;" 10617 + " package: " + applicationInfo.packageName 10618 + " activity: " + intent.activity.className 10619 + " origPrio: " + intent.getPriority()); 10620 } 10621 intent.setPriority(0); 10622 return; 10623 } 10624 } 10625 10626 // we found matching filter(s); app gets the max priority of all intents 10627 int cappedPriority = 0; 10628 for (int i = intentListCopy.size() - 1; i >= 0; --i) { 10629 cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority()); 10630 } 10631 if (intent.getPriority() > cappedPriority) { 10632 if (DEBUG_FILTERS) { 10633 Slog.i(TAG, "Found matching filter(s);" 10634 + " cap priority to " + cappedPriority + ";" 10635 + " package: " + applicationInfo.packageName 10636 + " activity: " + intent.activity.className 10637 + " origPrio: " + intent.getPriority()); 10638 } 10639 intent.setPriority(cappedPriority); 10640 return; 10641 } 10642 // all this for nothing; the requested priority was <= what was on the system 10643 } 10644 10645 public final void addActivity(PackageParser.Activity a, String type) { 10646 mActivities.put(a.getComponentName(), a); 10647 if (DEBUG_SHOW_INFO) 10648 Log.v( 10649 TAG, " " + type + " " + 10650 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":"); 10651 if (DEBUG_SHOW_INFO) 10652 Log.v(TAG, " Class=" + a.info.name); 10653 final int NI = a.intents.size(); 10654 for (int j=0; j<NI; j++) { 10655 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 10656 if ("activity".equals(type)) { 10657 final PackageSetting ps = 10658 mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName); 10659 final List<PackageParser.Activity> systemActivities = 10660 ps != null && ps.pkg != null ? ps.pkg.activities : null; 10661 adjustPriority(systemActivities, intent); 10662 } 10663 if (DEBUG_SHOW_INFO) { 10664 Log.v(TAG, " IntentFilter:"); 10665 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10666 } 10667 if (!intent.debugCheck()) { 10668 Log.w(TAG, "==> For Activity " + a.info.name); 10669 } 10670 addFilter(intent); 10671 } 10672 } 10673 10674 public final void removeActivity(PackageParser.Activity a, String type) { 10675 mActivities.remove(a.getComponentName()); 10676 if (DEBUG_SHOW_INFO) { 10677 Log.v(TAG, " " + type + " " 10678 + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel 10679 : a.info.name) + ":"); 10680 Log.v(TAG, " Class=" + a.info.name); 10681 } 10682 final int NI = a.intents.size(); 10683 for (int j=0; j<NI; j++) { 10684 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 10685 if (DEBUG_SHOW_INFO) { 10686 Log.v(TAG, " IntentFilter:"); 10687 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10688 } 10689 removeFilter(intent); 10690 } 10691 } 10692 10693 @Override 10694 protected boolean allowFilterResult( 10695 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) { 10696 ActivityInfo filterAi = filter.activity.info; 10697 for (int i=dest.size()-1; i>=0; i--) { 10698 ActivityInfo destAi = dest.get(i).activityInfo; 10699 if (destAi.name == filterAi.name 10700 && destAi.packageName == filterAi.packageName) { 10701 return false; 10702 } 10703 } 10704 return true; 10705 } 10706 10707 @Override 10708 protected ActivityIntentInfo[] newArray(int size) { 10709 return new ActivityIntentInfo[size]; 10710 } 10711 10712 @Override 10713 protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) { 10714 if (!sUserManager.exists(userId)) return true; 10715 PackageParser.Package p = filter.activity.owner; 10716 if (p != null) { 10717 PackageSetting ps = (PackageSetting)p.mExtras; 10718 if (ps != null) { 10719 // System apps are never considered stopped for purposes of 10720 // filtering, because there may be no way for the user to 10721 // actually re-launch them. 10722 return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0 10723 && ps.getStopped(userId); 10724 } 10725 } 10726 return false; 10727 } 10728 10729 @Override 10730 protected boolean isPackageForFilter(String packageName, 10731 PackageParser.ActivityIntentInfo info) { 10732 return packageName.equals(info.activity.owner.packageName); 10733 } 10734 10735 @Override 10736 protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info, 10737 int match, int userId) { 10738 if (!sUserManager.exists(userId)) return null; 10739 if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) { 10740 return null; 10741 } 10742 final PackageParser.Activity activity = info.activity; 10743 PackageSetting ps = (PackageSetting) activity.owner.mExtras; 10744 if (ps == null) { 10745 return null; 10746 } 10747 ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags, 10748 ps.readUserState(userId), userId); 10749 if (ai == null) { 10750 return null; 10751 } 10752 final ResolveInfo res = new ResolveInfo(); 10753 res.activityInfo = ai; 10754 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 10755 res.filter = info; 10756 } 10757 if (info != null) { 10758 res.handleAllWebDataURI = info.handleAllWebDataURI(); 10759 } 10760 res.priority = info.getPriority(); 10761 res.preferredOrder = activity.owner.mPreferredOrder; 10762 //System.out.println("Result: " + res.activityInfo.className + 10763 // " = " + res.priority); 10764 res.match = match; 10765 res.isDefault = info.hasDefault; 10766 res.labelRes = info.labelRes; 10767 res.nonLocalizedLabel = info.nonLocalizedLabel; 10768 if (userNeedsBadging(userId)) { 10769 res.noResourceId = true; 10770 } else { 10771 res.icon = info.icon; 10772 } 10773 res.iconResourceId = info.icon; 10774 res.system = res.activityInfo.applicationInfo.isSystemApp(); 10775 return res; 10776 } 10777 10778 @Override 10779 protected void sortResults(List<ResolveInfo> results) { 10780 Collections.sort(results, mResolvePrioritySorter); 10781 } 10782 10783 @Override 10784 protected void dumpFilter(PrintWriter out, String prefix, 10785 PackageParser.ActivityIntentInfo filter) { 10786 out.print(prefix); out.print( 10787 Integer.toHexString(System.identityHashCode(filter.activity))); 10788 out.print(' '); 10789 filter.activity.printComponentShortName(out); 10790 out.print(" filter "); 10791 out.println(Integer.toHexString(System.identityHashCode(filter))); 10792 } 10793 10794 @Override 10795 protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) { 10796 return filter.activity; 10797 } 10798 10799 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 10800 PackageParser.Activity activity = (PackageParser.Activity)label; 10801 out.print(prefix); out.print( 10802 Integer.toHexString(System.identityHashCode(activity))); 10803 out.print(' '); 10804 activity.printComponentShortName(out); 10805 if (count > 1) { 10806 out.print(" ("); out.print(count); out.print(" filters)"); 10807 } 10808 out.println(); 10809 } 10810 10811 // Keys are String (activity class name), values are Activity. 10812 private final ArrayMap<ComponentName, PackageParser.Activity> mActivities 10813 = new ArrayMap<ComponentName, PackageParser.Activity>(); 10814 private int mFlags; 10815 } 10816 10817 private final class ServiceIntentResolver 10818 extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> { 10819 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 10820 boolean defaultOnly, int userId) { 10821 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 10822 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 10823 } 10824 10825 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 10826 int userId) { 10827 if (!sUserManager.exists(userId)) return null; 10828 mFlags = flags; 10829 return super.queryIntent(intent, resolvedType, 10830 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 10831 } 10832 10833 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 10834 int flags, ArrayList<PackageParser.Service> packageServices, int userId) { 10835 if (!sUserManager.exists(userId)) return null; 10836 if (packageServices == null) { 10837 return null; 10838 } 10839 mFlags = flags; 10840 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 10841 final int N = packageServices.size(); 10842 ArrayList<PackageParser.ServiceIntentInfo[]> listCut = 10843 new ArrayList<PackageParser.ServiceIntentInfo[]>(N); 10844 10845 ArrayList<PackageParser.ServiceIntentInfo> intentFilters; 10846 for (int i = 0; i < N; ++i) { 10847 intentFilters = packageServices.get(i).intents; 10848 if (intentFilters != null && intentFilters.size() > 0) { 10849 PackageParser.ServiceIntentInfo[] array = 10850 new PackageParser.ServiceIntentInfo[intentFilters.size()]; 10851 intentFilters.toArray(array); 10852 listCut.add(array); 10853 } 10854 } 10855 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 10856 } 10857 10858 public final void addService(PackageParser.Service s) { 10859 mServices.put(s.getComponentName(), s); 10860 if (DEBUG_SHOW_INFO) { 10861 Log.v(TAG, " " 10862 + (s.info.nonLocalizedLabel != null 10863 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 10864 Log.v(TAG, " Class=" + s.info.name); 10865 } 10866 final int NI = s.intents.size(); 10867 int j; 10868 for (j=0; j<NI; j++) { 10869 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 10870 if (DEBUG_SHOW_INFO) { 10871 Log.v(TAG, " IntentFilter:"); 10872 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10873 } 10874 if (!intent.debugCheck()) { 10875 Log.w(TAG, "==> For Service " + s.info.name); 10876 } 10877 addFilter(intent); 10878 } 10879 } 10880 10881 public final void removeService(PackageParser.Service s) { 10882 mServices.remove(s.getComponentName()); 10883 if (DEBUG_SHOW_INFO) { 10884 Log.v(TAG, " " + (s.info.nonLocalizedLabel != null 10885 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 10886 Log.v(TAG, " Class=" + s.info.name); 10887 } 10888 final int NI = s.intents.size(); 10889 int j; 10890 for (j=0; j<NI; j++) { 10891 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 10892 if (DEBUG_SHOW_INFO) { 10893 Log.v(TAG, " IntentFilter:"); 10894 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10895 } 10896 removeFilter(intent); 10897 } 10898 } 10899 10900 @Override 10901 protected boolean allowFilterResult( 10902 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) { 10903 ServiceInfo filterSi = filter.service.info; 10904 for (int i=dest.size()-1; i>=0; i--) { 10905 ServiceInfo destAi = dest.get(i).serviceInfo; 10906 if (destAi.name == filterSi.name 10907 && destAi.packageName == filterSi.packageName) { 10908 return false; 10909 } 10910 } 10911 return true; 10912 } 10913 10914 @Override 10915 protected PackageParser.ServiceIntentInfo[] newArray(int size) { 10916 return new PackageParser.ServiceIntentInfo[size]; 10917 } 10918 10919 @Override 10920 protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) { 10921 if (!sUserManager.exists(userId)) return true; 10922 PackageParser.Package p = filter.service.owner; 10923 if (p != null) { 10924 PackageSetting ps = (PackageSetting)p.mExtras; 10925 if (ps != null) { 10926 // System apps are never considered stopped for purposes of 10927 // filtering, because there may be no way for the user to 10928 // actually re-launch them. 10929 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 10930 && ps.getStopped(userId); 10931 } 10932 } 10933 return false; 10934 } 10935 10936 @Override 10937 protected boolean isPackageForFilter(String packageName, 10938 PackageParser.ServiceIntentInfo info) { 10939 return packageName.equals(info.service.owner.packageName); 10940 } 10941 10942 @Override 10943 protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter, 10944 int match, int userId) { 10945 if (!sUserManager.exists(userId)) return null; 10946 final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter; 10947 if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) { 10948 return null; 10949 } 10950 final PackageParser.Service service = info.service; 10951 PackageSetting ps = (PackageSetting) service.owner.mExtras; 10952 if (ps == null) { 10953 return null; 10954 } 10955 ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags, 10956 ps.readUserState(userId), userId); 10957 if (si == null) { 10958 return null; 10959 } 10960 final ResolveInfo res = new ResolveInfo(); 10961 res.serviceInfo = si; 10962 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 10963 res.filter = filter; 10964 } 10965 res.priority = info.getPriority(); 10966 res.preferredOrder = service.owner.mPreferredOrder; 10967 res.match = match; 10968 res.isDefault = info.hasDefault; 10969 res.labelRes = info.labelRes; 10970 res.nonLocalizedLabel = info.nonLocalizedLabel; 10971 res.icon = info.icon; 10972 res.system = res.serviceInfo.applicationInfo.isSystemApp(); 10973 return res; 10974 } 10975 10976 @Override 10977 protected void sortResults(List<ResolveInfo> results) { 10978 Collections.sort(results, mResolvePrioritySorter); 10979 } 10980 10981 @Override 10982 protected void dumpFilter(PrintWriter out, String prefix, 10983 PackageParser.ServiceIntentInfo filter) { 10984 out.print(prefix); out.print( 10985 Integer.toHexString(System.identityHashCode(filter.service))); 10986 out.print(' '); 10987 filter.service.printComponentShortName(out); 10988 out.print(" filter "); 10989 out.println(Integer.toHexString(System.identityHashCode(filter))); 10990 } 10991 10992 @Override 10993 protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) { 10994 return filter.service; 10995 } 10996 10997 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 10998 PackageParser.Service service = (PackageParser.Service)label; 10999 out.print(prefix); out.print( 11000 Integer.toHexString(System.identityHashCode(service))); 11001 out.print(' '); 11002 service.printComponentShortName(out); 11003 if (count > 1) { 11004 out.print(" ("); out.print(count); out.print(" filters)"); 11005 } 11006 out.println(); 11007 } 11008 11009// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 11010// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 11011// final List<ResolveInfo> retList = Lists.newArrayList(); 11012// while (i.hasNext()) { 11013// final ResolveInfo resolveInfo = (ResolveInfo) i; 11014// if (isEnabledLP(resolveInfo.serviceInfo)) { 11015// retList.add(resolveInfo); 11016// } 11017// } 11018// return retList; 11019// } 11020 11021 // Keys are String (activity class name), values are Activity. 11022 private final ArrayMap<ComponentName, PackageParser.Service> mServices 11023 = new ArrayMap<ComponentName, PackageParser.Service>(); 11024 private int mFlags; 11025 }; 11026 11027 private final class ProviderIntentResolver 11028 extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> { 11029 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 11030 boolean defaultOnly, int userId) { 11031 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 11032 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 11033 } 11034 11035 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 11036 int userId) { 11037 if (!sUserManager.exists(userId)) 11038 return null; 11039 mFlags = flags; 11040 return super.queryIntent(intent, resolvedType, 11041 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 11042 } 11043 11044 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 11045 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) { 11046 if (!sUserManager.exists(userId)) 11047 return null; 11048 if (packageProviders == null) { 11049 return null; 11050 } 11051 mFlags = flags; 11052 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; 11053 final int N = packageProviders.size(); 11054 ArrayList<PackageParser.ProviderIntentInfo[]> listCut = 11055 new ArrayList<PackageParser.ProviderIntentInfo[]>(N); 11056 11057 ArrayList<PackageParser.ProviderIntentInfo> intentFilters; 11058 for (int i = 0; i < N; ++i) { 11059 intentFilters = packageProviders.get(i).intents; 11060 if (intentFilters != null && intentFilters.size() > 0) { 11061 PackageParser.ProviderIntentInfo[] array = 11062 new PackageParser.ProviderIntentInfo[intentFilters.size()]; 11063 intentFilters.toArray(array); 11064 listCut.add(array); 11065 } 11066 } 11067 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 11068 } 11069 11070 public final void addProvider(PackageParser.Provider p) { 11071 if (mProviders.containsKey(p.getComponentName())) { 11072 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring"); 11073 return; 11074 } 11075 11076 mProviders.put(p.getComponentName(), p); 11077 if (DEBUG_SHOW_INFO) { 11078 Log.v(TAG, " " 11079 + (p.info.nonLocalizedLabel != null 11080 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 11081 Log.v(TAG, " Class=" + p.info.name); 11082 } 11083 final int NI = p.intents.size(); 11084 int j; 11085 for (j = 0; j < NI; j++) { 11086 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 11087 if (DEBUG_SHOW_INFO) { 11088 Log.v(TAG, " IntentFilter:"); 11089 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 11090 } 11091 if (!intent.debugCheck()) { 11092 Log.w(TAG, "==> For Provider " + p.info.name); 11093 } 11094 addFilter(intent); 11095 } 11096 } 11097 11098 public final void removeProvider(PackageParser.Provider p) { 11099 mProviders.remove(p.getComponentName()); 11100 if (DEBUG_SHOW_INFO) { 11101 Log.v(TAG, " " + (p.info.nonLocalizedLabel != null 11102 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 11103 Log.v(TAG, " Class=" + p.info.name); 11104 } 11105 final int NI = p.intents.size(); 11106 int j; 11107 for (j = 0; j < NI; j++) { 11108 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 11109 if (DEBUG_SHOW_INFO) { 11110 Log.v(TAG, " IntentFilter:"); 11111 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 11112 } 11113 removeFilter(intent); 11114 } 11115 } 11116 11117 @Override 11118 protected boolean allowFilterResult( 11119 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) { 11120 ProviderInfo filterPi = filter.provider.info; 11121 for (int i = dest.size() - 1; i >= 0; i--) { 11122 ProviderInfo destPi = dest.get(i).providerInfo; 11123 if (destPi.name == filterPi.name 11124 && destPi.packageName == filterPi.packageName) { 11125 return false; 11126 } 11127 } 11128 return true; 11129 } 11130 11131 @Override 11132 protected PackageParser.ProviderIntentInfo[] newArray(int size) { 11133 return new PackageParser.ProviderIntentInfo[size]; 11134 } 11135 11136 @Override 11137 protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) { 11138 if (!sUserManager.exists(userId)) 11139 return true; 11140 PackageParser.Package p = filter.provider.owner; 11141 if (p != null) { 11142 PackageSetting ps = (PackageSetting) p.mExtras; 11143 if (ps != null) { 11144 // System apps are never considered stopped for purposes of 11145 // filtering, because there may be no way for the user to 11146 // actually re-launch them. 11147 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 11148 && ps.getStopped(userId); 11149 } 11150 } 11151 return false; 11152 } 11153 11154 @Override 11155 protected boolean isPackageForFilter(String packageName, 11156 PackageParser.ProviderIntentInfo info) { 11157 return packageName.equals(info.provider.owner.packageName); 11158 } 11159 11160 @Override 11161 protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter, 11162 int match, int userId) { 11163 if (!sUserManager.exists(userId)) 11164 return null; 11165 final PackageParser.ProviderIntentInfo info = filter; 11166 if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) { 11167 return null; 11168 } 11169 final PackageParser.Provider provider = info.provider; 11170 PackageSetting ps = (PackageSetting) provider.owner.mExtras; 11171 if (ps == null) { 11172 return null; 11173 } 11174 ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags, 11175 ps.readUserState(userId), userId); 11176 if (pi == null) { 11177 return null; 11178 } 11179 final ResolveInfo res = new ResolveInfo(); 11180 res.providerInfo = pi; 11181 if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) { 11182 res.filter = filter; 11183 } 11184 res.priority = info.getPriority(); 11185 res.preferredOrder = provider.owner.mPreferredOrder; 11186 res.match = match; 11187 res.isDefault = info.hasDefault; 11188 res.labelRes = info.labelRes; 11189 res.nonLocalizedLabel = info.nonLocalizedLabel; 11190 res.icon = info.icon; 11191 res.system = res.providerInfo.applicationInfo.isSystemApp(); 11192 return res; 11193 } 11194 11195 @Override 11196 protected void sortResults(List<ResolveInfo> results) { 11197 Collections.sort(results, mResolvePrioritySorter); 11198 } 11199 11200 @Override 11201 protected void dumpFilter(PrintWriter out, String prefix, 11202 PackageParser.ProviderIntentInfo filter) { 11203 out.print(prefix); 11204 out.print( 11205 Integer.toHexString(System.identityHashCode(filter.provider))); 11206 out.print(' '); 11207 filter.provider.printComponentShortName(out); 11208 out.print(" filter "); 11209 out.println(Integer.toHexString(System.identityHashCode(filter))); 11210 } 11211 11212 @Override 11213 protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) { 11214 return filter.provider; 11215 } 11216 11217 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 11218 PackageParser.Provider provider = (PackageParser.Provider)label; 11219 out.print(prefix); out.print( 11220 Integer.toHexString(System.identityHashCode(provider))); 11221 out.print(' '); 11222 provider.printComponentShortName(out); 11223 if (count > 1) { 11224 out.print(" ("); out.print(count); out.print(" filters)"); 11225 } 11226 out.println(); 11227 } 11228 11229 private final ArrayMap<ComponentName, PackageParser.Provider> mProviders 11230 = new ArrayMap<ComponentName, PackageParser.Provider>(); 11231 private int mFlags; 11232 } 11233 11234 private static final class EphemeralIntentResolver 11235 extends IntentResolver<EphemeralResolveIntentInfo, EphemeralResolveInfo> { 11236 @Override 11237 protected EphemeralResolveIntentInfo[] newArray(int size) { 11238 return new EphemeralResolveIntentInfo[size]; 11239 } 11240 11241 @Override 11242 protected boolean isPackageForFilter(String packageName, EphemeralResolveIntentInfo info) { 11243 return true; 11244 } 11245 11246 @Override 11247 protected EphemeralResolveInfo newResult(EphemeralResolveIntentInfo info, int match, 11248 int userId) { 11249 if (!sUserManager.exists(userId)) { 11250 return null; 11251 } 11252 return info.getEphemeralResolveInfo(); 11253 } 11254 } 11255 11256 private static final Comparator<ResolveInfo> mResolvePrioritySorter = 11257 new Comparator<ResolveInfo>() { 11258 public int compare(ResolveInfo r1, ResolveInfo r2) { 11259 int v1 = r1.priority; 11260 int v2 = r2.priority; 11261 //System.out.println("Comparing: q1=" + q1 + " q2=" + q2); 11262 if (v1 != v2) { 11263 return (v1 > v2) ? -1 : 1; 11264 } 11265 v1 = r1.preferredOrder; 11266 v2 = r2.preferredOrder; 11267 if (v1 != v2) { 11268 return (v1 > v2) ? -1 : 1; 11269 } 11270 if (r1.isDefault != r2.isDefault) { 11271 return r1.isDefault ? -1 : 1; 11272 } 11273 v1 = r1.match; 11274 v2 = r2.match; 11275 //System.out.println("Comparing: m1=" + m1 + " m2=" + m2); 11276 if (v1 != v2) { 11277 return (v1 > v2) ? -1 : 1; 11278 } 11279 if (r1.system != r2.system) { 11280 return r1.system ? -1 : 1; 11281 } 11282 if (r1.activityInfo != null) { 11283 return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName); 11284 } 11285 if (r1.serviceInfo != null) { 11286 return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName); 11287 } 11288 if (r1.providerInfo != null) { 11289 return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName); 11290 } 11291 return 0; 11292 } 11293 }; 11294 11295 private static final Comparator<ProviderInfo> mProviderInitOrderSorter = 11296 new Comparator<ProviderInfo>() { 11297 public int compare(ProviderInfo p1, ProviderInfo p2) { 11298 final int v1 = p1.initOrder; 11299 final int v2 = p2.initOrder; 11300 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0); 11301 } 11302 }; 11303 11304 final void sendPackageBroadcast(final String action, final String pkg, final Bundle extras, 11305 final int flags, final String targetPkg, final IIntentReceiver finishedReceiver, 11306 final int[] userIds) { 11307 mHandler.post(new Runnable() { 11308 @Override 11309 public void run() { 11310 try { 11311 final IActivityManager am = ActivityManagerNative.getDefault(); 11312 if (am == null) return; 11313 final int[] resolvedUserIds; 11314 if (userIds == null) { 11315 resolvedUserIds = am.getRunningUserIds(); 11316 } else { 11317 resolvedUserIds = userIds; 11318 } 11319 for (int id : resolvedUserIds) { 11320 final Intent intent = new Intent(action, 11321 pkg != null ? Uri.fromParts("package", pkg, null) : null); 11322 if (extras != null) { 11323 intent.putExtras(extras); 11324 } 11325 if (targetPkg != null) { 11326 intent.setPackage(targetPkg); 11327 } 11328 // Modify the UID when posting to other users 11329 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); 11330 if (uid > 0 && UserHandle.getUserId(uid) != id) { 11331 uid = UserHandle.getUid(id, UserHandle.getAppId(uid)); 11332 intent.putExtra(Intent.EXTRA_UID, uid); 11333 } 11334 intent.putExtra(Intent.EXTRA_USER_HANDLE, id); 11335 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags); 11336 if (DEBUG_BROADCASTS) { 11337 RuntimeException here = new RuntimeException("here"); 11338 here.fillInStackTrace(); 11339 Slog.d(TAG, "Sending to user " + id + ": " 11340 + intent.toShortString(false, true, false, false) 11341 + " " + intent.getExtras(), here); 11342 } 11343 am.broadcastIntent(null, intent, null, finishedReceiver, 11344 0, null, null, null, android.app.AppOpsManager.OP_NONE, 11345 null, finishedReceiver != null, false, id); 11346 } 11347 } catch (RemoteException ex) { 11348 } 11349 } 11350 }); 11351 } 11352 11353 /** 11354 * Check if the external storage media is available. This is true if there 11355 * is a mounted external storage medium or if the external storage is 11356 * emulated. 11357 */ 11358 private boolean isExternalMediaAvailable() { 11359 return mMediaMounted || Environment.isExternalStorageEmulated(); 11360 } 11361 11362 @Override 11363 public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) { 11364 // writer 11365 synchronized (mPackages) { 11366 if (!isExternalMediaAvailable()) { 11367 // If the external storage is no longer mounted at this point, 11368 // the caller may not have been able to delete all of this 11369 // packages files and can not delete any more. Bail. 11370 return null; 11371 } 11372 final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned; 11373 if (lastPackage != null) { 11374 pkgs.remove(lastPackage); 11375 } 11376 if (pkgs.size() > 0) { 11377 return pkgs.get(0); 11378 } 11379 } 11380 return null; 11381 } 11382 11383 void schedulePackageCleaning(String packageName, int userId, boolean andCode) { 11384 final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE, 11385 userId, andCode ? 1 : 0, packageName); 11386 if (mSystemReady) { 11387 msg.sendToTarget(); 11388 } else { 11389 if (mPostSystemReadyMessages == null) { 11390 mPostSystemReadyMessages = new ArrayList<>(); 11391 } 11392 mPostSystemReadyMessages.add(msg); 11393 } 11394 } 11395 11396 void startCleaningPackages() { 11397 // reader 11398 if (!isExternalMediaAvailable()) { 11399 return; 11400 } 11401 synchronized (mPackages) { 11402 if (mSettings.mPackagesToBeCleaned.isEmpty()) { 11403 return; 11404 } 11405 } 11406 Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE); 11407 intent.setComponent(DEFAULT_CONTAINER_COMPONENT); 11408 IActivityManager am = ActivityManagerNative.getDefault(); 11409 if (am != null) { 11410 try { 11411 am.startService(null, intent, null, mContext.getOpPackageName(), 11412 UserHandle.USER_SYSTEM); 11413 } catch (RemoteException e) { 11414 } 11415 } 11416 } 11417 11418 @Override 11419 public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer, 11420 int installFlags, String installerPackageName, int userId) { 11421 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null); 11422 11423 final int callingUid = Binder.getCallingUid(); 11424 enforceCrossUserPermission(callingUid, userId, 11425 true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser"); 11426 11427 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 11428 try { 11429 if (observer != null) { 11430 observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null); 11431 } 11432 } catch (RemoteException re) { 11433 } 11434 return; 11435 } 11436 11437 if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) { 11438 installFlags |= PackageManager.INSTALL_FROM_ADB; 11439 11440 } else { 11441 // Caller holds INSTALL_PACKAGES permission, so we're less strict 11442 // about installerPackageName. 11443 11444 installFlags &= ~PackageManager.INSTALL_FROM_ADB; 11445 installFlags &= ~PackageManager.INSTALL_ALL_USERS; 11446 } 11447 11448 UserHandle user; 11449 if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) { 11450 user = UserHandle.ALL; 11451 } else { 11452 user = new UserHandle(userId); 11453 } 11454 11455 // Only system components can circumvent runtime permissions when installing. 11456 if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0 11457 && mContext.checkCallingOrSelfPermission(Manifest.permission 11458 .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) { 11459 throw new SecurityException("You need the " 11460 + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission " 11461 + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag"); 11462 } 11463 11464 final File originFile = new File(originPath); 11465 final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile); 11466 11467 final Message msg = mHandler.obtainMessage(INIT_COPY); 11468 final VerificationInfo verificationInfo = new VerificationInfo( 11469 null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid); 11470 final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer, 11471 installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user, 11472 null /*packageAbiOverride*/, null /*grantedPermissions*/, 11473 null /*certificates*/); 11474 params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params)); 11475 msg.obj = params; 11476 11477 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser", 11478 System.identityHashCode(msg.obj)); 11479 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 11480 System.identityHashCode(msg.obj)); 11481 11482 mHandler.sendMessage(msg); 11483 } 11484 11485 void installStage(String packageName, File stagedDir, String stagedCid, 11486 IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams, 11487 String installerPackageName, int installerUid, UserHandle user, 11488 Certificate[][] certificates) { 11489 if (DEBUG_EPHEMERAL) { 11490 if ((sessionParams.installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) { 11491 Slog.d(TAG, "Ephemeral install of " + packageName); 11492 } 11493 } 11494 final VerificationInfo verificationInfo = new VerificationInfo( 11495 sessionParams.originatingUri, sessionParams.referrerUri, 11496 sessionParams.originatingUid, installerUid); 11497 11498 final OriginInfo origin; 11499 if (stagedDir != null) { 11500 origin = OriginInfo.fromStagedFile(stagedDir); 11501 } else { 11502 origin = OriginInfo.fromStagedContainer(stagedCid); 11503 } 11504 11505 final Message msg = mHandler.obtainMessage(INIT_COPY); 11506 final InstallParams params = new InstallParams(origin, null, observer, 11507 sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid, 11508 verificationInfo, user, sessionParams.abiOverride, 11509 sessionParams.grantedRuntimePermissions, certificates); 11510 params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params)); 11511 msg.obj = params; 11512 11513 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage", 11514 System.identityHashCode(msg.obj)); 11515 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 11516 System.identityHashCode(msg.obj)); 11517 11518 mHandler.sendMessage(msg); 11519 } 11520 11521 private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, 11522 int userId) { 11523 final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting); 11524 sendPackageAddedForUser(packageName, isSystem, pkgSetting.appId, userId); 11525 } 11526 11527 private void sendPackageAddedForUser(String packageName, boolean isSystem, 11528 int appId, int userId) { 11529 Bundle extras = new Bundle(1); 11530 extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, appId)); 11531 11532 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 11533 packageName, extras, 0, null, null, new int[] {userId}); 11534 try { 11535 IActivityManager am = ActivityManagerNative.getDefault(); 11536 if (isSystem && am.isUserRunning(userId, 0)) { 11537 // The just-installed/enabled app is bundled on the system, so presumed 11538 // to be able to run automatically without needing an explicit launch. 11539 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one. 11540 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED) 11541 .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES) 11542 .setPackage(packageName); 11543 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null, 11544 android.app.AppOpsManager.OP_NONE, null, false, false, userId); 11545 } 11546 } catch (RemoteException e) { 11547 // shouldn't happen 11548 Slog.w(TAG, "Unable to bootstrap installed package", e); 11549 } 11550 } 11551 11552 @Override 11553 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, 11554 int userId) { 11555 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 11556 PackageSetting pkgSetting; 11557 final int uid = Binder.getCallingUid(); 11558 enforceCrossUserPermission(uid, userId, 11559 true /* requireFullPermission */, true /* checkShell */, 11560 "setApplicationHiddenSetting for user " + userId); 11561 11562 if (hidden && isPackageDeviceAdmin(packageName, userId)) { 11563 Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin"); 11564 return false; 11565 } 11566 11567 long callingId = Binder.clearCallingIdentity(); 11568 try { 11569 boolean sendAdded = false; 11570 boolean sendRemoved = false; 11571 // writer 11572 synchronized (mPackages) { 11573 pkgSetting = mSettings.mPackages.get(packageName); 11574 if (pkgSetting == null) { 11575 return false; 11576 } 11577 // Do not allow "android" is being disabled 11578 if ("android".equals(packageName)) { 11579 Slog.w(TAG, "Cannot hide package: android"); 11580 return false; 11581 } 11582 // Only allow protected packages to hide themselves. 11583 if (hidden && !UserHandle.isSameApp(uid, pkgSetting.appId) 11584 && mProtectedPackages.isPackageStateProtected(userId, packageName)) { 11585 Slog.w(TAG, "Not hiding protected package: " + packageName); 11586 return false; 11587 } 11588 11589 if (pkgSetting.getHidden(userId) != hidden) { 11590 pkgSetting.setHidden(hidden, userId); 11591 mSettings.writePackageRestrictionsLPr(userId); 11592 if (hidden) { 11593 sendRemoved = true; 11594 } else { 11595 sendAdded = true; 11596 } 11597 } 11598 } 11599 if (sendAdded) { 11600 sendPackageAddedForUser(packageName, pkgSetting, userId); 11601 return true; 11602 } 11603 if (sendRemoved) { 11604 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId), 11605 "hiding pkg"); 11606 sendApplicationHiddenForUser(packageName, pkgSetting, userId); 11607 return true; 11608 } 11609 } finally { 11610 Binder.restoreCallingIdentity(callingId); 11611 } 11612 return false; 11613 } 11614 11615 private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting, 11616 int userId) { 11617 final PackageRemovedInfo info = new PackageRemovedInfo(); 11618 info.removedPackage = packageName; 11619 info.removedUsers = new int[] {userId}; 11620 info.uid = UserHandle.getUid(userId, pkgSetting.appId); 11621 info.sendPackageRemovedBroadcasts(true /*killApp*/); 11622 } 11623 11624 private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) { 11625 if (pkgList.length > 0) { 11626 Bundle extras = new Bundle(1); 11627 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 11628 11629 sendPackageBroadcast( 11630 suspended ? Intent.ACTION_PACKAGES_SUSPENDED 11631 : Intent.ACTION_PACKAGES_UNSUSPENDED, 11632 null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null, 11633 new int[] {userId}); 11634 } 11635 } 11636 11637 /** 11638 * Returns true if application is not found or there was an error. Otherwise it returns 11639 * the hidden state of the package for the given user. 11640 */ 11641 @Override 11642 public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) { 11643 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 11644 enforceCrossUserPermission(Binder.getCallingUid(), userId, 11645 true /* requireFullPermission */, false /* checkShell */, 11646 "getApplicationHidden for user " + userId); 11647 PackageSetting pkgSetting; 11648 long callingId = Binder.clearCallingIdentity(); 11649 try { 11650 // writer 11651 synchronized (mPackages) { 11652 pkgSetting = mSettings.mPackages.get(packageName); 11653 if (pkgSetting == null) { 11654 return true; 11655 } 11656 return pkgSetting.getHidden(userId); 11657 } 11658 } finally { 11659 Binder.restoreCallingIdentity(callingId); 11660 } 11661 } 11662 11663 /** 11664 * @hide 11665 */ 11666 @Override 11667 public int installExistingPackageAsUser(String packageName, int userId) { 11668 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, 11669 null); 11670 PackageSetting pkgSetting; 11671 final int uid = Binder.getCallingUid(); 11672 enforceCrossUserPermission(uid, userId, 11673 true /* requireFullPermission */, true /* checkShell */, 11674 "installExistingPackage for user " + userId); 11675 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 11676 return PackageManager.INSTALL_FAILED_USER_RESTRICTED; 11677 } 11678 11679 long callingId = Binder.clearCallingIdentity(); 11680 try { 11681 boolean installed = false; 11682 11683 // writer 11684 synchronized (mPackages) { 11685 pkgSetting = mSettings.mPackages.get(packageName); 11686 if (pkgSetting == null) { 11687 return PackageManager.INSTALL_FAILED_INVALID_URI; 11688 } 11689 if (!pkgSetting.getInstalled(userId)) { 11690 pkgSetting.setInstalled(true, userId); 11691 pkgSetting.setHidden(false, userId); 11692 mSettings.writePackageRestrictionsLPr(userId); 11693 installed = true; 11694 } 11695 } 11696 11697 if (installed) { 11698 if (pkgSetting.pkg != null) { 11699 synchronized (mInstallLock) { 11700 // We don't need to freeze for a brand new install 11701 prepareAppDataAfterInstallLIF(pkgSetting.pkg); 11702 } 11703 } 11704 sendPackageAddedForUser(packageName, pkgSetting, userId); 11705 } 11706 } finally { 11707 Binder.restoreCallingIdentity(callingId); 11708 } 11709 11710 return PackageManager.INSTALL_SUCCEEDED; 11711 } 11712 11713 boolean isUserRestricted(int userId, String restrictionKey) { 11714 Bundle restrictions = sUserManager.getUserRestrictions(userId); 11715 if (restrictions.getBoolean(restrictionKey, false)) { 11716 Log.w(TAG, "User is restricted: " + restrictionKey); 11717 return true; 11718 } 11719 return false; 11720 } 11721 11722 @Override 11723 public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended, 11724 int userId) { 11725 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 11726 enforceCrossUserPermission(Binder.getCallingUid(), userId, 11727 true /* requireFullPermission */, true /* checkShell */, 11728 "setPackagesSuspended for user " + userId); 11729 11730 if (ArrayUtils.isEmpty(packageNames)) { 11731 return packageNames; 11732 } 11733 11734 // List of package names for whom the suspended state has changed. 11735 List<String> changedPackages = new ArrayList<>(packageNames.length); 11736 // List of package names for whom the suspended state is not set as requested in this 11737 // method. 11738 List<String> unactionedPackages = new ArrayList<>(packageNames.length); 11739 long callingId = Binder.clearCallingIdentity(); 11740 try { 11741 for (int i = 0; i < packageNames.length; i++) { 11742 String packageName = packageNames[i]; 11743 boolean changed = false; 11744 final int appId; 11745 synchronized (mPackages) { 11746 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName); 11747 if (pkgSetting == null) { 11748 Slog.w(TAG, "Could not find package setting for package \"" + packageName 11749 + "\". Skipping suspending/un-suspending."); 11750 unactionedPackages.add(packageName); 11751 continue; 11752 } 11753 appId = pkgSetting.appId; 11754 if (pkgSetting.getSuspended(userId) != suspended) { 11755 if (!canSuspendPackageForUserLocked(packageName, userId)) { 11756 unactionedPackages.add(packageName); 11757 continue; 11758 } 11759 pkgSetting.setSuspended(suspended, userId); 11760 mSettings.writePackageRestrictionsLPr(userId); 11761 changed = true; 11762 changedPackages.add(packageName); 11763 } 11764 } 11765 11766 if (changed && suspended) { 11767 killApplication(packageName, UserHandle.getUid(userId, appId), 11768 "suspending package"); 11769 } 11770 } 11771 } finally { 11772 Binder.restoreCallingIdentity(callingId); 11773 } 11774 11775 if (!changedPackages.isEmpty()) { 11776 sendPackagesSuspendedForUser(changedPackages.toArray( 11777 new String[changedPackages.size()]), userId, suspended); 11778 } 11779 11780 return unactionedPackages.toArray(new String[unactionedPackages.size()]); 11781 } 11782 11783 @Override 11784 public boolean isPackageSuspendedForUser(String packageName, int userId) { 11785 enforceCrossUserPermission(Binder.getCallingUid(), userId, 11786 true /* requireFullPermission */, false /* checkShell */, 11787 "isPackageSuspendedForUser for user " + userId); 11788 synchronized (mPackages) { 11789 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName); 11790 if (pkgSetting == null) { 11791 throw new IllegalArgumentException("Unknown target package: " + packageName); 11792 } 11793 return pkgSetting.getSuspended(userId); 11794 } 11795 } 11796 11797 private boolean canSuspendPackageForUserLocked(String packageName, int userId) { 11798 if (isPackageDeviceAdmin(packageName, userId)) { 11799 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 11800 + "\": has an active device admin"); 11801 return false; 11802 } 11803 11804 String activeLauncherPackageName = getActiveLauncherPackageName(userId); 11805 if (packageName.equals(activeLauncherPackageName)) { 11806 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 11807 + "\": contains the active launcher"); 11808 return false; 11809 } 11810 11811 if (packageName.equals(mRequiredInstallerPackage)) { 11812 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 11813 + "\": required for package installation"); 11814 return false; 11815 } 11816 11817 if (packageName.equals(mRequiredVerifierPackage)) { 11818 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 11819 + "\": required for package verification"); 11820 return false; 11821 } 11822 11823 if (packageName.equals(getDefaultDialerPackageName(userId))) { 11824 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 11825 + "\": is the default dialer"); 11826 return false; 11827 } 11828 11829 if (mProtectedPackages.isPackageStateProtected(userId, packageName)) { 11830 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 11831 + "\": protected package"); 11832 return false; 11833 } 11834 11835 return true; 11836 } 11837 11838 private String getActiveLauncherPackageName(int userId) { 11839 Intent intent = new Intent(Intent.ACTION_MAIN); 11840 intent.addCategory(Intent.CATEGORY_HOME); 11841 ResolveInfo resolveInfo = resolveIntent( 11842 intent, 11843 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 11844 PackageManager.MATCH_DEFAULT_ONLY, 11845 userId); 11846 11847 return resolveInfo == null ? null : resolveInfo.activityInfo.packageName; 11848 } 11849 11850 private String getDefaultDialerPackageName(int userId) { 11851 synchronized (mPackages) { 11852 return mSettings.getDefaultDialerPackageNameLPw(userId); 11853 } 11854 } 11855 11856 @Override 11857 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException { 11858 mContext.enforceCallingOrSelfPermission( 11859 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 11860 "Only package verification agents can verify applications"); 11861 11862 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 11863 final PackageVerificationResponse response = new PackageVerificationResponse( 11864 verificationCode, Binder.getCallingUid()); 11865 msg.arg1 = id; 11866 msg.obj = response; 11867 mHandler.sendMessage(msg); 11868 } 11869 11870 @Override 11871 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, 11872 long millisecondsToDelay) { 11873 mContext.enforceCallingOrSelfPermission( 11874 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 11875 "Only package verification agents can extend verification timeouts"); 11876 11877 final PackageVerificationState state = mPendingVerification.get(id); 11878 final PackageVerificationResponse response = new PackageVerificationResponse( 11879 verificationCodeAtTimeout, Binder.getCallingUid()); 11880 11881 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) { 11882 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT; 11883 } 11884 if (millisecondsToDelay < 0) { 11885 millisecondsToDelay = 0; 11886 } 11887 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW) 11888 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) { 11889 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT; 11890 } 11891 11892 if ((state != null) && !state.timeoutExtended()) { 11893 state.extendTimeout(); 11894 11895 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 11896 msg.arg1 = id; 11897 msg.obj = response; 11898 mHandler.sendMessageDelayed(msg, millisecondsToDelay); 11899 } 11900 } 11901 11902 private void broadcastPackageVerified(int verificationId, Uri packageUri, 11903 int verificationCode, UserHandle user) { 11904 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED); 11905 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE); 11906 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 11907 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 11908 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode); 11909 11910 mContext.sendBroadcastAsUser(intent, user, 11911 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT); 11912 } 11913 11914 private ComponentName matchComponentForVerifier(String packageName, 11915 List<ResolveInfo> receivers) { 11916 ActivityInfo targetReceiver = null; 11917 11918 final int NR = receivers.size(); 11919 for (int i = 0; i < NR; i++) { 11920 final ResolveInfo info = receivers.get(i); 11921 if (info.activityInfo == null) { 11922 continue; 11923 } 11924 11925 if (packageName.equals(info.activityInfo.packageName)) { 11926 targetReceiver = info.activityInfo; 11927 break; 11928 } 11929 } 11930 11931 if (targetReceiver == null) { 11932 return null; 11933 } 11934 11935 return new ComponentName(targetReceiver.packageName, targetReceiver.name); 11936 } 11937 11938 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo, 11939 List<ResolveInfo> receivers, final PackageVerificationState verificationState) { 11940 if (pkgInfo.verifiers.length == 0) { 11941 return null; 11942 } 11943 11944 final int N = pkgInfo.verifiers.length; 11945 final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1); 11946 for (int i = 0; i < N; i++) { 11947 final VerifierInfo verifierInfo = pkgInfo.verifiers[i]; 11948 11949 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName, 11950 receivers); 11951 if (comp == null) { 11952 continue; 11953 } 11954 11955 final int verifierUid = getUidForVerifier(verifierInfo); 11956 if (verifierUid == -1) { 11957 continue; 11958 } 11959 11960 if (DEBUG_VERIFY) { 11961 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName 11962 + " with the correct signature"); 11963 } 11964 sufficientVerifiers.add(comp); 11965 verificationState.addSufficientVerifier(verifierUid); 11966 } 11967 11968 return sufficientVerifiers; 11969 } 11970 11971 private int getUidForVerifier(VerifierInfo verifierInfo) { 11972 synchronized (mPackages) { 11973 final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName); 11974 if (pkg == null) { 11975 return -1; 11976 } else if (pkg.mSignatures.length != 1) { 11977 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 11978 + " has more than one signature; ignoring"); 11979 return -1; 11980 } 11981 11982 /* 11983 * If the public key of the package's signature does not match 11984 * our expected public key, then this is a different package and 11985 * we should skip. 11986 */ 11987 11988 final byte[] expectedPublicKey; 11989 try { 11990 final Signature verifierSig = pkg.mSignatures[0]; 11991 final PublicKey publicKey = verifierSig.getPublicKey(); 11992 expectedPublicKey = publicKey.getEncoded(); 11993 } catch (CertificateException e) { 11994 return -1; 11995 } 11996 11997 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded(); 11998 11999 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) { 12000 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 12001 + " does not have the expected public key; ignoring"); 12002 return -1; 12003 } 12004 12005 return pkg.applicationInfo.uid; 12006 } 12007 } 12008 12009 @Override 12010 public void finishPackageInstall(int token, boolean didLaunch) { 12011 enforceSystemOrRoot("Only the system is allowed to finish installs"); 12012 12013 if (DEBUG_INSTALL) { 12014 Slog.v(TAG, "BM finishing package install for " + token); 12015 } 12016 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token); 12017 12018 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0); 12019 mHandler.sendMessage(msg); 12020 } 12021 12022 /** 12023 * Get the verification agent timeout. 12024 * 12025 * @return verification timeout in milliseconds 12026 */ 12027 private long getVerificationTimeout() { 12028 return android.provider.Settings.Global.getLong(mContext.getContentResolver(), 12029 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT, 12030 DEFAULT_VERIFICATION_TIMEOUT); 12031 } 12032 12033 /** 12034 * Get the default verification agent response code. 12035 * 12036 * @return default verification response code 12037 */ 12038 private int getDefaultVerificationResponse() { 12039 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 12040 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE, 12041 DEFAULT_VERIFICATION_RESPONSE); 12042 } 12043 12044 /** 12045 * Check whether or not package verification has been enabled. 12046 * 12047 * @return true if verification should be performed 12048 */ 12049 private boolean isVerificationEnabled(int userId, int installFlags) { 12050 if (!DEFAULT_VERIFY_ENABLE) { 12051 return false; 12052 } 12053 // Ephemeral apps don't get the full verification treatment 12054 if ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) { 12055 if (DEBUG_EPHEMERAL) { 12056 Slog.d(TAG, "INSTALL_EPHEMERAL so skipping verification"); 12057 } 12058 return false; 12059 } 12060 12061 boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS); 12062 12063 // Check if installing from ADB 12064 if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) { 12065 // Do not run verification in a test harness environment 12066 if (ActivityManager.isRunningInTestHarness()) { 12067 return false; 12068 } 12069 if (ensureVerifyAppsEnabled) { 12070 return true; 12071 } 12072 // Check if the developer does not want package verification for ADB installs 12073 if (android.provider.Settings.Global.getInt(mContext.getContentResolver(), 12074 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) { 12075 return false; 12076 } 12077 } 12078 12079 if (ensureVerifyAppsEnabled) { 12080 return true; 12081 } 12082 12083 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 12084 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1; 12085 } 12086 12087 @Override 12088 public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains) 12089 throws RemoteException { 12090 mContext.enforceCallingOrSelfPermission( 12091 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 12092 "Only intentfilter verification agents can verify applications"); 12093 12094 final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED); 12095 final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse( 12096 Binder.getCallingUid(), verificationCode, failedDomains); 12097 msg.arg1 = id; 12098 msg.obj = response; 12099 mHandler.sendMessage(msg); 12100 } 12101 12102 @Override 12103 public int getIntentVerificationStatus(String packageName, int userId) { 12104 synchronized (mPackages) { 12105 return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 12106 } 12107 } 12108 12109 @Override 12110 public boolean updateIntentVerificationStatus(String packageName, int status, int userId) { 12111 mContext.enforceCallingOrSelfPermission( 12112 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 12113 12114 boolean result = false; 12115 synchronized (mPackages) { 12116 result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId); 12117 } 12118 if (result) { 12119 scheduleWritePackageRestrictionsLocked(userId); 12120 } 12121 return result; 12122 } 12123 12124 @Override 12125 public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications( 12126 String packageName) { 12127 synchronized (mPackages) { 12128 return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName)); 12129 } 12130 } 12131 12132 @Override 12133 public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) { 12134 if (TextUtils.isEmpty(packageName)) { 12135 return ParceledListSlice.emptyList(); 12136 } 12137 synchronized (mPackages) { 12138 PackageParser.Package pkg = mPackages.get(packageName); 12139 if (pkg == null || pkg.activities == null) { 12140 return ParceledListSlice.emptyList(); 12141 } 12142 final int count = pkg.activities.size(); 12143 ArrayList<IntentFilter> result = new ArrayList<>(); 12144 for (int n=0; n<count; n++) { 12145 PackageParser.Activity activity = pkg.activities.get(n); 12146 if (activity.intents != null && activity.intents.size() > 0) { 12147 result.addAll(activity.intents); 12148 } 12149 } 12150 return new ParceledListSlice<>(result); 12151 } 12152 } 12153 12154 @Override 12155 public boolean setDefaultBrowserPackageName(String packageName, int userId) { 12156 mContext.enforceCallingOrSelfPermission( 12157 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 12158 12159 synchronized (mPackages) { 12160 boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId); 12161 if (packageName != null) { 12162 result |= updateIntentVerificationStatus(packageName, 12163 PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, 12164 userId); 12165 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr( 12166 packageName, userId); 12167 } 12168 return result; 12169 } 12170 } 12171 12172 @Override 12173 public String getDefaultBrowserPackageName(int userId) { 12174 synchronized (mPackages) { 12175 return mSettings.getDefaultBrowserPackageNameLPw(userId); 12176 } 12177 } 12178 12179 /** 12180 * Get the "allow unknown sources" setting. 12181 * 12182 * @return the current "allow unknown sources" setting 12183 */ 12184 private int getUnknownSourcesSettings() { 12185 return android.provider.Settings.Secure.getInt(mContext.getContentResolver(), 12186 android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS, 12187 -1); 12188 } 12189 12190 @Override 12191 public void setInstallerPackageName(String targetPackage, String installerPackageName) { 12192 final int uid = Binder.getCallingUid(); 12193 // writer 12194 synchronized (mPackages) { 12195 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage); 12196 if (targetPackageSetting == null) { 12197 throw new IllegalArgumentException("Unknown target package: " + targetPackage); 12198 } 12199 12200 PackageSetting installerPackageSetting; 12201 if (installerPackageName != null) { 12202 installerPackageSetting = mSettings.mPackages.get(installerPackageName); 12203 if (installerPackageSetting == null) { 12204 throw new IllegalArgumentException("Unknown installer package: " 12205 + installerPackageName); 12206 } 12207 } else { 12208 installerPackageSetting = null; 12209 } 12210 12211 Signature[] callerSignature; 12212 Object obj = mSettings.getUserIdLPr(uid); 12213 if (obj != null) { 12214 if (obj instanceof SharedUserSetting) { 12215 callerSignature = ((SharedUserSetting)obj).signatures.mSignatures; 12216 } else if (obj instanceof PackageSetting) { 12217 callerSignature = ((PackageSetting)obj).signatures.mSignatures; 12218 } else { 12219 throw new SecurityException("Bad object " + obj + " for uid " + uid); 12220 } 12221 } else { 12222 throw new SecurityException("Unknown calling UID: " + uid); 12223 } 12224 12225 // Verify: can't set installerPackageName to a package that is 12226 // not signed with the same cert as the caller. 12227 if (installerPackageSetting != null) { 12228 if (compareSignatures(callerSignature, 12229 installerPackageSetting.signatures.mSignatures) 12230 != PackageManager.SIGNATURE_MATCH) { 12231 throw new SecurityException( 12232 "Caller does not have same cert as new installer package " 12233 + installerPackageName); 12234 } 12235 } 12236 12237 // Verify: if target already has an installer package, it must 12238 // be signed with the same cert as the caller. 12239 if (targetPackageSetting.installerPackageName != null) { 12240 PackageSetting setting = mSettings.mPackages.get( 12241 targetPackageSetting.installerPackageName); 12242 // If the currently set package isn't valid, then it's always 12243 // okay to change it. 12244 if (setting != null) { 12245 if (compareSignatures(callerSignature, 12246 setting.signatures.mSignatures) 12247 != PackageManager.SIGNATURE_MATCH) { 12248 throw new SecurityException( 12249 "Caller does not have same cert as old installer package " 12250 + targetPackageSetting.installerPackageName); 12251 } 12252 } 12253 } 12254 12255 // Okay! 12256 targetPackageSetting.installerPackageName = installerPackageName; 12257 if (installerPackageName != null) { 12258 mSettings.mInstallerPackages.add(installerPackageName); 12259 } 12260 scheduleWriteSettingsLocked(); 12261 } 12262 } 12263 12264 private void processPendingInstall(final InstallArgs args, final int currentStatus) { 12265 // Queue up an async operation since the package installation may take a little while. 12266 mHandler.post(new Runnable() { 12267 public void run() { 12268 mHandler.removeCallbacks(this); 12269 // Result object to be returned 12270 PackageInstalledInfo res = new PackageInstalledInfo(); 12271 res.setReturnCode(currentStatus); 12272 res.uid = -1; 12273 res.pkg = null; 12274 res.removedInfo = null; 12275 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 12276 args.doPreInstall(res.returnCode); 12277 synchronized (mInstallLock) { 12278 installPackageTracedLI(args, res); 12279 } 12280 args.doPostInstall(res.returnCode, res.uid); 12281 } 12282 12283 // A restore should be performed at this point if (a) the install 12284 // succeeded, (b) the operation is not an update, and (c) the new 12285 // package has not opted out of backup participation. 12286 final boolean update = res.removedInfo != null 12287 && res.removedInfo.removedPackage != null; 12288 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags; 12289 boolean doRestore = !update 12290 && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0); 12291 12292 // Set up the post-install work request bookkeeping. This will be used 12293 // and cleaned up by the post-install event handling regardless of whether 12294 // there's a restore pass performed. Token values are >= 1. 12295 int token; 12296 if (mNextInstallToken < 0) mNextInstallToken = 1; 12297 token = mNextInstallToken++; 12298 12299 PostInstallData data = new PostInstallData(args, res); 12300 mRunningInstalls.put(token, data); 12301 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token); 12302 12303 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) { 12304 // Pass responsibility to the Backup Manager. It will perform a 12305 // restore if appropriate, then pass responsibility back to the 12306 // Package Manager to run the post-install observer callbacks 12307 // and broadcasts. 12308 IBackupManager bm = IBackupManager.Stub.asInterface( 12309 ServiceManager.getService(Context.BACKUP_SERVICE)); 12310 if (bm != null) { 12311 if (DEBUG_INSTALL) Log.v(TAG, "token " + token 12312 + " to BM for possible restore"); 12313 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token); 12314 try { 12315 // TODO: http://b/22388012 12316 if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) { 12317 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token); 12318 } else { 12319 doRestore = false; 12320 } 12321 } catch (RemoteException e) { 12322 // can't happen; the backup manager is local 12323 } catch (Exception e) { 12324 Slog.e(TAG, "Exception trying to enqueue restore", e); 12325 doRestore = false; 12326 } 12327 } else { 12328 Slog.e(TAG, "Backup Manager not found!"); 12329 doRestore = false; 12330 } 12331 } 12332 12333 if (!doRestore) { 12334 // No restore possible, or the Backup Manager was mysteriously not 12335 // available -- just fire the post-install work request directly. 12336 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token); 12337 12338 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token); 12339 12340 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 12341 mHandler.sendMessage(msg); 12342 } 12343 } 12344 }); 12345 } 12346 12347 /** 12348 * Callback from PackageSettings whenever an app is first transitioned out of the 12349 * 'stopped' state. Normally we just issue the broadcast, but we can't do that if 12350 * the app was "launched" for a restoreAtInstall operation. Therefore we check 12351 * here whether the app is the target of an ongoing install, and only send the 12352 * broadcast immediately if it is not in that state. If it *is* undergoing a restore, 12353 * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL 12354 * handling. 12355 */ 12356 void notifyFirstLaunch(final String pkgName, final String installerPackage, final int userId) { 12357 // Serialize this with the rest of the install-process message chain. In the 12358 // restore-at-install case, this Runnable will necessarily run before the 12359 // POST_INSTALL message is processed, so the contents of mRunningInstalls 12360 // are coherent. In the non-restore case, the app has already completed install 12361 // and been launched through some other means, so it is not in a problematic 12362 // state for observers to see the FIRST_LAUNCH signal. 12363 mHandler.post(new Runnable() { 12364 @Override 12365 public void run() { 12366 for (int i = 0; i < mRunningInstalls.size(); i++) { 12367 final PostInstallData data = mRunningInstalls.valueAt(i); 12368 if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 12369 continue; 12370 } 12371 if (pkgName.equals(data.res.pkg.applicationInfo.packageName)) { 12372 // right package; but is it for the right user? 12373 for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) { 12374 if (userId == data.res.newUsers[uIndex]) { 12375 if (DEBUG_BACKUP) { 12376 Slog.i(TAG, "Package " + pkgName 12377 + " being restored so deferring FIRST_LAUNCH"); 12378 } 12379 return; 12380 } 12381 } 12382 } 12383 } 12384 // didn't find it, so not being restored 12385 if (DEBUG_BACKUP) { 12386 Slog.i(TAG, "Package " + pkgName + " sending normal FIRST_LAUNCH"); 12387 } 12388 sendFirstLaunchBroadcast(pkgName, installerPackage, new int[] {userId}); 12389 } 12390 }); 12391 } 12392 12393 private void sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds) { 12394 sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0, 12395 installerPkg, null, userIds); 12396 } 12397 12398 private abstract class HandlerParams { 12399 private static final int MAX_RETRIES = 4; 12400 12401 /** 12402 * Number of times startCopy() has been attempted and had a non-fatal 12403 * error. 12404 */ 12405 private int mRetries = 0; 12406 12407 /** User handle for the user requesting the information or installation. */ 12408 private final UserHandle mUser; 12409 String traceMethod; 12410 int traceCookie; 12411 12412 HandlerParams(UserHandle user) { 12413 mUser = user; 12414 } 12415 12416 UserHandle getUser() { 12417 return mUser; 12418 } 12419 12420 HandlerParams setTraceMethod(String traceMethod) { 12421 this.traceMethod = traceMethod; 12422 return this; 12423 } 12424 12425 HandlerParams setTraceCookie(int traceCookie) { 12426 this.traceCookie = traceCookie; 12427 return this; 12428 } 12429 12430 final boolean startCopy() { 12431 boolean res; 12432 try { 12433 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this); 12434 12435 if (++mRetries > MAX_RETRIES) { 12436 Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up"); 12437 mHandler.sendEmptyMessage(MCS_GIVE_UP); 12438 handleServiceError(); 12439 return false; 12440 } else { 12441 handleStartCopy(); 12442 res = true; 12443 } 12444 } catch (RemoteException e) { 12445 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT"); 12446 mHandler.sendEmptyMessage(MCS_RECONNECT); 12447 res = false; 12448 } 12449 handleReturnCode(); 12450 return res; 12451 } 12452 12453 final void serviceError() { 12454 if (DEBUG_INSTALL) Slog.i(TAG, "serviceError"); 12455 handleServiceError(); 12456 handleReturnCode(); 12457 } 12458 12459 abstract void handleStartCopy() throws RemoteException; 12460 abstract void handleServiceError(); 12461 abstract void handleReturnCode(); 12462 } 12463 12464 class MeasureParams extends HandlerParams { 12465 private final PackageStats mStats; 12466 private boolean mSuccess; 12467 12468 private final IPackageStatsObserver mObserver; 12469 12470 public MeasureParams(PackageStats stats, IPackageStatsObserver observer) { 12471 super(new UserHandle(stats.userHandle)); 12472 mObserver = observer; 12473 mStats = stats; 12474 } 12475 12476 @Override 12477 public String toString() { 12478 return "MeasureParams{" 12479 + Integer.toHexString(System.identityHashCode(this)) 12480 + " " + mStats.packageName + "}"; 12481 } 12482 12483 @Override 12484 void handleStartCopy() throws RemoteException { 12485 synchronized (mInstallLock) { 12486 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats); 12487 } 12488 12489 if (mSuccess) { 12490 boolean mounted = false; 12491 try { 12492 final String status = Environment.getExternalStorageState(); 12493 mounted = (Environment.MEDIA_MOUNTED.equals(status) 12494 || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status)); 12495 } catch (Exception e) { 12496 } 12497 12498 if (mounted) { 12499 final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle); 12500 12501 mStats.externalCacheSize = calculateDirectorySize(mContainerService, 12502 userEnv.buildExternalStorageAppCacheDirs(mStats.packageName)); 12503 12504 mStats.externalDataSize = calculateDirectorySize(mContainerService, 12505 userEnv.buildExternalStorageAppDataDirs(mStats.packageName)); 12506 12507 // Always subtract cache size, since it's a subdirectory 12508 mStats.externalDataSize -= mStats.externalCacheSize; 12509 12510 mStats.externalMediaSize = calculateDirectorySize(mContainerService, 12511 userEnv.buildExternalStorageAppMediaDirs(mStats.packageName)); 12512 12513 mStats.externalObbSize = calculateDirectorySize(mContainerService, 12514 userEnv.buildExternalStorageAppObbDirs(mStats.packageName)); 12515 } 12516 } 12517 } 12518 12519 @Override 12520 void handleReturnCode() { 12521 if (mObserver != null) { 12522 try { 12523 mObserver.onGetStatsCompleted(mStats, mSuccess); 12524 } catch (RemoteException e) { 12525 Slog.i(TAG, "Observer no longer exists."); 12526 } 12527 } 12528 } 12529 12530 @Override 12531 void handleServiceError() { 12532 Slog.e(TAG, "Could not measure application " + mStats.packageName 12533 + " external storage"); 12534 } 12535 } 12536 12537 private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths) 12538 throws RemoteException { 12539 long result = 0; 12540 for (File path : paths) { 12541 result += mcs.calculateDirectorySize(path.getAbsolutePath()); 12542 } 12543 return result; 12544 } 12545 12546 private static void clearDirectory(IMediaContainerService mcs, File[] paths) { 12547 for (File path : paths) { 12548 try { 12549 mcs.clearDirectory(path.getAbsolutePath()); 12550 } catch (RemoteException e) { 12551 } 12552 } 12553 } 12554 12555 static class OriginInfo { 12556 /** 12557 * Location where install is coming from, before it has been 12558 * copied/renamed into place. This could be a single monolithic APK 12559 * file, or a cluster directory. This location may be untrusted. 12560 */ 12561 final File file; 12562 final String cid; 12563 12564 /** 12565 * Flag indicating that {@link #file} or {@link #cid} has already been 12566 * staged, meaning downstream users don't need to defensively copy the 12567 * contents. 12568 */ 12569 final boolean staged; 12570 12571 /** 12572 * Flag indicating that {@link #file} or {@link #cid} is an already 12573 * installed app that is being moved. 12574 */ 12575 final boolean existing; 12576 12577 final String resolvedPath; 12578 final File resolvedFile; 12579 12580 static OriginInfo fromNothing() { 12581 return new OriginInfo(null, null, false, false); 12582 } 12583 12584 static OriginInfo fromUntrustedFile(File file) { 12585 return new OriginInfo(file, null, false, false); 12586 } 12587 12588 static OriginInfo fromExistingFile(File file) { 12589 return new OriginInfo(file, null, false, true); 12590 } 12591 12592 static OriginInfo fromStagedFile(File file) { 12593 return new OriginInfo(file, null, true, false); 12594 } 12595 12596 static OriginInfo fromStagedContainer(String cid) { 12597 return new OriginInfo(null, cid, true, false); 12598 } 12599 12600 private OriginInfo(File file, String cid, boolean staged, boolean existing) { 12601 this.file = file; 12602 this.cid = cid; 12603 this.staged = staged; 12604 this.existing = existing; 12605 12606 if (cid != null) { 12607 resolvedPath = PackageHelper.getSdDir(cid); 12608 resolvedFile = new File(resolvedPath); 12609 } else if (file != null) { 12610 resolvedPath = file.getAbsolutePath(); 12611 resolvedFile = file; 12612 } else { 12613 resolvedPath = null; 12614 resolvedFile = null; 12615 } 12616 } 12617 } 12618 12619 static class MoveInfo { 12620 final int moveId; 12621 final String fromUuid; 12622 final String toUuid; 12623 final String packageName; 12624 final String dataAppName; 12625 final int appId; 12626 final String seinfo; 12627 final int targetSdkVersion; 12628 12629 public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName, 12630 String dataAppName, int appId, String seinfo, int targetSdkVersion) { 12631 this.moveId = moveId; 12632 this.fromUuid = fromUuid; 12633 this.toUuid = toUuid; 12634 this.packageName = packageName; 12635 this.dataAppName = dataAppName; 12636 this.appId = appId; 12637 this.seinfo = seinfo; 12638 this.targetSdkVersion = targetSdkVersion; 12639 } 12640 } 12641 12642 static class VerificationInfo { 12643 /** A constant used to indicate that a uid value is not present. */ 12644 public static final int NO_UID = -1; 12645 12646 /** URI referencing where the package was downloaded from. */ 12647 final Uri originatingUri; 12648 12649 /** HTTP referrer URI associated with the originatingURI. */ 12650 final Uri referrer; 12651 12652 /** UID of the application that the install request originated from. */ 12653 final int originatingUid; 12654 12655 /** UID of application requesting the install */ 12656 final int installerUid; 12657 12658 VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) { 12659 this.originatingUri = originatingUri; 12660 this.referrer = referrer; 12661 this.originatingUid = originatingUid; 12662 this.installerUid = installerUid; 12663 } 12664 } 12665 12666 class InstallParams extends HandlerParams { 12667 final OriginInfo origin; 12668 final MoveInfo move; 12669 final IPackageInstallObserver2 observer; 12670 int installFlags; 12671 final String installerPackageName; 12672 final String volumeUuid; 12673 private InstallArgs mArgs; 12674 private int mRet; 12675 final String packageAbiOverride; 12676 final String[] grantedRuntimePermissions; 12677 final VerificationInfo verificationInfo; 12678 final Certificate[][] certificates; 12679 12680 InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 12681 int installFlags, String installerPackageName, String volumeUuid, 12682 VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride, 12683 String[] grantedPermissions, Certificate[][] certificates) { 12684 super(user); 12685 this.origin = origin; 12686 this.move = move; 12687 this.observer = observer; 12688 this.installFlags = installFlags; 12689 this.installerPackageName = installerPackageName; 12690 this.volumeUuid = volumeUuid; 12691 this.verificationInfo = verificationInfo; 12692 this.packageAbiOverride = packageAbiOverride; 12693 this.grantedRuntimePermissions = grantedPermissions; 12694 this.certificates = certificates; 12695 } 12696 12697 @Override 12698 public String toString() { 12699 return "InstallParams{" + Integer.toHexString(System.identityHashCode(this)) 12700 + " file=" + origin.file + " cid=" + origin.cid + "}"; 12701 } 12702 12703 private int installLocationPolicy(PackageInfoLite pkgLite) { 12704 String packageName = pkgLite.packageName; 12705 int installLocation = pkgLite.installLocation; 12706 boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 12707 // reader 12708 synchronized (mPackages) { 12709 // Currently installed package which the new package is attempting to replace or 12710 // null if no such package is installed. 12711 PackageParser.Package installedPkg = mPackages.get(packageName); 12712 // Package which currently owns the data which the new package will own if installed. 12713 // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg 12714 // will be null whereas dataOwnerPkg will contain information about the package 12715 // which was uninstalled while keeping its data. 12716 PackageParser.Package dataOwnerPkg = installedPkg; 12717 if (dataOwnerPkg == null) { 12718 PackageSetting ps = mSettings.mPackages.get(packageName); 12719 if (ps != null) { 12720 dataOwnerPkg = ps.pkg; 12721 } 12722 } 12723 12724 if (dataOwnerPkg != null) { 12725 // If installed, the package will get access to data left on the device by its 12726 // predecessor. As a security measure, this is permited only if this is not a 12727 // version downgrade or if the predecessor package is marked as debuggable and 12728 // a downgrade is explicitly requested. 12729 // 12730 // On debuggable platform builds, downgrades are permitted even for 12731 // non-debuggable packages to make testing easier. Debuggable platform builds do 12732 // not offer security guarantees and thus it's OK to disable some security 12733 // mechanisms to make debugging/testing easier on those builds. However, even on 12734 // debuggable builds downgrades of packages are permitted only if requested via 12735 // installFlags. This is because we aim to keep the behavior of debuggable 12736 // platform builds as close as possible to the behavior of non-debuggable 12737 // platform builds. 12738 final boolean downgradeRequested = 12739 (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0; 12740 final boolean packageDebuggable = 12741 (dataOwnerPkg.applicationInfo.flags 12742 & ApplicationInfo.FLAG_DEBUGGABLE) != 0; 12743 final boolean downgradePermitted = 12744 (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable)); 12745 if (!downgradePermitted) { 12746 try { 12747 checkDowngrade(dataOwnerPkg, pkgLite); 12748 } catch (PackageManagerException e) { 12749 Slog.w(TAG, "Downgrade detected: " + e.getMessage()); 12750 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE; 12751 } 12752 } 12753 } 12754 12755 if (installedPkg != null) { 12756 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 12757 // Check for updated system application. 12758 if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 12759 if (onSd) { 12760 Slog.w(TAG, "Cannot install update to system app on sdcard"); 12761 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION; 12762 } 12763 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 12764 } else { 12765 if (onSd) { 12766 // Install flag overrides everything. 12767 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 12768 } 12769 // If current upgrade specifies particular preference 12770 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) { 12771 // Application explicitly specified internal. 12772 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 12773 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) { 12774 // App explictly prefers external. Let policy decide 12775 } else { 12776 // Prefer previous location 12777 if (isExternal(installedPkg)) { 12778 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 12779 } 12780 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 12781 } 12782 } 12783 } else { 12784 // Invalid install. Return error code 12785 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS; 12786 } 12787 } 12788 } 12789 // All the special cases have been taken care of. 12790 // Return result based on recommended install location. 12791 if (onSd) { 12792 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 12793 } 12794 return pkgLite.recommendedInstallLocation; 12795 } 12796 12797 /* 12798 * Invoke remote method to get package information and install 12799 * location values. Override install location based on default 12800 * policy if needed and then create install arguments based 12801 * on the install location. 12802 */ 12803 public void handleStartCopy() throws RemoteException { 12804 int ret = PackageManager.INSTALL_SUCCEEDED; 12805 12806 // If we're already staged, we've firmly committed to an install location 12807 if (origin.staged) { 12808 if (origin.file != null) { 12809 installFlags |= PackageManager.INSTALL_INTERNAL; 12810 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 12811 } else if (origin.cid != null) { 12812 installFlags |= PackageManager.INSTALL_EXTERNAL; 12813 installFlags &= ~PackageManager.INSTALL_INTERNAL; 12814 } else { 12815 throw new IllegalStateException("Invalid stage location"); 12816 } 12817 } 12818 12819 final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 12820 final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0; 12821 final boolean ephemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; 12822 PackageInfoLite pkgLite = null; 12823 12824 if (onInt && onSd) { 12825 // Check if both bits are set. 12826 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external"); 12827 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 12828 } else if (onSd && ephemeral) { 12829 Slog.w(TAG, "Conflicting flags specified for installing ephemeral on external"); 12830 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 12831 } else { 12832 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags, 12833 packageAbiOverride); 12834 12835 if (DEBUG_EPHEMERAL && ephemeral) { 12836 Slog.v(TAG, "pkgLite for install: " + pkgLite); 12837 } 12838 12839 /* 12840 * If we have too little free space, try to free cache 12841 * before giving up. 12842 */ 12843 if (!origin.staged && pkgLite.recommendedInstallLocation 12844 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 12845 // TODO: focus freeing disk space on the target device 12846 final StorageManager storage = StorageManager.from(mContext); 12847 final long lowThreshold = storage.getStorageLowBytes( 12848 Environment.getDataDirectory()); 12849 12850 final long sizeBytes = mContainerService.calculateInstalledSize( 12851 origin.resolvedPath, isForwardLocked(), packageAbiOverride); 12852 12853 try { 12854 mInstaller.freeCache(null, sizeBytes + lowThreshold); 12855 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, 12856 installFlags, packageAbiOverride); 12857 } catch (InstallerException e) { 12858 Slog.w(TAG, "Failed to free cache", e); 12859 } 12860 12861 /* 12862 * The cache free must have deleted the file we 12863 * downloaded to install. 12864 * 12865 * TODO: fix the "freeCache" call to not delete 12866 * the file we care about. 12867 */ 12868 if (pkgLite.recommendedInstallLocation 12869 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 12870 pkgLite.recommendedInstallLocation 12871 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE; 12872 } 12873 } 12874 } 12875 12876 if (ret == PackageManager.INSTALL_SUCCEEDED) { 12877 int loc = pkgLite.recommendedInstallLocation; 12878 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) { 12879 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 12880 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) { 12881 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 12882 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 12883 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 12884 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) { 12885 ret = PackageManager.INSTALL_FAILED_INVALID_APK; 12886 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 12887 ret = PackageManager.INSTALL_FAILED_INVALID_URI; 12888 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) { 12889 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE; 12890 } else { 12891 // Override with defaults if needed. 12892 loc = installLocationPolicy(pkgLite); 12893 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) { 12894 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 12895 } else if (!onSd && !onInt) { 12896 // Override install location with flags 12897 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) { 12898 // Set the flag to install on external media. 12899 installFlags |= PackageManager.INSTALL_EXTERNAL; 12900 installFlags &= ~PackageManager.INSTALL_INTERNAL; 12901 } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) { 12902 if (DEBUG_EPHEMERAL) { 12903 Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag"); 12904 } 12905 installFlags |= PackageManager.INSTALL_EPHEMERAL; 12906 installFlags &= ~(PackageManager.INSTALL_EXTERNAL 12907 |PackageManager.INSTALL_INTERNAL); 12908 } else { 12909 // Make sure the flag for installing on external 12910 // media is unset 12911 installFlags |= PackageManager.INSTALL_INTERNAL; 12912 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 12913 } 12914 } 12915 } 12916 } 12917 12918 final InstallArgs args = createInstallArgs(this); 12919 mArgs = args; 12920 12921 if (ret == PackageManager.INSTALL_SUCCEEDED) { 12922 // TODO: http://b/22976637 12923 // Apps installed for "all" users use the device owner to verify the app 12924 UserHandle verifierUser = getUser(); 12925 if (verifierUser == UserHandle.ALL) { 12926 verifierUser = UserHandle.SYSTEM; 12927 } 12928 12929 /* 12930 * Determine if we have any installed package verifiers. If we 12931 * do, then we'll defer to them to verify the packages. 12932 */ 12933 final int requiredUid = mRequiredVerifierPackage == null ? -1 12934 : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 12935 verifierUser.getIdentifier()); 12936 if (!origin.existing && requiredUid != -1 12937 && isVerificationEnabled(verifierUser.getIdentifier(), installFlags)) { 12938 final Intent verification = new Intent( 12939 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 12940 verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 12941 verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)), 12942 PACKAGE_MIME_TYPE); 12943 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 12944 12945 // Query all live verifiers based on current user state 12946 final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification, 12947 PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier()); 12948 12949 if (DEBUG_VERIFY) { 12950 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent " 12951 + verification.toString() + " with " + pkgLite.verifiers.length 12952 + " optional verifiers"); 12953 } 12954 12955 final int verificationId = mPendingVerificationToken++; 12956 12957 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 12958 12959 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE, 12960 installerPackageName); 12961 12962 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, 12963 installFlags); 12964 12965 verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME, 12966 pkgLite.packageName); 12967 12968 verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE, 12969 pkgLite.versionCode); 12970 12971 if (verificationInfo != null) { 12972 if (verificationInfo.originatingUri != null) { 12973 verification.putExtra(Intent.EXTRA_ORIGINATING_URI, 12974 verificationInfo.originatingUri); 12975 } 12976 if (verificationInfo.referrer != null) { 12977 verification.putExtra(Intent.EXTRA_REFERRER, 12978 verificationInfo.referrer); 12979 } 12980 if (verificationInfo.originatingUid >= 0) { 12981 verification.putExtra(Intent.EXTRA_ORIGINATING_UID, 12982 verificationInfo.originatingUid); 12983 } 12984 if (verificationInfo.installerUid >= 0) { 12985 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID, 12986 verificationInfo.installerUid); 12987 } 12988 } 12989 12990 final PackageVerificationState verificationState = new PackageVerificationState( 12991 requiredUid, args); 12992 12993 mPendingVerification.append(verificationId, verificationState); 12994 12995 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite, 12996 receivers, verificationState); 12997 12998 /* 12999 * If any sufficient verifiers were listed in the package 13000 * manifest, attempt to ask them. 13001 */ 13002 if (sufficientVerifiers != null) { 13003 final int N = sufficientVerifiers.size(); 13004 if (N == 0) { 13005 Slog.i(TAG, "Additional verifiers required, but none installed."); 13006 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 13007 } else { 13008 for (int i = 0; i < N; i++) { 13009 final ComponentName verifierComponent = sufficientVerifiers.get(i); 13010 13011 final Intent sufficientIntent = new Intent(verification); 13012 sufficientIntent.setComponent(verifierComponent); 13013 mContext.sendBroadcastAsUser(sufficientIntent, verifierUser); 13014 } 13015 } 13016 } 13017 13018 final ComponentName requiredVerifierComponent = matchComponentForVerifier( 13019 mRequiredVerifierPackage, receivers); 13020 if (ret == PackageManager.INSTALL_SUCCEEDED 13021 && mRequiredVerifierPackage != null) { 13022 Trace.asyncTraceBegin( 13023 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 13024 /* 13025 * Send the intent to the required verification agent, 13026 * but only start the verification timeout after the 13027 * target BroadcastReceivers have run. 13028 */ 13029 verification.setComponent(requiredVerifierComponent); 13030 mContext.sendOrderedBroadcastAsUser(verification, verifierUser, 13031 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 13032 new BroadcastReceiver() { 13033 @Override 13034 public void onReceive(Context context, Intent intent) { 13035 final Message msg = mHandler 13036 .obtainMessage(CHECK_PENDING_VERIFICATION); 13037 msg.arg1 = verificationId; 13038 mHandler.sendMessageDelayed(msg, getVerificationTimeout()); 13039 } 13040 }, null, 0, null, null); 13041 13042 /* 13043 * We don't want the copy to proceed until verification 13044 * succeeds, so null out this field. 13045 */ 13046 mArgs = null; 13047 } 13048 } else { 13049 /* 13050 * No package verification is enabled, so immediately start 13051 * the remote call to initiate copy using temporary file. 13052 */ 13053 ret = args.copyApk(mContainerService, true); 13054 } 13055 } 13056 13057 mRet = ret; 13058 } 13059 13060 @Override 13061 void handleReturnCode() { 13062 // If mArgs is null, then MCS couldn't be reached. When it 13063 // reconnects, it will try again to install. At that point, this 13064 // will succeed. 13065 if (mArgs != null) { 13066 processPendingInstall(mArgs, mRet); 13067 } 13068 } 13069 13070 @Override 13071 void handleServiceError() { 13072 mArgs = createInstallArgs(this); 13073 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 13074 } 13075 13076 public boolean isForwardLocked() { 13077 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 13078 } 13079 } 13080 13081 /** 13082 * Used during creation of InstallArgs 13083 * 13084 * @param installFlags package installation flags 13085 * @return true if should be installed on external storage 13086 */ 13087 private static boolean installOnExternalAsec(int installFlags) { 13088 if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) { 13089 return false; 13090 } 13091 if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) { 13092 return true; 13093 } 13094 return false; 13095 } 13096 13097 /** 13098 * Used during creation of InstallArgs 13099 * 13100 * @param installFlags package installation flags 13101 * @return true if should be installed as forward locked 13102 */ 13103 private static boolean installForwardLocked(int installFlags) { 13104 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 13105 } 13106 13107 private InstallArgs createInstallArgs(InstallParams params) { 13108 if (params.move != null) { 13109 return new MoveInstallArgs(params); 13110 } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) { 13111 return new AsecInstallArgs(params); 13112 } else { 13113 return new FileInstallArgs(params); 13114 } 13115 } 13116 13117 /** 13118 * Create args that describe an existing installed package. Typically used 13119 * when cleaning up old installs, or used as a move source. 13120 */ 13121 private InstallArgs createInstallArgsForExisting(int installFlags, String codePath, 13122 String resourcePath, String[] instructionSets) { 13123 final boolean isInAsec; 13124 if (installOnExternalAsec(installFlags)) { 13125 /* Apps on SD card are always in ASEC containers. */ 13126 isInAsec = true; 13127 } else if (installForwardLocked(installFlags) 13128 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) { 13129 /* 13130 * Forward-locked apps are only in ASEC containers if they're the 13131 * new style 13132 */ 13133 isInAsec = true; 13134 } else { 13135 isInAsec = false; 13136 } 13137 13138 if (isInAsec) { 13139 return new AsecInstallArgs(codePath, instructionSets, 13140 installOnExternalAsec(installFlags), installForwardLocked(installFlags)); 13141 } else { 13142 return new FileInstallArgs(codePath, resourcePath, instructionSets); 13143 } 13144 } 13145 13146 static abstract class InstallArgs { 13147 /** @see InstallParams#origin */ 13148 final OriginInfo origin; 13149 /** @see InstallParams#move */ 13150 final MoveInfo move; 13151 13152 final IPackageInstallObserver2 observer; 13153 // Always refers to PackageManager flags only 13154 final int installFlags; 13155 final String installerPackageName; 13156 final String volumeUuid; 13157 final UserHandle user; 13158 final String abiOverride; 13159 final String[] installGrantPermissions; 13160 /** If non-null, drop an async trace when the install completes */ 13161 final String traceMethod; 13162 final int traceCookie; 13163 final Certificate[][] certificates; 13164 13165 // The list of instruction sets supported by this app. This is currently 13166 // only used during the rmdex() phase to clean up resources. We can get rid of this 13167 // if we move dex files under the common app path. 13168 /* nullable */ String[] instructionSets; 13169 13170 InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 13171 int installFlags, String installerPackageName, String volumeUuid, 13172 UserHandle user, String[] instructionSets, 13173 String abiOverride, String[] installGrantPermissions, 13174 String traceMethod, int traceCookie, Certificate[][] certificates) { 13175 this.origin = origin; 13176 this.move = move; 13177 this.installFlags = installFlags; 13178 this.observer = observer; 13179 this.installerPackageName = installerPackageName; 13180 this.volumeUuid = volumeUuid; 13181 this.user = user; 13182 this.instructionSets = instructionSets; 13183 this.abiOverride = abiOverride; 13184 this.installGrantPermissions = installGrantPermissions; 13185 this.traceMethod = traceMethod; 13186 this.traceCookie = traceCookie; 13187 this.certificates = certificates; 13188 } 13189 13190 abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException; 13191 abstract int doPreInstall(int status); 13192 13193 /** 13194 * Rename package into final resting place. All paths on the given 13195 * scanned package should be updated to reflect the rename. 13196 */ 13197 abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath); 13198 abstract int doPostInstall(int status, int uid); 13199 13200 /** @see PackageSettingBase#codePathString */ 13201 abstract String getCodePath(); 13202 /** @see PackageSettingBase#resourcePathString */ 13203 abstract String getResourcePath(); 13204 13205 // Need installer lock especially for dex file removal. 13206 abstract void cleanUpResourcesLI(); 13207 abstract boolean doPostDeleteLI(boolean delete); 13208 13209 /** 13210 * Called before the source arguments are copied. This is used mostly 13211 * for MoveParams when it needs to read the source file to put it in the 13212 * destination. 13213 */ 13214 int doPreCopy() { 13215 return PackageManager.INSTALL_SUCCEEDED; 13216 } 13217 13218 /** 13219 * Called after the source arguments are copied. This is used mostly for 13220 * MoveParams when it needs to read the source file to put it in the 13221 * destination. 13222 */ 13223 int doPostCopy(int uid) { 13224 return PackageManager.INSTALL_SUCCEEDED; 13225 } 13226 13227 protected boolean isFwdLocked() { 13228 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 13229 } 13230 13231 protected boolean isExternalAsec() { 13232 return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 13233 } 13234 13235 protected boolean isEphemeral() { 13236 return (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; 13237 } 13238 13239 UserHandle getUser() { 13240 return user; 13241 } 13242 } 13243 13244 private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) { 13245 if (!allCodePaths.isEmpty()) { 13246 if (instructionSets == null) { 13247 throw new IllegalStateException("instructionSet == null"); 13248 } 13249 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); 13250 for (String codePath : allCodePaths) { 13251 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 13252 try { 13253 mInstaller.rmdex(codePath, dexCodeInstructionSet); 13254 } catch (InstallerException ignored) { 13255 } 13256 } 13257 } 13258 } 13259 } 13260 13261 /** 13262 * Logic to handle installation of non-ASEC applications, including copying 13263 * and renaming logic. 13264 */ 13265 class FileInstallArgs extends InstallArgs { 13266 private File codeFile; 13267 private File resourceFile; 13268 13269 // Example topology: 13270 // /data/app/com.example/base.apk 13271 // /data/app/com.example/split_foo.apk 13272 // /data/app/com.example/lib/arm/libfoo.so 13273 // /data/app/com.example/lib/arm64/libfoo.so 13274 // /data/app/com.example/dalvik/arm/base.apk@classes.dex 13275 13276 /** New install */ 13277 FileInstallArgs(InstallParams params) { 13278 super(params.origin, params.move, params.observer, params.installFlags, 13279 params.installerPackageName, params.volumeUuid, 13280 params.getUser(), null /*instructionSets*/, params.packageAbiOverride, 13281 params.grantedRuntimePermissions, 13282 params.traceMethod, params.traceCookie, params.certificates); 13283 if (isFwdLocked()) { 13284 throw new IllegalArgumentException("Forward locking only supported in ASEC"); 13285 } 13286 } 13287 13288 /** Existing install */ 13289 FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) { 13290 super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets, 13291 null, null, null, 0, null /*certificates*/); 13292 this.codeFile = (codePath != null) ? new File(codePath) : null; 13293 this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null; 13294 } 13295 13296 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 13297 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk"); 13298 try { 13299 return doCopyApk(imcs, temp); 13300 } finally { 13301 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13302 } 13303 } 13304 13305 private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 13306 if (origin.staged) { 13307 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy"); 13308 codeFile = origin.file; 13309 resourceFile = origin.file; 13310 return PackageManager.INSTALL_SUCCEEDED; 13311 } 13312 13313 try { 13314 final boolean isEphemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; 13315 final File tempDir = 13316 mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral); 13317 codeFile = tempDir; 13318 resourceFile = tempDir; 13319 } catch (IOException e) { 13320 Slog.w(TAG, "Failed to create copy file: " + e); 13321 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 13322 } 13323 13324 final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() { 13325 @Override 13326 public ParcelFileDescriptor open(String name, int mode) throws RemoteException { 13327 if (!FileUtils.isValidExtFilename(name)) { 13328 throw new IllegalArgumentException("Invalid filename: " + name); 13329 } 13330 try { 13331 final File file = new File(codeFile, name); 13332 final FileDescriptor fd = Os.open(file.getAbsolutePath(), 13333 O_RDWR | O_CREAT, 0644); 13334 Os.chmod(file.getAbsolutePath(), 0644); 13335 return new ParcelFileDescriptor(fd); 13336 } catch (ErrnoException e) { 13337 throw new RemoteException("Failed to open: " + e.getMessage()); 13338 } 13339 } 13340 }; 13341 13342 int ret = PackageManager.INSTALL_SUCCEEDED; 13343 ret = imcs.copyPackage(origin.file.getAbsolutePath(), target); 13344 if (ret != PackageManager.INSTALL_SUCCEEDED) { 13345 Slog.e(TAG, "Failed to copy package"); 13346 return ret; 13347 } 13348 13349 final File libraryRoot = new File(codeFile, LIB_DIR_NAME); 13350 NativeLibraryHelper.Handle handle = null; 13351 try { 13352 handle = NativeLibraryHelper.Handle.create(codeFile); 13353 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot, 13354 abiOverride); 13355 } catch (IOException e) { 13356 Slog.e(TAG, "Copying native libraries failed", e); 13357 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 13358 } finally { 13359 IoUtils.closeQuietly(handle); 13360 } 13361 13362 return ret; 13363 } 13364 13365 int doPreInstall(int status) { 13366 if (status != PackageManager.INSTALL_SUCCEEDED) { 13367 cleanUp(); 13368 } 13369 return status; 13370 } 13371 13372 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 13373 if (status != PackageManager.INSTALL_SUCCEEDED) { 13374 cleanUp(); 13375 return false; 13376 } 13377 13378 final File targetDir = codeFile.getParentFile(); 13379 final File beforeCodeFile = codeFile; 13380 final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName); 13381 13382 if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile); 13383 try { 13384 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath()); 13385 } catch (ErrnoException e) { 13386 Slog.w(TAG, "Failed to rename", e); 13387 return false; 13388 } 13389 13390 if (!SELinux.restoreconRecursive(afterCodeFile)) { 13391 Slog.w(TAG, "Failed to restorecon"); 13392 return false; 13393 } 13394 13395 // Reflect the rename internally 13396 codeFile = afterCodeFile; 13397 resourceFile = afterCodeFile; 13398 13399 // Reflect the rename in scanned details 13400 pkg.setCodePath(afterCodeFile.getAbsolutePath()); 13401 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile, 13402 afterCodeFile, pkg.baseCodePath)); 13403 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile, 13404 afterCodeFile, pkg.splitCodePaths)); 13405 13406 // Reflect the rename in app info 13407 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 13408 pkg.setApplicationInfoCodePath(pkg.codePath); 13409 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 13410 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 13411 pkg.setApplicationInfoResourcePath(pkg.codePath); 13412 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 13413 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 13414 13415 return true; 13416 } 13417 13418 int doPostInstall(int status, int uid) { 13419 if (status != PackageManager.INSTALL_SUCCEEDED) { 13420 cleanUp(); 13421 } 13422 return status; 13423 } 13424 13425 @Override 13426 String getCodePath() { 13427 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 13428 } 13429 13430 @Override 13431 String getResourcePath() { 13432 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 13433 } 13434 13435 private boolean cleanUp() { 13436 if (codeFile == null || !codeFile.exists()) { 13437 return false; 13438 } 13439 13440 removeCodePathLI(codeFile); 13441 13442 if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) { 13443 resourceFile.delete(); 13444 } 13445 13446 return true; 13447 } 13448 13449 void cleanUpResourcesLI() { 13450 // Try enumerating all code paths before deleting 13451 List<String> allCodePaths = Collections.EMPTY_LIST; 13452 if (codeFile != null && codeFile.exists()) { 13453 try { 13454 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 13455 allCodePaths = pkg.getAllCodePaths(); 13456 } catch (PackageParserException e) { 13457 // Ignored; we tried our best 13458 } 13459 } 13460 13461 cleanUp(); 13462 removeDexFiles(allCodePaths, instructionSets); 13463 } 13464 13465 boolean doPostDeleteLI(boolean delete) { 13466 // XXX err, shouldn't we respect the delete flag? 13467 cleanUpResourcesLI(); 13468 return true; 13469 } 13470 } 13471 13472 private boolean isAsecExternal(String cid) { 13473 final String asecPath = PackageHelper.getSdFilesystem(cid); 13474 return !asecPath.startsWith(mAsecInternalPath); 13475 } 13476 13477 private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws 13478 PackageManagerException { 13479 if (copyRet < 0) { 13480 if (copyRet != PackageManager.NO_NATIVE_LIBRARIES && 13481 copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) { 13482 throw new PackageManagerException(copyRet, message); 13483 } 13484 } 13485 } 13486 13487 /** 13488 * Extract the MountService "container ID" from the full code path of an 13489 * .apk. 13490 */ 13491 static String cidFromCodePath(String fullCodePath) { 13492 int eidx = fullCodePath.lastIndexOf("/"); 13493 String subStr1 = fullCodePath.substring(0, eidx); 13494 int sidx = subStr1.lastIndexOf("/"); 13495 return subStr1.substring(sidx+1, eidx); 13496 } 13497 13498 /** 13499 * Logic to handle installation of ASEC applications, including copying and 13500 * renaming logic. 13501 */ 13502 class AsecInstallArgs extends InstallArgs { 13503 static final String RES_FILE_NAME = "pkg.apk"; 13504 static final String PUBLIC_RES_FILE_NAME = "res.zip"; 13505 13506 String cid; 13507 String packagePath; 13508 String resourcePath; 13509 13510 /** New install */ 13511 AsecInstallArgs(InstallParams params) { 13512 super(params.origin, params.move, params.observer, params.installFlags, 13513 params.installerPackageName, params.volumeUuid, 13514 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 13515 params.grantedRuntimePermissions, 13516 params.traceMethod, params.traceCookie, params.certificates); 13517 } 13518 13519 /** Existing install */ 13520 AsecInstallArgs(String fullCodePath, String[] instructionSets, 13521 boolean isExternal, boolean isForwardLocked) { 13522 super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0) 13523 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, 13524 instructionSets, null, null, null, 0, null /*certificates*/); 13525 // Hackily pretend we're still looking at a full code path 13526 if (!fullCodePath.endsWith(RES_FILE_NAME)) { 13527 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath(); 13528 } 13529 13530 // Extract cid from fullCodePath 13531 int eidx = fullCodePath.lastIndexOf("/"); 13532 String subStr1 = fullCodePath.substring(0, eidx); 13533 int sidx = subStr1.lastIndexOf("/"); 13534 cid = subStr1.substring(sidx+1, eidx); 13535 setMountPath(subStr1); 13536 } 13537 13538 AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) { 13539 super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0) 13540 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, 13541 instructionSets, null, null, null, 0, null /*certificates*/); 13542 this.cid = cid; 13543 setMountPath(PackageHelper.getSdDir(cid)); 13544 } 13545 13546 void createCopyFile() { 13547 cid = mInstallerService.allocateExternalStageCidLegacy(); 13548 } 13549 13550 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 13551 if (origin.staged && origin.cid != null) { 13552 if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy"); 13553 cid = origin.cid; 13554 setMountPath(PackageHelper.getSdDir(cid)); 13555 return PackageManager.INSTALL_SUCCEEDED; 13556 } 13557 13558 if (temp) { 13559 createCopyFile(); 13560 } else { 13561 /* 13562 * Pre-emptively destroy the container since it's destroyed if 13563 * copying fails due to it existing anyway. 13564 */ 13565 PackageHelper.destroySdDir(cid); 13566 } 13567 13568 final String newMountPath = imcs.copyPackageToContainer( 13569 origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(), 13570 isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */)); 13571 13572 if (newMountPath != null) { 13573 setMountPath(newMountPath); 13574 return PackageManager.INSTALL_SUCCEEDED; 13575 } else { 13576 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 13577 } 13578 } 13579 13580 @Override 13581 String getCodePath() { 13582 return packagePath; 13583 } 13584 13585 @Override 13586 String getResourcePath() { 13587 return resourcePath; 13588 } 13589 13590 int doPreInstall(int status) { 13591 if (status != PackageManager.INSTALL_SUCCEEDED) { 13592 // Destroy container 13593 PackageHelper.destroySdDir(cid); 13594 } else { 13595 boolean mounted = PackageHelper.isContainerMounted(cid); 13596 if (!mounted) { 13597 String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(), 13598 Process.SYSTEM_UID); 13599 if (newMountPath != null) { 13600 setMountPath(newMountPath); 13601 } else { 13602 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 13603 } 13604 } 13605 } 13606 return status; 13607 } 13608 13609 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 13610 String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME); 13611 String newMountPath = null; 13612 if (PackageHelper.isContainerMounted(cid)) { 13613 // Unmount the container 13614 if (!PackageHelper.unMountSdDir(cid)) { 13615 Slog.i(TAG, "Failed to unmount " + cid + " before renaming"); 13616 return false; 13617 } 13618 } 13619 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 13620 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId + 13621 " which might be stale. Will try to clean up."); 13622 // Clean up the stale container and proceed to recreate. 13623 if (!PackageHelper.destroySdDir(newCacheId)) { 13624 Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId); 13625 return false; 13626 } 13627 // Successfully cleaned up stale container. Try to rename again. 13628 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 13629 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId 13630 + " inspite of cleaning it up."); 13631 return false; 13632 } 13633 } 13634 if (!PackageHelper.isContainerMounted(newCacheId)) { 13635 Slog.w(TAG, "Mounting container " + newCacheId); 13636 newMountPath = PackageHelper.mountSdDir(newCacheId, 13637 getEncryptKey(), Process.SYSTEM_UID); 13638 } else { 13639 newMountPath = PackageHelper.getSdDir(newCacheId); 13640 } 13641 if (newMountPath == null) { 13642 Slog.w(TAG, "Failed to get cache path for " + newCacheId); 13643 return false; 13644 } 13645 Log.i(TAG, "Succesfully renamed " + cid + 13646 " to " + newCacheId + 13647 " at new path: " + newMountPath); 13648 cid = newCacheId; 13649 13650 final File beforeCodeFile = new File(packagePath); 13651 setMountPath(newMountPath); 13652 final File afterCodeFile = new File(packagePath); 13653 13654 // Reflect the rename in scanned details 13655 pkg.setCodePath(afterCodeFile.getAbsolutePath()); 13656 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile, 13657 afterCodeFile, pkg.baseCodePath)); 13658 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile, 13659 afterCodeFile, pkg.splitCodePaths)); 13660 13661 // Reflect the rename in app info 13662 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 13663 pkg.setApplicationInfoCodePath(pkg.codePath); 13664 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 13665 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 13666 pkg.setApplicationInfoResourcePath(pkg.codePath); 13667 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 13668 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 13669 13670 return true; 13671 } 13672 13673 private void setMountPath(String mountPath) { 13674 final File mountFile = new File(mountPath); 13675 13676 final File monolithicFile = new File(mountFile, RES_FILE_NAME); 13677 if (monolithicFile.exists()) { 13678 packagePath = monolithicFile.getAbsolutePath(); 13679 if (isFwdLocked()) { 13680 resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath(); 13681 } else { 13682 resourcePath = packagePath; 13683 } 13684 } else { 13685 packagePath = mountFile.getAbsolutePath(); 13686 resourcePath = packagePath; 13687 } 13688 } 13689 13690 int doPostInstall(int status, int uid) { 13691 if (status != PackageManager.INSTALL_SUCCEEDED) { 13692 cleanUp(); 13693 } else { 13694 final int groupOwner; 13695 final String protectedFile; 13696 if (isFwdLocked()) { 13697 groupOwner = UserHandle.getSharedAppGid(uid); 13698 protectedFile = RES_FILE_NAME; 13699 } else { 13700 groupOwner = -1; 13701 protectedFile = null; 13702 } 13703 13704 if (uid < Process.FIRST_APPLICATION_UID 13705 || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) { 13706 Slog.e(TAG, "Failed to finalize " + cid); 13707 PackageHelper.destroySdDir(cid); 13708 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 13709 } 13710 13711 boolean mounted = PackageHelper.isContainerMounted(cid); 13712 if (!mounted) { 13713 PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid()); 13714 } 13715 } 13716 return status; 13717 } 13718 13719 private void cleanUp() { 13720 if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp"); 13721 13722 // Destroy secure container 13723 PackageHelper.destroySdDir(cid); 13724 } 13725 13726 private List<String> getAllCodePaths() { 13727 final File codeFile = new File(getCodePath()); 13728 if (codeFile != null && codeFile.exists()) { 13729 try { 13730 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 13731 return pkg.getAllCodePaths(); 13732 } catch (PackageParserException e) { 13733 // Ignored; we tried our best 13734 } 13735 } 13736 return Collections.EMPTY_LIST; 13737 } 13738 13739 void cleanUpResourcesLI() { 13740 // Enumerate all code paths before deleting 13741 cleanUpResourcesLI(getAllCodePaths()); 13742 } 13743 13744 private void cleanUpResourcesLI(List<String> allCodePaths) { 13745 cleanUp(); 13746 removeDexFiles(allCodePaths, instructionSets); 13747 } 13748 13749 String getPackageName() { 13750 return getAsecPackageName(cid); 13751 } 13752 13753 boolean doPostDeleteLI(boolean delete) { 13754 if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete); 13755 final List<String> allCodePaths = getAllCodePaths(); 13756 boolean mounted = PackageHelper.isContainerMounted(cid); 13757 if (mounted) { 13758 // Unmount first 13759 if (PackageHelper.unMountSdDir(cid)) { 13760 mounted = false; 13761 } 13762 } 13763 if (!mounted && delete) { 13764 cleanUpResourcesLI(allCodePaths); 13765 } 13766 return !mounted; 13767 } 13768 13769 @Override 13770 int doPreCopy() { 13771 if (isFwdLocked()) { 13772 if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE, 13773 MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) { 13774 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 13775 } 13776 } 13777 13778 return PackageManager.INSTALL_SUCCEEDED; 13779 } 13780 13781 @Override 13782 int doPostCopy(int uid) { 13783 if (isFwdLocked()) { 13784 if (uid < Process.FIRST_APPLICATION_UID 13785 || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid), 13786 RES_FILE_NAME)) { 13787 Slog.e(TAG, "Failed to finalize " + cid); 13788 PackageHelper.destroySdDir(cid); 13789 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 13790 } 13791 } 13792 13793 return PackageManager.INSTALL_SUCCEEDED; 13794 } 13795 } 13796 13797 /** 13798 * Logic to handle movement of existing installed applications. 13799 */ 13800 class MoveInstallArgs extends InstallArgs { 13801 private File codeFile; 13802 private File resourceFile; 13803 13804 /** New install */ 13805 MoveInstallArgs(InstallParams params) { 13806 super(params.origin, params.move, params.observer, params.installFlags, 13807 params.installerPackageName, params.volumeUuid, 13808 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 13809 params.grantedRuntimePermissions, 13810 params.traceMethod, params.traceCookie, params.certificates); 13811 } 13812 13813 int copyApk(IMediaContainerService imcs, boolean temp) { 13814 if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from " 13815 + move.fromUuid + " to " + move.toUuid); 13816 synchronized (mInstaller) { 13817 try { 13818 mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName, 13819 move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion); 13820 } catch (InstallerException e) { 13821 Slog.w(TAG, "Failed to move app", e); 13822 return PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 13823 } 13824 } 13825 13826 codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName); 13827 resourceFile = codeFile; 13828 if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile); 13829 13830 return PackageManager.INSTALL_SUCCEEDED; 13831 } 13832 13833 int doPreInstall(int status) { 13834 if (status != PackageManager.INSTALL_SUCCEEDED) { 13835 cleanUp(move.toUuid); 13836 } 13837 return status; 13838 } 13839 13840 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 13841 if (status != PackageManager.INSTALL_SUCCEEDED) { 13842 cleanUp(move.toUuid); 13843 return false; 13844 } 13845 13846 // Reflect the move in app info 13847 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 13848 pkg.setApplicationInfoCodePath(pkg.codePath); 13849 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 13850 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 13851 pkg.setApplicationInfoResourcePath(pkg.codePath); 13852 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 13853 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 13854 13855 return true; 13856 } 13857 13858 int doPostInstall(int status, int uid) { 13859 if (status == PackageManager.INSTALL_SUCCEEDED) { 13860 cleanUp(move.fromUuid); 13861 } else { 13862 cleanUp(move.toUuid); 13863 } 13864 return status; 13865 } 13866 13867 @Override 13868 String getCodePath() { 13869 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 13870 } 13871 13872 @Override 13873 String getResourcePath() { 13874 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 13875 } 13876 13877 private boolean cleanUp(String volumeUuid) { 13878 final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid), 13879 move.dataAppName); 13880 Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid); 13881 final int[] userIds = sUserManager.getUserIds(); 13882 synchronized (mInstallLock) { 13883 // Clean up both app data and code 13884 // All package moves are frozen until finished 13885 for (int userId : userIds) { 13886 try { 13887 mInstaller.destroyAppData(volumeUuid, move.packageName, userId, 13888 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0); 13889 } catch (InstallerException e) { 13890 Slog.w(TAG, String.valueOf(e)); 13891 } 13892 } 13893 removeCodePathLI(codeFile); 13894 } 13895 return true; 13896 } 13897 13898 void cleanUpResourcesLI() { 13899 throw new UnsupportedOperationException(); 13900 } 13901 13902 boolean doPostDeleteLI(boolean delete) { 13903 throw new UnsupportedOperationException(); 13904 } 13905 } 13906 13907 static String getAsecPackageName(String packageCid) { 13908 int idx = packageCid.lastIndexOf("-"); 13909 if (idx == -1) { 13910 return packageCid; 13911 } 13912 return packageCid.substring(0, idx); 13913 } 13914 13915 // Utility method used to create code paths based on package name and available index. 13916 private static String getNextCodePath(String oldCodePath, String prefix, String suffix) { 13917 String idxStr = ""; 13918 int idx = 1; 13919 // Fall back to default value of idx=1 if prefix is not 13920 // part of oldCodePath 13921 if (oldCodePath != null) { 13922 String subStr = oldCodePath; 13923 // Drop the suffix right away 13924 if (suffix != null && subStr.endsWith(suffix)) { 13925 subStr = subStr.substring(0, subStr.length() - suffix.length()); 13926 } 13927 // If oldCodePath already contains prefix find out the 13928 // ending index to either increment or decrement. 13929 int sidx = subStr.lastIndexOf(prefix); 13930 if (sidx != -1) { 13931 subStr = subStr.substring(sidx + prefix.length()); 13932 if (subStr != null) { 13933 if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) { 13934 subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length()); 13935 } 13936 try { 13937 idx = Integer.parseInt(subStr); 13938 if (idx <= 1) { 13939 idx++; 13940 } else { 13941 idx--; 13942 } 13943 } catch(NumberFormatException e) { 13944 } 13945 } 13946 } 13947 } 13948 idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx); 13949 return prefix + idxStr; 13950 } 13951 13952 private File getNextCodePath(File targetDir, String packageName) { 13953 int suffix = 1; 13954 File result; 13955 do { 13956 result = new File(targetDir, packageName + "-" + suffix); 13957 suffix++; 13958 } while (result.exists()); 13959 return result; 13960 } 13961 13962 // Utility method that returns the relative package path with respect 13963 // to the installation directory. Like say for /data/data/com.test-1.apk 13964 // string com.test-1 is returned. 13965 static String deriveCodePathName(String codePath) { 13966 if (codePath == null) { 13967 return null; 13968 } 13969 final File codeFile = new File(codePath); 13970 final String name = codeFile.getName(); 13971 if (codeFile.isDirectory()) { 13972 return name; 13973 } else if (name.endsWith(".apk") || name.endsWith(".tmp")) { 13974 final int lastDot = name.lastIndexOf('.'); 13975 return name.substring(0, lastDot); 13976 } else { 13977 Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK"); 13978 return null; 13979 } 13980 } 13981 13982 static class PackageInstalledInfo { 13983 String name; 13984 int uid; 13985 // The set of users that originally had this package installed. 13986 int[] origUsers; 13987 // The set of users that now have this package installed. 13988 int[] newUsers; 13989 PackageParser.Package pkg; 13990 int returnCode; 13991 String returnMsg; 13992 PackageRemovedInfo removedInfo; 13993 ArrayMap<String, PackageInstalledInfo> addedChildPackages; 13994 13995 public void setError(int code, String msg) { 13996 setReturnCode(code); 13997 setReturnMessage(msg); 13998 Slog.w(TAG, msg); 13999 } 14000 14001 public void setError(String msg, PackageParserException e) { 14002 setReturnCode(e.error); 14003 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e)); 14004 Slog.w(TAG, msg, e); 14005 } 14006 14007 public void setError(String msg, PackageManagerException e) { 14008 returnCode = e.error; 14009 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e)); 14010 Slog.w(TAG, msg, e); 14011 } 14012 14013 public void setReturnCode(int returnCode) { 14014 this.returnCode = returnCode; 14015 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0; 14016 for (int i = 0; i < childCount; i++) { 14017 addedChildPackages.valueAt(i).returnCode = returnCode; 14018 } 14019 } 14020 14021 private void setReturnMessage(String returnMsg) { 14022 this.returnMsg = returnMsg; 14023 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0; 14024 for (int i = 0; i < childCount; i++) { 14025 addedChildPackages.valueAt(i).returnMsg = returnMsg; 14026 } 14027 } 14028 14029 // In some error cases we want to convey more info back to the observer 14030 String origPackage; 14031 String origPermission; 14032 } 14033 14034 /* 14035 * Install a non-existing package. 14036 */ 14037 private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags, 14038 int scanFlags, UserHandle user, String installerPackageName, String volumeUuid, 14039 PackageInstalledInfo res) { 14040 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage"); 14041 14042 // Remember this for later, in case we need to rollback this install 14043 String pkgName = pkg.packageName; 14044 14045 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg); 14046 14047 synchronized(mPackages) { 14048 final String renamedPackage = mSettings.getRenamedPackage(pkgName); 14049 if (renamedPackage != null) { 14050 // A package with the same name is already installed, though 14051 // it has been renamed to an older name. The package we 14052 // are trying to install should be installed as an update to 14053 // the existing one, but that has not been requested, so bail. 14054 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 14055 + " without first uninstalling package running as " 14056 + renamedPackage); 14057 return; 14058 } 14059 if (mPackages.containsKey(pkgName)) { 14060 // Don't allow installation over an existing package with the same name. 14061 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 14062 + " without first uninstalling."); 14063 return; 14064 } 14065 } 14066 14067 try { 14068 PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 14069 System.currentTimeMillis(), user); 14070 14071 updateSettingsLI(newPackage, installerPackageName, null, res, user); 14072 14073 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 14074 prepareAppDataAfterInstallLIF(newPackage); 14075 14076 } else { 14077 // Remove package from internal structures, but keep around any 14078 // data that might have already existed 14079 deletePackageLIF(pkgName, UserHandle.ALL, false, null, 14080 PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null); 14081 } 14082 } catch (PackageManagerException e) { 14083 res.setError("Package couldn't be installed in " + pkg.codePath, e); 14084 } 14085 14086 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14087 } 14088 14089 private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) { 14090 // Can't rotate keys during boot or if sharedUser. 14091 if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null 14092 || !oldPs.keySetData.isUsingUpgradeKeySets()) { 14093 return false; 14094 } 14095 // app is using upgradeKeySets; make sure all are valid 14096 KeySetManagerService ksms = mSettings.mKeySetManagerService; 14097 long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets(); 14098 for (int i = 0; i < upgradeKeySets.length; i++) { 14099 if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) { 14100 Slog.wtf(TAG, "Package " 14101 + (oldPs.name != null ? oldPs.name : "<null>") 14102 + " contains upgrade-key-set reference to unknown key-set: " 14103 + upgradeKeySets[i] 14104 + " reverting to signatures check."); 14105 return false; 14106 } 14107 } 14108 return true; 14109 } 14110 14111 private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) { 14112 // Upgrade keysets are being used. Determine if new package has a superset of the 14113 // required keys. 14114 long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets(); 14115 KeySetManagerService ksms = mSettings.mKeySetManagerService; 14116 for (int i = 0; i < upgradeKeySets.length; i++) { 14117 Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]); 14118 if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) { 14119 return true; 14120 } 14121 } 14122 return false; 14123 } 14124 14125 private static void updateDigest(MessageDigest digest, File file) throws IOException { 14126 try (DigestInputStream digestStream = 14127 new DigestInputStream(new FileInputStream(file), digest)) { 14128 while (digestStream.read() != -1) {} // nothing to do; just plow through the file 14129 } 14130 } 14131 14132 private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags, 14133 UserHandle user, String installerPackageName, PackageInstalledInfo res) { 14134 final boolean isEphemeral = (policyFlags & PackageParser.PARSE_IS_EPHEMERAL) != 0; 14135 14136 final PackageParser.Package oldPackage; 14137 final String pkgName = pkg.packageName; 14138 final int[] allUsers; 14139 final int[] installedUsers; 14140 14141 synchronized(mPackages) { 14142 oldPackage = mPackages.get(pkgName); 14143 if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage); 14144 14145 // don't allow upgrade to target a release SDK from a pre-release SDK 14146 final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion 14147 == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT; 14148 final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion 14149 == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT; 14150 if (oldTargetsPreRelease 14151 && !newTargetsPreRelease 14152 && ((policyFlags & PackageParser.PARSE_FORCE_SDK) == 0)) { 14153 Slog.w(TAG, "Can't install package targeting released sdk"); 14154 res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE); 14155 return; 14156 } 14157 14158 // don't allow an upgrade from full to ephemeral 14159 final boolean oldIsEphemeral = oldPackage.applicationInfo.isEphemeralApp(); 14160 if (isEphemeral && !oldIsEphemeral) { 14161 // can't downgrade from full to ephemeral 14162 Slog.w(TAG, "Can't replace app with ephemeral: " + pkgName); 14163 res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID); 14164 return; 14165 } 14166 14167 // verify signatures are valid 14168 final PackageSetting ps = mSettings.mPackages.get(pkgName); 14169 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { 14170 if (!checkUpgradeKeySetLP(ps, pkg)) { 14171 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 14172 "New package not signed by keys specified by upgrade-keysets: " 14173 + pkgName); 14174 return; 14175 } 14176 } else { 14177 // default to original signature matching 14178 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures) 14179 != PackageManager.SIGNATURE_MATCH) { 14180 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 14181 "New package has a different signature: " + pkgName); 14182 return; 14183 } 14184 } 14185 14186 // don't allow a system upgrade unless the upgrade hash matches 14187 if (oldPackage.restrictUpdateHash != null && oldPackage.isSystemApp()) { 14188 byte[] digestBytes = null; 14189 try { 14190 final MessageDigest digest = MessageDigest.getInstance("SHA-512"); 14191 updateDigest(digest, new File(pkg.baseCodePath)); 14192 if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) { 14193 for (String path : pkg.splitCodePaths) { 14194 updateDigest(digest, new File(path)); 14195 } 14196 } 14197 digestBytes = digest.digest(); 14198 } catch (NoSuchAlgorithmException | IOException e) { 14199 res.setError(INSTALL_FAILED_INVALID_APK, 14200 "Could not compute hash: " + pkgName); 14201 return; 14202 } 14203 if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) { 14204 res.setError(INSTALL_FAILED_INVALID_APK, 14205 "New package fails restrict-update check: " + pkgName); 14206 return; 14207 } 14208 // retain upgrade restriction 14209 pkg.restrictUpdateHash = oldPackage.restrictUpdateHash; 14210 } 14211 14212 // Check for shared user id changes 14213 String invalidPackageName = 14214 getParentOrChildPackageChangedSharedUser(oldPackage, pkg); 14215 if (invalidPackageName != null) { 14216 res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 14217 "Package " + invalidPackageName + " tried to change user " 14218 + oldPackage.mSharedUserId); 14219 return; 14220 } 14221 14222 // In case of rollback, remember per-user/profile install state 14223 allUsers = sUserManager.getUserIds(); 14224 installedUsers = ps.queryInstalledUsers(allUsers, true); 14225 } 14226 14227 // Update what is removed 14228 res.removedInfo = new PackageRemovedInfo(); 14229 res.removedInfo.uid = oldPackage.applicationInfo.uid; 14230 res.removedInfo.removedPackage = oldPackage.packageName; 14231 res.removedInfo.isUpdate = true; 14232 res.removedInfo.origUsers = installedUsers; 14233 final int childCount = (oldPackage.childPackages != null) 14234 ? oldPackage.childPackages.size() : 0; 14235 for (int i = 0; i < childCount; i++) { 14236 boolean childPackageUpdated = false; 14237 PackageParser.Package childPkg = oldPackage.childPackages.get(i); 14238 if (res.addedChildPackages != null) { 14239 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName); 14240 if (childRes != null) { 14241 childRes.removedInfo.uid = childPkg.applicationInfo.uid; 14242 childRes.removedInfo.removedPackage = childPkg.packageName; 14243 childRes.removedInfo.isUpdate = true; 14244 childPackageUpdated = true; 14245 } 14246 } 14247 if (!childPackageUpdated) { 14248 PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(); 14249 childRemovedRes.removedPackage = childPkg.packageName; 14250 childRemovedRes.isUpdate = false; 14251 childRemovedRes.dataRemoved = true; 14252 synchronized (mPackages) { 14253 PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName); 14254 if (childPs != null) { 14255 childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true); 14256 } 14257 } 14258 if (res.removedInfo.removedChildPackages == null) { 14259 res.removedInfo.removedChildPackages = new ArrayMap<>(); 14260 } 14261 res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes); 14262 } 14263 } 14264 14265 boolean sysPkg = (isSystemApp(oldPackage)); 14266 if (sysPkg) { 14267 // Set the system/privileged flags as needed 14268 final boolean privileged = 14269 (oldPackage.applicationInfo.privateFlags 14270 & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; 14271 final int systemPolicyFlags = policyFlags 14272 | PackageParser.PARSE_IS_SYSTEM 14273 | (privileged ? PackageParser.PARSE_IS_PRIVILEGED : 0); 14274 14275 replaceSystemPackageLIF(oldPackage, pkg, systemPolicyFlags, scanFlags, 14276 user, allUsers, installerPackageName, res); 14277 } else { 14278 replaceNonSystemPackageLIF(oldPackage, pkg, policyFlags, scanFlags, 14279 user, allUsers, installerPackageName, res); 14280 } 14281 } 14282 14283 public List<String> getPreviousCodePaths(String packageName) { 14284 final PackageSetting ps = mSettings.mPackages.get(packageName); 14285 final List<String> result = new ArrayList<String>(); 14286 if (ps != null && ps.oldCodePaths != null) { 14287 result.addAll(ps.oldCodePaths); 14288 } 14289 return result; 14290 } 14291 14292 private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage, 14293 PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user, 14294 int[] allUsers, String installerPackageName, PackageInstalledInfo res) { 14295 if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old=" 14296 + deletedPackage); 14297 14298 String pkgName = deletedPackage.packageName; 14299 boolean deletedPkg = true; 14300 boolean addedPkg = false; 14301 boolean updatedSettings = false; 14302 final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0; 14303 final int deleteFlags = PackageManager.DELETE_KEEP_DATA 14304 | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP); 14305 14306 final long origUpdateTime = (pkg.mExtras != null) 14307 ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0; 14308 14309 // First delete the existing package while retaining the data directory 14310 if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags, 14311 res.removedInfo, true, pkg)) { 14312 // If the existing package wasn't successfully deleted 14313 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI"); 14314 deletedPkg = false; 14315 } else { 14316 // Successfully deleted the old package; proceed with replace. 14317 14318 // If deleted package lived in a container, give users a chance to 14319 // relinquish resources before killing. 14320 if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) { 14321 if (DEBUG_INSTALL) { 14322 Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE"); 14323 } 14324 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid }; 14325 final ArrayList<String> pkgList = new ArrayList<String>(1); 14326 pkgList.add(deletedPackage.applicationInfo.packageName); 14327 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null); 14328 } 14329 14330 clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE 14331 | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 14332 clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL); 14333 14334 try { 14335 final PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, 14336 scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user); 14337 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user); 14338 14339 // Update the in-memory copy of the previous code paths. 14340 PackageSetting ps = mSettings.mPackages.get(pkgName); 14341 if (!killApp) { 14342 if (ps.oldCodePaths == null) { 14343 ps.oldCodePaths = new ArraySet<>(); 14344 } 14345 Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath); 14346 if (deletedPackage.splitCodePaths != null) { 14347 Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths); 14348 } 14349 } else { 14350 ps.oldCodePaths = null; 14351 } 14352 if (ps.childPackageNames != null) { 14353 for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) { 14354 final String childPkgName = ps.childPackageNames.get(i); 14355 final PackageSetting childPs = mSettings.mPackages.get(childPkgName); 14356 childPs.oldCodePaths = ps.oldCodePaths; 14357 } 14358 } 14359 prepareAppDataAfterInstallLIF(newPackage); 14360 addedPkg = true; 14361 } catch (PackageManagerException e) { 14362 res.setError("Package couldn't be installed in " + pkg.codePath, e); 14363 } 14364 } 14365 14366 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 14367 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName); 14368 14369 // Revert all internal state mutations and added folders for the failed install 14370 if (addedPkg) { 14371 deletePackageLIF(pkgName, null, true, allUsers, deleteFlags, 14372 res.removedInfo, true, null); 14373 } 14374 14375 // Restore the old package 14376 if (deletedPkg) { 14377 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage); 14378 File restoreFile = new File(deletedPackage.codePath); 14379 // Parse old package 14380 boolean oldExternal = isExternal(deletedPackage); 14381 int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY | 14382 (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) | 14383 (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0); 14384 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME; 14385 try { 14386 scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, 14387 null); 14388 } catch (PackageManagerException e) { 14389 Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: " 14390 + e.getMessage()); 14391 return; 14392 } 14393 14394 synchronized (mPackages) { 14395 // Ensure the installer package name up to date 14396 setInstallerPackageNameLPw(deletedPackage, installerPackageName); 14397 14398 // Update permissions for restored package 14399 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL); 14400 14401 mSettings.writeLPr(); 14402 } 14403 14404 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade"); 14405 } 14406 } else { 14407 synchronized (mPackages) { 14408 PackageSetting ps = mSettings.peekPackageLPr(pkg.packageName); 14409 if (ps != null) { 14410 res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null; 14411 if (res.removedInfo.removedChildPackages != null) { 14412 final int childCount = res.removedInfo.removedChildPackages.size(); 14413 // Iterate in reverse as we may modify the collection 14414 for (int i = childCount - 1; i >= 0; i--) { 14415 String childPackageName = res.removedInfo.removedChildPackages.keyAt(i); 14416 if (res.addedChildPackages.containsKey(childPackageName)) { 14417 res.removedInfo.removedChildPackages.removeAt(i); 14418 } else { 14419 PackageRemovedInfo childInfo = res.removedInfo 14420 .removedChildPackages.valueAt(i); 14421 childInfo.removedForAllUsers = mPackages.get( 14422 childInfo.removedPackage) == null; 14423 } 14424 } 14425 } 14426 } 14427 } 14428 } 14429 } 14430 14431 private void replaceSystemPackageLIF(PackageParser.Package deletedPackage, 14432 PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user, 14433 int[] allUsers, String installerPackageName, PackageInstalledInfo res) { 14434 if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg 14435 + ", old=" + deletedPackage); 14436 14437 final boolean disabledSystem; 14438 14439 // Remove existing system package 14440 removePackageLI(deletedPackage, true); 14441 14442 synchronized (mPackages) { 14443 disabledSystem = disableSystemPackageLPw(deletedPackage, pkg); 14444 } 14445 if (!disabledSystem) { 14446 // We didn't need to disable the .apk as a current system package, 14447 // which means we are replacing another update that is already 14448 // installed. We need to make sure to delete the older one's .apk. 14449 res.removedInfo.args = createInstallArgsForExisting(0, 14450 deletedPackage.applicationInfo.getCodePath(), 14451 deletedPackage.applicationInfo.getResourcePath(), 14452 getAppDexInstructionSets(deletedPackage.applicationInfo)); 14453 } else { 14454 res.removedInfo.args = null; 14455 } 14456 14457 // Successfully disabled the old package. Now proceed with re-installation 14458 clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE 14459 | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 14460 clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL); 14461 14462 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 14463 pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP, 14464 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP); 14465 14466 PackageParser.Package newPackage = null; 14467 try { 14468 // Add the package to the internal data structures 14469 newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 0, user); 14470 14471 // Set the update and install times 14472 PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras; 14473 setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime, 14474 System.currentTimeMillis()); 14475 14476 // Update the package dynamic state if succeeded 14477 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 14478 // Now that the install succeeded make sure we remove data 14479 // directories for any child package the update removed. 14480 final int deletedChildCount = (deletedPackage.childPackages != null) 14481 ? deletedPackage.childPackages.size() : 0; 14482 final int newChildCount = (newPackage.childPackages != null) 14483 ? newPackage.childPackages.size() : 0; 14484 for (int i = 0; i < deletedChildCount; i++) { 14485 PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i); 14486 boolean childPackageDeleted = true; 14487 for (int j = 0; j < newChildCount; j++) { 14488 PackageParser.Package newChildPkg = newPackage.childPackages.get(j); 14489 if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) { 14490 childPackageDeleted = false; 14491 break; 14492 } 14493 } 14494 if (childPackageDeleted) { 14495 PackageSetting ps = mSettings.getDisabledSystemPkgLPr( 14496 deletedChildPkg.packageName); 14497 if (ps != null && res.removedInfo.removedChildPackages != null) { 14498 PackageRemovedInfo removedChildRes = res.removedInfo 14499 .removedChildPackages.get(deletedChildPkg.packageName); 14500 removePackageDataLIF(ps, allUsers, removedChildRes, 0, false); 14501 removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null; 14502 } 14503 } 14504 } 14505 14506 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user); 14507 prepareAppDataAfterInstallLIF(newPackage); 14508 } 14509 } catch (PackageManagerException e) { 14510 res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR); 14511 res.setError("Package couldn't be installed in " + pkg.codePath, e); 14512 } 14513 14514 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 14515 // Re installation failed. Restore old information 14516 // Remove new pkg information 14517 if (newPackage != null) { 14518 removeInstalledPackageLI(newPackage, true); 14519 } 14520 // Add back the old system package 14521 try { 14522 scanPackageTracedLI(deletedPackage, policyFlags, SCAN_UPDATE_SIGNATURE, 0, user); 14523 } catch (PackageManagerException e) { 14524 Slog.e(TAG, "Failed to restore original package: " + e.getMessage()); 14525 } 14526 14527 synchronized (mPackages) { 14528 if (disabledSystem) { 14529 enableSystemPackageLPw(deletedPackage); 14530 } 14531 14532 // Ensure the installer package name up to date 14533 setInstallerPackageNameLPw(deletedPackage, installerPackageName); 14534 14535 // Update permissions for restored package 14536 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL); 14537 14538 mSettings.writeLPr(); 14539 } 14540 14541 Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName 14542 + " after failed upgrade"); 14543 } 14544 } 14545 14546 /** 14547 * Checks whether the parent or any of the child packages have a change shared 14548 * user. For a package to be a valid update the shred users of the parent and 14549 * the children should match. We may later support changing child shared users. 14550 * @param oldPkg The updated package. 14551 * @param newPkg The update package. 14552 * @return The shared user that change between the versions. 14553 */ 14554 private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg, 14555 PackageParser.Package newPkg) { 14556 // Check parent shared user 14557 if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) { 14558 return newPkg.packageName; 14559 } 14560 // Check child shared users 14561 final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0; 14562 final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0; 14563 for (int i = 0; i < newChildCount; i++) { 14564 PackageParser.Package newChildPkg = newPkg.childPackages.get(i); 14565 // If this child was present, did it have the same shared user? 14566 for (int j = 0; j < oldChildCount; j++) { 14567 PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j); 14568 if (newChildPkg.packageName.equals(oldChildPkg.packageName) 14569 && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) { 14570 return newChildPkg.packageName; 14571 } 14572 } 14573 } 14574 return null; 14575 } 14576 14577 private void removeNativeBinariesLI(PackageSetting ps) { 14578 // Remove the lib path for the parent package 14579 if (ps != null) { 14580 NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString); 14581 // Remove the lib path for the child packages 14582 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0; 14583 for (int i = 0; i < childCount; i++) { 14584 PackageSetting childPs = null; 14585 synchronized (mPackages) { 14586 childPs = mSettings.peekPackageLPr(ps.childPackageNames.get(i)); 14587 } 14588 if (childPs != null) { 14589 NativeLibraryHelper.removeNativeBinariesLI(childPs 14590 .legacyNativeLibraryPathString); 14591 } 14592 } 14593 } 14594 } 14595 14596 private void enableSystemPackageLPw(PackageParser.Package pkg) { 14597 // Enable the parent package 14598 mSettings.enableSystemPackageLPw(pkg.packageName); 14599 // Enable the child packages 14600 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 14601 for (int i = 0; i < childCount; i++) { 14602 PackageParser.Package childPkg = pkg.childPackages.get(i); 14603 mSettings.enableSystemPackageLPw(childPkg.packageName); 14604 } 14605 } 14606 14607 private boolean disableSystemPackageLPw(PackageParser.Package oldPkg, 14608 PackageParser.Package newPkg) { 14609 // Disable the parent package (parent always replaced) 14610 boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true); 14611 // Disable the child packages 14612 final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0; 14613 for (int i = 0; i < childCount; i++) { 14614 PackageParser.Package childPkg = oldPkg.childPackages.get(i); 14615 final boolean replace = newPkg.hasChildPackage(childPkg.packageName); 14616 disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace); 14617 } 14618 return disabled; 14619 } 14620 14621 private void setInstallerPackageNameLPw(PackageParser.Package pkg, 14622 String installerPackageName) { 14623 // Enable the parent package 14624 mSettings.setInstallerPackageName(pkg.packageName, installerPackageName); 14625 // Enable the child packages 14626 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 14627 for (int i = 0; i < childCount; i++) { 14628 PackageParser.Package childPkg = pkg.childPackages.get(i); 14629 mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName); 14630 } 14631 } 14632 14633 private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) { 14634 // Collect all used permissions in the UID 14635 ArraySet<String> usedPermissions = new ArraySet<>(); 14636 final int packageCount = su.packages.size(); 14637 for (int i = 0; i < packageCount; i++) { 14638 PackageSetting ps = su.packages.valueAt(i); 14639 if (ps.pkg == null) { 14640 continue; 14641 } 14642 final int requestedPermCount = ps.pkg.requestedPermissions.size(); 14643 for (int j = 0; j < requestedPermCount; j++) { 14644 String permission = ps.pkg.requestedPermissions.get(j); 14645 BasePermission bp = mSettings.mPermissions.get(permission); 14646 if (bp != null) { 14647 usedPermissions.add(permission); 14648 } 14649 } 14650 } 14651 14652 PermissionsState permissionsState = su.getPermissionsState(); 14653 // Prune install permissions 14654 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates(); 14655 final int installPermCount = installPermStates.size(); 14656 for (int i = installPermCount - 1; i >= 0; i--) { 14657 PermissionState permissionState = installPermStates.get(i); 14658 if (!usedPermissions.contains(permissionState.getName())) { 14659 BasePermission bp = mSettings.mPermissions.get(permissionState.getName()); 14660 if (bp != null) { 14661 permissionsState.revokeInstallPermission(bp); 14662 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 14663 PackageManager.MASK_PERMISSION_FLAGS, 0); 14664 } 14665 } 14666 } 14667 14668 int[] runtimePermissionChangedUserIds = EmptyArray.INT; 14669 14670 // Prune runtime permissions 14671 for (int userId : allUserIds) { 14672 List<PermissionState> runtimePermStates = permissionsState 14673 .getRuntimePermissionStates(userId); 14674 final int runtimePermCount = runtimePermStates.size(); 14675 for (int i = runtimePermCount - 1; i >= 0; i--) { 14676 PermissionState permissionState = runtimePermStates.get(i); 14677 if (!usedPermissions.contains(permissionState.getName())) { 14678 BasePermission bp = mSettings.mPermissions.get(permissionState.getName()); 14679 if (bp != null) { 14680 permissionsState.revokeRuntimePermission(bp, userId); 14681 permissionsState.updatePermissionFlags(bp, userId, 14682 PackageManager.MASK_PERMISSION_FLAGS, 0); 14683 runtimePermissionChangedUserIds = ArrayUtils.appendInt( 14684 runtimePermissionChangedUserIds, userId); 14685 } 14686 } 14687 } 14688 } 14689 14690 return runtimePermissionChangedUserIds; 14691 } 14692 14693 private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, 14694 int[] allUsers, PackageInstalledInfo res, UserHandle user) { 14695 // Update the parent package setting 14696 updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers, 14697 res, user); 14698 // Update the child packages setting 14699 final int childCount = (newPackage.childPackages != null) 14700 ? newPackage.childPackages.size() : 0; 14701 for (int i = 0; i < childCount; i++) { 14702 PackageParser.Package childPackage = newPackage.childPackages.get(i); 14703 PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName); 14704 updateSettingsInternalLI(childPackage, installerPackageName, allUsers, 14705 childRes.origUsers, childRes, user); 14706 } 14707 } 14708 14709 private void updateSettingsInternalLI(PackageParser.Package newPackage, 14710 String installerPackageName, int[] allUsers, int[] installedForUsers, 14711 PackageInstalledInfo res, UserHandle user) { 14712 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 14713 14714 String pkgName = newPackage.packageName; 14715 synchronized (mPackages) { 14716 //write settings. the installStatus will be incomplete at this stage. 14717 //note that the new package setting would have already been 14718 //added to mPackages. It hasn't been persisted yet. 14719 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE); 14720 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings"); 14721 mSettings.writeLPr(); 14722 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14723 } 14724 14725 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath); 14726 synchronized (mPackages) { 14727 updatePermissionsLPw(newPackage.packageName, newPackage, 14728 UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0 14729 ? UPDATE_PERMISSIONS_ALL : 0)); 14730 // For system-bundled packages, we assume that installing an upgraded version 14731 // of the package implies that the user actually wants to run that new code, 14732 // so we enable the package. 14733 PackageSetting ps = mSettings.mPackages.get(pkgName); 14734 final int userId = user.getIdentifier(); 14735 if (ps != null) { 14736 if (isSystemApp(newPackage)) { 14737 if (DEBUG_INSTALL) { 14738 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName); 14739 } 14740 // Enable system package for requested users 14741 if (res.origUsers != null) { 14742 for (int origUserId : res.origUsers) { 14743 if (userId == UserHandle.USER_ALL || userId == origUserId) { 14744 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 14745 origUserId, installerPackageName); 14746 } 14747 } 14748 } 14749 // Also convey the prior install/uninstall state 14750 if (allUsers != null && installedForUsers != null) { 14751 for (int currentUserId : allUsers) { 14752 final boolean installed = ArrayUtils.contains( 14753 installedForUsers, currentUserId); 14754 if (DEBUG_INSTALL) { 14755 Slog.d(TAG, " user " + currentUserId + " => " + installed); 14756 } 14757 ps.setInstalled(installed, currentUserId); 14758 } 14759 // these install state changes will be persisted in the 14760 // upcoming call to mSettings.writeLPr(). 14761 } 14762 } 14763 // It's implied that when a user requests installation, they want the app to be 14764 // installed and enabled. 14765 if (userId != UserHandle.USER_ALL) { 14766 ps.setInstalled(true, userId); 14767 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName); 14768 } 14769 } 14770 res.name = pkgName; 14771 res.uid = newPackage.applicationInfo.uid; 14772 res.pkg = newPackage; 14773 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE); 14774 mSettings.setInstallerPackageName(pkgName, installerPackageName); 14775 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 14776 //to update install status 14777 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings"); 14778 mSettings.writeLPr(); 14779 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14780 } 14781 14782 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14783 } 14784 14785 private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) { 14786 try { 14787 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage"); 14788 installPackageLI(args, res); 14789 } finally { 14790 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14791 } 14792 } 14793 14794 private void installPackageLI(InstallArgs args, PackageInstalledInfo res) { 14795 final int installFlags = args.installFlags; 14796 final String installerPackageName = args.installerPackageName; 14797 final String volumeUuid = args.volumeUuid; 14798 final File tmpPackageFile = new File(args.getCodePath()); 14799 final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0); 14800 final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) 14801 || (args.volumeUuid != null)); 14802 final boolean ephemeral = ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0); 14803 final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0); 14804 boolean replace = false; 14805 int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE; 14806 if (args.move != null) { 14807 // moving a complete application; perform an initial scan on the new install location 14808 scanFlags |= SCAN_INITIAL; 14809 } 14810 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) { 14811 scanFlags |= SCAN_DONT_KILL_APP; 14812 } 14813 14814 // Result object to be returned 14815 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 14816 14817 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile); 14818 14819 // Sanity check 14820 if (ephemeral && (forwardLocked || onExternal)) { 14821 Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked 14822 + " external=" + onExternal); 14823 res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID); 14824 return; 14825 } 14826 14827 // Retrieve PackageSettings and parse package 14828 final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY 14829 | PackageParser.PARSE_ENFORCE_CODE 14830 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) 14831 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0) 14832 | (ephemeral ? PackageParser.PARSE_IS_EPHEMERAL : 0) 14833 | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0); 14834 PackageParser pp = new PackageParser(); 14835 pp.setSeparateProcesses(mSeparateProcesses); 14836 pp.setDisplayMetrics(mMetrics); 14837 14838 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage"); 14839 final PackageParser.Package pkg; 14840 try { 14841 pkg = pp.parsePackage(tmpPackageFile, parseFlags); 14842 } catch (PackageParserException e) { 14843 res.setError("Failed parse during installPackageLI", e); 14844 return; 14845 } finally { 14846 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14847 } 14848 14849 // If we are installing a clustered package add results for the children 14850 if (pkg.childPackages != null) { 14851 synchronized (mPackages) { 14852 final int childCount = pkg.childPackages.size(); 14853 for (int i = 0; i < childCount; i++) { 14854 PackageParser.Package childPkg = pkg.childPackages.get(i); 14855 PackageInstalledInfo childRes = new PackageInstalledInfo(); 14856 childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 14857 childRes.pkg = childPkg; 14858 childRes.name = childPkg.packageName; 14859 PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName); 14860 if (childPs != null) { 14861 childRes.origUsers = childPs.queryInstalledUsers( 14862 sUserManager.getUserIds(), true); 14863 } 14864 if ((mPackages.containsKey(childPkg.packageName))) { 14865 childRes.removedInfo = new PackageRemovedInfo(); 14866 childRes.removedInfo.removedPackage = childPkg.packageName; 14867 } 14868 if (res.addedChildPackages == null) { 14869 res.addedChildPackages = new ArrayMap<>(); 14870 } 14871 res.addedChildPackages.put(childPkg.packageName, childRes); 14872 } 14873 } 14874 } 14875 14876 // If package doesn't declare API override, mark that we have an install 14877 // time CPU ABI override. 14878 if (TextUtils.isEmpty(pkg.cpuAbiOverride)) { 14879 pkg.cpuAbiOverride = args.abiOverride; 14880 } 14881 14882 String pkgName = res.name = pkg.packageName; 14883 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) { 14884 if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) { 14885 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI"); 14886 return; 14887 } 14888 } 14889 14890 try { 14891 // either use what we've been given or parse directly from the APK 14892 if (args.certificates != null) { 14893 try { 14894 PackageParser.populateCertificates(pkg, args.certificates); 14895 } catch (PackageParserException e) { 14896 // there was something wrong with the certificates we were given; 14897 // try to pull them from the APK 14898 PackageParser.collectCertificates(pkg, parseFlags); 14899 } 14900 } else { 14901 PackageParser.collectCertificates(pkg, parseFlags); 14902 } 14903 } catch (PackageParserException e) { 14904 res.setError("Failed collect during installPackageLI", e); 14905 return; 14906 } 14907 14908 // Get rid of all references to package scan path via parser. 14909 pp = null; 14910 String oldCodePath = null; 14911 boolean systemApp = false; 14912 synchronized (mPackages) { 14913 // Check if installing already existing package 14914 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 14915 String oldName = mSettings.getRenamedPackage(pkgName); 14916 if (pkg.mOriginalPackages != null 14917 && pkg.mOriginalPackages.contains(oldName) 14918 && mPackages.containsKey(oldName)) { 14919 // This package is derived from an original package, 14920 // and this device has been updating from that original 14921 // name. We must continue using the original name, so 14922 // rename the new package here. 14923 pkg.setPackageName(oldName); 14924 pkgName = pkg.packageName; 14925 replace = true; 14926 if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName=" 14927 + oldName + " pkgName=" + pkgName); 14928 } else if (mPackages.containsKey(pkgName)) { 14929 // This package, under its official name, already exists 14930 // on the device; we should replace it. 14931 replace = true; 14932 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName); 14933 } 14934 14935 // Child packages are installed through the parent package 14936 if (pkg.parentPackage != null) { 14937 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME, 14938 "Package " + pkg.packageName + " is child of package " 14939 + pkg.parentPackage.parentPackage + ". Child packages " 14940 + "can be updated only through the parent package."); 14941 return; 14942 } 14943 14944 if (replace) { 14945 // Prevent apps opting out from runtime permissions 14946 PackageParser.Package oldPackage = mPackages.get(pkgName); 14947 final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion; 14948 final int newTargetSdk = pkg.applicationInfo.targetSdkVersion; 14949 if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1 14950 && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) { 14951 res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE, 14952 "Package " + pkg.packageName + " new target SDK " + newTargetSdk 14953 + " doesn't support runtime permissions but the old" 14954 + " target SDK " + oldTargetSdk + " does."); 14955 return; 14956 } 14957 14958 // Prevent installing of child packages 14959 if (oldPackage.parentPackage != null) { 14960 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME, 14961 "Package " + pkg.packageName + " is child of package " 14962 + oldPackage.parentPackage + ". Child packages " 14963 + "can be updated only through the parent package."); 14964 return; 14965 } 14966 } 14967 } 14968 14969 PackageSetting ps = mSettings.mPackages.get(pkgName); 14970 if (ps != null) { 14971 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps); 14972 14973 // Quick sanity check that we're signed correctly if updating; 14974 // we'll check this again later when scanning, but we want to 14975 // bail early here before tripping over redefined permissions. 14976 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { 14977 if (!checkUpgradeKeySetLP(ps, pkg)) { 14978 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 14979 + pkg.packageName + " upgrade keys do not match the " 14980 + "previously installed version"); 14981 return; 14982 } 14983 } else { 14984 try { 14985 verifySignaturesLP(ps, pkg); 14986 } catch (PackageManagerException e) { 14987 res.setError(e.error, e.getMessage()); 14988 return; 14989 } 14990 } 14991 14992 oldCodePath = mSettings.mPackages.get(pkgName).codePathString; 14993 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 14994 systemApp = (ps.pkg.applicationInfo.flags & 14995 ApplicationInfo.FLAG_SYSTEM) != 0; 14996 } 14997 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 14998 } 14999 15000 // Check whether the newly-scanned package wants to define an already-defined perm 15001 int N = pkg.permissions.size(); 15002 for (int i = N-1; i >= 0; i--) { 15003 PackageParser.Permission perm = pkg.permissions.get(i); 15004 BasePermission bp = mSettings.mPermissions.get(perm.info.name); 15005 if (bp != null) { 15006 // If the defining package is signed with our cert, it's okay. This 15007 // also includes the "updating the same package" case, of course. 15008 // "updating same package" could also involve key-rotation. 15009 final boolean sigsOk; 15010 if (bp.sourcePackage.equals(pkg.packageName) 15011 && (bp.packageSetting instanceof PackageSetting) 15012 && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting, 15013 scanFlags))) { 15014 sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg); 15015 } else { 15016 sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures, 15017 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 15018 } 15019 if (!sigsOk) { 15020 // If the owning package is the system itself, we log but allow 15021 // install to proceed; we fail the install on all other permission 15022 // redefinitions. 15023 if (!bp.sourcePackage.equals("android")) { 15024 res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package " 15025 + pkg.packageName + " attempting to redeclare permission " 15026 + perm.info.name + " already owned by " + bp.sourcePackage); 15027 res.origPermission = perm.info.name; 15028 res.origPackage = bp.sourcePackage; 15029 return; 15030 } else { 15031 Slog.w(TAG, "Package " + pkg.packageName 15032 + " attempting to redeclare system permission " 15033 + perm.info.name + "; ignoring new declaration"); 15034 pkg.permissions.remove(i); 15035 } 15036 } 15037 } 15038 } 15039 } 15040 15041 if (systemApp) { 15042 if (onExternal) { 15043 // Abort update; system app can't be replaced with app on sdcard 15044 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION, 15045 "Cannot install updates to system apps on sdcard"); 15046 return; 15047 } else if (ephemeral) { 15048 // Abort update; system app can't be replaced with an ephemeral app 15049 res.setError(INSTALL_FAILED_EPHEMERAL_INVALID, 15050 "Cannot update a system app with an ephemeral app"); 15051 return; 15052 } 15053 } 15054 15055 if (args.move != null) { 15056 // We did an in-place move, so dex is ready to roll 15057 scanFlags |= SCAN_NO_DEX; 15058 scanFlags |= SCAN_MOVE; 15059 15060 synchronized (mPackages) { 15061 final PackageSetting ps = mSettings.mPackages.get(pkgName); 15062 if (ps == null) { 15063 res.setError(INSTALL_FAILED_INTERNAL_ERROR, 15064 "Missing settings for moved package " + pkgName); 15065 } 15066 15067 // We moved the entire application as-is, so bring over the 15068 // previously derived ABI information. 15069 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString; 15070 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString; 15071 } 15072 15073 } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) { 15074 // Enable SCAN_NO_DEX flag to skip dexopt at a later stage 15075 scanFlags |= SCAN_NO_DEX; 15076 15077 try { 15078 String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ? 15079 args.abiOverride : pkg.cpuAbiOverride); 15080 derivePackageAbi(pkg, new File(pkg.codePath), abiOverride, 15081 true /* extract libs */); 15082 } catch (PackageManagerException pme) { 15083 Slog.e(TAG, "Error deriving application ABI", pme); 15084 res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI"); 15085 return; 15086 } 15087 15088 // Shared libraries for the package need to be updated. 15089 synchronized (mPackages) { 15090 try { 15091 updateSharedLibrariesLPw(pkg, null); 15092 } catch (PackageManagerException e) { 15093 Slog.e(TAG, "updateSharedLibrariesLPw failed: " + e.getMessage()); 15094 } 15095 } 15096 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 15097 // Do not run PackageDexOptimizer through the local performDexOpt 15098 // method because `pkg` may not be in `mPackages` yet. 15099 // 15100 // Also, don't fail application installs if the dexopt step fails. 15101 mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles, 15102 null /* instructionSets */, false /* checkProfiles */, 15103 getCompilerFilterForReason(REASON_INSTALL), 15104 getOrCreateCompilerPackageStats(pkg)); 15105 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 15106 15107 // Notify BackgroundDexOptService that the package has been changed. 15108 // If this is an update of a package which used to fail to compile, 15109 // BDOS will remove it from its blacklist. 15110 BackgroundDexOptService.notifyPackageChanged(pkg.packageName); 15111 } 15112 15113 if (!args.doRename(res.returnCode, pkg, oldCodePath)) { 15114 res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename"); 15115 return; 15116 } 15117 15118 startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg); 15119 15120 try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags, 15121 "installPackageLI")) { 15122 if (replace) { 15123 replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user, 15124 installerPackageName, res); 15125 } else { 15126 installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES, 15127 args.user, installerPackageName, volumeUuid, res); 15128 } 15129 } 15130 synchronized (mPackages) { 15131 final PackageSetting ps = mSettings.mPackages.get(pkgName); 15132 if (ps != null) { 15133 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 15134 } 15135 15136 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 15137 for (int i = 0; i < childCount; i++) { 15138 PackageParser.Package childPkg = pkg.childPackages.get(i); 15139 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName); 15140 PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName); 15141 if (childPs != null) { 15142 childRes.newUsers = childPs.queryInstalledUsers( 15143 sUserManager.getUserIds(), true); 15144 } 15145 } 15146 } 15147 } 15148 15149 private void startIntentFilterVerifications(int userId, boolean replacing, 15150 PackageParser.Package pkg) { 15151 if (mIntentFilterVerifierComponent == null) { 15152 Slog.w(TAG, "No IntentFilter verification will not be done as " 15153 + "there is no IntentFilterVerifier available!"); 15154 return; 15155 } 15156 15157 final int verifierUid = getPackageUid( 15158 mIntentFilterVerifierComponent.getPackageName(), 15159 MATCH_DEBUG_TRIAGED_MISSING, 15160 (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId); 15161 15162 Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 15163 msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid); 15164 mHandler.sendMessage(msg); 15165 15166 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 15167 for (int i = 0; i < childCount; i++) { 15168 PackageParser.Package childPkg = pkg.childPackages.get(i); 15169 msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 15170 msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid); 15171 mHandler.sendMessage(msg); 15172 } 15173 } 15174 15175 private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing, 15176 PackageParser.Package pkg) { 15177 int size = pkg.activities.size(); 15178 if (size == 0) { 15179 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 15180 "No activity, so no need to verify any IntentFilter!"); 15181 return; 15182 } 15183 15184 final boolean hasDomainURLs = hasDomainURLs(pkg); 15185 if (!hasDomainURLs) { 15186 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 15187 "No domain URLs, so no need to verify any IntentFilter!"); 15188 return; 15189 } 15190 15191 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId 15192 + " if any IntentFilter from the " + size 15193 + " Activities needs verification ..."); 15194 15195 int count = 0; 15196 final String packageName = pkg.packageName; 15197 15198 synchronized (mPackages) { 15199 // If this is a new install and we see that we've already run verification for this 15200 // package, we have nothing to do: it means the state was restored from backup. 15201 if (!replacing) { 15202 IntentFilterVerificationInfo ivi = 15203 mSettings.getIntentFilterVerificationLPr(packageName); 15204 if (ivi != null) { 15205 if (DEBUG_DOMAIN_VERIFICATION) { 15206 Slog.i(TAG, "Package " + packageName+ " already verified: status=" 15207 + ivi.getStatusString()); 15208 } 15209 return; 15210 } 15211 } 15212 15213 // If any filters need to be verified, then all need to be. 15214 boolean needToVerify = false; 15215 for (PackageParser.Activity a : pkg.activities) { 15216 for (ActivityIntentInfo filter : a.intents) { 15217 if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) { 15218 if (DEBUG_DOMAIN_VERIFICATION) { 15219 Slog.d(TAG, "Intent filter needs verification, so processing all filters"); 15220 } 15221 needToVerify = true; 15222 break; 15223 } 15224 } 15225 } 15226 15227 if (needToVerify) { 15228 final int verificationId = mIntentFilterVerificationToken++; 15229 for (PackageParser.Activity a : pkg.activities) { 15230 for (ActivityIntentInfo filter : a.intents) { 15231 if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) { 15232 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 15233 "Verification needed for IntentFilter:" + filter.toString()); 15234 mIntentFilterVerifier.addOneIntentFilterVerification( 15235 verifierUid, userId, verificationId, filter, packageName); 15236 count++; 15237 } 15238 } 15239 } 15240 } 15241 } 15242 15243 if (count > 0) { 15244 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count 15245 + " IntentFilter verification" + (count > 1 ? "s" : "") 15246 + " for userId:" + userId); 15247 mIntentFilterVerifier.startVerifications(userId); 15248 } else { 15249 if (DEBUG_DOMAIN_VERIFICATION) { 15250 Slog.d(TAG, "No filters or not all autoVerify for " + packageName); 15251 } 15252 } 15253 } 15254 15255 private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) { 15256 final ComponentName cn = filter.activity.getComponentName(); 15257 final String packageName = cn.getPackageName(); 15258 15259 IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr( 15260 packageName); 15261 if (ivi == null) { 15262 return true; 15263 } 15264 int status = ivi.getStatus(); 15265 switch (status) { 15266 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 15267 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 15268 return true; 15269 15270 default: 15271 // Nothing to do 15272 return false; 15273 } 15274 } 15275 15276 private static boolean isMultiArch(ApplicationInfo info) { 15277 return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0; 15278 } 15279 15280 private static boolean isExternal(PackageParser.Package pkg) { 15281 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 15282 } 15283 15284 private static boolean isExternal(PackageSetting ps) { 15285 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 15286 } 15287 15288 private static boolean isEphemeral(PackageParser.Package pkg) { 15289 return pkg.applicationInfo.isEphemeralApp(); 15290 } 15291 15292 private static boolean isEphemeral(PackageSetting ps) { 15293 return ps.pkg != null && isEphemeral(ps.pkg); 15294 } 15295 15296 private static boolean isSystemApp(PackageParser.Package pkg) { 15297 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 15298 } 15299 15300 private static boolean isPrivilegedApp(PackageParser.Package pkg) { 15301 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; 15302 } 15303 15304 private static boolean hasDomainURLs(PackageParser.Package pkg) { 15305 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0; 15306 } 15307 15308 private static boolean isSystemApp(PackageSetting ps) { 15309 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0; 15310 } 15311 15312 private static boolean isUpdatedSystemApp(PackageSetting ps) { 15313 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; 15314 } 15315 15316 private int packageFlagsToInstallFlags(PackageSetting ps) { 15317 int installFlags = 0; 15318 if (isEphemeral(ps)) { 15319 installFlags |= PackageManager.INSTALL_EPHEMERAL; 15320 } 15321 if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) { 15322 // This existing package was an external ASEC install when we have 15323 // the external flag without a UUID 15324 installFlags |= PackageManager.INSTALL_EXTERNAL; 15325 } 15326 if (ps.isForwardLocked()) { 15327 installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 15328 } 15329 return installFlags; 15330 } 15331 15332 private String getVolumeUuidForPackage(PackageParser.Package pkg) { 15333 if (isExternal(pkg)) { 15334 if (TextUtils.isEmpty(pkg.volumeUuid)) { 15335 return StorageManager.UUID_PRIMARY_PHYSICAL; 15336 } else { 15337 return pkg.volumeUuid; 15338 } 15339 } else { 15340 return StorageManager.UUID_PRIVATE_INTERNAL; 15341 } 15342 } 15343 15344 private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) { 15345 if (isExternal(pkg)) { 15346 if (TextUtils.isEmpty(pkg.volumeUuid)) { 15347 return mSettings.getExternalVersion(); 15348 } else { 15349 return mSettings.findOrCreateVersion(pkg.volumeUuid); 15350 } 15351 } else { 15352 return mSettings.getInternalVersion(); 15353 } 15354 } 15355 15356 private void deleteTempPackageFiles() { 15357 final FilenameFilter filter = new FilenameFilter() { 15358 public boolean accept(File dir, String name) { 15359 return name.startsWith("vmdl") && name.endsWith(".tmp"); 15360 } 15361 }; 15362 for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) { 15363 file.delete(); 15364 } 15365 } 15366 15367 @Override 15368 public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId, 15369 int flags) { 15370 deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId, 15371 flags); 15372 } 15373 15374 @Override 15375 public void deletePackage(final String packageName, 15376 final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) { 15377 mContext.enforceCallingOrSelfPermission( 15378 android.Manifest.permission.DELETE_PACKAGES, null); 15379 Preconditions.checkNotNull(packageName); 15380 Preconditions.checkNotNull(observer); 15381 final int uid = Binder.getCallingUid(); 15382 final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0; 15383 final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId }; 15384 if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) { 15385 mContext.enforceCallingOrSelfPermission( 15386 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 15387 "deletePackage for user " + userId); 15388 } 15389 15390 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) { 15391 try { 15392 observer.onPackageDeleted(packageName, 15393 PackageManager.DELETE_FAILED_USER_RESTRICTED, null); 15394 } catch (RemoteException re) { 15395 } 15396 return; 15397 } 15398 15399 if (!deleteAllUsers && getBlockUninstallForUser(packageName, userId)) { 15400 try { 15401 observer.onPackageDeleted(packageName, 15402 PackageManager.DELETE_FAILED_OWNER_BLOCKED, null); 15403 } catch (RemoteException re) { 15404 } 15405 return; 15406 } 15407 15408 if (DEBUG_REMOVE) { 15409 Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId 15410 + " deleteAllUsers: " + deleteAllUsers ); 15411 } 15412 // Queue up an async operation since the package deletion may take a little while. 15413 mHandler.post(new Runnable() { 15414 public void run() { 15415 mHandler.removeCallbacks(this); 15416 int returnCode; 15417 if (!deleteAllUsers) { 15418 returnCode = deletePackageX(packageName, userId, deleteFlags); 15419 } else { 15420 int[] blockUninstallUserIds = getBlockUninstallForUsers(packageName, users); 15421 // If nobody is blocking uninstall, proceed with delete for all users 15422 if (ArrayUtils.isEmpty(blockUninstallUserIds)) { 15423 returnCode = deletePackageX(packageName, userId, deleteFlags); 15424 } else { 15425 // Otherwise uninstall individually for users with blockUninstalls=false 15426 final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS; 15427 for (int userId : users) { 15428 if (!ArrayUtils.contains(blockUninstallUserIds, userId)) { 15429 returnCode = deletePackageX(packageName, userId, userFlags); 15430 if (returnCode != PackageManager.DELETE_SUCCEEDED) { 15431 Slog.w(TAG, "Package delete failed for user " + userId 15432 + ", returnCode " + returnCode); 15433 } 15434 } 15435 } 15436 // The app has only been marked uninstalled for certain users. 15437 // We still need to report that delete was blocked 15438 returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED; 15439 } 15440 } 15441 try { 15442 observer.onPackageDeleted(packageName, returnCode, null); 15443 } catch (RemoteException e) { 15444 Log.i(TAG, "Observer no longer exists."); 15445 } //end catch 15446 } //end run 15447 }); 15448 } 15449 15450 private int[] getBlockUninstallForUsers(String packageName, int[] userIds) { 15451 int[] result = EMPTY_INT_ARRAY; 15452 for (int userId : userIds) { 15453 if (getBlockUninstallForUser(packageName, userId)) { 15454 result = ArrayUtils.appendInt(result, userId); 15455 } 15456 } 15457 return result; 15458 } 15459 15460 @Override 15461 public boolean isPackageDeviceAdminOnAnyUser(String packageName) { 15462 return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL); 15463 } 15464 15465 private boolean isPackageDeviceAdmin(String packageName, int userId) { 15466 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface( 15467 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); 15468 try { 15469 if (dpm != null) { 15470 final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent( 15471 /* callingUserOnly =*/ false); 15472 final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null 15473 : deviceOwnerComponentName.getPackageName(); 15474 // Does the package contains the device owner? 15475 // TODO Do we have to do it even if userId != UserHandle.USER_ALL? Otherwise, 15476 // this check is probably not needed, since DO should be registered as a device 15477 // admin on some user too. (Original bug for this: b/17657954) 15478 if (packageName.equals(deviceOwnerPackageName)) { 15479 return true; 15480 } 15481 // Does it contain a device admin for any user? 15482 int[] users; 15483 if (userId == UserHandle.USER_ALL) { 15484 users = sUserManager.getUserIds(); 15485 } else { 15486 users = new int[]{userId}; 15487 } 15488 for (int i = 0; i < users.length; ++i) { 15489 if (dpm.packageHasActiveAdmins(packageName, users[i])) { 15490 return true; 15491 } 15492 } 15493 } 15494 } catch (RemoteException e) { 15495 } 15496 return false; 15497 } 15498 15499 private boolean shouldKeepUninstalledPackageLPr(String packageName) { 15500 return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName); 15501 } 15502 15503 /** 15504 * This method is an internal method that could be get invoked either 15505 * to delete an installed package or to clean up a failed installation. 15506 * After deleting an installed package, a broadcast is sent to notify any 15507 * listeners that the package has been removed. For cleaning up a failed 15508 * installation, the broadcast is not necessary since the package's 15509 * installation wouldn't have sent the initial broadcast either 15510 * The key steps in deleting a package are 15511 * deleting the package information in internal structures like mPackages, 15512 * deleting the packages base directories through installd 15513 * updating mSettings to reflect current status 15514 * persisting settings for later use 15515 * sending a broadcast if necessary 15516 */ 15517 private int deletePackageX(String packageName, int userId, int deleteFlags) { 15518 final PackageRemovedInfo info = new PackageRemovedInfo(); 15519 final boolean res; 15520 15521 final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0 15522 ? UserHandle.USER_ALL : userId; 15523 15524 if (isPackageDeviceAdmin(packageName, removeUser)) { 15525 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin"); 15526 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER; 15527 } 15528 15529 PackageSetting uninstalledPs = null; 15530 15531 // for the uninstall-updates case and restricted profiles, remember the per- 15532 // user handle installed state 15533 int[] allUsers; 15534 synchronized (mPackages) { 15535 uninstalledPs = mSettings.mPackages.get(packageName); 15536 if (uninstalledPs == null) { 15537 Slog.w(TAG, "Not removing non-existent package " + packageName); 15538 return PackageManager.DELETE_FAILED_INTERNAL_ERROR; 15539 } 15540 allUsers = sUserManager.getUserIds(); 15541 info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true); 15542 } 15543 15544 final int freezeUser; 15545 if (isUpdatedSystemApp(uninstalledPs) 15546 && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) { 15547 // We're downgrading a system app, which will apply to all users, so 15548 // freeze them all during the downgrade 15549 freezeUser = UserHandle.USER_ALL; 15550 } else { 15551 freezeUser = removeUser; 15552 } 15553 15554 synchronized (mInstallLock) { 15555 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId); 15556 try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser, 15557 deleteFlags, "deletePackageX")) { 15558 res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers, 15559 deleteFlags | REMOVE_CHATTY, info, true, null); 15560 } 15561 synchronized (mPackages) { 15562 if (res) { 15563 mEphemeralApplicationRegistry.onPackageUninstalledLPw(uninstalledPs.pkg); 15564 } 15565 } 15566 } 15567 15568 if (res) { 15569 final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0; 15570 info.sendPackageRemovedBroadcasts(killApp); 15571 info.sendSystemPackageUpdatedBroadcasts(); 15572 info.sendSystemPackageAppearedBroadcasts(); 15573 } 15574 // Force a gc here. 15575 Runtime.getRuntime().gc(); 15576 // Delete the resources here after sending the broadcast to let 15577 // other processes clean up before deleting resources. 15578 if (info.args != null) { 15579 synchronized (mInstallLock) { 15580 info.args.doPostDeleteLI(true); 15581 } 15582 } 15583 15584 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR; 15585 } 15586 15587 class PackageRemovedInfo { 15588 String removedPackage; 15589 int uid = -1; 15590 int removedAppId = -1; 15591 int[] origUsers; 15592 int[] removedUsers = null; 15593 boolean isRemovedPackageSystemUpdate = false; 15594 boolean isUpdate; 15595 boolean dataRemoved; 15596 boolean removedForAllUsers; 15597 // Clean up resources deleted packages. 15598 InstallArgs args = null; 15599 ArrayMap<String, PackageRemovedInfo> removedChildPackages; 15600 ArrayMap<String, PackageInstalledInfo> appearedChildPackages; 15601 15602 void sendPackageRemovedBroadcasts(boolean killApp) { 15603 sendPackageRemovedBroadcastInternal(killApp); 15604 final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0; 15605 for (int i = 0; i < childCount; i++) { 15606 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i); 15607 childInfo.sendPackageRemovedBroadcastInternal(killApp); 15608 } 15609 } 15610 15611 void sendSystemPackageUpdatedBroadcasts() { 15612 if (isRemovedPackageSystemUpdate) { 15613 sendSystemPackageUpdatedBroadcastsInternal(); 15614 final int childCount = (removedChildPackages != null) 15615 ? removedChildPackages.size() : 0; 15616 for (int i = 0; i < childCount; i++) { 15617 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i); 15618 if (childInfo.isRemovedPackageSystemUpdate) { 15619 childInfo.sendSystemPackageUpdatedBroadcastsInternal(); 15620 } 15621 } 15622 } 15623 } 15624 15625 void sendSystemPackageAppearedBroadcasts() { 15626 final int packageCount = (appearedChildPackages != null) 15627 ? appearedChildPackages.size() : 0; 15628 for (int i = 0; i < packageCount; i++) { 15629 PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i); 15630 for (int userId : installedInfo.newUsers) { 15631 sendPackageAddedForUser(installedInfo.name, true, 15632 UserHandle.getAppId(installedInfo.uid), userId); 15633 } 15634 } 15635 } 15636 15637 private void sendSystemPackageUpdatedBroadcastsInternal() { 15638 Bundle extras = new Bundle(2); 15639 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 15640 extras.putBoolean(Intent.EXTRA_REPLACING, true); 15641 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, removedPackage, 15642 extras, 0, null, null, null); 15643 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, removedPackage, 15644 extras, 0, null, null, null); 15645 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null, 15646 null, 0, removedPackage, null, null); 15647 } 15648 15649 private void sendPackageRemovedBroadcastInternal(boolean killApp) { 15650 Bundle extras = new Bundle(2); 15651 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 15652 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved); 15653 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp); 15654 if (isUpdate || isRemovedPackageSystemUpdate) { 15655 extras.putBoolean(Intent.EXTRA_REPLACING, true); 15656 } 15657 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers); 15658 if (removedPackage != null) { 15659 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, 15660 extras, 0, null, null, removedUsers); 15661 if (dataRemoved && !isRemovedPackageSystemUpdate) { 15662 sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, 15663 removedPackage, extras, 0, null, null, removedUsers); 15664 } 15665 } 15666 if (removedAppId >= 0) { 15667 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, 0, null, null, 15668 removedUsers); 15669 } 15670 } 15671 } 15672 15673 /* 15674 * This method deletes the package from internal data structures. If the DONT_DELETE_DATA 15675 * flag is not set, the data directory is removed as well. 15676 * make sure this flag is set for partially installed apps. If not its meaningless to 15677 * delete a partially installed application. 15678 */ 15679 private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles, 15680 PackageRemovedInfo outInfo, int flags, boolean writeSettings) { 15681 String packageName = ps.name; 15682 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps); 15683 // Retrieve object to delete permissions for shared user later on 15684 final PackageParser.Package deletedPkg; 15685 final PackageSetting deletedPs; 15686 // reader 15687 synchronized (mPackages) { 15688 deletedPkg = mPackages.get(packageName); 15689 deletedPs = mSettings.mPackages.get(packageName); 15690 if (outInfo != null) { 15691 outInfo.removedPackage = packageName; 15692 outInfo.removedUsers = deletedPs != null 15693 ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true) 15694 : null; 15695 } 15696 } 15697 15698 removePackageLI(ps, (flags & REMOVE_CHATTY) != 0); 15699 15700 if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) { 15701 final PackageParser.Package resolvedPkg; 15702 if (deletedPkg != null) { 15703 resolvedPkg = deletedPkg; 15704 } else { 15705 // We don't have a parsed package when it lives on an ejected 15706 // adopted storage device, so fake something together 15707 resolvedPkg = new PackageParser.Package(ps.name); 15708 resolvedPkg.setVolumeUuid(ps.volumeUuid); 15709 } 15710 destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL, 15711 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 15712 destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL); 15713 if (outInfo != null) { 15714 outInfo.dataRemoved = true; 15715 } 15716 schedulePackageCleaning(packageName, UserHandle.USER_ALL, true); 15717 } 15718 15719 // writer 15720 synchronized (mPackages) { 15721 if (deletedPs != null) { 15722 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 15723 clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL); 15724 clearDefaultBrowserIfNeeded(packageName); 15725 if (outInfo != null) { 15726 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName); 15727 outInfo.removedAppId = mSettings.removePackageLPw(packageName); 15728 } 15729 updatePermissionsLPw(deletedPs.name, null, 0); 15730 if (deletedPs.sharedUser != null) { 15731 // Remove permissions associated with package. Since runtime 15732 // permissions are per user we have to kill the removed package 15733 // or packages running under the shared user of the removed 15734 // package if revoking the permissions requested only by the removed 15735 // package is successful and this causes a change in gids. 15736 for (int userId : UserManagerService.getInstance().getUserIds()) { 15737 final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs, 15738 userId); 15739 if (userIdToKill == UserHandle.USER_ALL 15740 || userIdToKill >= UserHandle.USER_SYSTEM) { 15741 // If gids changed for this user, kill all affected packages. 15742 mHandler.post(new Runnable() { 15743 @Override 15744 public void run() { 15745 // This has to happen with no lock held. 15746 killApplication(deletedPs.name, deletedPs.appId, 15747 KILL_APP_REASON_GIDS_CHANGED); 15748 } 15749 }); 15750 break; 15751 } 15752 } 15753 } 15754 clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL); 15755 } 15756 // make sure to preserve per-user disabled state if this removal was just 15757 // a downgrade of a system app to the factory package 15758 if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) { 15759 if (DEBUG_REMOVE) { 15760 Slog.d(TAG, "Propagating install state across downgrade"); 15761 } 15762 for (int userId : allUserHandles) { 15763 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId); 15764 if (DEBUG_REMOVE) { 15765 Slog.d(TAG, " user " + userId + " => " + installed); 15766 } 15767 ps.setInstalled(installed, userId); 15768 } 15769 } 15770 } 15771 // can downgrade to reader 15772 if (writeSettings) { 15773 // Save settings now 15774 mSettings.writeLPr(); 15775 } 15776 } 15777 if (outInfo != null) { 15778 // A user ID was deleted here. Go through all users and remove it 15779 // from KeyStore. 15780 removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId); 15781 } 15782 } 15783 15784 static boolean locationIsPrivileged(File path) { 15785 try { 15786 final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app") 15787 .getCanonicalPath(); 15788 return path.getCanonicalPath().startsWith(privilegedAppDir); 15789 } catch (IOException e) { 15790 Slog.e(TAG, "Unable to access code path " + path); 15791 } 15792 return false; 15793 } 15794 15795 /* 15796 * Tries to delete system package. 15797 */ 15798 private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg, 15799 PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo, 15800 boolean writeSettings) { 15801 if (deletedPs.parentPackageName != null) { 15802 Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName); 15803 return false; 15804 } 15805 15806 final boolean applyUserRestrictions 15807 = (allUserHandles != null) && (outInfo.origUsers != null); 15808 final PackageSetting disabledPs; 15809 // Confirm if the system package has been updated 15810 // An updated system app can be deleted. This will also have to restore 15811 // the system pkg from system partition 15812 // reader 15813 synchronized (mPackages) { 15814 disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name); 15815 } 15816 15817 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName 15818 + " disabledPs=" + disabledPs); 15819 15820 if (disabledPs == null) { 15821 Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName); 15822 return false; 15823 } else if (DEBUG_REMOVE) { 15824 Slog.d(TAG, "Deleting system pkg from data partition"); 15825 } 15826 15827 if (DEBUG_REMOVE) { 15828 if (applyUserRestrictions) { 15829 Slog.d(TAG, "Remembering install states:"); 15830 for (int userId : allUserHandles) { 15831 final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId); 15832 Slog.d(TAG, " u=" + userId + " inst=" + finstalled); 15833 } 15834 } 15835 } 15836 15837 // Delete the updated package 15838 outInfo.isRemovedPackageSystemUpdate = true; 15839 if (outInfo.removedChildPackages != null) { 15840 final int childCount = (deletedPs.childPackageNames != null) 15841 ? deletedPs.childPackageNames.size() : 0; 15842 for (int i = 0; i < childCount; i++) { 15843 String childPackageName = deletedPs.childPackageNames.get(i); 15844 if (disabledPs.childPackageNames != null && disabledPs.childPackageNames 15845 .contains(childPackageName)) { 15846 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get( 15847 childPackageName); 15848 if (childInfo != null) { 15849 childInfo.isRemovedPackageSystemUpdate = true; 15850 } 15851 } 15852 } 15853 } 15854 15855 if (disabledPs.versionCode < deletedPs.versionCode) { 15856 // Delete data for downgrades 15857 flags &= ~PackageManager.DELETE_KEEP_DATA; 15858 } else { 15859 // Preserve data by setting flag 15860 flags |= PackageManager.DELETE_KEEP_DATA; 15861 } 15862 15863 boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles, 15864 outInfo, writeSettings, disabledPs.pkg); 15865 if (!ret) { 15866 return false; 15867 } 15868 15869 // writer 15870 synchronized (mPackages) { 15871 // Reinstate the old system package 15872 enableSystemPackageLPw(disabledPs.pkg); 15873 // Remove any native libraries from the upgraded package. 15874 removeNativeBinariesLI(deletedPs); 15875 } 15876 15877 // Install the system package 15878 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs); 15879 int parseFlags = mDefParseFlags 15880 | PackageParser.PARSE_MUST_BE_APK 15881 | PackageParser.PARSE_IS_SYSTEM 15882 | PackageParser.PARSE_IS_SYSTEM_DIR; 15883 if (locationIsPrivileged(disabledPs.codePath)) { 15884 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 15885 } 15886 15887 final PackageParser.Package newPkg; 15888 try { 15889 newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null); 15890 } catch (PackageManagerException e) { 15891 Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": " 15892 + e.getMessage()); 15893 return false; 15894 } 15895 15896 prepareAppDataAfterInstallLIF(newPkg); 15897 15898 // writer 15899 synchronized (mPackages) { 15900 PackageSetting ps = mSettings.mPackages.get(newPkg.packageName); 15901 15902 // Propagate the permissions state as we do not want to drop on the floor 15903 // runtime permissions. The update permissions method below will take 15904 // care of removing obsolete permissions and grant install permissions. 15905 ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState()); 15906 updatePermissionsLPw(newPkg.packageName, newPkg, 15907 UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG); 15908 15909 if (applyUserRestrictions) { 15910 if (DEBUG_REMOVE) { 15911 Slog.d(TAG, "Propagating install state across reinstall"); 15912 } 15913 for (int userId : allUserHandles) { 15914 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId); 15915 if (DEBUG_REMOVE) { 15916 Slog.d(TAG, " user " + userId + " => " + installed); 15917 } 15918 ps.setInstalled(installed, userId); 15919 15920 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 15921 } 15922 // Regardless of writeSettings we need to ensure that this restriction 15923 // state propagation is persisted 15924 mSettings.writeAllUsersPackageRestrictionsLPr(); 15925 } 15926 // can downgrade to reader here 15927 if (writeSettings) { 15928 mSettings.writeLPr(); 15929 } 15930 } 15931 return true; 15932 } 15933 15934 private boolean deleteInstalledPackageLIF(PackageSetting ps, 15935 boolean deleteCodeAndResources, int flags, int[] allUserHandles, 15936 PackageRemovedInfo outInfo, boolean writeSettings, 15937 PackageParser.Package replacingPackage) { 15938 synchronized (mPackages) { 15939 if (outInfo != null) { 15940 outInfo.uid = ps.appId; 15941 } 15942 15943 if (outInfo != null && outInfo.removedChildPackages != null) { 15944 final int childCount = (ps.childPackageNames != null) 15945 ? ps.childPackageNames.size() : 0; 15946 for (int i = 0; i < childCount; i++) { 15947 String childPackageName = ps.childPackageNames.get(i); 15948 PackageSetting childPs = mSettings.mPackages.get(childPackageName); 15949 if (childPs == null) { 15950 return false; 15951 } 15952 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get( 15953 childPackageName); 15954 if (childInfo != null) { 15955 childInfo.uid = childPs.appId; 15956 } 15957 } 15958 } 15959 } 15960 15961 // Delete package data from internal structures and also remove data if flag is set 15962 removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings); 15963 15964 // Delete the child packages data 15965 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0; 15966 for (int i = 0; i < childCount; i++) { 15967 PackageSetting childPs; 15968 synchronized (mPackages) { 15969 childPs = mSettings.peekPackageLPr(ps.childPackageNames.get(i)); 15970 } 15971 if (childPs != null) { 15972 PackageRemovedInfo childOutInfo = (outInfo != null 15973 && outInfo.removedChildPackages != null) 15974 ? outInfo.removedChildPackages.get(childPs.name) : null; 15975 final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0 15976 && (replacingPackage != null 15977 && !replacingPackage.hasChildPackage(childPs.name)) 15978 ? flags & ~DELETE_KEEP_DATA : flags; 15979 removePackageDataLIF(childPs, allUserHandles, childOutInfo, 15980 deleteFlags, writeSettings); 15981 } 15982 } 15983 15984 // Delete application code and resources only for parent packages 15985 if (ps.parentPackageName == null) { 15986 if (deleteCodeAndResources && (outInfo != null)) { 15987 outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 15988 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 15989 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args); 15990 } 15991 } 15992 15993 return true; 15994 } 15995 15996 @Override 15997 public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall, 15998 int userId) { 15999 mContext.enforceCallingOrSelfPermission( 16000 android.Manifest.permission.DELETE_PACKAGES, null); 16001 synchronized (mPackages) { 16002 PackageSetting ps = mSettings.mPackages.get(packageName); 16003 if (ps == null) { 16004 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName); 16005 return false; 16006 } 16007 if (!ps.getInstalled(userId)) { 16008 // Can't block uninstall for an app that is not installed or enabled. 16009 Log.i(TAG, "Package not installed in set block uninstall " + packageName); 16010 return false; 16011 } 16012 ps.setBlockUninstall(blockUninstall, userId); 16013 mSettings.writePackageRestrictionsLPr(userId); 16014 } 16015 return true; 16016 } 16017 16018 @Override 16019 public boolean getBlockUninstallForUser(String packageName, int userId) { 16020 synchronized (mPackages) { 16021 PackageSetting ps = mSettings.mPackages.get(packageName); 16022 if (ps == null) { 16023 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName); 16024 return false; 16025 } 16026 return ps.getBlockUninstall(userId); 16027 } 16028 } 16029 16030 @Override 16031 public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) { 16032 int callingUid = Binder.getCallingUid(); 16033 if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) { 16034 throw new SecurityException( 16035 "setRequiredForSystemUser can only be run by the system or root"); 16036 } 16037 synchronized (mPackages) { 16038 PackageSetting ps = mSettings.mPackages.get(packageName); 16039 if (ps == null) { 16040 Log.w(TAG, "Package doesn't exist: " + packageName); 16041 return false; 16042 } 16043 if (systemUserApp) { 16044 ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER; 16045 } else { 16046 ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER; 16047 } 16048 mSettings.writeLPr(); 16049 } 16050 return true; 16051 } 16052 16053 /* 16054 * This method handles package deletion in general 16055 */ 16056 private boolean deletePackageLIF(String packageName, UserHandle user, 16057 boolean deleteCodeAndResources, int[] allUserHandles, int flags, 16058 PackageRemovedInfo outInfo, boolean writeSettings, 16059 PackageParser.Package replacingPackage) { 16060 if (packageName == null) { 16061 Slog.w(TAG, "Attempt to delete null packageName."); 16062 return false; 16063 } 16064 16065 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user); 16066 16067 PackageSetting ps; 16068 16069 synchronized (mPackages) { 16070 ps = mSettings.mPackages.get(packageName); 16071 if (ps == null) { 16072 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 16073 return false; 16074 } 16075 16076 if (ps.parentPackageName != null && (!isSystemApp(ps) 16077 || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) { 16078 if (DEBUG_REMOVE) { 16079 Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:" 16080 + ((user == null) ? UserHandle.USER_ALL : user)); 16081 } 16082 final int removedUserId = (user != null) ? user.getIdentifier() 16083 : UserHandle.USER_ALL; 16084 if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) { 16085 return false; 16086 } 16087 markPackageUninstalledForUserLPw(ps, user); 16088 scheduleWritePackageRestrictionsLocked(user); 16089 return true; 16090 } 16091 } 16092 16093 if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null 16094 && user.getIdentifier() != UserHandle.USER_ALL)) { 16095 // The caller is asking that the package only be deleted for a single 16096 // user. To do this, we just mark its uninstalled state and delete 16097 // its data. If this is a system app, we only allow this to happen if 16098 // they have set the special DELETE_SYSTEM_APP which requests different 16099 // semantics than normal for uninstalling system apps. 16100 markPackageUninstalledForUserLPw(ps, user); 16101 16102 if (!isSystemApp(ps)) { 16103 // Do not uninstall the APK if an app should be cached 16104 boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName); 16105 if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) { 16106 // Other user still have this package installed, so all 16107 // we need to do is clear this user's data and save that 16108 // it is uninstalled. 16109 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users"); 16110 if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) { 16111 return false; 16112 } 16113 scheduleWritePackageRestrictionsLocked(user); 16114 return true; 16115 } else { 16116 // We need to set it back to 'installed' so the uninstall 16117 // broadcasts will be sent correctly. 16118 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete"); 16119 ps.setInstalled(true, user.getIdentifier()); 16120 } 16121 } else { 16122 // This is a system app, so we assume that the 16123 // other users still have this package installed, so all 16124 // we need to do is clear this user's data and save that 16125 // it is uninstalled. 16126 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app"); 16127 if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) { 16128 return false; 16129 } 16130 scheduleWritePackageRestrictionsLocked(user); 16131 return true; 16132 } 16133 } 16134 16135 // If we are deleting a composite package for all users, keep track 16136 // of result for each child. 16137 if (ps.childPackageNames != null && outInfo != null) { 16138 synchronized (mPackages) { 16139 final int childCount = ps.childPackageNames.size(); 16140 outInfo.removedChildPackages = new ArrayMap<>(childCount); 16141 for (int i = 0; i < childCount; i++) { 16142 String childPackageName = ps.childPackageNames.get(i); 16143 PackageRemovedInfo childInfo = new PackageRemovedInfo(); 16144 childInfo.removedPackage = childPackageName; 16145 outInfo.removedChildPackages.put(childPackageName, childInfo); 16146 PackageSetting childPs = mSettings.peekPackageLPr(childPackageName); 16147 if (childPs != null) { 16148 childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true); 16149 } 16150 } 16151 } 16152 } 16153 16154 boolean ret = false; 16155 if (isSystemApp(ps)) { 16156 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name); 16157 // When an updated system application is deleted we delete the existing resources 16158 // as well and fall back to existing code in system partition 16159 ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings); 16160 } else { 16161 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name); 16162 ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles, 16163 outInfo, writeSettings, replacingPackage); 16164 } 16165 16166 // Take a note whether we deleted the package for all users 16167 if (outInfo != null) { 16168 outInfo.removedForAllUsers = mPackages.get(ps.name) == null; 16169 if (outInfo.removedChildPackages != null) { 16170 synchronized (mPackages) { 16171 final int childCount = outInfo.removedChildPackages.size(); 16172 for (int i = 0; i < childCount; i++) { 16173 PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i); 16174 if (childInfo != null) { 16175 childInfo.removedForAllUsers = mPackages.get( 16176 childInfo.removedPackage) == null; 16177 } 16178 } 16179 } 16180 } 16181 // If we uninstalled an update to a system app there may be some 16182 // child packages that appeared as they are declared in the system 16183 // app but were not declared in the update. 16184 if (isSystemApp(ps)) { 16185 synchronized (mPackages) { 16186 PackageSetting updatedPs = mSettings.peekPackageLPr(ps.name); 16187 final int childCount = (updatedPs.childPackageNames != null) 16188 ? updatedPs.childPackageNames.size() : 0; 16189 for (int i = 0; i < childCount; i++) { 16190 String childPackageName = updatedPs.childPackageNames.get(i); 16191 if (outInfo.removedChildPackages == null 16192 || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) { 16193 PackageSetting childPs = mSettings.peekPackageLPr(childPackageName); 16194 if (childPs == null) { 16195 continue; 16196 } 16197 PackageInstalledInfo installRes = new PackageInstalledInfo(); 16198 installRes.name = childPackageName; 16199 installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true); 16200 installRes.pkg = mPackages.get(childPackageName); 16201 installRes.uid = childPs.pkg.applicationInfo.uid; 16202 if (outInfo.appearedChildPackages == null) { 16203 outInfo.appearedChildPackages = new ArrayMap<>(); 16204 } 16205 outInfo.appearedChildPackages.put(childPackageName, installRes); 16206 } 16207 } 16208 } 16209 } 16210 } 16211 16212 return ret; 16213 } 16214 16215 private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) { 16216 final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL) 16217 ? sUserManager.getUserIds() : new int[] {user.getIdentifier()}; 16218 for (int nextUserId : userIds) { 16219 if (DEBUG_REMOVE) { 16220 Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId); 16221 } 16222 ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT, 16223 false /*installed*/, true /*stopped*/, true /*notLaunched*/, 16224 false /*hidden*/, false /*suspended*/, null, null, null, 16225 false /*blockUninstall*/, 16226 ps.readUserState(nextUserId).domainVerificationStatus, 0); 16227 } 16228 } 16229 16230 private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId, 16231 PackageRemovedInfo outInfo) { 16232 final PackageParser.Package pkg; 16233 synchronized (mPackages) { 16234 pkg = mPackages.get(ps.name); 16235 } 16236 16237 final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() 16238 : new int[] {userId}; 16239 for (int nextUserId : userIds) { 16240 if (DEBUG_REMOVE) { 16241 Slog.d(TAG, "Updating package:" + ps.name + " install state for user:" 16242 + nextUserId); 16243 } 16244 16245 destroyAppDataLIF(pkg, userId, 16246 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 16247 destroyAppProfilesLIF(pkg, userId); 16248 removeKeystoreDataIfNeeded(nextUserId, ps.appId); 16249 schedulePackageCleaning(ps.name, nextUserId, false); 16250 synchronized (mPackages) { 16251 if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) { 16252 scheduleWritePackageRestrictionsLocked(nextUserId); 16253 } 16254 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId); 16255 } 16256 } 16257 16258 if (outInfo != null) { 16259 outInfo.removedPackage = ps.name; 16260 outInfo.removedAppId = ps.appId; 16261 outInfo.removedUsers = userIds; 16262 } 16263 16264 return true; 16265 } 16266 16267 private final class ClearStorageConnection implements ServiceConnection { 16268 IMediaContainerService mContainerService; 16269 16270 @Override 16271 public void onServiceConnected(ComponentName name, IBinder service) { 16272 synchronized (this) { 16273 mContainerService = IMediaContainerService.Stub.asInterface(service); 16274 notifyAll(); 16275 } 16276 } 16277 16278 @Override 16279 public void onServiceDisconnected(ComponentName name) { 16280 } 16281 } 16282 16283 private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) { 16284 if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return; 16285 16286 final boolean mounted; 16287 if (Environment.isExternalStorageEmulated()) { 16288 mounted = true; 16289 } else { 16290 final String status = Environment.getExternalStorageState(); 16291 16292 mounted = status.equals(Environment.MEDIA_MOUNTED) 16293 || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY); 16294 } 16295 16296 if (!mounted) { 16297 return; 16298 } 16299 16300 final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 16301 int[] users; 16302 if (userId == UserHandle.USER_ALL) { 16303 users = sUserManager.getUserIds(); 16304 } else { 16305 users = new int[] { userId }; 16306 } 16307 final ClearStorageConnection conn = new ClearStorageConnection(); 16308 if (mContext.bindServiceAsUser( 16309 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) { 16310 try { 16311 for (int curUser : users) { 16312 long timeout = SystemClock.uptimeMillis() + 5000; 16313 synchronized (conn) { 16314 long now; 16315 while (conn.mContainerService == null && 16316 (now = SystemClock.uptimeMillis()) < timeout) { 16317 try { 16318 conn.wait(timeout - now); 16319 } catch (InterruptedException e) { 16320 } 16321 } 16322 } 16323 if (conn.mContainerService == null) { 16324 return; 16325 } 16326 16327 final UserEnvironment userEnv = new UserEnvironment(curUser); 16328 clearDirectory(conn.mContainerService, 16329 userEnv.buildExternalStorageAppCacheDirs(packageName)); 16330 if (allData) { 16331 clearDirectory(conn.mContainerService, 16332 userEnv.buildExternalStorageAppDataDirs(packageName)); 16333 clearDirectory(conn.mContainerService, 16334 userEnv.buildExternalStorageAppMediaDirs(packageName)); 16335 } 16336 } 16337 } finally { 16338 mContext.unbindService(conn); 16339 } 16340 } 16341 } 16342 16343 @Override 16344 public void clearApplicationProfileData(String packageName) { 16345 enforceSystemOrRoot("Only the system can clear all profile data"); 16346 16347 final PackageParser.Package pkg; 16348 synchronized (mPackages) { 16349 pkg = mPackages.get(packageName); 16350 } 16351 16352 try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) { 16353 synchronized (mInstallLock) { 16354 clearAppProfilesLIF(pkg, UserHandle.USER_ALL); 16355 destroyAppReferenceProfileLeafLIF(pkg, UserHandle.USER_ALL, 16356 true /* removeBaseMarker */); 16357 } 16358 } 16359 } 16360 16361 @Override 16362 public void clearApplicationUserData(final String packageName, 16363 final IPackageDataObserver observer, final int userId) { 16364 mContext.enforceCallingOrSelfPermission( 16365 android.Manifest.permission.CLEAR_APP_USER_DATA, null); 16366 16367 enforceCrossUserPermission(Binder.getCallingUid(), userId, 16368 true /* requireFullPermission */, false /* checkShell */, "clear application data"); 16369 16370 if (mProtectedPackages.isPackageDataProtected(userId, packageName)) { 16371 throw new SecurityException("Cannot clear data for a protected package: " 16372 + packageName); 16373 } 16374 // Queue up an async operation since the package deletion may take a little while. 16375 mHandler.post(new Runnable() { 16376 public void run() { 16377 mHandler.removeCallbacks(this); 16378 final boolean succeeded; 16379 try (PackageFreezer freezer = freezePackage(packageName, 16380 "clearApplicationUserData")) { 16381 synchronized (mInstallLock) { 16382 succeeded = clearApplicationUserDataLIF(packageName, userId); 16383 } 16384 clearExternalStorageDataSync(packageName, userId, true); 16385 } 16386 if (succeeded) { 16387 // invoke DeviceStorageMonitor's update method to clear any notifications 16388 DeviceStorageMonitorInternal dsm = LocalServices 16389 .getService(DeviceStorageMonitorInternal.class); 16390 if (dsm != null) { 16391 dsm.checkMemory(); 16392 } 16393 } 16394 if(observer != null) { 16395 try { 16396 observer.onRemoveCompleted(packageName, succeeded); 16397 } catch (RemoteException e) { 16398 Log.i(TAG, "Observer no longer exists."); 16399 } 16400 } //end if observer 16401 } //end run 16402 }); 16403 } 16404 16405 private boolean clearApplicationUserDataLIF(String packageName, int userId) { 16406 if (packageName == null) { 16407 Slog.w(TAG, "Attempt to delete null packageName."); 16408 return false; 16409 } 16410 16411 // Try finding details about the requested package 16412 PackageParser.Package pkg; 16413 synchronized (mPackages) { 16414 pkg = mPackages.get(packageName); 16415 if (pkg == null) { 16416 final PackageSetting ps = mSettings.mPackages.get(packageName); 16417 if (ps != null) { 16418 pkg = ps.pkg; 16419 } 16420 } 16421 16422 if (pkg == null) { 16423 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 16424 return false; 16425 } 16426 16427 PackageSetting ps = (PackageSetting) pkg.mExtras; 16428 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 16429 } 16430 16431 clearAppDataLIF(pkg, userId, 16432 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 16433 16434 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); 16435 removeKeystoreDataIfNeeded(userId, appId); 16436 16437 UserManagerInternal umInternal = getUserManagerInternal(); 16438 final int flags; 16439 if (umInternal.isUserUnlockingOrUnlocked(userId)) { 16440 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 16441 } else if (umInternal.isUserRunning(userId)) { 16442 flags = StorageManager.FLAG_STORAGE_DE; 16443 } else { 16444 flags = 0; 16445 } 16446 prepareAppDataContentsLIF(pkg, userId, flags); 16447 16448 return true; 16449 } 16450 16451 /** 16452 * Reverts user permission state changes (permissions and flags) in 16453 * all packages for a given user. 16454 * 16455 * @param userId The device user for which to do a reset. 16456 */ 16457 private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) { 16458 final int packageCount = mPackages.size(); 16459 for (int i = 0; i < packageCount; i++) { 16460 PackageParser.Package pkg = mPackages.valueAt(i); 16461 PackageSetting ps = (PackageSetting) pkg.mExtras; 16462 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 16463 } 16464 } 16465 16466 private void resetNetworkPolicies(int userId) { 16467 LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId); 16468 } 16469 16470 /** 16471 * Reverts user permission state changes (permissions and flags). 16472 * 16473 * @param ps The package for which to reset. 16474 * @param userId The device user for which to do a reset. 16475 */ 16476 private void resetUserChangesToRuntimePermissionsAndFlagsLPw( 16477 final PackageSetting ps, final int userId) { 16478 if (ps.pkg == null) { 16479 return; 16480 } 16481 16482 // These are flags that can change base on user actions. 16483 final int userSettableMask = FLAG_PERMISSION_USER_SET 16484 | FLAG_PERMISSION_USER_FIXED 16485 | FLAG_PERMISSION_REVOKE_ON_UPGRADE 16486 | FLAG_PERMISSION_REVIEW_REQUIRED; 16487 16488 final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED 16489 | FLAG_PERMISSION_POLICY_FIXED; 16490 16491 boolean writeInstallPermissions = false; 16492 boolean writeRuntimePermissions = false; 16493 16494 final int permissionCount = ps.pkg.requestedPermissions.size(); 16495 for (int i = 0; i < permissionCount; i++) { 16496 String permission = ps.pkg.requestedPermissions.get(i); 16497 16498 BasePermission bp = mSettings.mPermissions.get(permission); 16499 if (bp == null) { 16500 continue; 16501 } 16502 16503 // If shared user we just reset the state to which only this app contributed. 16504 if (ps.sharedUser != null) { 16505 boolean used = false; 16506 final int packageCount = ps.sharedUser.packages.size(); 16507 for (int j = 0; j < packageCount; j++) { 16508 PackageSetting pkg = ps.sharedUser.packages.valueAt(j); 16509 if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName) 16510 && pkg.pkg.requestedPermissions.contains(permission)) { 16511 used = true; 16512 break; 16513 } 16514 } 16515 if (used) { 16516 continue; 16517 } 16518 } 16519 16520 PermissionsState permissionsState = ps.getPermissionsState(); 16521 16522 final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId); 16523 16524 // Always clear the user settable flags. 16525 final boolean hasInstallState = permissionsState.getInstallPermissionState( 16526 bp.name) != null; 16527 // If permission review is enabled and this is a legacy app, mark the 16528 // permission as requiring a review as this is the initial state. 16529 int flags = 0; 16530 if ((mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED) 16531 && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 16532 flags |= FLAG_PERMISSION_REVIEW_REQUIRED; 16533 } 16534 if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) { 16535 if (hasInstallState) { 16536 writeInstallPermissions = true; 16537 } else { 16538 writeRuntimePermissions = true; 16539 } 16540 } 16541 16542 // Below is only runtime permission handling. 16543 if (!bp.isRuntime()) { 16544 continue; 16545 } 16546 16547 // Never clobber system or policy. 16548 if ((oldFlags & policyOrSystemFlags) != 0) { 16549 continue; 16550 } 16551 16552 // If this permission was granted by default, make sure it is. 16553 if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) { 16554 if (permissionsState.grantRuntimePermission(bp, userId) 16555 != PERMISSION_OPERATION_FAILURE) { 16556 writeRuntimePermissions = true; 16557 } 16558 // If permission review is enabled the permissions for a legacy apps 16559 // are represented as constantly granted runtime ones, so don't revoke. 16560 } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) { 16561 // Otherwise, reset the permission. 16562 final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId); 16563 switch (revokeResult) { 16564 case PERMISSION_OPERATION_SUCCESS: 16565 case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 16566 writeRuntimePermissions = true; 16567 final int appId = ps.appId; 16568 mHandler.post(new Runnable() { 16569 @Override 16570 public void run() { 16571 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED); 16572 } 16573 }); 16574 } break; 16575 } 16576 } 16577 } 16578 16579 // Synchronously write as we are taking permissions away. 16580 if (writeRuntimePermissions) { 16581 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 16582 } 16583 16584 // Synchronously write as we are taking permissions away. 16585 if (writeInstallPermissions) { 16586 mSettings.writeLPr(); 16587 } 16588 } 16589 16590 /** 16591 * Remove entries from the keystore daemon. Will only remove it if the 16592 * {@code appId} is valid. 16593 */ 16594 private static void removeKeystoreDataIfNeeded(int userId, int appId) { 16595 if (appId < 0) { 16596 return; 16597 } 16598 16599 final KeyStore keyStore = KeyStore.getInstance(); 16600 if (keyStore != null) { 16601 if (userId == UserHandle.USER_ALL) { 16602 for (final int individual : sUserManager.getUserIds()) { 16603 keyStore.clearUid(UserHandle.getUid(individual, appId)); 16604 } 16605 } else { 16606 keyStore.clearUid(UserHandle.getUid(userId, appId)); 16607 } 16608 } else { 16609 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId); 16610 } 16611 } 16612 16613 @Override 16614 public void deleteApplicationCacheFiles(final String packageName, 16615 final IPackageDataObserver observer) { 16616 final int userId = UserHandle.getCallingUserId(); 16617 deleteApplicationCacheFilesAsUser(packageName, userId, observer); 16618 } 16619 16620 @Override 16621 public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId, 16622 final IPackageDataObserver observer) { 16623 mContext.enforceCallingOrSelfPermission( 16624 android.Manifest.permission.DELETE_CACHE_FILES, null); 16625 enforceCrossUserPermission(Binder.getCallingUid(), userId, 16626 /* requireFullPermission= */ true, /* checkShell= */ false, 16627 "delete application cache files"); 16628 16629 final PackageParser.Package pkg; 16630 synchronized (mPackages) { 16631 pkg = mPackages.get(packageName); 16632 } 16633 16634 // Queue up an async operation since the package deletion may take a little while. 16635 mHandler.post(new Runnable() { 16636 public void run() { 16637 synchronized (mInstallLock) { 16638 final int flags = StorageManager.FLAG_STORAGE_DE 16639 | StorageManager.FLAG_STORAGE_CE; 16640 // We're only clearing cache files, so we don't care if the 16641 // app is unfrozen and still able to run 16642 clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY); 16643 clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 16644 } 16645 clearExternalStorageDataSync(packageName, userId, false); 16646 if (observer != null) { 16647 try { 16648 observer.onRemoveCompleted(packageName, true); 16649 } catch (RemoteException e) { 16650 Log.i(TAG, "Observer no longer exists."); 16651 } 16652 } 16653 } 16654 }); 16655 } 16656 16657 @Override 16658 public void getPackageSizeInfo(final String packageName, int userHandle, 16659 final IPackageStatsObserver observer) { 16660 mContext.enforceCallingOrSelfPermission( 16661 android.Manifest.permission.GET_PACKAGE_SIZE, null); 16662 if (packageName == null) { 16663 throw new IllegalArgumentException("Attempt to get size of null packageName"); 16664 } 16665 16666 PackageStats stats = new PackageStats(packageName, userHandle); 16667 16668 /* 16669 * Queue up an async operation since the package measurement may take a 16670 * little while. 16671 */ 16672 Message msg = mHandler.obtainMessage(INIT_COPY); 16673 msg.obj = new MeasureParams(stats, observer); 16674 mHandler.sendMessage(msg); 16675 } 16676 16677 private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) { 16678 final PackageSetting ps; 16679 synchronized (mPackages) { 16680 ps = mSettings.mPackages.get(packageName); 16681 if (ps == null) { 16682 Slog.w(TAG, "Failed to find settings for " + packageName); 16683 return false; 16684 } 16685 } 16686 try { 16687 mInstaller.getAppSize(ps.volumeUuid, packageName, userId, 16688 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 16689 ps.getCeDataInode(userId), ps.codePathString, stats); 16690 } catch (InstallerException e) { 16691 Slog.w(TAG, String.valueOf(e)); 16692 return false; 16693 } 16694 16695 // For now, ignore code size of packages on system partition 16696 if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) { 16697 stats.codeSize = 0; 16698 } 16699 16700 return true; 16701 } 16702 16703 private int getUidTargetSdkVersionLockedLPr(int uid) { 16704 Object obj = mSettings.getUserIdLPr(uid); 16705 if (obj instanceof SharedUserSetting) { 16706 final SharedUserSetting sus = (SharedUserSetting) obj; 16707 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT; 16708 final Iterator<PackageSetting> it = sus.packages.iterator(); 16709 while (it.hasNext()) { 16710 final PackageSetting ps = it.next(); 16711 if (ps.pkg != null) { 16712 int v = ps.pkg.applicationInfo.targetSdkVersion; 16713 if (v < vers) vers = v; 16714 } 16715 } 16716 return vers; 16717 } else if (obj instanceof PackageSetting) { 16718 final PackageSetting ps = (PackageSetting) obj; 16719 if (ps.pkg != null) { 16720 return ps.pkg.applicationInfo.targetSdkVersion; 16721 } 16722 } 16723 return Build.VERSION_CODES.CUR_DEVELOPMENT; 16724 } 16725 16726 @Override 16727 public void addPreferredActivity(IntentFilter filter, int match, 16728 ComponentName[] set, ComponentName activity, int userId) { 16729 addPreferredActivityInternal(filter, match, set, activity, true, userId, 16730 "Adding preferred"); 16731 } 16732 16733 private void addPreferredActivityInternal(IntentFilter filter, int match, 16734 ComponentName[] set, ComponentName activity, boolean always, int userId, 16735 String opname) { 16736 // writer 16737 int callingUid = Binder.getCallingUid(); 16738 enforceCrossUserPermission(callingUid, userId, 16739 true /* requireFullPermission */, false /* checkShell */, "add preferred activity"); 16740 if (filter.countActions() == 0) { 16741 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 16742 return; 16743 } 16744 synchronized (mPackages) { 16745 if (mContext.checkCallingOrSelfPermission( 16746 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 16747 != PackageManager.PERMISSION_GRANTED) { 16748 if (getUidTargetSdkVersionLockedLPr(callingUid) 16749 < Build.VERSION_CODES.FROYO) { 16750 Slog.w(TAG, "Ignoring addPreferredActivity() from uid " 16751 + callingUid); 16752 return; 16753 } 16754 mContext.enforceCallingOrSelfPermission( 16755 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 16756 } 16757 16758 PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId); 16759 Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user " 16760 + userId + ":"); 16761 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 16762 pir.addFilter(new PreferredActivity(filter, match, set, activity, always)); 16763 scheduleWritePackageRestrictionsLocked(userId); 16764 postPreferredActivityChangedBroadcast(userId); 16765 } 16766 } 16767 16768 private void postPreferredActivityChangedBroadcast(int userId) { 16769 mHandler.post(() -> { 16770 final IActivityManager am = ActivityManagerNative.getDefault(); 16771 if (am == null) { 16772 return; 16773 } 16774 16775 final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED); 16776 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16777 try { 16778 am.broadcastIntent(null, intent, null, null, 16779 0, null, null, null, android.app.AppOpsManager.OP_NONE, 16780 null, false, false, userId); 16781 } catch (RemoteException e) { 16782 } 16783 }); 16784 } 16785 16786 @Override 16787 public void replacePreferredActivity(IntentFilter filter, int match, 16788 ComponentName[] set, ComponentName activity, int userId) { 16789 if (filter.countActions() != 1) { 16790 throw new IllegalArgumentException( 16791 "replacePreferredActivity expects filter to have only 1 action."); 16792 } 16793 if (filter.countDataAuthorities() != 0 16794 || filter.countDataPaths() != 0 16795 || filter.countDataSchemes() > 1 16796 || filter.countDataTypes() != 0) { 16797 throw new IllegalArgumentException( 16798 "replacePreferredActivity expects filter to have no data authorities, " + 16799 "paths, or types; and at most one scheme."); 16800 } 16801 16802 final int callingUid = Binder.getCallingUid(); 16803 enforceCrossUserPermission(callingUid, userId, 16804 true /* requireFullPermission */, false /* checkShell */, 16805 "replace preferred activity"); 16806 synchronized (mPackages) { 16807 if (mContext.checkCallingOrSelfPermission( 16808 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 16809 != PackageManager.PERMISSION_GRANTED) { 16810 if (getUidTargetSdkVersionLockedLPr(callingUid) 16811 < Build.VERSION_CODES.FROYO) { 16812 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid " 16813 + Binder.getCallingUid()); 16814 return; 16815 } 16816 mContext.enforceCallingOrSelfPermission( 16817 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 16818 } 16819 16820 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 16821 if (pir != null) { 16822 // Get all of the existing entries that exactly match this filter. 16823 ArrayList<PreferredActivity> existing = pir.findFilters(filter); 16824 if (existing != null && existing.size() == 1) { 16825 PreferredActivity cur = existing.get(0); 16826 if (DEBUG_PREFERRED) { 16827 Slog.i(TAG, "Checking replace of preferred:"); 16828 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 16829 if (!cur.mPref.mAlways) { 16830 Slog.i(TAG, " -- CUR; not mAlways!"); 16831 } else { 16832 Slog.i(TAG, " -- CUR: mMatch=" + cur.mPref.mMatch); 16833 Slog.i(TAG, " -- CUR: mSet=" 16834 + Arrays.toString(cur.mPref.mSetComponents)); 16835 Slog.i(TAG, " -- CUR: mComponent=" + cur.mPref.mShortComponent); 16836 Slog.i(TAG, " -- NEW: mMatch=" 16837 + (match&IntentFilter.MATCH_CATEGORY_MASK)); 16838 Slog.i(TAG, " -- CUR: mSet=" + Arrays.toString(set)); 16839 Slog.i(TAG, " -- CUR: mComponent=" + activity.flattenToShortString()); 16840 } 16841 } 16842 if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity) 16843 && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK) 16844 && cur.mPref.sameSet(set)) { 16845 // Setting the preferred activity to what it happens to be already 16846 if (DEBUG_PREFERRED) { 16847 Slog.i(TAG, "Replacing with same preferred activity " 16848 + cur.mPref.mShortComponent + " for user " 16849 + userId + ":"); 16850 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 16851 } 16852 return; 16853 } 16854 } 16855 16856 if (existing != null) { 16857 if (DEBUG_PREFERRED) { 16858 Slog.i(TAG, existing.size() + " existing preferred matches for:"); 16859 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 16860 } 16861 for (int i = 0; i < existing.size(); i++) { 16862 PreferredActivity pa = existing.get(i); 16863 if (DEBUG_PREFERRED) { 16864 Slog.i(TAG, "Removing existing preferred activity " 16865 + pa.mPref.mComponent + ":"); 16866 pa.dump(new LogPrinter(Log.INFO, TAG), " "); 16867 } 16868 pir.removeFilter(pa); 16869 } 16870 } 16871 } 16872 addPreferredActivityInternal(filter, match, set, activity, true, userId, 16873 "Replacing preferred"); 16874 } 16875 } 16876 16877 @Override 16878 public void clearPackagePreferredActivities(String packageName) { 16879 final int uid = Binder.getCallingUid(); 16880 // writer 16881 synchronized (mPackages) { 16882 PackageParser.Package pkg = mPackages.get(packageName); 16883 if (pkg == null || pkg.applicationInfo.uid != uid) { 16884 if (mContext.checkCallingOrSelfPermission( 16885 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 16886 != PackageManager.PERMISSION_GRANTED) { 16887 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid()) 16888 < Build.VERSION_CODES.FROYO) { 16889 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid " 16890 + Binder.getCallingUid()); 16891 return; 16892 } 16893 mContext.enforceCallingOrSelfPermission( 16894 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 16895 } 16896 } 16897 16898 int user = UserHandle.getCallingUserId(); 16899 if (clearPackagePreferredActivitiesLPw(packageName, user)) { 16900 scheduleWritePackageRestrictionsLocked(user); 16901 } 16902 } 16903 } 16904 16905 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 16906 boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) { 16907 ArrayList<PreferredActivity> removed = null; 16908 boolean changed = false; 16909 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 16910 final int thisUserId = mSettings.mPreferredActivities.keyAt(i); 16911 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 16912 if (userId != UserHandle.USER_ALL && userId != thisUserId) { 16913 continue; 16914 } 16915 Iterator<PreferredActivity> it = pir.filterIterator(); 16916 while (it.hasNext()) { 16917 PreferredActivity pa = it.next(); 16918 // Mark entry for removal only if it matches the package name 16919 // and the entry is of type "always". 16920 if (packageName == null || 16921 (pa.mPref.mComponent.getPackageName().equals(packageName) 16922 && pa.mPref.mAlways)) { 16923 if (removed == null) { 16924 removed = new ArrayList<PreferredActivity>(); 16925 } 16926 removed.add(pa); 16927 } 16928 } 16929 if (removed != null) { 16930 for (int j=0; j<removed.size(); j++) { 16931 PreferredActivity pa = removed.get(j); 16932 pir.removeFilter(pa); 16933 } 16934 changed = true; 16935 } 16936 } 16937 if (changed) { 16938 postPreferredActivityChangedBroadcast(userId); 16939 } 16940 return changed; 16941 } 16942 16943 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 16944 private void clearIntentFilterVerificationsLPw(int userId) { 16945 final int packageCount = mPackages.size(); 16946 for (int i = 0; i < packageCount; i++) { 16947 PackageParser.Package pkg = mPackages.valueAt(i); 16948 clearIntentFilterVerificationsLPw(pkg.packageName, userId); 16949 } 16950 } 16951 16952 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 16953 void clearIntentFilterVerificationsLPw(String packageName, int userId) { 16954 if (userId == UserHandle.USER_ALL) { 16955 if (mSettings.removeIntentFilterVerificationLPw(packageName, 16956 sUserManager.getUserIds())) { 16957 for (int oneUserId : sUserManager.getUserIds()) { 16958 scheduleWritePackageRestrictionsLocked(oneUserId); 16959 } 16960 } 16961 } else { 16962 if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) { 16963 scheduleWritePackageRestrictionsLocked(userId); 16964 } 16965 } 16966 } 16967 16968 void clearDefaultBrowserIfNeeded(String packageName) { 16969 for (int oneUserId : sUserManager.getUserIds()) { 16970 String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId); 16971 if (TextUtils.isEmpty(defaultBrowserPackageName)) continue; 16972 if (packageName.equals(defaultBrowserPackageName)) { 16973 setDefaultBrowserPackageName(null, oneUserId); 16974 } 16975 } 16976 } 16977 16978 @Override 16979 public void resetApplicationPreferences(int userId) { 16980 mContext.enforceCallingOrSelfPermission( 16981 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 16982 final long identity = Binder.clearCallingIdentity(); 16983 // writer 16984 try { 16985 synchronized (mPackages) { 16986 clearPackagePreferredActivitiesLPw(null, userId); 16987 mSettings.applyDefaultPreferredAppsLPw(this, userId); 16988 // TODO: We have to reset the default SMS and Phone. This requires 16989 // significant refactoring to keep all default apps in the package 16990 // manager (cleaner but more work) or have the services provide 16991 // callbacks to the package manager to request a default app reset. 16992 applyFactoryDefaultBrowserLPw(userId); 16993 clearIntentFilterVerificationsLPw(userId); 16994 primeDomainVerificationsLPw(userId); 16995 resetUserChangesToRuntimePermissionsAndFlagsLPw(userId); 16996 scheduleWritePackageRestrictionsLocked(userId); 16997 } 16998 resetNetworkPolicies(userId); 16999 } finally { 17000 Binder.restoreCallingIdentity(identity); 17001 } 17002 } 17003 17004 @Override 17005 public int getPreferredActivities(List<IntentFilter> outFilters, 17006 List<ComponentName> outActivities, String packageName) { 17007 17008 int num = 0; 17009 final int userId = UserHandle.getCallingUserId(); 17010 // reader 17011 synchronized (mPackages) { 17012 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 17013 if (pir != null) { 17014 final Iterator<PreferredActivity> it = pir.filterIterator(); 17015 while (it.hasNext()) { 17016 final PreferredActivity pa = it.next(); 17017 if (packageName == null 17018 || (pa.mPref.mComponent.getPackageName().equals(packageName) 17019 && pa.mPref.mAlways)) { 17020 if (outFilters != null) { 17021 outFilters.add(new IntentFilter(pa)); 17022 } 17023 if (outActivities != null) { 17024 outActivities.add(pa.mPref.mComponent); 17025 } 17026 } 17027 } 17028 } 17029 } 17030 17031 return num; 17032 } 17033 17034 @Override 17035 public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity, 17036 int userId) { 17037 int callingUid = Binder.getCallingUid(); 17038 if (callingUid != Process.SYSTEM_UID) { 17039 throw new SecurityException( 17040 "addPersistentPreferredActivity can only be run by the system"); 17041 } 17042 if (filter.countActions() == 0) { 17043 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 17044 return; 17045 } 17046 synchronized (mPackages) { 17047 Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId + 17048 ":"); 17049 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 17050 mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter( 17051 new PersistentPreferredActivity(filter, activity)); 17052 scheduleWritePackageRestrictionsLocked(userId); 17053 postPreferredActivityChangedBroadcast(userId); 17054 } 17055 } 17056 17057 @Override 17058 public void clearPackagePersistentPreferredActivities(String packageName, int userId) { 17059 int callingUid = Binder.getCallingUid(); 17060 if (callingUid != Process.SYSTEM_UID) { 17061 throw new SecurityException( 17062 "clearPackagePersistentPreferredActivities can only be run by the system"); 17063 } 17064 ArrayList<PersistentPreferredActivity> removed = null; 17065 boolean changed = false; 17066 synchronized (mPackages) { 17067 for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) { 17068 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i); 17069 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 17070 .valueAt(i); 17071 if (userId != thisUserId) { 17072 continue; 17073 } 17074 Iterator<PersistentPreferredActivity> it = ppir.filterIterator(); 17075 while (it.hasNext()) { 17076 PersistentPreferredActivity ppa = it.next(); 17077 // Mark entry for removal only if it matches the package name. 17078 if (ppa.mComponent.getPackageName().equals(packageName)) { 17079 if (removed == null) { 17080 removed = new ArrayList<PersistentPreferredActivity>(); 17081 } 17082 removed.add(ppa); 17083 } 17084 } 17085 if (removed != null) { 17086 for (int j=0; j<removed.size(); j++) { 17087 PersistentPreferredActivity ppa = removed.get(j); 17088 ppir.removeFilter(ppa); 17089 } 17090 changed = true; 17091 } 17092 } 17093 17094 if (changed) { 17095 scheduleWritePackageRestrictionsLocked(userId); 17096 postPreferredActivityChangedBroadcast(userId); 17097 } 17098 } 17099 } 17100 17101 /** 17102 * Common machinery for picking apart a restored XML blob and passing 17103 * it to a caller-supplied functor to be applied to the running system. 17104 */ 17105 private void restoreFromXml(XmlPullParser parser, int userId, 17106 String expectedStartTag, BlobXmlRestorer functor) 17107 throws IOException, XmlPullParserException { 17108 int type; 17109 while ((type = parser.next()) != XmlPullParser.START_TAG 17110 && type != XmlPullParser.END_DOCUMENT) { 17111 } 17112 if (type != XmlPullParser.START_TAG) { 17113 // oops didn't find a start tag?! 17114 if (DEBUG_BACKUP) { 17115 Slog.e(TAG, "Didn't find start tag during restore"); 17116 } 17117 return; 17118 } 17119Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName()); 17120 // this is supposed to be TAG_PREFERRED_BACKUP 17121 if (!expectedStartTag.equals(parser.getName())) { 17122 if (DEBUG_BACKUP) { 17123 Slog.e(TAG, "Found unexpected tag " + parser.getName()); 17124 } 17125 return; 17126 } 17127 17128 // skip interfering stuff, then we're aligned with the backing implementation 17129 while ((type = parser.next()) == XmlPullParser.TEXT) { } 17130Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); 17131 functor.apply(parser, userId); 17132 } 17133 17134 private interface BlobXmlRestorer { 17135 public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException; 17136 } 17137 17138 /** 17139 * Non-Binder method, support for the backup/restore mechanism: write the 17140 * full set of preferred activities in its canonical XML format. Returns the 17141 * XML output as a byte array, or null if there is none. 17142 */ 17143 @Override 17144 public byte[] getPreferredActivityBackup(int userId) { 17145 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17146 throw new SecurityException("Only the system may call getPreferredActivityBackup()"); 17147 } 17148 17149 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 17150 try { 17151 final XmlSerializer serializer = new FastXmlSerializer(); 17152 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 17153 serializer.startDocument(null, true); 17154 serializer.startTag(null, TAG_PREFERRED_BACKUP); 17155 17156 synchronized (mPackages) { 17157 mSettings.writePreferredActivitiesLPr(serializer, userId, true); 17158 } 17159 17160 serializer.endTag(null, TAG_PREFERRED_BACKUP); 17161 serializer.endDocument(); 17162 serializer.flush(); 17163 } catch (Exception e) { 17164 if (DEBUG_BACKUP) { 17165 Slog.e(TAG, "Unable to write preferred activities for backup", e); 17166 } 17167 return null; 17168 } 17169 17170 return dataStream.toByteArray(); 17171 } 17172 17173 @Override 17174 public void restorePreferredActivities(byte[] backup, int userId) { 17175 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17176 throw new SecurityException("Only the system may call restorePreferredActivities()"); 17177 } 17178 17179 try { 17180 final XmlPullParser parser = Xml.newPullParser(); 17181 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 17182 restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP, 17183 new BlobXmlRestorer() { 17184 @Override 17185 public void apply(XmlPullParser parser, int userId) 17186 throws XmlPullParserException, IOException { 17187 synchronized (mPackages) { 17188 mSettings.readPreferredActivitiesLPw(parser, userId); 17189 } 17190 } 17191 } ); 17192 } catch (Exception e) { 17193 if (DEBUG_BACKUP) { 17194 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 17195 } 17196 } 17197 } 17198 17199 /** 17200 * Non-Binder method, support for the backup/restore mechanism: write the 17201 * default browser (etc) settings in its canonical XML format. Returns the default 17202 * browser XML representation as a byte array, or null if there is none. 17203 */ 17204 @Override 17205 public byte[] getDefaultAppsBackup(int userId) { 17206 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17207 throw new SecurityException("Only the system may call getDefaultAppsBackup()"); 17208 } 17209 17210 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 17211 try { 17212 final XmlSerializer serializer = new FastXmlSerializer(); 17213 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 17214 serializer.startDocument(null, true); 17215 serializer.startTag(null, TAG_DEFAULT_APPS); 17216 17217 synchronized (mPackages) { 17218 mSettings.writeDefaultAppsLPr(serializer, userId); 17219 } 17220 17221 serializer.endTag(null, TAG_DEFAULT_APPS); 17222 serializer.endDocument(); 17223 serializer.flush(); 17224 } catch (Exception e) { 17225 if (DEBUG_BACKUP) { 17226 Slog.e(TAG, "Unable to write default apps for backup", e); 17227 } 17228 return null; 17229 } 17230 17231 return dataStream.toByteArray(); 17232 } 17233 17234 @Override 17235 public void restoreDefaultApps(byte[] backup, int userId) { 17236 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17237 throw new SecurityException("Only the system may call restoreDefaultApps()"); 17238 } 17239 17240 try { 17241 final XmlPullParser parser = Xml.newPullParser(); 17242 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 17243 restoreFromXml(parser, userId, TAG_DEFAULT_APPS, 17244 new BlobXmlRestorer() { 17245 @Override 17246 public void apply(XmlPullParser parser, int userId) 17247 throws XmlPullParserException, IOException { 17248 synchronized (mPackages) { 17249 mSettings.readDefaultAppsLPw(parser, userId); 17250 } 17251 } 17252 } ); 17253 } catch (Exception e) { 17254 if (DEBUG_BACKUP) { 17255 Slog.e(TAG, "Exception restoring default apps: " + e.getMessage()); 17256 } 17257 } 17258 } 17259 17260 @Override 17261 public byte[] getIntentFilterVerificationBackup(int userId) { 17262 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17263 throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()"); 17264 } 17265 17266 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 17267 try { 17268 final XmlSerializer serializer = new FastXmlSerializer(); 17269 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 17270 serializer.startDocument(null, true); 17271 serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION); 17272 17273 synchronized (mPackages) { 17274 mSettings.writeAllDomainVerificationsLPr(serializer, userId); 17275 } 17276 17277 serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION); 17278 serializer.endDocument(); 17279 serializer.flush(); 17280 } catch (Exception e) { 17281 if (DEBUG_BACKUP) { 17282 Slog.e(TAG, "Unable to write default apps for backup", e); 17283 } 17284 return null; 17285 } 17286 17287 return dataStream.toByteArray(); 17288 } 17289 17290 @Override 17291 public void restoreIntentFilterVerification(byte[] backup, int userId) { 17292 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17293 throw new SecurityException("Only the system may call restorePreferredActivities()"); 17294 } 17295 17296 try { 17297 final XmlPullParser parser = Xml.newPullParser(); 17298 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 17299 restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION, 17300 new BlobXmlRestorer() { 17301 @Override 17302 public void apply(XmlPullParser parser, int userId) 17303 throws XmlPullParserException, IOException { 17304 synchronized (mPackages) { 17305 mSettings.readAllDomainVerificationsLPr(parser, userId); 17306 mSettings.writeLPr(); 17307 } 17308 } 17309 } ); 17310 } catch (Exception e) { 17311 if (DEBUG_BACKUP) { 17312 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 17313 } 17314 } 17315 } 17316 17317 @Override 17318 public byte[] getPermissionGrantBackup(int userId) { 17319 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17320 throw new SecurityException("Only the system may call getPermissionGrantBackup()"); 17321 } 17322 17323 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 17324 try { 17325 final XmlSerializer serializer = new FastXmlSerializer(); 17326 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 17327 serializer.startDocument(null, true); 17328 serializer.startTag(null, TAG_PERMISSION_BACKUP); 17329 17330 synchronized (mPackages) { 17331 serializeRuntimePermissionGrantsLPr(serializer, userId); 17332 } 17333 17334 serializer.endTag(null, TAG_PERMISSION_BACKUP); 17335 serializer.endDocument(); 17336 serializer.flush(); 17337 } catch (Exception e) { 17338 if (DEBUG_BACKUP) { 17339 Slog.e(TAG, "Unable to write default apps for backup", e); 17340 } 17341 return null; 17342 } 17343 17344 return dataStream.toByteArray(); 17345 } 17346 17347 @Override 17348 public void restorePermissionGrants(byte[] backup, int userId) { 17349 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17350 throw new SecurityException("Only the system may call restorePermissionGrants()"); 17351 } 17352 17353 try { 17354 final XmlPullParser parser = Xml.newPullParser(); 17355 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 17356 restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP, 17357 new BlobXmlRestorer() { 17358 @Override 17359 public void apply(XmlPullParser parser, int userId) 17360 throws XmlPullParserException, IOException { 17361 synchronized (mPackages) { 17362 processRestoredPermissionGrantsLPr(parser, userId); 17363 } 17364 } 17365 } ); 17366 } catch (Exception e) { 17367 if (DEBUG_BACKUP) { 17368 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 17369 } 17370 } 17371 } 17372 17373 private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId) 17374 throws IOException { 17375 serializer.startTag(null, TAG_ALL_GRANTS); 17376 17377 final int N = mSettings.mPackages.size(); 17378 for (int i = 0; i < N; i++) { 17379 final PackageSetting ps = mSettings.mPackages.valueAt(i); 17380 boolean pkgGrantsKnown = false; 17381 17382 PermissionsState packagePerms = ps.getPermissionsState(); 17383 17384 for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) { 17385 final int grantFlags = state.getFlags(); 17386 // only look at grants that are not system/policy fixed 17387 if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) { 17388 final boolean isGranted = state.isGranted(); 17389 // And only back up the user-twiddled state bits 17390 if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) { 17391 final String packageName = mSettings.mPackages.keyAt(i); 17392 if (!pkgGrantsKnown) { 17393 serializer.startTag(null, TAG_GRANT); 17394 serializer.attribute(null, ATTR_PACKAGE_NAME, packageName); 17395 pkgGrantsKnown = true; 17396 } 17397 17398 final boolean userSet = 17399 (grantFlags & FLAG_PERMISSION_USER_SET) != 0; 17400 final boolean userFixed = 17401 (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0; 17402 final boolean revoke = 17403 (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0; 17404 17405 serializer.startTag(null, TAG_PERMISSION); 17406 serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName()); 17407 if (isGranted) { 17408 serializer.attribute(null, ATTR_IS_GRANTED, "true"); 17409 } 17410 if (userSet) { 17411 serializer.attribute(null, ATTR_USER_SET, "true"); 17412 } 17413 if (userFixed) { 17414 serializer.attribute(null, ATTR_USER_FIXED, "true"); 17415 } 17416 if (revoke) { 17417 serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true"); 17418 } 17419 serializer.endTag(null, TAG_PERMISSION); 17420 } 17421 } 17422 } 17423 17424 if (pkgGrantsKnown) { 17425 serializer.endTag(null, TAG_GRANT); 17426 } 17427 } 17428 17429 serializer.endTag(null, TAG_ALL_GRANTS); 17430 } 17431 17432 private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId) 17433 throws XmlPullParserException, IOException { 17434 String pkgName = null; 17435 int outerDepth = parser.getDepth(); 17436 int type; 17437 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 17438 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 17439 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 17440 continue; 17441 } 17442 17443 final String tagName = parser.getName(); 17444 if (tagName.equals(TAG_GRANT)) { 17445 pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME); 17446 if (DEBUG_BACKUP) { 17447 Slog.v(TAG, "+++ Restoring grants for package " + pkgName); 17448 } 17449 } else if (tagName.equals(TAG_PERMISSION)) { 17450 17451 final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED)); 17452 final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME); 17453 17454 int newFlagSet = 0; 17455 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) { 17456 newFlagSet |= FLAG_PERMISSION_USER_SET; 17457 } 17458 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) { 17459 newFlagSet |= FLAG_PERMISSION_USER_FIXED; 17460 } 17461 if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) { 17462 newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE; 17463 } 17464 if (DEBUG_BACKUP) { 17465 Slog.v(TAG, " + Restoring grant: pkg=" + pkgName + " perm=" + permName 17466 + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet)); 17467 } 17468 final PackageSetting ps = mSettings.mPackages.get(pkgName); 17469 if (ps != null) { 17470 // Already installed so we apply the grant immediately 17471 if (DEBUG_BACKUP) { 17472 Slog.v(TAG, " + already installed; applying"); 17473 } 17474 PermissionsState perms = ps.getPermissionsState(); 17475 BasePermission bp = mSettings.mPermissions.get(permName); 17476 if (bp != null) { 17477 if (isGranted) { 17478 perms.grantRuntimePermission(bp, userId); 17479 } 17480 if (newFlagSet != 0) { 17481 perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet); 17482 } 17483 } 17484 } else { 17485 // Need to wait for post-restore install to apply the grant 17486 if (DEBUG_BACKUP) { 17487 Slog.v(TAG, " - not yet installed; saving for later"); 17488 } 17489 mSettings.processRestoredPermissionGrantLPr(pkgName, permName, 17490 isGranted, newFlagSet, userId); 17491 } 17492 } else { 17493 PackageManagerService.reportSettingsProblem(Log.WARN, 17494 "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName); 17495 XmlUtils.skipCurrentTag(parser); 17496 } 17497 } 17498 17499 scheduleWriteSettingsLocked(); 17500 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 17501 } 17502 17503 @Override 17504 public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage, 17505 int sourceUserId, int targetUserId, int flags) { 17506 mContext.enforceCallingOrSelfPermission( 17507 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 17508 int callingUid = Binder.getCallingUid(); 17509 enforceOwnerRights(ownerPackage, callingUid); 17510 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 17511 if (intentFilter.countActions() == 0) { 17512 Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions"); 17513 return; 17514 } 17515 synchronized (mPackages) { 17516 CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter, 17517 ownerPackage, targetUserId, flags); 17518 CrossProfileIntentResolver resolver = 17519 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 17520 ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter); 17521 // We have all those whose filter is equal. Now checking if the rest is equal as well. 17522 if (existing != null) { 17523 int size = existing.size(); 17524 for (int i = 0; i < size; i++) { 17525 if (newFilter.equalsIgnoreFilter(existing.get(i))) { 17526 return; 17527 } 17528 } 17529 } 17530 resolver.addFilter(newFilter); 17531 scheduleWritePackageRestrictionsLocked(sourceUserId); 17532 } 17533 } 17534 17535 @Override 17536 public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) { 17537 mContext.enforceCallingOrSelfPermission( 17538 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 17539 int callingUid = Binder.getCallingUid(); 17540 enforceOwnerRights(ownerPackage, callingUid); 17541 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 17542 synchronized (mPackages) { 17543 CrossProfileIntentResolver resolver = 17544 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 17545 ArraySet<CrossProfileIntentFilter> set = 17546 new ArraySet<CrossProfileIntentFilter>(resolver.filterSet()); 17547 for (CrossProfileIntentFilter filter : set) { 17548 if (filter.getOwnerPackage().equals(ownerPackage)) { 17549 resolver.removeFilter(filter); 17550 } 17551 } 17552 scheduleWritePackageRestrictionsLocked(sourceUserId); 17553 } 17554 } 17555 17556 // Enforcing that callingUid is owning pkg on userId 17557 private void enforceOwnerRights(String pkg, int callingUid) { 17558 // The system owns everything. 17559 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) { 17560 return; 17561 } 17562 int callingUserId = UserHandle.getUserId(callingUid); 17563 PackageInfo pi = getPackageInfo(pkg, 0, callingUserId); 17564 if (pi == null) { 17565 throw new IllegalArgumentException("Unknown package " + pkg + " on user " 17566 + callingUserId); 17567 } 17568 if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) { 17569 throw new SecurityException("Calling uid " + callingUid 17570 + " does not own package " + pkg); 17571 } 17572 } 17573 17574 @Override 17575 public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) { 17576 return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId()); 17577 } 17578 17579 private Intent getHomeIntent() { 17580 Intent intent = new Intent(Intent.ACTION_MAIN); 17581 intent.addCategory(Intent.CATEGORY_HOME); 17582 intent.addCategory(Intent.CATEGORY_DEFAULT); 17583 return intent; 17584 } 17585 17586 private IntentFilter getHomeFilter() { 17587 IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN); 17588 filter.addCategory(Intent.CATEGORY_HOME); 17589 filter.addCategory(Intent.CATEGORY_DEFAULT); 17590 return filter; 17591 } 17592 17593 ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, 17594 int userId) { 17595 Intent intent = getHomeIntent(); 17596 List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null, 17597 PackageManager.GET_META_DATA, userId); 17598 ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0, 17599 true, false, false, userId); 17600 17601 allHomeCandidates.clear(); 17602 if (list != null) { 17603 for (ResolveInfo ri : list) { 17604 allHomeCandidates.add(ri); 17605 } 17606 } 17607 return (preferred == null || preferred.activityInfo == null) 17608 ? null 17609 : new ComponentName(preferred.activityInfo.packageName, 17610 preferred.activityInfo.name); 17611 } 17612 17613 @Override 17614 public void setHomeActivity(ComponentName comp, int userId) { 17615 ArrayList<ResolveInfo> homeActivities = new ArrayList<>(); 17616 getHomeActivitiesAsUser(homeActivities, userId); 17617 17618 boolean found = false; 17619 17620 final int size = homeActivities.size(); 17621 final ComponentName[] set = new ComponentName[size]; 17622 for (int i = 0; i < size; i++) { 17623 final ResolveInfo candidate = homeActivities.get(i); 17624 final ActivityInfo info = candidate.activityInfo; 17625 final ComponentName activityName = new ComponentName(info.packageName, info.name); 17626 set[i] = activityName; 17627 if (!found && activityName.equals(comp)) { 17628 found = true; 17629 } 17630 } 17631 if (!found) { 17632 throw new IllegalArgumentException("Component " + comp + " cannot be home on user " 17633 + userId); 17634 } 17635 replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY, 17636 set, comp, userId); 17637 } 17638 17639 private @Nullable String getSetupWizardPackageName() { 17640 final Intent intent = new Intent(Intent.ACTION_MAIN); 17641 intent.addCategory(Intent.CATEGORY_SETUP_WIZARD); 17642 17643 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, 17644 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE 17645 | MATCH_DISABLED_COMPONENTS, 17646 UserHandle.myUserId()); 17647 if (matches.size() == 1) { 17648 return matches.get(0).getComponentInfo().packageName; 17649 } else { 17650 Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size() 17651 + ": matches=" + matches); 17652 return null; 17653 } 17654 } 17655 17656 @Override 17657 public void setApplicationEnabledSetting(String appPackageName, 17658 int newState, int flags, int userId, String callingPackage) { 17659 if (!sUserManager.exists(userId)) return; 17660 if (callingPackage == null) { 17661 callingPackage = Integer.toString(Binder.getCallingUid()); 17662 } 17663 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage); 17664 } 17665 17666 @Override 17667 public void setComponentEnabledSetting(ComponentName componentName, 17668 int newState, int flags, int userId) { 17669 if (!sUserManager.exists(userId)) return; 17670 setEnabledSetting(componentName.getPackageName(), 17671 componentName.getClassName(), newState, flags, userId, null); 17672 } 17673 17674 private void setEnabledSetting(final String packageName, String className, int newState, 17675 final int flags, int userId, String callingPackage) { 17676 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT 17677 || newState == COMPONENT_ENABLED_STATE_ENABLED 17678 || newState == COMPONENT_ENABLED_STATE_DISABLED 17679 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER 17680 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) { 17681 throw new IllegalArgumentException("Invalid new component state: " 17682 + newState); 17683 } 17684 PackageSetting pkgSetting; 17685 final int uid = Binder.getCallingUid(); 17686 final int permission; 17687 if (uid == Process.SYSTEM_UID) { 17688 permission = PackageManager.PERMISSION_GRANTED; 17689 } else { 17690 permission = mContext.checkCallingOrSelfPermission( 17691 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 17692 } 17693 enforceCrossUserPermission(uid, userId, 17694 false /* requireFullPermission */, true /* checkShell */, "set enabled"); 17695 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 17696 boolean sendNow = false; 17697 boolean isApp = (className == null); 17698 String componentName = isApp ? packageName : className; 17699 int packageUid = -1; 17700 ArrayList<String> components; 17701 17702 // writer 17703 synchronized (mPackages) { 17704 pkgSetting = mSettings.mPackages.get(packageName); 17705 if (pkgSetting == null) { 17706 if (className == null) { 17707 throw new IllegalArgumentException("Unknown package: " + packageName); 17708 } 17709 throw new IllegalArgumentException( 17710 "Unknown component: " + packageName + "/" + className); 17711 } 17712 } 17713 17714 // Limit who can change which apps 17715 if (!UserHandle.isSameApp(uid, pkgSetting.appId)) { 17716 // Don't allow apps that don't have permission to modify other apps 17717 if (!allowedByPermission) { 17718 throw new SecurityException( 17719 "Permission Denial: attempt to change component state from pid=" 17720 + Binder.getCallingPid() 17721 + ", uid=" + uid + ", package uid=" + pkgSetting.appId); 17722 } 17723 // Don't allow changing protected packages. 17724 if (mProtectedPackages.isPackageStateProtected(userId, packageName)) { 17725 throw new SecurityException("Cannot disable a protected package: " + packageName); 17726 } 17727 } 17728 17729 synchronized (mPackages) { 17730 if (uid == Process.SHELL_UID) { 17731 // Shell can only change whole packages between ENABLED and DISABLED_USER states 17732 int oldState = pkgSetting.getEnabled(userId); 17733 if (className == null 17734 && 17735 (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER 17736 || oldState == COMPONENT_ENABLED_STATE_DEFAULT 17737 || oldState == COMPONENT_ENABLED_STATE_ENABLED) 17738 && 17739 (newState == COMPONENT_ENABLED_STATE_DISABLED_USER 17740 || newState == COMPONENT_ENABLED_STATE_DEFAULT 17741 || newState == COMPONENT_ENABLED_STATE_ENABLED)) { 17742 // ok 17743 } else { 17744 throw new SecurityException( 17745 "Shell cannot change component state for " + packageName + "/" 17746 + className + " to " + newState); 17747 } 17748 } 17749 if (className == null) { 17750 // We're dealing with an application/package level state change 17751 if (pkgSetting.getEnabled(userId) == newState) { 17752 // Nothing to do 17753 return; 17754 } 17755 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT 17756 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { 17757 // Don't care about who enables an app. 17758 callingPackage = null; 17759 } 17760 pkgSetting.setEnabled(newState, userId, callingPackage); 17761 // pkgSetting.pkg.mSetEnabled = newState; 17762 } else { 17763 // We're dealing with a component level state change 17764 // First, verify that this is a valid class name. 17765 PackageParser.Package pkg = pkgSetting.pkg; 17766 if (pkg == null || !pkg.hasComponentClassName(className)) { 17767 if (pkg != null && 17768 pkg.applicationInfo.targetSdkVersion >= 17769 Build.VERSION_CODES.JELLY_BEAN) { 17770 throw new IllegalArgumentException("Component class " + className 17771 + " does not exist in " + packageName); 17772 } else { 17773 Slog.w(TAG, "Failed setComponentEnabledSetting: component class " 17774 + className + " does not exist in " + packageName); 17775 } 17776 } 17777 switch (newState) { 17778 case COMPONENT_ENABLED_STATE_ENABLED: 17779 if (!pkgSetting.enableComponentLPw(className, userId)) { 17780 return; 17781 } 17782 break; 17783 case COMPONENT_ENABLED_STATE_DISABLED: 17784 if (!pkgSetting.disableComponentLPw(className, userId)) { 17785 return; 17786 } 17787 break; 17788 case COMPONENT_ENABLED_STATE_DEFAULT: 17789 if (!pkgSetting.restoreComponentLPw(className, userId)) { 17790 return; 17791 } 17792 break; 17793 default: 17794 Slog.e(TAG, "Invalid new component state: " + newState); 17795 return; 17796 } 17797 } 17798 scheduleWritePackageRestrictionsLocked(userId); 17799 components = mPendingBroadcasts.get(userId, packageName); 17800 final boolean newPackage = components == null; 17801 if (newPackage) { 17802 components = new ArrayList<String>(); 17803 } 17804 if (!components.contains(componentName)) { 17805 components.add(componentName); 17806 } 17807 if ((flags&PackageManager.DONT_KILL_APP) == 0) { 17808 sendNow = true; 17809 // Purge entry from pending broadcast list if another one exists already 17810 // since we are sending one right away. 17811 mPendingBroadcasts.remove(userId, packageName); 17812 } else { 17813 if (newPackage) { 17814 mPendingBroadcasts.put(userId, packageName, components); 17815 } 17816 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) { 17817 // Schedule a message 17818 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY); 17819 } 17820 } 17821 } 17822 17823 long callingId = Binder.clearCallingIdentity(); 17824 try { 17825 if (sendNow) { 17826 packageUid = UserHandle.getUid(userId, pkgSetting.appId); 17827 sendPackageChangedBroadcast(packageName, 17828 (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid); 17829 } 17830 } finally { 17831 Binder.restoreCallingIdentity(callingId); 17832 } 17833 } 17834 17835 @Override 17836 public void flushPackageRestrictionsAsUser(int userId) { 17837 if (!sUserManager.exists(userId)) { 17838 return; 17839 } 17840 enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/, 17841 false /* checkShell */, "flushPackageRestrictions"); 17842 synchronized (mPackages) { 17843 mSettings.writePackageRestrictionsLPr(userId); 17844 mDirtyUsers.remove(userId); 17845 if (mDirtyUsers.isEmpty()) { 17846 mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS); 17847 } 17848 } 17849 } 17850 17851 private void sendPackageChangedBroadcast(String packageName, 17852 boolean killFlag, ArrayList<String> componentNames, int packageUid) { 17853 if (DEBUG_INSTALL) 17854 Log.v(TAG, "Sending package changed: package=" + packageName + " components=" 17855 + componentNames); 17856 Bundle extras = new Bundle(4); 17857 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0)); 17858 String nameList[] = new String[componentNames.size()]; 17859 componentNames.toArray(nameList); 17860 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList); 17861 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag); 17862 extras.putInt(Intent.EXTRA_UID, packageUid); 17863 // If this is not reporting a change of the overall package, then only send it 17864 // to registered receivers. We don't want to launch a swath of apps for every 17865 // little component state change. 17866 final int flags = !componentNames.contains(packageName) 17867 ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0; 17868 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, flags, null, null, 17869 new int[] {UserHandle.getUserId(packageUid)}); 17870 } 17871 17872 @Override 17873 public void setPackageStoppedState(String packageName, boolean stopped, int userId) { 17874 if (!sUserManager.exists(userId)) return; 17875 final int uid = Binder.getCallingUid(); 17876 final int permission = mContext.checkCallingOrSelfPermission( 17877 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 17878 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 17879 enforceCrossUserPermission(uid, userId, 17880 true /* requireFullPermission */, true /* checkShell */, "stop package"); 17881 // writer 17882 synchronized (mPackages) { 17883 if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped, 17884 allowedByPermission, uid, userId)) { 17885 scheduleWritePackageRestrictionsLocked(userId); 17886 } 17887 } 17888 } 17889 17890 @Override 17891 public String getInstallerPackageName(String packageName) { 17892 // reader 17893 synchronized (mPackages) { 17894 return mSettings.getInstallerPackageNameLPr(packageName); 17895 } 17896 } 17897 17898 public boolean isOrphaned(String packageName) { 17899 // reader 17900 synchronized (mPackages) { 17901 return mSettings.isOrphaned(packageName); 17902 } 17903 } 17904 17905 @Override 17906 public int getApplicationEnabledSetting(String packageName, int userId) { 17907 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 17908 int uid = Binder.getCallingUid(); 17909 enforceCrossUserPermission(uid, userId, 17910 false /* requireFullPermission */, false /* checkShell */, "get enabled"); 17911 // reader 17912 synchronized (mPackages) { 17913 return mSettings.getApplicationEnabledSettingLPr(packageName, userId); 17914 } 17915 } 17916 17917 @Override 17918 public int getComponentEnabledSetting(ComponentName componentName, int userId) { 17919 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 17920 int uid = Binder.getCallingUid(); 17921 enforceCrossUserPermission(uid, userId, 17922 false /* requireFullPermission */, false /* checkShell */, "get component enabled"); 17923 // reader 17924 synchronized (mPackages) { 17925 return mSettings.getComponentEnabledSettingLPr(componentName, userId); 17926 } 17927 } 17928 17929 @Override 17930 public void enterSafeMode() { 17931 enforceSystemOrRoot("Only the system can request entering safe mode"); 17932 17933 if (!mSystemReady) { 17934 mSafeMode = true; 17935 } 17936 } 17937 17938 @Override 17939 public void systemReady() { 17940 mSystemReady = true; 17941 17942 // Disable any carrier apps. We do this very early in boot to prevent the apps from being 17943 // disabled after already being started. 17944 CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this, 17945 mContext.getContentResolver(), UserHandle.USER_SYSTEM); 17946 17947 // Read the compatibilty setting when the system is ready. 17948 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt( 17949 mContext.getContentResolver(), 17950 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1; 17951 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled); 17952 if (DEBUG_SETTINGS) { 17953 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled); 17954 } 17955 17956 int[] grantPermissionsUserIds = EMPTY_INT_ARRAY; 17957 17958 synchronized (mPackages) { 17959 // Verify that all of the preferred activity components actually 17960 // exist. It is possible for applications to be updated and at 17961 // that point remove a previously declared activity component that 17962 // had been set as a preferred activity. We try to clean this up 17963 // the next time we encounter that preferred activity, but it is 17964 // possible for the user flow to never be able to return to that 17965 // situation so here we do a sanity check to make sure we haven't 17966 // left any junk around. 17967 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>(); 17968 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 17969 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 17970 removed.clear(); 17971 for (PreferredActivity pa : pir.filterSet()) { 17972 if (mActivities.mActivities.get(pa.mPref.mComponent) == null) { 17973 removed.add(pa); 17974 } 17975 } 17976 if (removed.size() > 0) { 17977 for (int r=0; r<removed.size(); r++) { 17978 PreferredActivity pa = removed.get(r); 17979 Slog.w(TAG, "Removing dangling preferred activity: " 17980 + pa.mPref.mComponent); 17981 pir.removeFilter(pa); 17982 } 17983 mSettings.writePackageRestrictionsLPr( 17984 mSettings.mPreferredActivities.keyAt(i)); 17985 } 17986 } 17987 17988 for (int userId : UserManagerService.getInstance().getUserIds()) { 17989 if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) { 17990 grantPermissionsUserIds = ArrayUtils.appendInt( 17991 grantPermissionsUserIds, userId); 17992 } 17993 } 17994 } 17995 sUserManager.systemReady(); 17996 17997 // If we upgraded grant all default permissions before kicking off. 17998 for (int userId : grantPermissionsUserIds) { 17999 mDefaultPermissionPolicy.grantDefaultPermissions(userId); 18000 } 18001 18002 // Kick off any messages waiting for system ready 18003 if (mPostSystemReadyMessages != null) { 18004 for (Message msg : mPostSystemReadyMessages) { 18005 msg.sendToTarget(); 18006 } 18007 mPostSystemReadyMessages = null; 18008 } 18009 18010 // Watch for external volumes that come and go over time 18011 final StorageManager storage = mContext.getSystemService(StorageManager.class); 18012 storage.registerListener(mStorageListener); 18013 18014 mInstallerService.systemReady(); 18015 mPackageDexOptimizer.systemReady(); 18016 18017 MountServiceInternal mountServiceInternal = LocalServices.getService( 18018 MountServiceInternal.class); 18019 mountServiceInternal.addExternalStoragePolicy( 18020 new MountServiceInternal.ExternalStorageMountPolicy() { 18021 @Override 18022 public int getMountMode(int uid, String packageName) { 18023 if (Process.isIsolated(uid)) { 18024 return Zygote.MOUNT_EXTERNAL_NONE; 18025 } 18026 if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) { 18027 return Zygote.MOUNT_EXTERNAL_DEFAULT; 18028 } 18029 if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { 18030 return Zygote.MOUNT_EXTERNAL_DEFAULT; 18031 } 18032 if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { 18033 return Zygote.MOUNT_EXTERNAL_READ; 18034 } 18035 return Zygote.MOUNT_EXTERNAL_WRITE; 18036 } 18037 18038 @Override 18039 public boolean hasExternalStorage(int uid, String packageName) { 18040 return true; 18041 } 18042 }); 18043 18044 // Now that we're mostly running, clean up stale users and apps 18045 reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL); 18046 reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL); 18047 } 18048 18049 @Override 18050 public boolean isSafeMode() { 18051 return mSafeMode; 18052 } 18053 18054 @Override 18055 public boolean hasSystemUidErrors() { 18056 return mHasSystemUidErrors; 18057 } 18058 18059 static String arrayToString(int[] array) { 18060 StringBuffer buf = new StringBuffer(128); 18061 buf.append('['); 18062 if (array != null) { 18063 for (int i=0; i<array.length; i++) { 18064 if (i > 0) buf.append(", "); 18065 buf.append(array[i]); 18066 } 18067 } 18068 buf.append(']'); 18069 return buf.toString(); 18070 } 18071 18072 static class DumpState { 18073 public static final int DUMP_LIBS = 1 << 0; 18074 public static final int DUMP_FEATURES = 1 << 1; 18075 public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2; 18076 public static final int DUMP_SERVICE_RESOLVERS = 1 << 3; 18077 public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4; 18078 public static final int DUMP_CONTENT_RESOLVERS = 1 << 5; 18079 public static final int DUMP_PERMISSIONS = 1 << 6; 18080 public static final int DUMP_PACKAGES = 1 << 7; 18081 public static final int DUMP_SHARED_USERS = 1 << 8; 18082 public static final int DUMP_MESSAGES = 1 << 9; 18083 public static final int DUMP_PROVIDERS = 1 << 10; 18084 public static final int DUMP_VERIFIERS = 1 << 11; 18085 public static final int DUMP_PREFERRED = 1 << 12; 18086 public static final int DUMP_PREFERRED_XML = 1 << 13; 18087 public static final int DUMP_KEYSETS = 1 << 14; 18088 public static final int DUMP_VERSION = 1 << 15; 18089 public static final int DUMP_INSTALLS = 1 << 16; 18090 public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17; 18091 public static final int DUMP_DOMAIN_PREFERRED = 1 << 18; 18092 public static final int DUMP_FROZEN = 1 << 19; 18093 public static final int DUMP_DEXOPT = 1 << 20; 18094 public static final int DUMP_COMPILER_STATS = 1 << 21; 18095 18096 public static final int OPTION_SHOW_FILTERS = 1 << 0; 18097 18098 private int mTypes; 18099 18100 private int mOptions; 18101 18102 private boolean mTitlePrinted; 18103 18104 private SharedUserSetting mSharedUser; 18105 18106 public boolean isDumping(int type) { 18107 if (mTypes == 0 && type != DUMP_PREFERRED_XML) { 18108 return true; 18109 } 18110 18111 return (mTypes & type) != 0; 18112 } 18113 18114 public void setDump(int type) { 18115 mTypes |= type; 18116 } 18117 18118 public boolean isOptionEnabled(int option) { 18119 return (mOptions & option) != 0; 18120 } 18121 18122 public void setOptionEnabled(int option) { 18123 mOptions |= option; 18124 } 18125 18126 public boolean onTitlePrinted() { 18127 final boolean printed = mTitlePrinted; 18128 mTitlePrinted = true; 18129 return printed; 18130 } 18131 18132 public boolean getTitlePrinted() { 18133 return mTitlePrinted; 18134 } 18135 18136 public void setTitlePrinted(boolean enabled) { 18137 mTitlePrinted = enabled; 18138 } 18139 18140 public SharedUserSetting getSharedUser() { 18141 return mSharedUser; 18142 } 18143 18144 public void setSharedUser(SharedUserSetting user) { 18145 mSharedUser = user; 18146 } 18147 } 18148 18149 @Override 18150 public void onShellCommand(FileDescriptor in, FileDescriptor out, 18151 FileDescriptor err, String[] args, ResultReceiver resultReceiver) { 18152 (new PackageManagerShellCommand(this)).exec( 18153 this, in, out, err, args, resultReceiver); 18154 } 18155 18156 @Override 18157 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 18158 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 18159 != PackageManager.PERMISSION_GRANTED) { 18160 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 18161 + Binder.getCallingPid() 18162 + ", uid=" + Binder.getCallingUid() 18163 + " without permission " 18164 + android.Manifest.permission.DUMP); 18165 return; 18166 } 18167 18168 DumpState dumpState = new DumpState(); 18169 boolean fullPreferred = false; 18170 boolean checkin = false; 18171 18172 String packageName = null; 18173 ArraySet<String> permissionNames = null; 18174 18175 int opti = 0; 18176 while (opti < args.length) { 18177 String opt = args[opti]; 18178 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 18179 break; 18180 } 18181 opti++; 18182 18183 if ("-a".equals(opt)) { 18184 // Right now we only know how to print all. 18185 } else if ("-h".equals(opt)) { 18186 pw.println("Package manager dump options:"); 18187 pw.println(" [-h] [-f] [--checkin] [cmd] ..."); 18188 pw.println(" --checkin: dump for a checkin"); 18189 pw.println(" -f: print details of intent filters"); 18190 pw.println(" -h: print this help"); 18191 pw.println(" cmd may be one of:"); 18192 pw.println(" l[ibraries]: list known shared libraries"); 18193 pw.println(" f[eatures]: list device features"); 18194 pw.println(" k[eysets]: print known keysets"); 18195 pw.println(" r[esolvers] [activity|service|receiver|content]: dump intent resolvers"); 18196 pw.println(" perm[issions]: dump permissions"); 18197 pw.println(" permission [name ...]: dump declaration and use of given permission"); 18198 pw.println(" pref[erred]: print preferred package settings"); 18199 pw.println(" preferred-xml [--full]: print preferred package settings as xml"); 18200 pw.println(" prov[iders]: dump content providers"); 18201 pw.println(" p[ackages]: dump installed packages"); 18202 pw.println(" s[hared-users]: dump shared user IDs"); 18203 pw.println(" m[essages]: print collected runtime messages"); 18204 pw.println(" v[erifiers]: print package verifier info"); 18205 pw.println(" d[omain-preferred-apps]: print domains preferred apps"); 18206 pw.println(" i[ntent-filter-verifiers]|ifv: print intent filter verifier info"); 18207 pw.println(" version: print database version info"); 18208 pw.println(" write: write current settings now"); 18209 pw.println(" installs: details about install sessions"); 18210 pw.println(" check-permission <permission> <package> [<user>]: does pkg hold perm?"); 18211 pw.println(" dexopt: dump dexopt state"); 18212 pw.println(" compiler-stats: dump compiler statistics"); 18213 pw.println(" <package.name>: info about given package"); 18214 return; 18215 } else if ("--checkin".equals(opt)) { 18216 checkin = true; 18217 } else if ("-f".equals(opt)) { 18218 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 18219 } else { 18220 pw.println("Unknown argument: " + opt + "; use -h for help"); 18221 } 18222 } 18223 18224 // Is the caller requesting to dump a particular piece of data? 18225 if (opti < args.length) { 18226 String cmd = args[opti]; 18227 opti++; 18228 // Is this a package name? 18229 if ("android".equals(cmd) || cmd.contains(".")) { 18230 packageName = cmd; 18231 // When dumping a single package, we always dump all of its 18232 // filter information since the amount of data will be reasonable. 18233 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 18234 } else if ("check-permission".equals(cmd)) { 18235 if (opti >= args.length) { 18236 pw.println("Error: check-permission missing permission argument"); 18237 return; 18238 } 18239 String perm = args[opti]; 18240 opti++; 18241 if (opti >= args.length) { 18242 pw.println("Error: check-permission missing package argument"); 18243 return; 18244 } 18245 String pkg = args[opti]; 18246 opti++; 18247 int user = UserHandle.getUserId(Binder.getCallingUid()); 18248 if (opti < args.length) { 18249 try { 18250 user = Integer.parseInt(args[opti]); 18251 } catch (NumberFormatException e) { 18252 pw.println("Error: check-permission user argument is not a number: " 18253 + args[opti]); 18254 return; 18255 } 18256 } 18257 pw.println(checkPermission(perm, pkg, user)); 18258 return; 18259 } else if ("l".equals(cmd) || "libraries".equals(cmd)) { 18260 dumpState.setDump(DumpState.DUMP_LIBS); 18261 } else if ("f".equals(cmd) || "features".equals(cmd)) { 18262 dumpState.setDump(DumpState.DUMP_FEATURES); 18263 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) { 18264 if (opti >= args.length) { 18265 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS 18266 | DumpState.DUMP_SERVICE_RESOLVERS 18267 | DumpState.DUMP_RECEIVER_RESOLVERS 18268 | DumpState.DUMP_CONTENT_RESOLVERS); 18269 } else { 18270 while (opti < args.length) { 18271 String name = args[opti]; 18272 if ("a".equals(name) || "activity".equals(name)) { 18273 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS); 18274 } else if ("s".equals(name) || "service".equals(name)) { 18275 dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS); 18276 } else if ("r".equals(name) || "receiver".equals(name)) { 18277 dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS); 18278 } else if ("c".equals(name) || "content".equals(name)) { 18279 dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS); 18280 } else { 18281 pw.println("Error: unknown resolver table type: " + name); 18282 return; 18283 } 18284 opti++; 18285 } 18286 } 18287 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) { 18288 dumpState.setDump(DumpState.DUMP_PERMISSIONS); 18289 } else if ("permission".equals(cmd)) { 18290 if (opti >= args.length) { 18291 pw.println("Error: permission requires permission name"); 18292 return; 18293 } 18294 permissionNames = new ArraySet<>(); 18295 while (opti < args.length) { 18296 permissionNames.add(args[opti]); 18297 opti++; 18298 } 18299 dumpState.setDump(DumpState.DUMP_PERMISSIONS 18300 | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS); 18301 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) { 18302 dumpState.setDump(DumpState.DUMP_PREFERRED); 18303 } else if ("preferred-xml".equals(cmd)) { 18304 dumpState.setDump(DumpState.DUMP_PREFERRED_XML); 18305 if (opti < args.length && "--full".equals(args[opti])) { 18306 fullPreferred = true; 18307 opti++; 18308 } 18309 } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) { 18310 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED); 18311 } else if ("p".equals(cmd) || "packages".equals(cmd)) { 18312 dumpState.setDump(DumpState.DUMP_PACKAGES); 18313 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) { 18314 dumpState.setDump(DumpState.DUMP_SHARED_USERS); 18315 } else if ("prov".equals(cmd) || "providers".equals(cmd)) { 18316 dumpState.setDump(DumpState.DUMP_PROVIDERS); 18317 } else if ("m".equals(cmd) || "messages".equals(cmd)) { 18318 dumpState.setDump(DumpState.DUMP_MESSAGES); 18319 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) { 18320 dumpState.setDump(DumpState.DUMP_VERIFIERS); 18321 } else if ("i".equals(cmd) || "ifv".equals(cmd) 18322 || "intent-filter-verifiers".equals(cmd)) { 18323 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS); 18324 } else if ("version".equals(cmd)) { 18325 dumpState.setDump(DumpState.DUMP_VERSION); 18326 } else if ("k".equals(cmd) || "keysets".equals(cmd)) { 18327 dumpState.setDump(DumpState.DUMP_KEYSETS); 18328 } else if ("installs".equals(cmd)) { 18329 dumpState.setDump(DumpState.DUMP_INSTALLS); 18330 } else if ("frozen".equals(cmd)) { 18331 dumpState.setDump(DumpState.DUMP_FROZEN); 18332 } else if ("dexopt".equals(cmd)) { 18333 dumpState.setDump(DumpState.DUMP_DEXOPT); 18334 } else if ("compiler-stats".equals(cmd)) { 18335 dumpState.setDump(DumpState.DUMP_COMPILER_STATS); 18336 } else if ("write".equals(cmd)) { 18337 synchronized (mPackages) { 18338 mSettings.writeLPr(); 18339 pw.println("Settings written."); 18340 return; 18341 } 18342 } 18343 } 18344 18345 if (checkin) { 18346 pw.println("vers,1"); 18347 } 18348 18349 // reader 18350 synchronized (mPackages) { 18351 if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) { 18352 if (!checkin) { 18353 if (dumpState.onTitlePrinted()) 18354 pw.println(); 18355 pw.println("Database versions:"); 18356 mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, " ")); 18357 } 18358 } 18359 18360 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) { 18361 if (!checkin) { 18362 if (dumpState.onTitlePrinted()) 18363 pw.println(); 18364 pw.println("Verifiers:"); 18365 pw.print(" Required: "); 18366 pw.print(mRequiredVerifierPackage); 18367 pw.print(" (uid="); 18368 pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 18369 UserHandle.USER_SYSTEM)); 18370 pw.println(")"); 18371 } else if (mRequiredVerifierPackage != null) { 18372 pw.print("vrfy,"); pw.print(mRequiredVerifierPackage); 18373 pw.print(","); 18374 pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 18375 UserHandle.USER_SYSTEM)); 18376 } 18377 } 18378 18379 if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) && 18380 packageName == null) { 18381 if (mIntentFilterVerifierComponent != null) { 18382 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName(); 18383 if (!checkin) { 18384 if (dumpState.onTitlePrinted()) 18385 pw.println(); 18386 pw.println("Intent Filter Verifier:"); 18387 pw.print(" Using: "); 18388 pw.print(verifierPackageName); 18389 pw.print(" (uid="); 18390 pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING, 18391 UserHandle.USER_SYSTEM)); 18392 pw.println(")"); 18393 } else if (verifierPackageName != null) { 18394 pw.print("ifv,"); pw.print(verifierPackageName); 18395 pw.print(","); 18396 pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING, 18397 UserHandle.USER_SYSTEM)); 18398 } 18399 } else { 18400 pw.println(); 18401 pw.println("No Intent Filter Verifier available!"); 18402 } 18403 } 18404 18405 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) { 18406 boolean printedHeader = false; 18407 final Iterator<String> it = mSharedLibraries.keySet().iterator(); 18408 while (it.hasNext()) { 18409 String name = it.next(); 18410 SharedLibraryEntry ent = mSharedLibraries.get(name); 18411 if (!checkin) { 18412 if (!printedHeader) { 18413 if (dumpState.onTitlePrinted()) 18414 pw.println(); 18415 pw.println("Libraries:"); 18416 printedHeader = true; 18417 } 18418 pw.print(" "); 18419 } else { 18420 pw.print("lib,"); 18421 } 18422 pw.print(name); 18423 if (!checkin) { 18424 pw.print(" -> "); 18425 } 18426 if (ent.path != null) { 18427 if (!checkin) { 18428 pw.print("(jar) "); 18429 pw.print(ent.path); 18430 } else { 18431 pw.print(",jar,"); 18432 pw.print(ent.path); 18433 } 18434 } else { 18435 if (!checkin) { 18436 pw.print("(apk) "); 18437 pw.print(ent.apk); 18438 } else { 18439 pw.print(",apk,"); 18440 pw.print(ent.apk); 18441 } 18442 } 18443 pw.println(); 18444 } 18445 } 18446 18447 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) { 18448 if (dumpState.onTitlePrinted()) 18449 pw.println(); 18450 if (!checkin) { 18451 pw.println("Features:"); 18452 } 18453 18454 for (FeatureInfo feat : mAvailableFeatures.values()) { 18455 if (checkin) { 18456 pw.print("feat,"); 18457 pw.print(feat.name); 18458 pw.print(","); 18459 pw.println(feat.version); 18460 } else { 18461 pw.print(" "); 18462 pw.print(feat.name); 18463 if (feat.version > 0) { 18464 pw.print(" version="); 18465 pw.print(feat.version); 18466 } 18467 pw.println(); 18468 } 18469 } 18470 } 18471 18472 if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) { 18473 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:" 18474 : "Activity Resolver Table:", " ", packageName, 18475 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 18476 dumpState.setTitlePrinted(true); 18477 } 18478 } 18479 if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) { 18480 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:" 18481 : "Receiver Resolver Table:", " ", packageName, 18482 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 18483 dumpState.setTitlePrinted(true); 18484 } 18485 } 18486 if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) { 18487 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:" 18488 : "Service Resolver Table:", " ", packageName, 18489 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 18490 dumpState.setTitlePrinted(true); 18491 } 18492 } 18493 if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) { 18494 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:" 18495 : "Provider Resolver Table:", " ", packageName, 18496 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 18497 dumpState.setTitlePrinted(true); 18498 } 18499 } 18500 18501 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) { 18502 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 18503 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 18504 int user = mSettings.mPreferredActivities.keyAt(i); 18505 if (pir.dump(pw, 18506 dumpState.getTitlePrinted() 18507 ? "\nPreferred Activities User " + user + ":" 18508 : "Preferred Activities User " + user + ":", " ", 18509 packageName, true, false)) { 18510 dumpState.setTitlePrinted(true); 18511 } 18512 } 18513 } 18514 18515 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) { 18516 pw.flush(); 18517 FileOutputStream fout = new FileOutputStream(fd); 18518 BufferedOutputStream str = new BufferedOutputStream(fout); 18519 XmlSerializer serializer = new FastXmlSerializer(); 18520 try { 18521 serializer.setOutput(str, StandardCharsets.UTF_8.name()); 18522 serializer.startDocument(null, true); 18523 serializer.setFeature( 18524 "http://xmlpull.org/v1/doc/features.html#indent-output", true); 18525 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred); 18526 serializer.endDocument(); 18527 serializer.flush(); 18528 } catch (IllegalArgumentException e) { 18529 pw.println("Failed writing: " + e); 18530 } catch (IllegalStateException e) { 18531 pw.println("Failed writing: " + e); 18532 } catch (IOException e) { 18533 pw.println("Failed writing: " + e); 18534 } 18535 } 18536 18537 if (!checkin 18538 && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED) 18539 && packageName == null) { 18540 pw.println(); 18541 int count = mSettings.mPackages.size(); 18542 if (count == 0) { 18543 pw.println("No applications!"); 18544 pw.println(); 18545 } else { 18546 final String prefix = " "; 18547 Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values(); 18548 if (allPackageSettings.size() == 0) { 18549 pw.println("No domain preferred apps!"); 18550 pw.println(); 18551 } else { 18552 pw.println("App verification status:"); 18553 pw.println(); 18554 count = 0; 18555 for (PackageSetting ps : allPackageSettings) { 18556 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo(); 18557 if (ivi == null || ivi.getPackageName() == null) continue; 18558 pw.println(prefix + "Package: " + ivi.getPackageName()); 18559 pw.println(prefix + "Domains: " + ivi.getDomainsString()); 18560 pw.println(prefix + "Status: " + ivi.getStatusString()); 18561 pw.println(); 18562 count++; 18563 } 18564 if (count == 0) { 18565 pw.println(prefix + "No app verification established."); 18566 pw.println(); 18567 } 18568 for (int userId : sUserManager.getUserIds()) { 18569 pw.println("App linkages for user " + userId + ":"); 18570 pw.println(); 18571 count = 0; 18572 for (PackageSetting ps : allPackageSettings) { 18573 final long status = ps.getDomainVerificationStatusForUser(userId); 18574 if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 18575 continue; 18576 } 18577 pw.println(prefix + "Package: " + ps.name); 18578 pw.println(prefix + "Domains: " + dumpDomainString(ps.name)); 18579 String statusStr = IntentFilterVerificationInfo. 18580 getStatusStringFromValue(status); 18581 pw.println(prefix + "Status: " + statusStr); 18582 pw.println(); 18583 count++; 18584 } 18585 if (count == 0) { 18586 pw.println(prefix + "No configured app linkages."); 18587 pw.println(); 18588 } 18589 } 18590 } 18591 } 18592 } 18593 18594 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) { 18595 mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState); 18596 if (packageName == null && permissionNames == null) { 18597 for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) { 18598 if (iperm == 0) { 18599 if (dumpState.onTitlePrinted()) 18600 pw.println(); 18601 pw.println("AppOp Permissions:"); 18602 } 18603 pw.print(" AppOp Permission "); 18604 pw.print(mAppOpPermissionPackages.keyAt(iperm)); 18605 pw.println(":"); 18606 ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm); 18607 for (int ipkg=0; ipkg<pkgs.size(); ipkg++) { 18608 pw.print(" "); pw.println(pkgs.valueAt(ipkg)); 18609 } 18610 } 18611 } 18612 } 18613 18614 if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) { 18615 boolean printedSomething = false; 18616 for (PackageParser.Provider p : mProviders.mProviders.values()) { 18617 if (packageName != null && !packageName.equals(p.info.packageName)) { 18618 continue; 18619 } 18620 if (!printedSomething) { 18621 if (dumpState.onTitlePrinted()) 18622 pw.println(); 18623 pw.println("Registered ContentProviders:"); 18624 printedSomething = true; 18625 } 18626 pw.print(" "); p.printComponentShortName(pw); pw.println(":"); 18627 pw.print(" "); pw.println(p.toString()); 18628 } 18629 printedSomething = false; 18630 for (Map.Entry<String, PackageParser.Provider> entry : 18631 mProvidersByAuthority.entrySet()) { 18632 PackageParser.Provider p = entry.getValue(); 18633 if (packageName != null && !packageName.equals(p.info.packageName)) { 18634 continue; 18635 } 18636 if (!printedSomething) { 18637 if (dumpState.onTitlePrinted()) 18638 pw.println(); 18639 pw.println("ContentProvider Authorities:"); 18640 printedSomething = true; 18641 } 18642 pw.print(" ["); pw.print(entry.getKey()); pw.println("]:"); 18643 pw.print(" "); pw.println(p.toString()); 18644 if (p.info != null && p.info.applicationInfo != null) { 18645 final String appInfo = p.info.applicationInfo.toString(); 18646 pw.print(" applicationInfo="); pw.println(appInfo); 18647 } 18648 } 18649 } 18650 18651 if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) { 18652 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState); 18653 } 18654 18655 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) { 18656 mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin); 18657 } 18658 18659 if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) { 18660 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin); 18661 } 18662 18663 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) { 18664 mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState); 18665 } 18666 18667 if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) { 18668 // XXX should handle packageName != null by dumping only install data that 18669 // the given package is involved with. 18670 if (dumpState.onTitlePrinted()) pw.println(); 18671 mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120)); 18672 } 18673 18674 if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) { 18675 // XXX should handle packageName != null by dumping only install data that 18676 // the given package is involved with. 18677 if (dumpState.onTitlePrinted()) pw.println(); 18678 18679 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120); 18680 ipw.println(); 18681 ipw.println("Frozen packages:"); 18682 ipw.increaseIndent(); 18683 if (mFrozenPackages.size() == 0) { 18684 ipw.println("(none)"); 18685 } else { 18686 for (int i = 0; i < mFrozenPackages.size(); i++) { 18687 ipw.println(mFrozenPackages.valueAt(i)); 18688 } 18689 } 18690 ipw.decreaseIndent(); 18691 } 18692 18693 if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) { 18694 if (dumpState.onTitlePrinted()) pw.println(); 18695 dumpDexoptStateLPr(pw, packageName); 18696 } 18697 18698 if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) { 18699 if (dumpState.onTitlePrinted()) pw.println(); 18700 dumpCompilerStatsLPr(pw, packageName); 18701 } 18702 18703 if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) { 18704 if (dumpState.onTitlePrinted()) pw.println(); 18705 mSettings.dumpReadMessagesLPr(pw, dumpState); 18706 18707 pw.println(); 18708 pw.println("Package warning messages:"); 18709 BufferedReader in = null; 18710 String line = null; 18711 try { 18712 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 18713 while ((line = in.readLine()) != null) { 18714 if (line.contains("ignored: updated version")) continue; 18715 pw.println(line); 18716 } 18717 } catch (IOException ignored) { 18718 } finally { 18719 IoUtils.closeQuietly(in); 18720 } 18721 } 18722 18723 if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) { 18724 BufferedReader in = null; 18725 String line = null; 18726 try { 18727 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 18728 while ((line = in.readLine()) != null) { 18729 if (line.contains("ignored: updated version")) continue; 18730 pw.print("msg,"); 18731 pw.println(line); 18732 } 18733 } catch (IOException ignored) { 18734 } finally { 18735 IoUtils.closeQuietly(in); 18736 } 18737 } 18738 } 18739 } 18740 18741 private void dumpDexoptStateLPr(PrintWriter pw, String packageName) { 18742 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120); 18743 ipw.println(); 18744 ipw.println("Dexopt state:"); 18745 ipw.increaseIndent(); 18746 Collection<PackageParser.Package> packages = null; 18747 if (packageName != null) { 18748 PackageParser.Package targetPackage = mPackages.get(packageName); 18749 if (targetPackage != null) { 18750 packages = Collections.singletonList(targetPackage); 18751 } else { 18752 ipw.println("Unable to find package: " + packageName); 18753 return; 18754 } 18755 } else { 18756 packages = mPackages.values(); 18757 } 18758 18759 for (PackageParser.Package pkg : packages) { 18760 ipw.println("[" + pkg.packageName + "]"); 18761 ipw.increaseIndent(); 18762 mPackageDexOptimizer.dumpDexoptState(ipw, pkg); 18763 ipw.decreaseIndent(); 18764 } 18765 } 18766 18767 private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) { 18768 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120); 18769 ipw.println(); 18770 ipw.println("Compiler stats:"); 18771 ipw.increaseIndent(); 18772 Collection<PackageParser.Package> packages = null; 18773 if (packageName != null) { 18774 PackageParser.Package targetPackage = mPackages.get(packageName); 18775 if (targetPackage != null) { 18776 packages = Collections.singletonList(targetPackage); 18777 } else { 18778 ipw.println("Unable to find package: " + packageName); 18779 return; 18780 } 18781 } else { 18782 packages = mPackages.values(); 18783 } 18784 18785 for (PackageParser.Package pkg : packages) { 18786 ipw.println("[" + pkg.packageName + "]"); 18787 ipw.increaseIndent(); 18788 18789 CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName); 18790 if (stats == null) { 18791 ipw.println("(No recorded stats)"); 18792 } else { 18793 stats.dump(ipw); 18794 } 18795 ipw.decreaseIndent(); 18796 } 18797 } 18798 18799 private String dumpDomainString(String packageName) { 18800 List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName) 18801 .getList(); 18802 List<IntentFilter> filters = getAllIntentFilters(packageName).getList(); 18803 18804 ArraySet<String> result = new ArraySet<>(); 18805 if (iviList.size() > 0) { 18806 for (IntentFilterVerificationInfo ivi : iviList) { 18807 for (String host : ivi.getDomains()) { 18808 result.add(host); 18809 } 18810 } 18811 } 18812 if (filters != null && filters.size() > 0) { 18813 for (IntentFilter filter : filters) { 18814 if (filter.hasCategory(Intent.CATEGORY_BROWSABLE) 18815 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 18816 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) { 18817 result.addAll(filter.getHostsList()); 18818 } 18819 } 18820 } 18821 18822 StringBuilder sb = new StringBuilder(result.size() * 16); 18823 for (String domain : result) { 18824 if (sb.length() > 0) sb.append(" "); 18825 sb.append(domain); 18826 } 18827 return sb.toString(); 18828 } 18829 18830 // ------- apps on sdcard specific code ------- 18831 static final boolean DEBUG_SD_INSTALL = false; 18832 18833 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD"; 18834 18835 private static final String SD_ENCRYPTION_ALGORITHM = "AES"; 18836 18837 private boolean mMediaMounted = false; 18838 18839 static String getEncryptKey() { 18840 try { 18841 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString( 18842 SD_ENCRYPTION_KEYSTORE_NAME); 18843 if (sdEncKey == null) { 18844 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128, 18845 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME); 18846 if (sdEncKey == null) { 18847 Slog.e(TAG, "Failed to create encryption keys"); 18848 return null; 18849 } 18850 } 18851 return sdEncKey; 18852 } catch (NoSuchAlgorithmException nsae) { 18853 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae); 18854 return null; 18855 } catch (IOException ioe) { 18856 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe); 18857 return null; 18858 } 18859 } 18860 18861 /* 18862 * Update media status on PackageManager. 18863 */ 18864 @Override 18865 public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) { 18866 int callingUid = Binder.getCallingUid(); 18867 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 18868 throw new SecurityException("Media status can only be updated by the system"); 18869 } 18870 // reader; this apparently protects mMediaMounted, but should probably 18871 // be a different lock in that case. 18872 synchronized (mPackages) { 18873 Log.i(TAG, "Updating external media status from " 18874 + (mMediaMounted ? "mounted" : "unmounted") + " to " 18875 + (mediaStatus ? "mounted" : "unmounted")); 18876 if (DEBUG_SD_INSTALL) 18877 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus 18878 + ", mMediaMounted=" + mMediaMounted); 18879 if (mediaStatus == mMediaMounted) { 18880 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 18881 : 0, -1); 18882 mHandler.sendMessage(msg); 18883 return; 18884 } 18885 mMediaMounted = mediaStatus; 18886 } 18887 // Queue up an async operation since the package installation may take a 18888 // little while. 18889 mHandler.post(new Runnable() { 18890 public void run() { 18891 updateExternalMediaStatusInner(mediaStatus, reportStatus, true); 18892 } 18893 }); 18894 } 18895 18896 /** 18897 * Called by MountService when the initial ASECs to scan are available. 18898 * Should block until all the ASEC containers are finished being scanned. 18899 */ 18900 public void scanAvailableAsecs() { 18901 updateExternalMediaStatusInner(true, false, false); 18902 } 18903 18904 /* 18905 * Collect information of applications on external media, map them against 18906 * existing containers and update information based on current mount status. 18907 * Please note that we always have to report status if reportStatus has been 18908 * set to true especially when unloading packages. 18909 */ 18910 private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus, 18911 boolean externalStorage) { 18912 ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>(); 18913 int[] uidArr = EmptyArray.INT; 18914 18915 final String[] list = PackageHelper.getSecureContainerList(); 18916 if (ArrayUtils.isEmpty(list)) { 18917 Log.i(TAG, "No secure containers found"); 18918 } else { 18919 // Process list of secure containers and categorize them 18920 // as active or stale based on their package internal state. 18921 18922 // reader 18923 synchronized (mPackages) { 18924 for (String cid : list) { 18925 // Leave stages untouched for now; installer service owns them 18926 if (PackageInstallerService.isStageName(cid)) continue; 18927 18928 if (DEBUG_SD_INSTALL) 18929 Log.i(TAG, "Processing container " + cid); 18930 String pkgName = getAsecPackageName(cid); 18931 if (pkgName == null) { 18932 Slog.i(TAG, "Found stale container " + cid + " with no package name"); 18933 continue; 18934 } 18935 if (DEBUG_SD_INSTALL) 18936 Log.i(TAG, "Looking for pkg : " + pkgName); 18937 18938 final PackageSetting ps = mSettings.mPackages.get(pkgName); 18939 if (ps == null) { 18940 Slog.i(TAG, "Found stale container " + cid + " with no matching settings"); 18941 continue; 18942 } 18943 18944 /* 18945 * Skip packages that are not external if we're unmounting 18946 * external storage. 18947 */ 18948 if (externalStorage && !isMounted && !isExternal(ps)) { 18949 continue; 18950 } 18951 18952 final AsecInstallArgs args = new AsecInstallArgs(cid, 18953 getAppDexInstructionSets(ps), ps.isForwardLocked()); 18954 // The package status is changed only if the code path 18955 // matches between settings and the container id. 18956 if (ps.codePathString != null 18957 && ps.codePathString.startsWith(args.getCodePath())) { 18958 if (DEBUG_SD_INSTALL) { 18959 Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName 18960 + " at code path: " + ps.codePathString); 18961 } 18962 18963 // We do have a valid package installed on sdcard 18964 processCids.put(args, ps.codePathString); 18965 final int uid = ps.appId; 18966 if (uid != -1) { 18967 uidArr = ArrayUtils.appendInt(uidArr, uid); 18968 } 18969 } else { 18970 Slog.i(TAG, "Found stale container " + cid + ": expected codePath=" 18971 + ps.codePathString); 18972 } 18973 } 18974 } 18975 18976 Arrays.sort(uidArr); 18977 } 18978 18979 // Process packages with valid entries. 18980 if (isMounted) { 18981 if (DEBUG_SD_INSTALL) 18982 Log.i(TAG, "Loading packages"); 18983 loadMediaPackages(processCids, uidArr, externalStorage); 18984 startCleaningPackages(); 18985 mInstallerService.onSecureContainersAvailable(); 18986 } else { 18987 if (DEBUG_SD_INSTALL) 18988 Log.i(TAG, "Unloading packages"); 18989 unloadMediaPackages(processCids, uidArr, reportStatus); 18990 } 18991 } 18992 18993 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 18994 ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) { 18995 final int size = infos.size(); 18996 final String[] packageNames = new String[size]; 18997 final int[] packageUids = new int[size]; 18998 for (int i = 0; i < size; i++) { 18999 final ApplicationInfo info = infos.get(i); 19000 packageNames[i] = info.packageName; 19001 packageUids[i] = info.uid; 19002 } 19003 sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids, 19004 finishedReceiver); 19005 } 19006 19007 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 19008 ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 19009 sendResourcesChangedBroadcast(mediaStatus, replacing, 19010 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver); 19011 } 19012 19013 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 19014 String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 19015 int size = pkgList.length; 19016 if (size > 0) { 19017 // Send broadcasts here 19018 Bundle extras = new Bundle(); 19019 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 19020 if (uidArr != null) { 19021 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr); 19022 } 19023 if (replacing) { 19024 extras.putBoolean(Intent.EXTRA_REPLACING, replacing); 19025 } 19026 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE 19027 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE; 19028 sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null); 19029 } 19030 } 19031 19032 /* 19033 * Look at potentially valid container ids from processCids If package 19034 * information doesn't match the one on record or package scanning fails, 19035 * the cid is added to list of removeCids. We currently don't delete stale 19036 * containers. 19037 */ 19038 private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr, 19039 boolean externalStorage) { 19040 ArrayList<String> pkgList = new ArrayList<String>(); 19041 Set<AsecInstallArgs> keys = processCids.keySet(); 19042 19043 for (AsecInstallArgs args : keys) { 19044 String codePath = processCids.get(args); 19045 if (DEBUG_SD_INSTALL) 19046 Log.i(TAG, "Loading container : " + args.cid); 19047 int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 19048 try { 19049 // Make sure there are no container errors first. 19050 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) { 19051 Slog.e(TAG, "Failed to mount cid : " + args.cid 19052 + " when installing from sdcard"); 19053 continue; 19054 } 19055 // Check code path here. 19056 if (codePath == null || !codePath.startsWith(args.getCodePath())) { 19057 Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath() 19058 + " does not match one in settings " + codePath); 19059 continue; 19060 } 19061 // Parse package 19062 int parseFlags = mDefParseFlags; 19063 if (args.isExternalAsec()) { 19064 parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE; 19065 } 19066 if (args.isFwdLocked()) { 19067 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 19068 } 19069 19070 synchronized (mInstallLock) { 19071 PackageParser.Package pkg = null; 19072 try { 19073 // Sadly we don't know the package name yet to freeze it 19074 pkg = scanPackageTracedLI(new File(codePath), parseFlags, 19075 SCAN_IGNORE_FROZEN, 0, null); 19076 } catch (PackageManagerException e) { 19077 Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage()); 19078 } 19079 // Scan the package 19080 if (pkg != null) { 19081 /* 19082 * TODO why is the lock being held? doPostInstall is 19083 * called in other places without the lock. This needs 19084 * to be straightened out. 19085 */ 19086 // writer 19087 synchronized (mPackages) { 19088 retCode = PackageManager.INSTALL_SUCCEEDED; 19089 pkgList.add(pkg.packageName); 19090 // Post process args 19091 args.doPostInstall(PackageManager.INSTALL_SUCCEEDED, 19092 pkg.applicationInfo.uid); 19093 } 19094 } else { 19095 Slog.i(TAG, "Failed to install pkg from " + codePath + " from sdcard"); 19096 } 19097 } 19098 19099 } finally { 19100 if (retCode != PackageManager.INSTALL_SUCCEEDED) { 19101 Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode); 19102 } 19103 } 19104 } 19105 // writer 19106 synchronized (mPackages) { 19107 // If the platform SDK has changed since the last time we booted, 19108 // we need to re-grant app permission to catch any new ones that 19109 // appear. This is really a hack, and means that apps can in some 19110 // cases get permissions that the user didn't initially explicitly 19111 // allow... it would be nice to have some better way to handle 19112 // this situation. 19113 final VersionInfo ver = externalStorage ? mSettings.getExternalVersion() 19114 : mSettings.getInternalVersion(); 19115 final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL 19116 : StorageManager.UUID_PRIVATE_INTERNAL; 19117 19118 int updateFlags = UPDATE_PERMISSIONS_ALL; 19119 if (ver.sdkVersion != mSdkVersion) { 19120 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " 19121 + mSdkVersion + "; regranting permissions for external"); 19122 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 19123 } 19124 updatePermissionsLPw(null, null, volumeUuid, updateFlags); 19125 19126 // Yay, everything is now upgraded 19127 ver.forceCurrent(); 19128 19129 // can downgrade to reader 19130 // Persist settings 19131 mSettings.writeLPr(); 19132 } 19133 // Send a broadcast to let everyone know we are done processing 19134 if (pkgList.size() > 0) { 19135 sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null); 19136 } 19137 } 19138 19139 /* 19140 * Utility method to unload a list of specified containers 19141 */ 19142 private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) { 19143 // Just unmount all valid containers. 19144 for (AsecInstallArgs arg : cidArgs) { 19145 synchronized (mInstallLock) { 19146 arg.doPostDeleteLI(false); 19147 } 19148 } 19149 } 19150 19151 /* 19152 * Unload packages mounted on external media. This involves deleting package 19153 * data from internal structures, sending broadcasts about disabled packages, 19154 * gc'ing to free up references, unmounting all secure containers 19155 * corresponding to packages on external media, and posting a 19156 * UPDATED_MEDIA_STATUS message if status has been requested. Please note 19157 * that we always have to post this message if status has been requested no 19158 * matter what. 19159 */ 19160 private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[], 19161 final boolean reportStatus) { 19162 if (DEBUG_SD_INSTALL) 19163 Log.i(TAG, "unloading media packages"); 19164 ArrayList<String> pkgList = new ArrayList<String>(); 19165 ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>(); 19166 final Set<AsecInstallArgs> keys = processCids.keySet(); 19167 for (AsecInstallArgs args : keys) { 19168 String pkgName = args.getPackageName(); 19169 if (DEBUG_SD_INSTALL) 19170 Log.i(TAG, "Trying to unload pkg : " + pkgName); 19171 // Delete package internally 19172 PackageRemovedInfo outInfo = new PackageRemovedInfo(); 19173 synchronized (mInstallLock) { 19174 final int deleteFlags = PackageManager.DELETE_KEEP_DATA; 19175 final boolean res; 19176 try (PackageFreezer freezer = freezePackageForDelete(pkgName, deleteFlags, 19177 "unloadMediaPackages")) { 19178 res = deletePackageLIF(pkgName, null, false, null, deleteFlags, outInfo, false, 19179 null); 19180 } 19181 if (res) { 19182 pkgList.add(pkgName); 19183 } else { 19184 Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName); 19185 failedList.add(args); 19186 } 19187 } 19188 } 19189 19190 // reader 19191 synchronized (mPackages) { 19192 // We didn't update the settings after removing each package; 19193 // write them now for all packages. 19194 mSettings.writeLPr(); 19195 } 19196 19197 // We have to absolutely send UPDATED_MEDIA_STATUS only 19198 // after confirming that all the receivers processed the ordered 19199 // broadcast when packages get disabled, force a gc to clean things up. 19200 // and unload all the containers. 19201 if (pkgList.size() > 0) { 19202 sendResourcesChangedBroadcast(false, false, pkgList, uidArr, 19203 new IIntentReceiver.Stub() { 19204 public void performReceive(Intent intent, int resultCode, String data, 19205 Bundle extras, boolean ordered, boolean sticky, 19206 int sendingUser) throws RemoteException { 19207 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, 19208 reportStatus ? 1 : 0, 1, keys); 19209 mHandler.sendMessage(msg); 19210 } 19211 }); 19212 } else { 19213 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1, 19214 keys); 19215 mHandler.sendMessage(msg); 19216 } 19217 } 19218 19219 private void loadPrivatePackages(final VolumeInfo vol) { 19220 mHandler.post(new Runnable() { 19221 @Override 19222 public void run() { 19223 loadPrivatePackagesInner(vol); 19224 } 19225 }); 19226 } 19227 19228 private void loadPrivatePackagesInner(VolumeInfo vol) { 19229 final String volumeUuid = vol.fsUuid; 19230 if (TextUtils.isEmpty(volumeUuid)) { 19231 Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring"); 19232 return; 19233 } 19234 19235 final ArrayList<PackageFreezer> freezers = new ArrayList<>(); 19236 final ArrayList<ApplicationInfo> loaded = new ArrayList<>(); 19237 final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE; 19238 19239 final VersionInfo ver; 19240 final List<PackageSetting> packages; 19241 synchronized (mPackages) { 19242 ver = mSettings.findOrCreateVersion(volumeUuid); 19243 packages = mSettings.getVolumePackagesLPr(volumeUuid); 19244 } 19245 19246 for (PackageSetting ps : packages) { 19247 freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner")); 19248 synchronized (mInstallLock) { 19249 final PackageParser.Package pkg; 19250 try { 19251 pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null); 19252 loaded.add(pkg.applicationInfo); 19253 19254 } catch (PackageManagerException e) { 19255 Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage()); 19256 } 19257 19258 if (!Build.FINGERPRINT.equals(ver.fingerprint)) { 19259 clearAppDataLIF(ps.pkg, UserHandle.USER_ALL, 19260 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE 19261 | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 19262 } 19263 } 19264 } 19265 19266 // Reconcile app data for all started/unlocked users 19267 final StorageManager sm = mContext.getSystemService(StorageManager.class); 19268 final UserManager um = mContext.getSystemService(UserManager.class); 19269 UserManagerInternal umInternal = getUserManagerInternal(); 19270 for (UserInfo user : um.getUsers()) { 19271 final int flags; 19272 if (umInternal.isUserUnlockingOrUnlocked(user.id)) { 19273 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 19274 } else if (umInternal.isUserRunning(user.id)) { 19275 flags = StorageManager.FLAG_STORAGE_DE; 19276 } else { 19277 continue; 19278 } 19279 19280 try { 19281 sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags); 19282 synchronized (mInstallLock) { 19283 reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */); 19284 } 19285 } catch (IllegalStateException e) { 19286 // Device was probably ejected, and we'll process that event momentarily 19287 Slog.w(TAG, "Failed to prepare storage: " + e); 19288 } 19289 } 19290 19291 synchronized (mPackages) { 19292 int updateFlags = UPDATE_PERMISSIONS_ALL; 19293 if (ver.sdkVersion != mSdkVersion) { 19294 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " 19295 + mSdkVersion + "; regranting permissions for " + volumeUuid); 19296 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 19297 } 19298 updatePermissionsLPw(null, null, volumeUuid, updateFlags); 19299 19300 // Yay, everything is now upgraded 19301 ver.forceCurrent(); 19302 19303 mSettings.writeLPr(); 19304 } 19305 19306 for (PackageFreezer freezer : freezers) { 19307 freezer.close(); 19308 } 19309 19310 if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded); 19311 sendResourcesChangedBroadcast(true, false, loaded, null); 19312 } 19313 19314 private void unloadPrivatePackages(final VolumeInfo vol) { 19315 mHandler.post(new Runnable() { 19316 @Override 19317 public void run() { 19318 unloadPrivatePackagesInner(vol); 19319 } 19320 }); 19321 } 19322 19323 private void unloadPrivatePackagesInner(VolumeInfo vol) { 19324 final String volumeUuid = vol.fsUuid; 19325 if (TextUtils.isEmpty(volumeUuid)) { 19326 Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring"); 19327 return; 19328 } 19329 19330 final ArrayList<ApplicationInfo> unloaded = new ArrayList<>(); 19331 synchronized (mInstallLock) { 19332 synchronized (mPackages) { 19333 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid); 19334 for (PackageSetting ps : packages) { 19335 if (ps.pkg == null) continue; 19336 19337 final ApplicationInfo info = ps.pkg.applicationInfo; 19338 final int deleteFlags = PackageManager.DELETE_KEEP_DATA; 19339 final PackageRemovedInfo outInfo = new PackageRemovedInfo(); 19340 19341 try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags, 19342 "unloadPrivatePackagesInner")) { 19343 if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo, 19344 false, null)) { 19345 unloaded.add(info); 19346 } else { 19347 Slog.w(TAG, "Failed to unload " + ps.codePath); 19348 } 19349 } 19350 19351 // Try very hard to release any references to this package 19352 // so we don't risk the system server being killed due to 19353 // open FDs 19354 AttributeCache.instance().removePackage(ps.name); 19355 } 19356 19357 mSettings.writeLPr(); 19358 } 19359 } 19360 19361 if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded); 19362 sendResourcesChangedBroadcast(false, false, unloaded, null); 19363 19364 // Try very hard to release any references to this path so we don't risk 19365 // the system server being killed due to open FDs 19366 ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath()); 19367 19368 for (int i = 0; i < 3; i++) { 19369 System.gc(); 19370 System.runFinalization(); 19371 } 19372 } 19373 19374 /** 19375 * Prepare storage areas for given user on all mounted devices. 19376 */ 19377 void prepareUserData(int userId, int userSerial, int flags) { 19378 synchronized (mInstallLock) { 19379 final StorageManager storage = mContext.getSystemService(StorageManager.class); 19380 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 19381 final String volumeUuid = vol.getFsUuid(); 19382 prepareUserDataLI(volumeUuid, userId, userSerial, flags, true); 19383 } 19384 } 19385 } 19386 19387 private void prepareUserDataLI(String volumeUuid, int userId, int userSerial, int flags, 19388 boolean allowRecover) { 19389 // Prepare storage and verify that serial numbers are consistent; if 19390 // there's a mismatch we need to destroy to avoid leaking data 19391 final StorageManager storage = mContext.getSystemService(StorageManager.class); 19392 try { 19393 storage.prepareUserStorage(volumeUuid, userId, userSerial, flags); 19394 19395 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0 && !mOnlyCore) { 19396 UserManagerService.enforceSerialNumber( 19397 Environment.getDataUserDeDirectory(volumeUuid, userId), userSerial); 19398 if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) { 19399 UserManagerService.enforceSerialNumber( 19400 Environment.getDataSystemDeDirectory(userId), userSerial); 19401 } 19402 } 19403 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && !mOnlyCore) { 19404 UserManagerService.enforceSerialNumber( 19405 Environment.getDataUserCeDirectory(volumeUuid, userId), userSerial); 19406 if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) { 19407 UserManagerService.enforceSerialNumber( 19408 Environment.getDataSystemCeDirectory(userId), userSerial); 19409 } 19410 } 19411 19412 synchronized (mInstallLock) { 19413 mInstaller.createUserData(volumeUuid, userId, userSerial, flags); 19414 } 19415 } catch (Exception e) { 19416 logCriticalInfo(Log.WARN, "Destroying user " + userId + " on volume " + volumeUuid 19417 + " because we failed to prepare: " + e); 19418 destroyUserDataLI(volumeUuid, userId, 19419 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 19420 19421 if (allowRecover) { 19422 // Try one last time; if we fail again we're really in trouble 19423 prepareUserDataLI(volumeUuid, userId, userSerial, flags, false); 19424 } 19425 } 19426 } 19427 19428 /** 19429 * Destroy storage areas for given user on all mounted devices. 19430 */ 19431 void destroyUserData(int userId, int flags) { 19432 synchronized (mInstallLock) { 19433 final StorageManager storage = mContext.getSystemService(StorageManager.class); 19434 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 19435 final String volumeUuid = vol.getFsUuid(); 19436 destroyUserDataLI(volumeUuid, userId, flags); 19437 } 19438 } 19439 } 19440 19441 private void destroyUserDataLI(String volumeUuid, int userId, int flags) { 19442 final StorageManager storage = mContext.getSystemService(StorageManager.class); 19443 try { 19444 // Clean up app data, profile data, and media data 19445 mInstaller.destroyUserData(volumeUuid, userId, flags); 19446 19447 // Clean up system data 19448 if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) { 19449 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) { 19450 FileUtils.deleteContentsAndDir(Environment.getUserSystemDirectory(userId)); 19451 FileUtils.deleteContentsAndDir(Environment.getDataSystemDeDirectory(userId)); 19452 } 19453 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 19454 FileUtils.deleteContentsAndDir(Environment.getDataSystemCeDirectory(userId)); 19455 } 19456 } 19457 19458 // Data with special labels is now gone, so finish the job 19459 storage.destroyUserStorage(volumeUuid, userId, flags); 19460 19461 } catch (Exception e) { 19462 logCriticalInfo(Log.WARN, 19463 "Failed to destroy user " + userId + " on volume " + volumeUuid + ": " + e); 19464 } 19465 } 19466 19467 /** 19468 * Examine all users present on given mounted volume, and destroy data 19469 * belonging to users that are no longer valid, or whose user ID has been 19470 * recycled. 19471 */ 19472 private void reconcileUsers(String volumeUuid) { 19473 final List<File> files = new ArrayList<>(); 19474 Collections.addAll(files, FileUtils 19475 .listFilesOrEmpty(Environment.getDataUserDeDirectory(volumeUuid))); 19476 Collections.addAll(files, FileUtils 19477 .listFilesOrEmpty(Environment.getDataUserCeDirectory(volumeUuid))); 19478 Collections.addAll(files, FileUtils 19479 .listFilesOrEmpty(Environment.getDataSystemDeDirectory())); 19480 Collections.addAll(files, FileUtils 19481 .listFilesOrEmpty(Environment.getDataSystemCeDirectory())); 19482 for (File file : files) { 19483 if (!file.isDirectory()) continue; 19484 19485 final int userId; 19486 final UserInfo info; 19487 try { 19488 userId = Integer.parseInt(file.getName()); 19489 info = sUserManager.getUserInfo(userId); 19490 } catch (NumberFormatException e) { 19491 Slog.w(TAG, "Invalid user directory " + file); 19492 continue; 19493 } 19494 19495 boolean destroyUser = false; 19496 if (info == null) { 19497 logCriticalInfo(Log.WARN, "Destroying user directory " + file 19498 + " because no matching user was found"); 19499 destroyUser = true; 19500 } else if (!mOnlyCore) { 19501 try { 19502 UserManagerService.enforceSerialNumber(file, info.serialNumber); 19503 } catch (IOException e) { 19504 logCriticalInfo(Log.WARN, "Destroying user directory " + file 19505 + " because we failed to enforce serial number: " + e); 19506 destroyUser = true; 19507 } 19508 } 19509 19510 if (destroyUser) { 19511 synchronized (mInstallLock) { 19512 destroyUserDataLI(volumeUuid, userId, 19513 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 19514 } 19515 } 19516 } 19517 } 19518 19519 private void assertPackageKnown(String volumeUuid, String packageName) 19520 throws PackageManagerException { 19521 synchronized (mPackages) { 19522 final PackageSetting ps = mSettings.mPackages.get(packageName); 19523 if (ps == null) { 19524 throw new PackageManagerException("Package " + packageName + " is unknown"); 19525 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) { 19526 throw new PackageManagerException( 19527 "Package " + packageName + " found on unknown volume " + volumeUuid 19528 + "; expected volume " + ps.volumeUuid); 19529 } 19530 } 19531 } 19532 19533 private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId) 19534 throws PackageManagerException { 19535 synchronized (mPackages) { 19536 final PackageSetting ps = mSettings.mPackages.get(packageName); 19537 if (ps == null) { 19538 throw new PackageManagerException("Package " + packageName + " is unknown"); 19539 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) { 19540 throw new PackageManagerException( 19541 "Package " + packageName + " found on unknown volume " + volumeUuid 19542 + "; expected volume " + ps.volumeUuid); 19543 } else if (!ps.getInstalled(userId)) { 19544 throw new PackageManagerException( 19545 "Package " + packageName + " not installed for user " + userId); 19546 } 19547 } 19548 } 19549 19550 /** 19551 * Examine all apps present on given mounted volume, and destroy apps that 19552 * aren't expected, either due to uninstallation or reinstallation on 19553 * another volume. 19554 */ 19555 private void reconcileApps(String volumeUuid) { 19556 final File[] files = FileUtils 19557 .listFilesOrEmpty(Environment.getDataAppDirectory(volumeUuid)); 19558 for (File file : files) { 19559 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 19560 && !PackageInstallerService.isStageName(file.getName()); 19561 if (!isPackage) { 19562 // Ignore entries which are not packages 19563 continue; 19564 } 19565 19566 try { 19567 final PackageLite pkg = PackageParser.parsePackageLite(file, 19568 PackageParser.PARSE_MUST_BE_APK); 19569 assertPackageKnown(volumeUuid, pkg.packageName); 19570 19571 } catch (PackageParserException | PackageManagerException e) { 19572 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 19573 synchronized (mInstallLock) { 19574 removeCodePathLI(file); 19575 } 19576 } 19577 } 19578 } 19579 19580 /** 19581 * Reconcile all app data for the given user. 19582 * <p> 19583 * Verifies that directories exist and that ownership and labeling is 19584 * correct for all installed apps on all mounted volumes. 19585 */ 19586 void reconcileAppsData(int userId, int flags, boolean migrateAppsData) { 19587 final StorageManager storage = mContext.getSystemService(StorageManager.class); 19588 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 19589 final String volumeUuid = vol.getFsUuid(); 19590 synchronized (mInstallLock) { 19591 reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData); 19592 } 19593 } 19594 } 19595 19596 /** 19597 * Reconcile all app data on given mounted volume. 19598 * <p> 19599 * Destroys app data that isn't expected, either due to uninstallation or 19600 * reinstallation on another volume. 19601 * <p> 19602 * Verifies that directories exist and that ownership and labeling is 19603 * correct for all installed apps. 19604 */ 19605 private void reconcileAppsDataLI(String volumeUuid, int userId, int flags, 19606 boolean migrateAppData) { 19607 Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x" 19608 + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData); 19609 19610 final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId); 19611 final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId); 19612 19613 boolean restoreconNeeded = false; 19614 19615 // First look for stale data that doesn't belong, and check if things 19616 // have changed since we did our last restorecon 19617 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 19618 if (StorageManager.isFileEncryptedNativeOrEmulated() 19619 && !StorageManager.isUserKeyUnlocked(userId)) { 19620 throw new RuntimeException( 19621 "Yikes, someone asked us to reconcile CE storage while " + userId 19622 + " was still locked; this would have caused massive data loss!"); 19623 } 19624 19625 restoreconNeeded |= SELinuxMMAC.isRestoreconNeeded(ceDir); 19626 19627 final File[] files = FileUtils.listFilesOrEmpty(ceDir); 19628 for (File file : files) { 19629 final String packageName = file.getName(); 19630 try { 19631 assertPackageKnownAndInstalled(volumeUuid, packageName, userId); 19632 } catch (PackageManagerException e) { 19633 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 19634 try { 19635 mInstaller.destroyAppData(volumeUuid, packageName, userId, 19636 StorageManager.FLAG_STORAGE_CE, 0); 19637 } catch (InstallerException e2) { 19638 logCriticalInfo(Log.WARN, "Failed to destroy: " + e2); 19639 } 19640 } 19641 } 19642 } 19643 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) { 19644 restoreconNeeded |= SELinuxMMAC.isRestoreconNeeded(deDir); 19645 19646 final File[] files = FileUtils.listFilesOrEmpty(deDir); 19647 for (File file : files) { 19648 final String packageName = file.getName(); 19649 try { 19650 assertPackageKnownAndInstalled(volumeUuid, packageName, userId); 19651 } catch (PackageManagerException e) { 19652 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 19653 try { 19654 mInstaller.destroyAppData(volumeUuid, packageName, userId, 19655 StorageManager.FLAG_STORAGE_DE, 0); 19656 } catch (InstallerException e2) { 19657 logCriticalInfo(Log.WARN, "Failed to destroy: " + e2); 19658 } 19659 } 19660 } 19661 } 19662 19663 // Ensure that data directories are ready to roll for all packages 19664 // installed for this volume and user 19665 final List<PackageSetting> packages; 19666 synchronized (mPackages) { 19667 packages = mSettings.getVolumePackagesLPr(volumeUuid); 19668 } 19669 int preparedCount = 0; 19670 for (PackageSetting ps : packages) { 19671 final String packageName = ps.name; 19672 if (ps.pkg == null) { 19673 Slog.w(TAG, "Odd, missing scanned package " + packageName); 19674 // TODO: might be due to legacy ASEC apps; we should circle back 19675 // and reconcile again once they're scanned 19676 continue; 19677 } 19678 19679 if (ps.getInstalled(userId)) { 19680 prepareAppDataLIF(ps.pkg, userId, flags, restoreconNeeded); 19681 19682 if (migrateAppData && maybeMigrateAppDataLIF(ps.pkg, userId)) { 19683 // We may have just shuffled around app data directories, so 19684 // prepare them one more time 19685 prepareAppDataLIF(ps.pkg, userId, flags, restoreconNeeded); 19686 } 19687 19688 preparedCount++; 19689 } 19690 } 19691 19692 if (restoreconNeeded) { 19693 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 19694 SELinuxMMAC.setRestoreconDone(ceDir); 19695 } 19696 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) { 19697 SELinuxMMAC.setRestoreconDone(deDir); 19698 } 19699 } 19700 19701 Slog.v(TAG, "reconcileAppsData finished " + preparedCount 19702 + " packages; restoreconNeeded was " + restoreconNeeded); 19703 } 19704 19705 /** 19706 * Prepare app data for the given app just after it was installed or 19707 * upgraded. This method carefully only touches users that it's installed 19708 * for, and it forces a restorecon to handle any seinfo changes. 19709 * <p> 19710 * Verifies that directories exist and that ownership and labeling is 19711 * correct for all installed apps. If there is an ownership mismatch, it 19712 * will try recovering system apps by wiping data; third-party app data is 19713 * left intact. 19714 * <p> 19715 * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em> 19716 */ 19717 private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) { 19718 final PackageSetting ps; 19719 synchronized (mPackages) { 19720 ps = mSettings.mPackages.get(pkg.packageName); 19721 mSettings.writeKernelMappingLPr(ps); 19722 } 19723 19724 final UserManager um = mContext.getSystemService(UserManager.class); 19725 UserManagerInternal umInternal = getUserManagerInternal(); 19726 for (UserInfo user : um.getUsers()) { 19727 final int flags; 19728 if (umInternal.isUserUnlockingOrUnlocked(user.id)) { 19729 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 19730 } else if (umInternal.isUserRunning(user.id)) { 19731 flags = StorageManager.FLAG_STORAGE_DE; 19732 } else { 19733 continue; 19734 } 19735 19736 if (ps.getInstalled(user.id)) { 19737 // Whenever an app changes, force a restorecon of its data 19738 // TODO: when user data is locked, mark that we're still dirty 19739 prepareAppDataLIF(pkg, user.id, flags, true); 19740 } 19741 } 19742 } 19743 19744 /** 19745 * Prepare app data for the given app. 19746 * <p> 19747 * Verifies that directories exist and that ownership and labeling is 19748 * correct for all installed apps. If there is an ownership mismatch, this 19749 * will try recovering system apps by wiping data; third-party app data is 19750 * left intact. 19751 */ 19752 private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags, 19753 boolean restoreconNeeded) { 19754 if (pkg == null) { 19755 Slog.wtf(TAG, "Package was null!", new Throwable()); 19756 return; 19757 } 19758 prepareAppDataLeafLIF(pkg, userId, flags, restoreconNeeded); 19759 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 19760 for (int i = 0; i < childCount; i++) { 19761 prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags, restoreconNeeded); 19762 } 19763 } 19764 19765 private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags, 19766 boolean restoreconNeeded) { 19767 if (DEBUG_APP_DATA) { 19768 Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x" 19769 + Integer.toHexString(flags) + (restoreconNeeded ? " restoreconNeeded" : "")); 19770 } 19771 19772 final String volumeUuid = pkg.volumeUuid; 19773 final String packageName = pkg.packageName; 19774 final ApplicationInfo app = pkg.applicationInfo; 19775 final int appId = UserHandle.getAppId(app.uid); 19776 19777 Preconditions.checkNotNull(app.seinfo); 19778 19779 try { 19780 mInstaller.createAppData(volumeUuid, packageName, userId, flags, 19781 appId, app.seinfo, app.targetSdkVersion); 19782 } catch (InstallerException e) { 19783 if (app.isSystemApp()) { 19784 logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName 19785 + ", but trying to recover: " + e); 19786 destroyAppDataLeafLIF(pkg, userId, flags); 19787 try { 19788 mInstaller.createAppData(volumeUuid, packageName, userId, flags, 19789 appId, app.seinfo, app.targetSdkVersion); 19790 logCriticalInfo(Log.DEBUG, "Recovery succeeded!"); 19791 } catch (InstallerException e2) { 19792 logCriticalInfo(Log.DEBUG, "Recovery failed!"); 19793 } 19794 } else { 19795 Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e); 19796 } 19797 } 19798 19799 if (restoreconNeeded) { 19800 try { 19801 mInstaller.restoreconAppData(volumeUuid, packageName, userId, flags, appId, 19802 app.seinfo); 19803 } catch (InstallerException e) { 19804 Slog.e(TAG, "Failed to restorecon for " + packageName + ": " + e); 19805 } 19806 } 19807 19808 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 19809 try { 19810 // CE storage is unlocked right now, so read out the inode and 19811 // remember for use later when it's locked 19812 // TODO: mark this structure as dirty so we persist it! 19813 final long ceDataInode = mInstaller.getAppDataInode(volumeUuid, packageName, userId, 19814 StorageManager.FLAG_STORAGE_CE); 19815 synchronized (mPackages) { 19816 final PackageSetting ps = mSettings.mPackages.get(packageName); 19817 if (ps != null) { 19818 ps.setCeDataInode(ceDataInode, userId); 19819 } 19820 } 19821 } catch (InstallerException e) { 19822 Slog.e(TAG, "Failed to find inode for " + packageName + ": " + e); 19823 } 19824 } 19825 19826 prepareAppDataContentsLeafLIF(pkg, userId, flags); 19827 } 19828 19829 private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) { 19830 if (pkg == null) { 19831 Slog.wtf(TAG, "Package was null!", new Throwable()); 19832 return; 19833 } 19834 prepareAppDataContentsLeafLIF(pkg, userId, flags); 19835 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 19836 for (int i = 0; i < childCount; i++) { 19837 prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags); 19838 } 19839 } 19840 19841 private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) { 19842 final String volumeUuid = pkg.volumeUuid; 19843 final String packageName = pkg.packageName; 19844 final ApplicationInfo app = pkg.applicationInfo; 19845 19846 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 19847 // Create a native library symlink only if we have native libraries 19848 // and if the native libraries are 32 bit libraries. We do not provide 19849 // this symlink for 64 bit libraries. 19850 if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) { 19851 final String nativeLibPath = app.nativeLibraryDir; 19852 try { 19853 mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName, 19854 nativeLibPath, userId); 19855 } catch (InstallerException e) { 19856 Slog.e(TAG, "Failed to link native for " + packageName + ": " + e); 19857 } 19858 } 19859 } 19860 } 19861 19862 /** 19863 * For system apps on non-FBE devices, this method migrates any existing 19864 * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag 19865 * requested by the app. 19866 */ 19867 private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) { 19868 if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated() 19869 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) { 19870 final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage() 19871 ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE; 19872 try { 19873 mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId, 19874 storageTarget); 19875 } catch (InstallerException e) { 19876 logCriticalInfo(Log.WARN, 19877 "Failed to migrate " + pkg.packageName + ": " + e.getMessage()); 19878 } 19879 return true; 19880 } else { 19881 return false; 19882 } 19883 } 19884 19885 public PackageFreezer freezePackage(String packageName, String killReason) { 19886 return freezePackage(packageName, UserHandle.USER_ALL, killReason); 19887 } 19888 19889 public PackageFreezer freezePackage(String packageName, int userId, String killReason) { 19890 return new PackageFreezer(packageName, userId, killReason); 19891 } 19892 19893 public PackageFreezer freezePackageForInstall(String packageName, int installFlags, 19894 String killReason) { 19895 return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason); 19896 } 19897 19898 public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags, 19899 String killReason) { 19900 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) { 19901 return new PackageFreezer(); 19902 } else { 19903 return freezePackage(packageName, userId, killReason); 19904 } 19905 } 19906 19907 public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags, 19908 String killReason) { 19909 return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason); 19910 } 19911 19912 public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags, 19913 String killReason) { 19914 if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) { 19915 return new PackageFreezer(); 19916 } else { 19917 return freezePackage(packageName, userId, killReason); 19918 } 19919 } 19920 19921 /** 19922 * Class that freezes and kills the given package upon creation, and 19923 * unfreezes it upon closing. This is typically used when doing surgery on 19924 * app code/data to prevent the app from running while you're working. 19925 */ 19926 private class PackageFreezer implements AutoCloseable { 19927 private final String mPackageName; 19928 private final PackageFreezer[] mChildren; 19929 19930 private final boolean mWeFroze; 19931 19932 private final AtomicBoolean mClosed = new AtomicBoolean(); 19933 private final CloseGuard mCloseGuard = CloseGuard.get(); 19934 19935 /** 19936 * Create and return a stub freezer that doesn't actually do anything, 19937 * typically used when someone requested 19938 * {@link PackageManager#INSTALL_DONT_KILL_APP} or 19939 * {@link PackageManager#DELETE_DONT_KILL_APP}. 19940 */ 19941 public PackageFreezer() { 19942 mPackageName = null; 19943 mChildren = null; 19944 mWeFroze = false; 19945 mCloseGuard.open("close"); 19946 } 19947 19948 public PackageFreezer(String packageName, int userId, String killReason) { 19949 synchronized (mPackages) { 19950 mPackageName = packageName; 19951 mWeFroze = mFrozenPackages.add(mPackageName); 19952 19953 final PackageSetting ps = mSettings.mPackages.get(mPackageName); 19954 if (ps != null) { 19955 killApplication(ps.name, ps.appId, userId, killReason); 19956 } 19957 19958 final PackageParser.Package p = mPackages.get(packageName); 19959 if (p != null && p.childPackages != null) { 19960 final int N = p.childPackages.size(); 19961 mChildren = new PackageFreezer[N]; 19962 for (int i = 0; i < N; i++) { 19963 mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName, 19964 userId, killReason); 19965 } 19966 } else { 19967 mChildren = null; 19968 } 19969 } 19970 mCloseGuard.open("close"); 19971 } 19972 19973 @Override 19974 protected void finalize() throws Throwable { 19975 try { 19976 mCloseGuard.warnIfOpen(); 19977 close(); 19978 } finally { 19979 super.finalize(); 19980 } 19981 } 19982 19983 @Override 19984 public void close() { 19985 mCloseGuard.close(); 19986 if (mClosed.compareAndSet(false, true)) { 19987 synchronized (mPackages) { 19988 if (mWeFroze) { 19989 mFrozenPackages.remove(mPackageName); 19990 } 19991 19992 if (mChildren != null) { 19993 for (PackageFreezer freezer : mChildren) { 19994 freezer.close(); 19995 } 19996 } 19997 } 19998 } 19999 } 20000 } 20001 20002 /** 20003 * Verify that given package is currently frozen. 20004 */ 20005 private void checkPackageFrozen(String packageName) { 20006 synchronized (mPackages) { 20007 if (!mFrozenPackages.contains(packageName)) { 20008 Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable()); 20009 } 20010 } 20011 } 20012 20013 @Override 20014 public int movePackage(final String packageName, final String volumeUuid) { 20015 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 20016 20017 final UserHandle user = new UserHandle(UserHandle.getCallingUserId()); 20018 final int moveId = mNextMoveId.getAndIncrement(); 20019 mHandler.post(new Runnable() { 20020 @Override 20021 public void run() { 20022 try { 20023 movePackageInternal(packageName, volumeUuid, moveId, user); 20024 } catch (PackageManagerException e) { 20025 Slog.w(TAG, "Failed to move " + packageName, e); 20026 mMoveCallbacks.notifyStatusChanged(moveId, 20027 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 20028 } 20029 } 20030 }); 20031 return moveId; 20032 } 20033 20034 private void movePackageInternal(final String packageName, final String volumeUuid, 20035 final int moveId, UserHandle user) throws PackageManagerException { 20036 final StorageManager storage = mContext.getSystemService(StorageManager.class); 20037 final PackageManager pm = mContext.getPackageManager(); 20038 20039 final boolean currentAsec; 20040 final String currentVolumeUuid; 20041 final File codeFile; 20042 final String installerPackageName; 20043 final String packageAbiOverride; 20044 final int appId; 20045 final String seinfo; 20046 final String label; 20047 final int targetSdkVersion; 20048 final PackageFreezer freezer; 20049 final int[] installedUserIds; 20050 20051 // reader 20052 synchronized (mPackages) { 20053 final PackageParser.Package pkg = mPackages.get(packageName); 20054 final PackageSetting ps = mSettings.mPackages.get(packageName); 20055 if (pkg == null || ps == null) { 20056 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package"); 20057 } 20058 20059 if (pkg.applicationInfo.isSystemApp()) { 20060 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE, 20061 "Cannot move system application"); 20062 } 20063 20064 if (pkg.applicationInfo.isExternalAsec()) { 20065 currentAsec = true; 20066 currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL; 20067 } else if (pkg.applicationInfo.isForwardLocked()) { 20068 currentAsec = true; 20069 currentVolumeUuid = "forward_locked"; 20070 } else { 20071 currentAsec = false; 20072 currentVolumeUuid = ps.volumeUuid; 20073 20074 final File probe = new File(pkg.codePath); 20075 final File probeOat = new File(probe, "oat"); 20076 if (!probe.isDirectory() || !probeOat.isDirectory()) { 20077 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 20078 "Move only supported for modern cluster style installs"); 20079 } 20080 } 20081 20082 if (Objects.equals(currentVolumeUuid, volumeUuid)) { 20083 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 20084 "Package already moved to " + volumeUuid); 20085 } 20086 if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) { 20087 throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN, 20088 "Device admin cannot be moved"); 20089 } 20090 20091 if (mFrozenPackages.contains(packageName)) { 20092 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING, 20093 "Failed to move already frozen package"); 20094 } 20095 20096 codeFile = new File(pkg.codePath); 20097 installerPackageName = ps.installerPackageName; 20098 packageAbiOverride = ps.cpuAbiOverrideString; 20099 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 20100 seinfo = pkg.applicationInfo.seinfo; 20101 label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo)); 20102 targetSdkVersion = pkg.applicationInfo.targetSdkVersion; 20103 freezer = freezePackage(packageName, "movePackageInternal"); 20104 installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 20105 } 20106 20107 final Bundle extras = new Bundle(); 20108 extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName); 20109 extras.putString(Intent.EXTRA_TITLE, label); 20110 mMoveCallbacks.notifyCreated(moveId, extras); 20111 20112 int installFlags; 20113 final boolean moveCompleteApp; 20114 final File measurePath; 20115 20116 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) { 20117 installFlags = INSTALL_INTERNAL; 20118 moveCompleteApp = !currentAsec; 20119 measurePath = Environment.getDataAppDirectory(volumeUuid); 20120 } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) { 20121 installFlags = INSTALL_EXTERNAL; 20122 moveCompleteApp = false; 20123 measurePath = storage.getPrimaryPhysicalVolume().getPath(); 20124 } else { 20125 final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid); 20126 if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE 20127 || !volume.isMountedWritable()) { 20128 freezer.close(); 20129 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 20130 "Move location not mounted private volume"); 20131 } 20132 20133 Preconditions.checkState(!currentAsec); 20134 20135 installFlags = INSTALL_INTERNAL; 20136 moveCompleteApp = true; 20137 measurePath = Environment.getDataAppDirectory(volumeUuid); 20138 } 20139 20140 final PackageStats stats = new PackageStats(null, -1); 20141 synchronized (mInstaller) { 20142 for (int userId : installedUserIds) { 20143 if (!getPackageSizeInfoLI(packageName, userId, stats)) { 20144 freezer.close(); 20145 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 20146 "Failed to measure package size"); 20147 } 20148 } 20149 } 20150 20151 if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size " 20152 + stats.dataSize); 20153 20154 final long startFreeBytes = measurePath.getFreeSpace(); 20155 final long sizeBytes; 20156 if (moveCompleteApp) { 20157 sizeBytes = stats.codeSize + stats.dataSize; 20158 } else { 20159 sizeBytes = stats.codeSize; 20160 } 20161 20162 if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) { 20163 freezer.close(); 20164 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 20165 "Not enough free space to move"); 20166 } 20167 20168 mMoveCallbacks.notifyStatusChanged(moveId, 10); 20169 20170 final CountDownLatch installedLatch = new CountDownLatch(1); 20171 final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() { 20172 @Override 20173 public void onUserActionRequired(Intent intent) throws RemoteException { 20174 throw new IllegalStateException(); 20175 } 20176 20177 @Override 20178 public void onPackageInstalled(String basePackageName, int returnCode, String msg, 20179 Bundle extras) throws RemoteException { 20180 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: " 20181 + PackageManager.installStatusToString(returnCode, msg)); 20182 20183 installedLatch.countDown(); 20184 freezer.close(); 20185 20186 final int status = PackageManager.installStatusToPublicStatus(returnCode); 20187 switch (status) { 20188 case PackageInstaller.STATUS_SUCCESS: 20189 mMoveCallbacks.notifyStatusChanged(moveId, 20190 PackageManager.MOVE_SUCCEEDED); 20191 break; 20192 case PackageInstaller.STATUS_FAILURE_STORAGE: 20193 mMoveCallbacks.notifyStatusChanged(moveId, 20194 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE); 20195 break; 20196 default: 20197 mMoveCallbacks.notifyStatusChanged(moveId, 20198 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 20199 break; 20200 } 20201 } 20202 }; 20203 20204 final MoveInfo move; 20205 if (moveCompleteApp) { 20206 // Kick off a thread to report progress estimates 20207 new Thread() { 20208 @Override 20209 public void run() { 20210 while (true) { 20211 try { 20212 if (installedLatch.await(1, TimeUnit.SECONDS)) { 20213 break; 20214 } 20215 } catch (InterruptedException ignored) { 20216 } 20217 20218 final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace(); 20219 final int progress = 10 + (int) MathUtils.constrain( 20220 ((deltaFreeBytes * 80) / sizeBytes), 0, 80); 20221 mMoveCallbacks.notifyStatusChanged(moveId, progress); 20222 } 20223 } 20224 }.start(); 20225 20226 final String dataAppName = codeFile.getName(); 20227 move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName, 20228 dataAppName, appId, seinfo, targetSdkVersion); 20229 } else { 20230 move = null; 20231 } 20232 20233 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 20234 20235 final Message msg = mHandler.obtainMessage(INIT_COPY); 20236 final OriginInfo origin = OriginInfo.fromExistingFile(codeFile); 20237 final InstallParams params = new InstallParams(origin, move, installObserver, installFlags, 20238 installerPackageName, volumeUuid, null /*verificationInfo*/, user, 20239 packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/); 20240 params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params)); 20241 msg.obj = params; 20242 20243 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage", 20244 System.identityHashCode(msg.obj)); 20245 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 20246 System.identityHashCode(msg.obj)); 20247 20248 mHandler.sendMessage(msg); 20249 } 20250 20251 @Override 20252 public int movePrimaryStorage(String volumeUuid) throws RemoteException { 20253 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 20254 20255 final int realMoveId = mNextMoveId.getAndIncrement(); 20256 final Bundle extras = new Bundle(); 20257 extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid); 20258 mMoveCallbacks.notifyCreated(realMoveId, extras); 20259 20260 final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() { 20261 @Override 20262 public void onCreated(int moveId, Bundle extras) { 20263 // Ignored 20264 } 20265 20266 @Override 20267 public void onStatusChanged(int moveId, int status, long estMillis) { 20268 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis); 20269 } 20270 }; 20271 20272 final StorageManager storage = mContext.getSystemService(StorageManager.class); 20273 storage.setPrimaryStorageUuid(volumeUuid, callback); 20274 return realMoveId; 20275 } 20276 20277 @Override 20278 public int getMoveStatus(int moveId) { 20279 mContext.enforceCallingOrSelfPermission( 20280 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 20281 return mMoveCallbacks.mLastStatus.get(moveId); 20282 } 20283 20284 @Override 20285 public void registerMoveCallback(IPackageMoveObserver callback) { 20286 mContext.enforceCallingOrSelfPermission( 20287 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 20288 mMoveCallbacks.register(callback); 20289 } 20290 20291 @Override 20292 public void unregisterMoveCallback(IPackageMoveObserver callback) { 20293 mContext.enforceCallingOrSelfPermission( 20294 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 20295 mMoveCallbacks.unregister(callback); 20296 } 20297 20298 @Override 20299 public boolean setInstallLocation(int loc) { 20300 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, 20301 null); 20302 if (getInstallLocation() == loc) { 20303 return true; 20304 } 20305 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL 20306 || loc == PackageHelper.APP_INSTALL_EXTERNAL) { 20307 android.provider.Settings.Global.putInt(mContext.getContentResolver(), 20308 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc); 20309 return true; 20310 } 20311 return false; 20312 } 20313 20314 @Override 20315 public int getInstallLocation() { 20316 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 20317 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, 20318 PackageHelper.APP_INSTALL_AUTO); 20319 } 20320 20321 /** Called by UserManagerService */ 20322 void cleanUpUser(UserManagerService userManager, int userHandle) { 20323 synchronized (mPackages) { 20324 mDirtyUsers.remove(userHandle); 20325 mUserNeedsBadging.delete(userHandle); 20326 mSettings.removeUserLPw(userHandle); 20327 mPendingBroadcasts.remove(userHandle); 20328 mEphemeralApplicationRegistry.onUserRemovedLPw(userHandle); 20329 removeUnusedPackagesLPw(userManager, userHandle); 20330 } 20331 } 20332 20333 /** 20334 * We're removing userHandle and would like to remove any downloaded packages 20335 * that are no longer in use by any other user. 20336 * @param userHandle the user being removed 20337 */ 20338 private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) { 20339 final boolean DEBUG_CLEAN_APKS = false; 20340 int [] users = userManager.getUserIds(); 20341 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 20342 while (psit.hasNext()) { 20343 PackageSetting ps = psit.next(); 20344 if (ps.pkg == null) { 20345 continue; 20346 } 20347 final String packageName = ps.pkg.packageName; 20348 // Skip over if system app 20349 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) { 20350 continue; 20351 } 20352 if (DEBUG_CLEAN_APKS) { 20353 Slog.i(TAG, "Checking package " + packageName); 20354 } 20355 boolean keep = shouldKeepUninstalledPackageLPr(packageName); 20356 if (keep) { 20357 if (DEBUG_CLEAN_APKS) { 20358 Slog.i(TAG, " Keeping package " + packageName + " - requested by DO"); 20359 } 20360 } else { 20361 for (int i = 0; i < users.length; i++) { 20362 if (users[i] != userHandle && ps.getInstalled(users[i])) { 20363 keep = true; 20364 if (DEBUG_CLEAN_APKS) { 20365 Slog.i(TAG, " Keeping package " + packageName + " for user " 20366 + users[i]); 20367 } 20368 break; 20369 } 20370 } 20371 } 20372 if (!keep) { 20373 if (DEBUG_CLEAN_APKS) { 20374 Slog.i(TAG, " Removing package " + packageName); 20375 } 20376 mHandler.post(new Runnable() { 20377 public void run() { 20378 deletePackageX(packageName, userHandle, 0); 20379 } //end run 20380 }); 20381 } 20382 } 20383 } 20384 20385 /** Called by UserManagerService */ 20386 void createNewUser(int userId) { 20387 synchronized (mInstallLock) { 20388 mSettings.createNewUserLI(this, mInstaller, userId); 20389 } 20390 synchronized (mPackages) { 20391 scheduleWritePackageRestrictionsLocked(userId); 20392 scheduleWritePackageListLocked(userId); 20393 applyFactoryDefaultBrowserLPw(userId); 20394 primeDomainVerificationsLPw(userId); 20395 } 20396 } 20397 20398 void onNewUserCreated(final int userId) { 20399 mDefaultPermissionPolicy.grantDefaultPermissions(userId); 20400 // If permission review for legacy apps is required, we represent 20401 // dagerous permissions for such apps as always granted runtime 20402 // permissions to keep per user flag state whether review is needed. 20403 // Hence, if a new user is added we have to propagate dangerous 20404 // permission grants for these legacy apps. 20405 if (mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED) { 20406 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL 20407 | UPDATE_PERMISSIONS_REPLACE_ALL); 20408 } 20409 } 20410 20411 @Override 20412 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException { 20413 mContext.enforceCallingOrSelfPermission( 20414 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 20415 "Only package verification agents can read the verifier device identity"); 20416 20417 synchronized (mPackages) { 20418 return mSettings.getVerifierDeviceIdentityLPw(); 20419 } 20420 } 20421 20422 @Override 20423 public void setPermissionEnforced(String permission, boolean enforced) { 20424 // TODO: Now that we no longer change GID for storage, this should to away. 20425 mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 20426 "setPermissionEnforced"); 20427 if (READ_EXTERNAL_STORAGE.equals(permission)) { 20428 synchronized (mPackages) { 20429 if (mSettings.mReadExternalStorageEnforced == null 20430 || mSettings.mReadExternalStorageEnforced != enforced) { 20431 mSettings.mReadExternalStorageEnforced = enforced; 20432 mSettings.writeLPr(); 20433 } 20434 } 20435 // kill any non-foreground processes so we restart them and 20436 // grant/revoke the GID. 20437 final IActivityManager am = ActivityManagerNative.getDefault(); 20438 if (am != null) { 20439 final long token = Binder.clearCallingIdentity(); 20440 try { 20441 am.killProcessesBelowForeground("setPermissionEnforcement"); 20442 } catch (RemoteException e) { 20443 } finally { 20444 Binder.restoreCallingIdentity(token); 20445 } 20446 } 20447 } else { 20448 throw new IllegalArgumentException("No selective enforcement for " + permission); 20449 } 20450 } 20451 20452 @Override 20453 @Deprecated 20454 public boolean isPermissionEnforced(String permission) { 20455 return true; 20456 } 20457 20458 @Override 20459 public boolean isStorageLow() { 20460 final long token = Binder.clearCallingIdentity(); 20461 try { 20462 final DeviceStorageMonitorInternal 20463 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 20464 if (dsm != null) { 20465 return dsm.isMemoryLow(); 20466 } else { 20467 return false; 20468 } 20469 } finally { 20470 Binder.restoreCallingIdentity(token); 20471 } 20472 } 20473 20474 @Override 20475 public IPackageInstaller getPackageInstaller() { 20476 return mInstallerService; 20477 } 20478 20479 private boolean userNeedsBadging(int userId) { 20480 int index = mUserNeedsBadging.indexOfKey(userId); 20481 if (index < 0) { 20482 final UserInfo userInfo; 20483 final long token = Binder.clearCallingIdentity(); 20484 try { 20485 userInfo = sUserManager.getUserInfo(userId); 20486 } finally { 20487 Binder.restoreCallingIdentity(token); 20488 } 20489 final boolean b; 20490 if (userInfo != null && userInfo.isManagedProfile()) { 20491 b = true; 20492 } else { 20493 b = false; 20494 } 20495 mUserNeedsBadging.put(userId, b); 20496 return b; 20497 } 20498 return mUserNeedsBadging.valueAt(index); 20499 } 20500 20501 @Override 20502 public KeySet getKeySetByAlias(String packageName, String alias) { 20503 if (packageName == null || alias == null) { 20504 return null; 20505 } 20506 synchronized(mPackages) { 20507 final PackageParser.Package pkg = mPackages.get(packageName); 20508 if (pkg == null) { 20509 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 20510 throw new IllegalArgumentException("Unknown package: " + packageName); 20511 } 20512 KeySetManagerService ksms = mSettings.mKeySetManagerService; 20513 return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias)); 20514 } 20515 } 20516 20517 @Override 20518 public KeySet getSigningKeySet(String packageName) { 20519 if (packageName == null) { 20520 return null; 20521 } 20522 synchronized(mPackages) { 20523 final PackageParser.Package pkg = mPackages.get(packageName); 20524 if (pkg == null) { 20525 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 20526 throw new IllegalArgumentException("Unknown package: " + packageName); 20527 } 20528 if (pkg.applicationInfo.uid != Binder.getCallingUid() 20529 && Process.SYSTEM_UID != Binder.getCallingUid()) { 20530 throw new SecurityException("May not access signing KeySet of other apps."); 20531 } 20532 KeySetManagerService ksms = mSettings.mKeySetManagerService; 20533 return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName)); 20534 } 20535 } 20536 20537 @Override 20538 public boolean isPackageSignedByKeySet(String packageName, KeySet ks) { 20539 if (packageName == null || ks == null) { 20540 return false; 20541 } 20542 synchronized(mPackages) { 20543 final PackageParser.Package pkg = mPackages.get(packageName); 20544 if (pkg == null) { 20545 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 20546 throw new IllegalArgumentException("Unknown package: " + packageName); 20547 } 20548 IBinder ksh = ks.getToken(); 20549 if (ksh instanceof KeySetHandle) { 20550 KeySetManagerService ksms = mSettings.mKeySetManagerService; 20551 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh); 20552 } 20553 return false; 20554 } 20555 } 20556 20557 @Override 20558 public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) { 20559 if (packageName == null || ks == null) { 20560 return false; 20561 } 20562 synchronized(mPackages) { 20563 final PackageParser.Package pkg = mPackages.get(packageName); 20564 if (pkg == null) { 20565 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 20566 throw new IllegalArgumentException("Unknown package: " + packageName); 20567 } 20568 IBinder ksh = ks.getToken(); 20569 if (ksh instanceof KeySetHandle) { 20570 KeySetManagerService ksms = mSettings.mKeySetManagerService; 20571 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh); 20572 } 20573 return false; 20574 } 20575 } 20576 20577 private void deletePackageIfUnusedLPr(final String packageName) { 20578 PackageSetting ps = mSettings.mPackages.get(packageName); 20579 if (ps == null) { 20580 return; 20581 } 20582 if (!ps.isAnyInstalled(sUserManager.getUserIds())) { 20583 // TODO Implement atomic delete if package is unused 20584 // It is currently possible that the package will be deleted even if it is installed 20585 // after this method returns. 20586 mHandler.post(new Runnable() { 20587 public void run() { 20588 deletePackageX(packageName, 0, PackageManager.DELETE_ALL_USERS); 20589 } 20590 }); 20591 } 20592 } 20593 20594 /** 20595 * Check and throw if the given before/after packages would be considered a 20596 * downgrade. 20597 */ 20598 private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after) 20599 throws PackageManagerException { 20600 if (after.versionCode < before.mVersionCode) { 20601 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 20602 "Update version code " + after.versionCode + " is older than current " 20603 + before.mVersionCode); 20604 } else if (after.versionCode == before.mVersionCode) { 20605 if (after.baseRevisionCode < before.baseRevisionCode) { 20606 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 20607 "Update base revision code " + after.baseRevisionCode 20608 + " is older than current " + before.baseRevisionCode); 20609 } 20610 20611 if (!ArrayUtils.isEmpty(after.splitNames)) { 20612 for (int i = 0; i < after.splitNames.length; i++) { 20613 final String splitName = after.splitNames[i]; 20614 final int j = ArrayUtils.indexOf(before.splitNames, splitName); 20615 if (j != -1) { 20616 if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) { 20617 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 20618 "Update split " + splitName + " revision code " 20619 + after.splitRevisionCodes[i] + " is older than current " 20620 + before.splitRevisionCodes[j]); 20621 } 20622 } 20623 } 20624 } 20625 } 20626 } 20627 20628 private static class MoveCallbacks extends Handler { 20629 private static final int MSG_CREATED = 1; 20630 private static final int MSG_STATUS_CHANGED = 2; 20631 20632 private final RemoteCallbackList<IPackageMoveObserver> 20633 mCallbacks = new RemoteCallbackList<>(); 20634 20635 private final SparseIntArray mLastStatus = new SparseIntArray(); 20636 20637 public MoveCallbacks(Looper looper) { 20638 super(looper); 20639 } 20640 20641 public void register(IPackageMoveObserver callback) { 20642 mCallbacks.register(callback); 20643 } 20644 20645 public void unregister(IPackageMoveObserver callback) { 20646 mCallbacks.unregister(callback); 20647 } 20648 20649 @Override 20650 public void handleMessage(Message msg) { 20651 final SomeArgs args = (SomeArgs) msg.obj; 20652 final int n = mCallbacks.beginBroadcast(); 20653 for (int i = 0; i < n; i++) { 20654 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i); 20655 try { 20656 invokeCallback(callback, msg.what, args); 20657 } catch (RemoteException ignored) { 20658 } 20659 } 20660 mCallbacks.finishBroadcast(); 20661 args.recycle(); 20662 } 20663 20664 private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args) 20665 throws RemoteException { 20666 switch (what) { 20667 case MSG_CREATED: { 20668 callback.onCreated(args.argi1, (Bundle) args.arg2); 20669 break; 20670 } 20671 case MSG_STATUS_CHANGED: { 20672 callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3); 20673 break; 20674 } 20675 } 20676 } 20677 20678 private void notifyCreated(int moveId, Bundle extras) { 20679 Slog.v(TAG, "Move " + moveId + " created " + extras.toString()); 20680 20681 final SomeArgs args = SomeArgs.obtain(); 20682 args.argi1 = moveId; 20683 args.arg2 = extras; 20684 obtainMessage(MSG_CREATED, args).sendToTarget(); 20685 } 20686 20687 private void notifyStatusChanged(int moveId, int status) { 20688 notifyStatusChanged(moveId, status, -1); 20689 } 20690 20691 private void notifyStatusChanged(int moveId, int status, long estMillis) { 20692 Slog.v(TAG, "Move " + moveId + " status " + status); 20693 20694 final SomeArgs args = SomeArgs.obtain(); 20695 args.argi1 = moveId; 20696 args.argi2 = status; 20697 args.arg3 = estMillis; 20698 obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget(); 20699 20700 synchronized (mLastStatus) { 20701 mLastStatus.put(moveId, status); 20702 } 20703 } 20704 } 20705 20706 private final static class OnPermissionChangeListeners extends Handler { 20707 private static final int MSG_ON_PERMISSIONS_CHANGED = 1; 20708 20709 private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners = 20710 new RemoteCallbackList<>(); 20711 20712 public OnPermissionChangeListeners(Looper looper) { 20713 super(looper); 20714 } 20715 20716 @Override 20717 public void handleMessage(Message msg) { 20718 switch (msg.what) { 20719 case MSG_ON_PERMISSIONS_CHANGED: { 20720 final int uid = msg.arg1; 20721 handleOnPermissionsChanged(uid); 20722 } break; 20723 } 20724 } 20725 20726 public void addListenerLocked(IOnPermissionsChangeListener listener) { 20727 mPermissionListeners.register(listener); 20728 20729 } 20730 20731 public void removeListenerLocked(IOnPermissionsChangeListener listener) { 20732 mPermissionListeners.unregister(listener); 20733 } 20734 20735 public void onPermissionsChanged(int uid) { 20736 if (mPermissionListeners.getRegisteredCallbackCount() > 0) { 20737 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget(); 20738 } 20739 } 20740 20741 private void handleOnPermissionsChanged(int uid) { 20742 final int count = mPermissionListeners.beginBroadcast(); 20743 try { 20744 for (int i = 0; i < count; i++) { 20745 IOnPermissionsChangeListener callback = mPermissionListeners 20746 .getBroadcastItem(i); 20747 try { 20748 callback.onPermissionsChanged(uid); 20749 } catch (RemoteException e) { 20750 Log.e(TAG, "Permission listener is dead", e); 20751 } 20752 } 20753 } finally { 20754 mPermissionListeners.finishBroadcast(); 20755 } 20756 } 20757 } 20758 20759 private class PackageManagerInternalImpl extends PackageManagerInternal { 20760 @Override 20761 public void setLocationPackagesProvider(PackagesProvider provider) { 20762 synchronized (mPackages) { 20763 mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider); 20764 } 20765 } 20766 20767 @Override 20768 public void setVoiceInteractionPackagesProvider(PackagesProvider provider) { 20769 synchronized (mPackages) { 20770 mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider); 20771 } 20772 } 20773 20774 @Override 20775 public void setSmsAppPackagesProvider(PackagesProvider provider) { 20776 synchronized (mPackages) { 20777 mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider); 20778 } 20779 } 20780 20781 @Override 20782 public void setDialerAppPackagesProvider(PackagesProvider provider) { 20783 synchronized (mPackages) { 20784 mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider); 20785 } 20786 } 20787 20788 @Override 20789 public void setSimCallManagerPackagesProvider(PackagesProvider provider) { 20790 synchronized (mPackages) { 20791 mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider); 20792 } 20793 } 20794 20795 @Override 20796 public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) { 20797 synchronized (mPackages) { 20798 mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider); 20799 } 20800 } 20801 20802 @Override 20803 public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) { 20804 synchronized (mPackages) { 20805 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr( 20806 packageName, userId); 20807 } 20808 } 20809 20810 @Override 20811 public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) { 20812 synchronized (mPackages) { 20813 mSettings.setDefaultDialerPackageNameLPw(packageName, userId); 20814 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr( 20815 packageName, userId); 20816 } 20817 } 20818 20819 @Override 20820 public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) { 20821 synchronized (mPackages) { 20822 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr( 20823 packageName, userId); 20824 } 20825 } 20826 20827 @Override 20828 public void setKeepUninstalledPackages(final List<String> packageList) { 20829 Preconditions.checkNotNull(packageList); 20830 List<String> removedFromList = null; 20831 synchronized (mPackages) { 20832 if (mKeepUninstalledPackages != null) { 20833 final int packagesCount = mKeepUninstalledPackages.size(); 20834 for (int i = 0; i < packagesCount; i++) { 20835 String oldPackage = mKeepUninstalledPackages.get(i); 20836 if (packageList != null && packageList.contains(oldPackage)) { 20837 continue; 20838 } 20839 if (removedFromList == null) { 20840 removedFromList = new ArrayList<>(); 20841 } 20842 removedFromList.add(oldPackage); 20843 } 20844 } 20845 mKeepUninstalledPackages = new ArrayList<>(packageList); 20846 if (removedFromList != null) { 20847 final int removedCount = removedFromList.size(); 20848 for (int i = 0; i < removedCount; i++) { 20849 deletePackageIfUnusedLPr(removedFromList.get(i)); 20850 } 20851 } 20852 } 20853 } 20854 20855 @Override 20856 public boolean isPermissionsReviewRequired(String packageName, int userId) { 20857 synchronized (mPackages) { 20858 // If we do not support permission review, done. 20859 if (!mPermissionReviewRequired && !Build.PERMISSIONS_REVIEW_REQUIRED) { 20860 return false; 20861 } 20862 20863 PackageSetting packageSetting = mSettings.mPackages.get(packageName); 20864 if (packageSetting == null) { 20865 return false; 20866 } 20867 20868 // Permission review applies only to apps not supporting the new permission model. 20869 if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) { 20870 return false; 20871 } 20872 20873 // Legacy apps have the permission and get user consent on launch. 20874 PermissionsState permissionsState = packageSetting.getPermissionsState(); 20875 return permissionsState.isPermissionReviewRequired(userId); 20876 } 20877 } 20878 20879 @Override 20880 public ApplicationInfo getApplicationInfo(String packageName, int userId) { 20881 return PackageManagerService.this.getApplicationInfo(packageName, 0 /*flags*/, userId); 20882 } 20883 20884 @Override 20885 public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, 20886 int userId) { 20887 return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId); 20888 } 20889 20890 @Override 20891 public void setDeviceAndProfileOwnerPackages( 20892 int deviceOwnerUserId, String deviceOwnerPackage, 20893 SparseArray<String> profileOwnerPackages) { 20894 mProtectedPackages.setDeviceAndProfileOwnerPackages( 20895 deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages); 20896 } 20897 20898 @Override 20899 public boolean isPackageDataProtected(int userId, String packageName) { 20900 return mProtectedPackages.isPackageDataProtected(userId, packageName); 20901 } 20902 } 20903 20904 @Override 20905 public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) { 20906 enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps"); 20907 synchronized (mPackages) { 20908 final long identity = Binder.clearCallingIdentity(); 20909 try { 20910 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr( 20911 packageNames, userId); 20912 } finally { 20913 Binder.restoreCallingIdentity(identity); 20914 } 20915 } 20916 } 20917 20918 private static void enforceSystemOrPhoneCaller(String tag) { 20919 int callingUid = Binder.getCallingUid(); 20920 if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) { 20921 throw new SecurityException( 20922 "Cannot call " + tag + " from UID " + callingUid); 20923 } 20924 } 20925 20926 boolean isHistoricalPackageUsageAvailable() { 20927 return mPackageUsage.isHistoricalPackageUsageAvailable(); 20928 } 20929 20930 /** 20931 * Return a <b>copy</b> of the collection of packages known to the package manager. 20932 * @return A copy of the values of mPackages. 20933 */ 20934 Collection<PackageParser.Package> getPackages() { 20935 synchronized (mPackages) { 20936 return new ArrayList<>(mPackages.values()); 20937 } 20938 } 20939 20940 /** 20941 * Logs process start information (including base APK hash) to the security log. 20942 * @hide 20943 */ 20944 public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo, 20945 String apkFile, int pid) { 20946 if (!SecurityLog.isLoggingEnabled()) { 20947 return; 20948 } 20949 Bundle data = new Bundle(); 20950 data.putLong("startTimestamp", System.currentTimeMillis()); 20951 data.putString("processName", processName); 20952 data.putInt("uid", uid); 20953 data.putString("seinfo", seinfo); 20954 data.putString("apkFile", apkFile); 20955 data.putInt("pid", pid); 20956 Message msg = mProcessLoggingHandler.obtainMessage( 20957 ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG); 20958 msg.setData(data); 20959 mProcessLoggingHandler.sendMessage(msg); 20960 } 20961 20962 public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) { 20963 return mCompilerStats.getPackageStats(pkgName); 20964 } 20965 20966 public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) { 20967 return getOrCreateCompilerPackageStats(pkg.packageName); 20968 } 20969 20970 public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) { 20971 return mCompilerStats.getOrCreatePackageStats(pkgName); 20972 } 20973 20974 public void deleteCompilerPackageStats(String pkgName) { 20975 mCompilerStats.deletePackageStats(pkgName); 20976 } 20977} 20978