PackageManagerService.java revision 1c6f72397320c8e4aeb34d55429ee62e2acd432a
1/* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.pm; 18 19import static android.Manifest.permission.READ_EXTERNAL_STORAGE; 20import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE; 21import static android.Manifest.permission.WRITE_MEDIA_STORAGE; 22import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 23import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED; 24import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED; 25import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER; 26import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; 27import static android.content.pm.PackageManager.DELETE_KEEP_DATA; 28import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 29import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED; 30import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 31import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE; 32import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 33import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED; 34import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET; 35import static android.content.pm.PackageManager.INSTALL_EXTERNAL; 36import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 37import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER; 38import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE; 39import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION; 40import static android.content.pm.PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID; 41import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 42import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 43import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK; 44import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 45import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY; 46import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED; 47import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE; 48import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE; 49import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY; 50import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE; 51import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED; 52import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 53import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK; 54import static android.content.pm.PackageManager.INSTALL_INTERNAL; 55import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; 56import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 57import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK; 58import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 59import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER; 60import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 61import static android.content.pm.PackageManager.MATCH_ALL; 62import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING; 63import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE; 64import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE; 65import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS; 66import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY; 67import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY; 68import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES; 69import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN; 70import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST; 71import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR; 72import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING; 73import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE; 74import static android.content.pm.PackageManager.PERMISSION_DENIED; 75import static android.content.pm.PackageManager.PERMISSION_GRANTED; 76import static android.content.pm.PackageParser.PARSE_IS_PRIVILEGED; 77import static android.content.pm.PackageParser.isApkFile; 78import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; 79import static android.system.OsConstants.O_CREAT; 80import static android.system.OsConstants.O_RDWR; 81 82import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE; 83import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT; 84import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME; 85import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME; 86import static com.android.internal.util.ArrayUtils.appendInt; 87import static com.android.server.pm.Installer.DEXOPT_PUBLIC; 88import static com.android.server.pm.InstructionSets.getAppDexInstructionSets; 89import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet; 90import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets; 91import static com.android.server.pm.InstructionSets.getPreferredInstructionSet; 92import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet; 93import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason; 94import static com.android.server.pm.PackageManagerServiceCompilerMapping.getFullCompilerFilter; 95import static com.android.server.pm.PackageManagerServiceCompilerMapping.getNonProfileGuidedCompilerFilter; 96import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE; 97import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS; 98import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED; 99 100import android.Manifest; 101import android.annotation.NonNull; 102import android.annotation.Nullable; 103import android.app.ActivityManager; 104import android.app.ActivityManagerNative; 105import android.app.IActivityManager; 106import android.app.ResourcesManager; 107import android.app.admin.IDevicePolicyManager; 108import android.app.admin.SecurityLog; 109import android.app.backup.IBackupManager; 110import android.content.BroadcastReceiver; 111import android.content.ComponentName; 112import android.content.ContentResolver; 113import android.content.Context; 114import android.content.IIntentReceiver; 115import android.content.Intent; 116import android.content.IntentFilter; 117import android.content.IntentSender; 118import android.content.IntentSender.SendIntentException; 119import android.content.ServiceConnection; 120import android.content.pm.ActivityInfo; 121import android.content.pm.ApplicationInfo; 122import android.content.pm.AppsQueryHelper; 123import android.content.pm.ComponentInfo; 124import android.content.pm.EphemeralApplicationInfo; 125import android.content.pm.EphemeralResolveInfo; 126import android.content.pm.EphemeralResolveInfo.EphemeralDigest; 127import android.content.pm.EphemeralResolveInfo.EphemeralResolveIntentInfo; 128import android.content.pm.FeatureInfo; 129import android.content.pm.IOnPermissionsChangeListener; 130import android.content.pm.IPackageDataObserver; 131import android.content.pm.IPackageDeleteObserver; 132import android.content.pm.IPackageDeleteObserver2; 133import android.content.pm.IPackageInstallObserver2; 134import android.content.pm.IPackageInstaller; 135import android.content.pm.IPackageManager; 136import android.content.pm.IPackageMoveObserver; 137import android.content.pm.IPackageStatsObserver; 138import android.content.pm.InstrumentationInfo; 139import android.content.pm.IntentFilterVerificationInfo; 140import android.content.pm.KeySet; 141import android.content.pm.PackageCleanItem; 142import android.content.pm.PackageInfo; 143import android.content.pm.PackageInfoLite; 144import android.content.pm.PackageInstaller; 145import android.content.pm.PackageManager; 146import android.content.pm.PackageManager.LegacyPackageDeleteObserver; 147import android.content.pm.PackageManagerInternal; 148import android.content.pm.PackageParser; 149import android.content.pm.PackageParser.ActivityIntentInfo; 150import android.content.pm.PackageParser.PackageLite; 151import android.content.pm.PackageParser.PackageParserException; 152import android.content.pm.PackageStats; 153import android.content.pm.PackageUserState; 154import android.content.pm.ParceledListSlice; 155import android.content.pm.PermissionGroupInfo; 156import android.content.pm.PermissionInfo; 157import android.content.pm.ProviderInfo; 158import android.content.pm.ResolveInfo; 159import android.content.pm.ServiceInfo; 160import android.content.pm.Signature; 161import android.content.pm.UserInfo; 162import android.content.pm.VerifierDeviceIdentity; 163import android.content.pm.VerifierInfo; 164import android.content.res.Resources; 165import android.graphics.Bitmap; 166import android.hardware.display.DisplayManager; 167import android.net.Uri; 168import android.os.Binder; 169import android.os.Build; 170import android.os.Bundle; 171import android.os.Debug; 172import android.os.Environment; 173import android.os.Environment.UserEnvironment; 174import android.os.FileUtils; 175import android.os.Handler; 176import android.os.IBinder; 177import android.os.Looper; 178import android.os.Message; 179import android.os.Parcel; 180import android.os.ParcelFileDescriptor; 181import android.os.PatternMatcher; 182import android.os.Process; 183import android.os.RemoteCallbackList; 184import android.os.RemoteException; 185import android.os.ResultReceiver; 186import android.os.SELinux; 187import android.os.ServiceManager; 188import android.os.SystemClock; 189import android.os.SystemProperties; 190import android.os.Trace; 191import android.os.UserHandle; 192import android.os.UserManager; 193import android.os.UserManagerInternal; 194import android.os.storage.IMountService; 195import android.os.storage.MountServiceInternal; 196import android.os.storage.StorageEventListener; 197import android.os.storage.StorageManager; 198import android.os.storage.VolumeInfo; 199import android.os.storage.VolumeRecord; 200import android.provider.Settings.Global; 201import android.provider.Settings.Secure; 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.Pair; 217import android.util.PrintStreamPrinter; 218import android.util.Slog; 219import android.util.SparseArray; 220import android.util.SparseBooleanArray; 221import android.util.SparseIntArray; 222import android.util.Xml; 223import android.util.jar.StrictJarFile; 224import android.view.Display; 225 226import com.android.internal.R; 227import com.android.internal.annotations.GuardedBy; 228import com.android.internal.app.IMediaContainerService; 229import com.android.internal.app.ResolverActivity; 230import com.android.internal.content.NativeLibraryHelper; 231import com.android.internal.content.PackageHelper; 232import com.android.internal.logging.MetricsLogger; 233import com.android.internal.os.IParcelFileDescriptorFactory; 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.Installer.InstallerException; 253import com.android.server.pm.PermissionsState.PermissionState; 254import com.android.server.pm.Settings.DatabaseVersion; 255import com.android.server.pm.Settings.VersionInfo; 256import com.android.server.storage.DeviceStorageMonitorInternal; 257 258import dalvik.system.CloseGuard; 259import dalvik.system.DexFile; 260import dalvik.system.VMRuntime; 261 262import libcore.io.IoUtils; 263import libcore.util.EmptyArray; 264 265import org.xmlpull.v1.XmlPullParser; 266import org.xmlpull.v1.XmlPullParserException; 267import org.xmlpull.v1.XmlSerializer; 268 269import java.io.BufferedOutputStream; 270import java.io.BufferedReader; 271import java.io.ByteArrayInputStream; 272import java.io.ByteArrayOutputStream; 273import java.io.File; 274import java.io.FileDescriptor; 275import java.io.FileInputStream; 276import java.io.FileNotFoundException; 277import java.io.FileOutputStream; 278import java.io.FileReader; 279import java.io.FilenameFilter; 280import java.io.IOException; 281import java.io.PrintWriter; 282import java.nio.charset.StandardCharsets; 283import java.security.DigestInputStream; 284import java.security.MessageDigest; 285import java.security.NoSuchAlgorithmException; 286import java.security.PublicKey; 287import java.security.cert.Certificate; 288import java.security.cert.CertificateEncodingException; 289import java.security.cert.CertificateException; 290import java.text.SimpleDateFormat; 291import java.util.ArrayList; 292import java.util.Arrays; 293import java.util.Collection; 294import java.util.Collections; 295import java.util.Comparator; 296import java.util.Date; 297import java.util.HashSet; 298import java.util.Iterator; 299import java.util.List; 300import java.util.Map; 301import java.util.Objects; 302import java.util.Set; 303import java.util.concurrent.CountDownLatch; 304import java.util.concurrent.TimeUnit; 305import java.util.concurrent.atomic.AtomicBoolean; 306import java.util.concurrent.atomic.AtomicInteger; 307 308/** 309 * Keep track of all those APKs everywhere. 310 * <p> 311 * Internally there are two important locks: 312 * <ul> 313 * <li>{@link #mPackages} is used to guard all in-memory parsed package details 314 * and other related state. It is a fine-grained lock that should only be held 315 * momentarily, as it's one of the most contended locks in the system. 316 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose 317 * operations typically involve heavy lifting of application data on disk. Since 318 * {@code installd} is single-threaded, and it's operations can often be slow, 319 * this lock should never be acquired while already holding {@link #mPackages}. 320 * Conversely, it's safe to acquire {@link #mPackages} momentarily while already 321 * holding {@link #mInstallLock}. 322 * </ul> 323 * Many internal methods rely on the caller to hold the appropriate locks, and 324 * this contract is expressed through method name suffixes: 325 * <ul> 326 * <li>fooLI(): the caller must hold {@link #mInstallLock} 327 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package 328 * being modified must be frozen 329 * <li>fooLPr(): the caller must hold {@link #mPackages} for reading 330 * <li>fooLPw(): the caller must hold {@link #mPackages} for writing 331 * </ul> 332 * <p> 333 * Because this class is very central to the platform's security; please run all 334 * CTS and unit tests whenever making modifications: 335 * 336 * <pre> 337 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core 338 * $ cts-tradefed run commandAndExit cts -m AppSecurityTests 339 * </pre> 340 */ 341public class PackageManagerService extends IPackageManager.Stub { 342 static final String TAG = "PackageManager"; 343 static final boolean DEBUG_SETTINGS = false; 344 static final boolean DEBUG_PREFERRED = false; 345 static final boolean DEBUG_UPGRADE = false; 346 static final boolean DEBUG_DOMAIN_VERIFICATION = false; 347 private static final boolean DEBUG_BACKUP = false; 348 private static final boolean DEBUG_INSTALL = false; 349 private static final boolean DEBUG_REMOVE = false; 350 private static final boolean DEBUG_BROADCASTS = false; 351 private static final boolean DEBUG_SHOW_INFO = false; 352 private static final boolean DEBUG_PACKAGE_INFO = false; 353 private static final boolean DEBUG_INTENT_MATCHING = false; 354 private static final boolean DEBUG_PACKAGE_SCANNING = false; 355 private static final boolean DEBUG_VERIFY = false; 356 private static final boolean DEBUG_FILTERS = false; 357 358 // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService 359 // and PackageDexOptimizer. All these classes have their own flag to allow switching a single 360 // user, but by default initialize to this. 361 static final boolean DEBUG_DEXOPT = false; 362 363 private static final boolean DEBUG_ABI_SELECTION = false; 364 private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE; 365 private static final boolean DEBUG_TRIAGED_MISSING = false; 366 private static final boolean DEBUG_APP_DATA = false; 367 368 static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false; 369 370 private static final boolean DISABLE_EPHEMERAL_APPS = false; 371 private static final boolean HIDE_EPHEMERAL_APIS = true; 372 373 private static final int RADIO_UID = Process.PHONE_UID; 374 private static final int LOG_UID = Process.LOG_UID; 375 private static final int NFC_UID = Process.NFC_UID; 376 private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID; 377 private static final int SHELL_UID = Process.SHELL_UID; 378 379 // Cap the size of permission trees that 3rd party apps can define 380 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768; // characters of text 381 382 // Suffix used during package installation when copying/moving 383 // package apks to install directory. 384 private static final String INSTALL_PACKAGE_SUFFIX = "-"; 385 386 static final int SCAN_NO_DEX = 1<<1; 387 static final int SCAN_FORCE_DEX = 1<<2; 388 static final int SCAN_UPDATE_SIGNATURE = 1<<3; 389 static final int SCAN_NEW_INSTALL = 1<<4; 390 static final int SCAN_NO_PATHS = 1<<5; 391 static final int SCAN_UPDATE_TIME = 1<<6; 392 static final int SCAN_DEFER_DEX = 1<<7; 393 static final int SCAN_BOOTING = 1<<8; 394 static final int SCAN_TRUSTED_OVERLAY = 1<<9; 395 static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10; 396 static final int SCAN_REPLACING = 1<<11; 397 static final int SCAN_REQUIRE_KNOWN = 1<<12; 398 static final int SCAN_MOVE = 1<<13; 399 static final int SCAN_INITIAL = 1<<14; 400 static final int SCAN_CHECK_ONLY = 1<<15; 401 static final int SCAN_DONT_KILL_APP = 1<<17; 402 static final int SCAN_IGNORE_FROZEN = 1<<18; 403 404 static final int REMOVE_CHATTY = 1<<16; 405 406 private static final int[] EMPTY_INT_ARRAY = new int[0]; 407 408 /** 409 * Timeout (in milliseconds) after which the watchdog should declare that 410 * our handler thread is wedged. The usual default for such things is one 411 * minute but we sometimes do very lengthy I/O operations on this thread, 412 * such as installing multi-gigabyte applications, so ours needs to be longer. 413 */ 414 private static final long WATCHDOG_TIMEOUT = 1000*60*10; // ten minutes 415 416 /** 417 * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim 418 * be run on this device. We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL 419 * settings entry if available, otherwise we use the hardcoded default. If it's been 420 * more than this long since the last fstrim, we force one during the boot sequence. 421 * 422 * This backstops other fstrim scheduling: if the device is alive at midnight+idle, 423 * one gets run at the next available charging+idle time. This final mandatory 424 * no-fstrim check kicks in only of the other scheduling criteria is never met. 425 */ 426 private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS; 427 428 /** 429 * Whether verification is enabled by default. 430 */ 431 private static final boolean DEFAULT_VERIFY_ENABLE = true; 432 433 /** 434 * The default maximum time to wait for the verification agent to return in 435 * milliseconds. 436 */ 437 private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000; 438 439 /** 440 * The default response for package verification timeout. 441 * 442 * This can be either PackageManager.VERIFICATION_ALLOW or 443 * PackageManager.VERIFICATION_REJECT. 444 */ 445 private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW; 446 447 static final String PLATFORM_PACKAGE_NAME = "android"; 448 449 static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer"; 450 451 static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName( 452 DEFAULT_CONTAINER_PACKAGE, 453 "com.android.defcontainer.DefaultContainerService"); 454 455 private static final String KILL_APP_REASON_GIDS_CHANGED = 456 "permission grant or revoke changed gids"; 457 458 private static final String KILL_APP_REASON_PERMISSIONS_REVOKED = 459 "permissions revoked"; 460 461 private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive"; 462 463 private static final String PACKAGE_SCHEME = "package"; 464 465 private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay"; 466 /** 467 * If VENDOR_OVERLAY_SKU_PROPERTY is set, search for runtime resource overlay APKs in 468 * VENDOR_OVERLAY_DIR/<value of VENDOR_OVERLAY_SKU_PROPERTY> rather than in 469 * VENDOR_OVERLAY_DIR. 470 */ 471 private static final String VENDOR_OVERLAY_SKU_PROPERTY = "ro.boot.vendor.overlay.sku"; 472 473 private static int DEFAULT_EPHEMERAL_HASH_PREFIX_MASK = 0xFFFFF000; 474 private static int DEFAULT_EPHEMERAL_HASH_PREFIX_COUNT = 5; 475 476 /** Permission grant: not grant the permission. */ 477 private static final int GRANT_DENIED = 1; 478 479 /** Permission grant: grant the permission as an install permission. */ 480 private static final int GRANT_INSTALL = 2; 481 482 /** Permission grant: grant the permission as a runtime one. */ 483 private static final int GRANT_RUNTIME = 3; 484 485 /** Permission grant: grant as runtime a permission that was granted as an install time one. */ 486 private static final int GRANT_UPGRADE = 4; 487 488 /** Canonical intent used to identify what counts as a "web browser" app */ 489 private static final Intent sBrowserIntent; 490 static { 491 sBrowserIntent = new Intent(); 492 sBrowserIntent.setAction(Intent.ACTION_VIEW); 493 sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE); 494 sBrowserIntent.setData(Uri.parse("http:")); 495 } 496 497 /** 498 * The set of all protected actions [i.e. those actions for which a high priority 499 * intent filter is disallowed]. 500 */ 501 private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>(); 502 static { 503 PROTECTED_ACTIONS.add(Intent.ACTION_SEND); 504 PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO); 505 PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE); 506 PROTECTED_ACTIONS.add(Intent.ACTION_VIEW); 507 } 508 509 // Compilation reasons. 510 public static final int REASON_FIRST_BOOT = 0; 511 public static final int REASON_BOOT = 1; 512 public static final int REASON_INSTALL = 2; 513 public static final int REASON_BACKGROUND_DEXOPT = 3; 514 public static final int REASON_AB_OTA = 4; 515 public static final int REASON_NON_SYSTEM_LIBRARY = 5; 516 public static final int REASON_SHARED_APK = 6; 517 public static final int REASON_FORCED_DEXOPT = 7; 518 public static final int REASON_CORE_APP = 8; 519 520 public static final int REASON_LAST = REASON_CORE_APP; 521 522 /** Special library name that skips shared libraries check during compilation. */ 523 private static final String SKIP_SHARED_LIBRARY_CHECK = "&"; 524 525 final ServiceThread mHandlerThread; 526 527 final PackageHandler mHandler; 528 529 private final ProcessLoggingHandler mProcessLoggingHandler; 530 531 /** 532 * Messages for {@link #mHandler} that need to wait for system ready before 533 * being dispatched. 534 */ 535 private ArrayList<Message> mPostSystemReadyMessages; 536 537 final int mSdkVersion = Build.VERSION.SDK_INT; 538 539 final Context mContext; 540 final boolean mFactoryTest; 541 final boolean mOnlyCore; 542 final DisplayMetrics mMetrics; 543 final int mDefParseFlags; 544 final String[] mSeparateProcesses; 545 final boolean mIsUpgrade; 546 final boolean mIsPreNUpgrade; 547 final boolean mIsPreNMR1Upgrade; 548 549 @GuardedBy("mPackages") 550 private boolean mDexOptDialogShown; 551 552 /** The location for ASEC container files on internal storage. */ 553 final String mAsecInternalPath; 554 555 // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages 556 // LOCK HELD. Can be called with mInstallLock held. 557 @GuardedBy("mInstallLock") 558 final Installer mInstaller; 559 560 /** Directory where installed third-party apps stored */ 561 final File mAppInstallDir; 562 final File mEphemeralInstallDir; 563 564 /** 565 * Directory to which applications installed internally have their 566 * 32 bit native libraries copied. 567 */ 568 private File mAppLib32InstallDir; 569 570 // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked 571 // apps. 572 final File mDrmAppPrivateInstallDir; 573 574 // ---------------------------------------------------------------- 575 576 // Lock for state used when installing and doing other long running 577 // operations. Methods that must be called with this lock held have 578 // the suffix "LI". 579 final Object mInstallLock = new Object(); 580 581 // ---------------------------------------------------------------- 582 583 // Keys are String (package name), values are Package. This also serves 584 // as the lock for the global state. Methods that must be called with 585 // this lock held have the prefix "LP". 586 @GuardedBy("mPackages") 587 final ArrayMap<String, PackageParser.Package> mPackages = 588 new ArrayMap<String, PackageParser.Package>(); 589 590 final ArrayMap<String, Set<String>> mKnownCodebase = 591 new ArrayMap<String, Set<String>>(); 592 593 // Tracks available target package names -> overlay package paths. 594 final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays = 595 new ArrayMap<String, ArrayMap<String, PackageParser.Package>>(); 596 597 /** 598 * Tracks new system packages [received in an OTA] that we expect to 599 * find updated user-installed versions. Keys are package name, values 600 * are package location. 601 */ 602 final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>(); 603 /** 604 * Tracks high priority intent filters for protected actions. During boot, certain 605 * filter actions are protected and should never be allowed to have a high priority 606 * intent filter for them. However, there is one, and only one exception -- the 607 * setup wizard. It must be able to define a high priority intent filter for these 608 * actions to ensure there are no escapes from the wizard. We need to delay processing 609 * of these during boot as we need to look at all of the system packages in order 610 * to know which component is the setup wizard. 611 */ 612 private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>(); 613 /** 614 * Whether or not processing protected filters should be deferred. 615 */ 616 private boolean mDeferProtectedFilters = true; 617 618 /** 619 * Tracks existing system packages prior to receiving an OTA. Keys are package name. 620 */ 621 final private ArraySet<String> mExistingSystemPackages = new ArraySet<>(); 622 /** 623 * Whether or not system app permissions should be promoted from install to runtime. 624 */ 625 boolean mPromoteSystemApps; 626 627 @GuardedBy("mPackages") 628 final Settings mSettings; 629 630 /** 631 * Set of package names that are currently "frozen", which means active 632 * surgery is being done on the code/data for that package. The platform 633 * will refuse to launch frozen packages to avoid race conditions. 634 * 635 * @see PackageFreezer 636 */ 637 @GuardedBy("mPackages") 638 final ArraySet<String> mFrozenPackages = new ArraySet<>(); 639 640 final ProtectedPackages mProtectedPackages; 641 642 boolean mFirstBoot; 643 644 // System configuration read by SystemConfig. 645 final int[] mGlobalGids; 646 final SparseArray<ArraySet<String>> mSystemPermissions; 647 final ArrayMap<String, FeatureInfo> mAvailableFeatures; 648 649 // If mac_permissions.xml was found for seinfo labeling. 650 boolean mFoundPolicyFile; 651 652 private final EphemeralApplicationRegistry mEphemeralApplicationRegistry; 653 654 public static final class SharedLibraryEntry { 655 public final String path; 656 public final String apk; 657 658 SharedLibraryEntry(String _path, String _apk) { 659 path = _path; 660 apk = _apk; 661 } 662 } 663 664 // Currently known shared libraries. 665 final ArrayMap<String, SharedLibraryEntry> mSharedLibraries = 666 new ArrayMap<String, SharedLibraryEntry>(); 667 668 // All available activities, for your resolving pleasure. 669 final ActivityIntentResolver mActivities = 670 new ActivityIntentResolver(); 671 672 // All available receivers, for your resolving pleasure. 673 final ActivityIntentResolver mReceivers = 674 new ActivityIntentResolver(); 675 676 // All available services, for your resolving pleasure. 677 final ServiceIntentResolver mServices = new ServiceIntentResolver(); 678 679 // All available providers, for your resolving pleasure. 680 final ProviderIntentResolver mProviders = new ProviderIntentResolver(); 681 682 // Mapping from provider base names (first directory in content URI codePath) 683 // to the provider information. 684 final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority = 685 new ArrayMap<String, PackageParser.Provider>(); 686 687 // Mapping from instrumentation class names to info about them. 688 final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation = 689 new ArrayMap<ComponentName, PackageParser.Instrumentation>(); 690 691 // Mapping from permission names to info about them. 692 final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups = 693 new ArrayMap<String, PackageParser.PermissionGroup>(); 694 695 // Packages whose data we have transfered into another package, thus 696 // should no longer exist. 697 final ArraySet<String> mTransferedPackages = new ArraySet<String>(); 698 699 // Broadcast actions that are only available to the system. 700 final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>(); 701 702 /** List of packages waiting for verification. */ 703 final SparseArray<PackageVerificationState> mPendingVerification 704 = new SparseArray<PackageVerificationState>(); 705 706 /** Set of packages associated with each app op permission. */ 707 final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>(); 708 709 final PackageInstallerService mInstallerService; 710 711 private final PackageDexOptimizer mPackageDexOptimizer; 712 713 private AtomicInteger mNextMoveId = new AtomicInteger(); 714 private final MoveCallbacks mMoveCallbacks; 715 716 private final OnPermissionChangeListeners mOnPermissionChangeListeners; 717 718 // Cache of users who need badging. 719 SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray(); 720 721 /** Token for keys in mPendingVerification. */ 722 private int mPendingVerificationToken = 0; 723 724 volatile boolean mSystemReady; 725 volatile boolean mSafeMode; 726 volatile boolean mHasSystemUidErrors; 727 728 ApplicationInfo mAndroidApplication; 729 final ActivityInfo mResolveActivity = new ActivityInfo(); 730 final ResolveInfo mResolveInfo = new ResolveInfo(); 731 ComponentName mResolveComponentName; 732 PackageParser.Package mPlatformPackage; 733 ComponentName mCustomResolverComponentName; 734 735 boolean mResolverReplaced = false; 736 737 private final @Nullable ComponentName mIntentFilterVerifierComponent; 738 private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier; 739 740 private int mIntentFilterVerificationToken = 0; 741 742 /** Component that knows whether or not an ephemeral application exists */ 743 final ComponentName mEphemeralResolverComponent; 744 /** The service connection to the ephemeral resolver */ 745 final EphemeralResolverConnection mEphemeralResolverConnection; 746 747 /** Component used to install ephemeral applications */ 748 final ComponentName mEphemeralInstallerComponent; 749 final ActivityInfo mEphemeralInstallerActivity = new ActivityInfo(); 750 final ResolveInfo mEphemeralInstallerInfo = new ResolveInfo(); 751 752 final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates 753 = new SparseArray<IntentFilterVerificationState>(); 754 755 final DefaultPermissionGrantPolicy mDefaultPermissionPolicy; 756 757 // List of packages names to keep cached, even if they are uninstalled for all users 758 private List<String> mKeepUninstalledPackages; 759 760 private UserManagerInternal mUserManagerInternal; 761 762 private static class IFVerificationParams { 763 PackageParser.Package pkg; 764 boolean replacing; 765 int userId; 766 int verifierUid; 767 768 public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing, 769 int _userId, int _verifierUid) { 770 pkg = _pkg; 771 replacing = _replacing; 772 userId = _userId; 773 replacing = _replacing; 774 verifierUid = _verifierUid; 775 } 776 } 777 778 private interface IntentFilterVerifier<T extends IntentFilter> { 779 boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId, 780 T filter, String packageName); 781 void startVerifications(int userId); 782 void receiveVerificationResponse(int verificationId); 783 } 784 785 private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> { 786 private Context mContext; 787 private ComponentName mIntentFilterVerifierComponent; 788 private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>(); 789 790 public IntentVerifierProxy(Context context, ComponentName verifierComponent) { 791 mContext = context; 792 mIntentFilterVerifierComponent = verifierComponent; 793 } 794 795 private String getDefaultScheme() { 796 return IntentFilter.SCHEME_HTTPS; 797 } 798 799 @Override 800 public void startVerifications(int userId) { 801 // Launch verifications requests 802 int count = mCurrentIntentFilterVerifications.size(); 803 for (int n=0; n<count; n++) { 804 int verificationId = mCurrentIntentFilterVerifications.get(n); 805 final IntentFilterVerificationState ivs = 806 mIntentFilterVerificationStates.get(verificationId); 807 808 String packageName = ivs.getPackageName(); 809 810 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 811 final int filterCount = filters.size(); 812 ArraySet<String> domainsSet = new ArraySet<>(); 813 for (int m=0; m<filterCount; m++) { 814 PackageParser.ActivityIntentInfo filter = filters.get(m); 815 domainsSet.addAll(filter.getHostsList()); 816 } 817 ArrayList<String> domainsList = new ArrayList<>(domainsSet); 818 synchronized (mPackages) { 819 if (mSettings.createIntentFilterVerificationIfNeededLPw( 820 packageName, domainsList) != null) { 821 scheduleWriteSettingsLocked(); 822 } 823 } 824 sendVerificationRequest(userId, verificationId, ivs); 825 } 826 mCurrentIntentFilterVerifications.clear(); 827 } 828 829 private void sendVerificationRequest(int userId, int verificationId, 830 IntentFilterVerificationState ivs) { 831 832 Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 833 verificationIntent.putExtra( 834 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID, 835 verificationId); 836 verificationIntent.putExtra( 837 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME, 838 getDefaultScheme()); 839 verificationIntent.putExtra( 840 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS, 841 ivs.getHostsString()); 842 verificationIntent.putExtra( 843 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME, 844 ivs.getPackageName()); 845 verificationIntent.setComponent(mIntentFilterVerifierComponent); 846 verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 847 848 UserHandle user = new UserHandle(userId); 849 mContext.sendBroadcastAsUser(verificationIntent, user); 850 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 851 "Sending IntentFilter verification broadcast"); 852 } 853 854 public void receiveVerificationResponse(int verificationId) { 855 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 856 857 final boolean verified = ivs.isVerified(); 858 859 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 860 final int count = filters.size(); 861 if (DEBUG_DOMAIN_VERIFICATION) { 862 Slog.i(TAG, "Received verification response " + verificationId 863 + " for " + count + " filters, verified=" + verified); 864 } 865 for (int n=0; n<count; n++) { 866 PackageParser.ActivityIntentInfo filter = filters.get(n); 867 filter.setVerified(verified); 868 869 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString() 870 + " verified with result:" + verified + " and hosts:" 871 + ivs.getHostsString()); 872 } 873 874 mIntentFilterVerificationStates.remove(verificationId); 875 876 final String packageName = ivs.getPackageName(); 877 IntentFilterVerificationInfo ivi = null; 878 879 synchronized (mPackages) { 880 ivi = mSettings.getIntentFilterVerificationLPr(packageName); 881 } 882 if (ivi == null) { 883 Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:" 884 + verificationId + " packageName:" + packageName); 885 return; 886 } 887 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 888 "Updating IntentFilterVerificationInfo for package " + packageName 889 +" verificationId:" + verificationId); 890 891 synchronized (mPackages) { 892 if (verified) { 893 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS); 894 } else { 895 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK); 896 } 897 scheduleWriteSettingsLocked(); 898 899 final int userId = ivs.getUserId(); 900 if (userId != UserHandle.USER_ALL) { 901 final int userStatus = 902 mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 903 904 int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 905 boolean needUpdate = false; 906 907 // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have 908 // already been set by the User thru the Disambiguation dialog 909 switch (userStatus) { 910 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 911 if (verified) { 912 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 913 } else { 914 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 915 } 916 needUpdate = true; 917 break; 918 919 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 920 if (verified) { 921 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 922 needUpdate = true; 923 } 924 break; 925 926 default: 927 // Nothing to do 928 } 929 930 if (needUpdate) { 931 mSettings.updateIntentFilterVerificationStatusLPw( 932 packageName, updatedStatus, userId); 933 scheduleWritePackageRestrictionsLocked(userId); 934 } 935 } 936 } 937 } 938 939 @Override 940 public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId, 941 ActivityIntentInfo filter, String packageName) { 942 if (!hasValidDomains(filter)) { 943 return false; 944 } 945 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 946 if (ivs == null) { 947 ivs = createDomainVerificationState(verifierUid, userId, verificationId, 948 packageName); 949 } 950 if (DEBUG_DOMAIN_VERIFICATION) { 951 Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter); 952 } 953 ivs.addFilter(filter); 954 return true; 955 } 956 957 private IntentFilterVerificationState createDomainVerificationState(int verifierUid, 958 int userId, int verificationId, String packageName) { 959 IntentFilterVerificationState ivs = new IntentFilterVerificationState( 960 verifierUid, userId, packageName); 961 ivs.setPendingState(); 962 synchronized (mPackages) { 963 mIntentFilterVerificationStates.append(verificationId, ivs); 964 mCurrentIntentFilterVerifications.add(verificationId); 965 } 966 return ivs; 967 } 968 } 969 970 private static boolean hasValidDomains(ActivityIntentInfo filter) { 971 return filter.hasCategory(Intent.CATEGORY_BROWSABLE) 972 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 973 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS)); 974 } 975 976 // Set of pending broadcasts for aggregating enable/disable of components. 977 static class PendingPackageBroadcasts { 978 // for each user id, a map of <package name -> components within that package> 979 final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap; 980 981 public PendingPackageBroadcasts() { 982 mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2); 983 } 984 985 public ArrayList<String> get(int userId, String packageName) { 986 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 987 return packages.get(packageName); 988 } 989 990 public void put(int userId, String packageName, ArrayList<String> components) { 991 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 992 packages.put(packageName, components); 993 } 994 995 public void remove(int userId, String packageName) { 996 ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId); 997 if (packages != null) { 998 packages.remove(packageName); 999 } 1000 } 1001 1002 public void remove(int userId) { 1003 mUidMap.remove(userId); 1004 } 1005 1006 public int userIdCount() { 1007 return mUidMap.size(); 1008 } 1009 1010 public int userIdAt(int n) { 1011 return mUidMap.keyAt(n); 1012 } 1013 1014 public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) { 1015 return mUidMap.get(userId); 1016 } 1017 1018 public int size() { 1019 // total number of pending broadcast entries across all userIds 1020 int num = 0; 1021 for (int i = 0; i< mUidMap.size(); i++) { 1022 num += mUidMap.valueAt(i).size(); 1023 } 1024 return num; 1025 } 1026 1027 public void clear() { 1028 mUidMap.clear(); 1029 } 1030 1031 private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) { 1032 ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId); 1033 if (map == null) { 1034 map = new ArrayMap<String, ArrayList<String>>(); 1035 mUidMap.put(userId, map); 1036 } 1037 return map; 1038 } 1039 } 1040 final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts(); 1041 1042 // Service Connection to remote media container service to copy 1043 // package uri's from external media onto secure containers 1044 // or internal storage. 1045 private IMediaContainerService mContainerService = null; 1046 1047 static final int SEND_PENDING_BROADCAST = 1; 1048 static final int MCS_BOUND = 3; 1049 static final int END_COPY = 4; 1050 static final int INIT_COPY = 5; 1051 static final int MCS_UNBIND = 6; 1052 static final int START_CLEANING_PACKAGE = 7; 1053 static final int FIND_INSTALL_LOC = 8; 1054 static final int POST_INSTALL = 9; 1055 static final int MCS_RECONNECT = 10; 1056 static final int MCS_GIVE_UP = 11; 1057 static final int UPDATED_MEDIA_STATUS = 12; 1058 static final int WRITE_SETTINGS = 13; 1059 static final int WRITE_PACKAGE_RESTRICTIONS = 14; 1060 static final int PACKAGE_VERIFIED = 15; 1061 static final int CHECK_PENDING_VERIFICATION = 16; 1062 static final int START_INTENT_FILTER_VERIFICATIONS = 17; 1063 static final int INTENT_FILTER_VERIFIED = 18; 1064 static final int WRITE_PACKAGE_LIST = 19; 1065 1066 static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds 1067 1068 // Delay time in millisecs 1069 static final int BROADCAST_DELAY = 10 * 1000; 1070 1071 static UserManagerService sUserManager; 1072 1073 // Stores a list of users whose package restrictions file needs to be updated 1074 private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>(); 1075 1076 final private DefaultContainerConnection mDefContainerConn = 1077 new DefaultContainerConnection(); 1078 class DefaultContainerConnection implements ServiceConnection { 1079 public void onServiceConnected(ComponentName name, IBinder service) { 1080 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected"); 1081 IMediaContainerService imcs = 1082 IMediaContainerService.Stub.asInterface(service); 1083 mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs)); 1084 } 1085 1086 public void onServiceDisconnected(ComponentName name) { 1087 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected"); 1088 } 1089 } 1090 1091 // Recordkeeping of restore-after-install operations that are currently in flight 1092 // between the Package Manager and the Backup Manager 1093 static class PostInstallData { 1094 public InstallArgs args; 1095 public PackageInstalledInfo res; 1096 1097 PostInstallData(InstallArgs _a, PackageInstalledInfo _r) { 1098 args = _a; 1099 res = _r; 1100 } 1101 } 1102 1103 final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>(); 1104 int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows 1105 1106 // XML tags for backup/restore of various bits of state 1107 private static final String TAG_PREFERRED_BACKUP = "pa"; 1108 private static final String TAG_DEFAULT_APPS = "da"; 1109 private static final String TAG_INTENT_FILTER_VERIFICATION = "iv"; 1110 1111 private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup"; 1112 private static final String TAG_ALL_GRANTS = "rt-grants"; 1113 private static final String TAG_GRANT = "grant"; 1114 private static final String ATTR_PACKAGE_NAME = "pkg"; 1115 1116 private static final String TAG_PERMISSION = "perm"; 1117 private static final String ATTR_PERMISSION_NAME = "name"; 1118 private static final String ATTR_IS_GRANTED = "g"; 1119 private static final String ATTR_USER_SET = "set"; 1120 private static final String ATTR_USER_FIXED = "fixed"; 1121 private static final String ATTR_REVOKE_ON_UPGRADE = "rou"; 1122 1123 // System/policy permission grants are not backed up 1124 private static final int SYSTEM_RUNTIME_GRANT_MASK = 1125 FLAG_PERMISSION_POLICY_FIXED 1126 | FLAG_PERMISSION_SYSTEM_FIXED 1127 | FLAG_PERMISSION_GRANTED_BY_DEFAULT; 1128 1129 // And we back up these user-adjusted states 1130 private static final int USER_RUNTIME_GRANT_MASK = 1131 FLAG_PERMISSION_USER_SET 1132 | FLAG_PERMISSION_USER_FIXED 1133 | FLAG_PERMISSION_REVOKE_ON_UPGRADE; 1134 1135 final @Nullable String mRequiredVerifierPackage; 1136 final @NonNull String mRequiredInstallerPackage; 1137 final @NonNull String mRequiredUninstallerPackage; 1138 final @Nullable String mSetupWizardPackage; 1139 final @Nullable String mStorageManagerPackage; 1140 final @NonNull String mServicesSystemSharedLibraryPackageName; 1141 final @NonNull String mSharedSystemSharedLibraryPackageName; 1142 1143 final boolean mPermissionReviewRequired; 1144 1145 private final PackageUsage mPackageUsage = new PackageUsage(); 1146 private final CompilerStats mCompilerStats = new CompilerStats(); 1147 1148 class PackageHandler extends Handler { 1149 private boolean mBound = false; 1150 final ArrayList<HandlerParams> mPendingInstalls = 1151 new ArrayList<HandlerParams>(); 1152 1153 private boolean connectToService() { 1154 if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" + 1155 " DefaultContainerService"); 1156 Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 1157 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1158 if (mContext.bindServiceAsUser(service, mDefContainerConn, 1159 Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) { 1160 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1161 mBound = true; 1162 return true; 1163 } 1164 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1165 return false; 1166 } 1167 1168 private void disconnectService() { 1169 mContainerService = null; 1170 mBound = false; 1171 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1172 mContext.unbindService(mDefContainerConn); 1173 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1174 } 1175 1176 PackageHandler(Looper looper) { 1177 super(looper); 1178 } 1179 1180 public void handleMessage(Message msg) { 1181 try { 1182 doHandleMessage(msg); 1183 } finally { 1184 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1185 } 1186 } 1187 1188 void doHandleMessage(Message msg) { 1189 switch (msg.what) { 1190 case INIT_COPY: { 1191 HandlerParams params = (HandlerParams) msg.obj; 1192 int idx = mPendingInstalls.size(); 1193 if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params); 1194 // If a bind was already initiated we dont really 1195 // need to do anything. The pending install 1196 // will be processed later on. 1197 if (!mBound) { 1198 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1199 System.identityHashCode(mHandler)); 1200 // If this is the only one pending we might 1201 // have to bind to the service again. 1202 if (!connectToService()) { 1203 Slog.e(TAG, "Failed to bind to media container service"); 1204 params.serviceError(); 1205 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1206 System.identityHashCode(mHandler)); 1207 if (params.traceMethod != null) { 1208 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod, 1209 params.traceCookie); 1210 } 1211 return; 1212 } else { 1213 // Once we bind to the service, the first 1214 // pending request will be processed. 1215 mPendingInstalls.add(idx, params); 1216 } 1217 } else { 1218 mPendingInstalls.add(idx, params); 1219 // Already bound to the service. Just make 1220 // sure we trigger off processing the first request. 1221 if (idx == 0) { 1222 mHandler.sendEmptyMessage(MCS_BOUND); 1223 } 1224 } 1225 break; 1226 } 1227 case MCS_BOUND: { 1228 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound"); 1229 if (msg.obj != null) { 1230 mContainerService = (IMediaContainerService) msg.obj; 1231 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1232 System.identityHashCode(mHandler)); 1233 } 1234 if (mContainerService == null) { 1235 if (!mBound) { 1236 // Something seriously wrong since we are not bound and we are not 1237 // waiting for connection. Bail out. 1238 Slog.e(TAG, "Cannot bind to media container service"); 1239 for (HandlerParams params : mPendingInstalls) { 1240 // Indicate service bind error 1241 params.serviceError(); 1242 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1243 System.identityHashCode(params)); 1244 if (params.traceMethod != null) { 1245 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, 1246 params.traceMethod, params.traceCookie); 1247 } 1248 return; 1249 } 1250 mPendingInstalls.clear(); 1251 } else { 1252 Slog.w(TAG, "Waiting to connect to media container service"); 1253 } 1254 } else if (mPendingInstalls.size() > 0) { 1255 HandlerParams params = mPendingInstalls.get(0); 1256 if (params != null) { 1257 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1258 System.identityHashCode(params)); 1259 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy"); 1260 if (params.startCopy()) { 1261 // We are done... look for more work or to 1262 // go idle. 1263 if (DEBUG_SD_INSTALL) Log.i(TAG, 1264 "Checking for more work or unbind..."); 1265 // Delete pending install 1266 if (mPendingInstalls.size() > 0) { 1267 mPendingInstalls.remove(0); 1268 } 1269 if (mPendingInstalls.size() == 0) { 1270 if (mBound) { 1271 if (DEBUG_SD_INSTALL) Log.i(TAG, 1272 "Posting delayed MCS_UNBIND"); 1273 removeMessages(MCS_UNBIND); 1274 Message ubmsg = obtainMessage(MCS_UNBIND); 1275 // Unbind after a little delay, to avoid 1276 // continual thrashing. 1277 sendMessageDelayed(ubmsg, 10000); 1278 } 1279 } else { 1280 // There are more pending requests in queue. 1281 // Just post MCS_BOUND message to trigger processing 1282 // of next pending install. 1283 if (DEBUG_SD_INSTALL) Log.i(TAG, 1284 "Posting MCS_BOUND for next work"); 1285 mHandler.sendEmptyMessage(MCS_BOUND); 1286 } 1287 } 1288 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 1289 } 1290 } else { 1291 // Should never happen ideally. 1292 Slog.w(TAG, "Empty queue"); 1293 } 1294 break; 1295 } 1296 case MCS_RECONNECT: { 1297 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect"); 1298 if (mPendingInstalls.size() > 0) { 1299 if (mBound) { 1300 disconnectService(); 1301 } 1302 if (!connectToService()) { 1303 Slog.e(TAG, "Failed to bind to media container service"); 1304 for (HandlerParams params : mPendingInstalls) { 1305 // Indicate service bind error 1306 params.serviceError(); 1307 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1308 System.identityHashCode(params)); 1309 } 1310 mPendingInstalls.clear(); 1311 } 1312 } 1313 break; 1314 } 1315 case MCS_UNBIND: { 1316 // If there is no actual work left, then time to unbind. 1317 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind"); 1318 1319 if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) { 1320 if (mBound) { 1321 if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()"); 1322 1323 disconnectService(); 1324 } 1325 } else if (mPendingInstalls.size() > 0) { 1326 // There are more pending requests in queue. 1327 // Just post MCS_BOUND message to trigger processing 1328 // of next pending install. 1329 mHandler.sendEmptyMessage(MCS_BOUND); 1330 } 1331 1332 break; 1333 } 1334 case MCS_GIVE_UP: { 1335 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries"); 1336 HandlerParams params = mPendingInstalls.remove(0); 1337 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1338 System.identityHashCode(params)); 1339 break; 1340 } 1341 case SEND_PENDING_BROADCAST: { 1342 String packages[]; 1343 ArrayList<String> components[]; 1344 int size = 0; 1345 int uids[]; 1346 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1347 synchronized (mPackages) { 1348 if (mPendingBroadcasts == null) { 1349 return; 1350 } 1351 size = mPendingBroadcasts.size(); 1352 if (size <= 0) { 1353 // Nothing to be done. Just return 1354 return; 1355 } 1356 packages = new String[size]; 1357 components = new ArrayList[size]; 1358 uids = new int[size]; 1359 int i = 0; // filling out the above arrays 1360 1361 for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) { 1362 int packageUserId = mPendingBroadcasts.userIdAt(n); 1363 Iterator<Map.Entry<String, ArrayList<String>>> it 1364 = mPendingBroadcasts.packagesForUserId(packageUserId) 1365 .entrySet().iterator(); 1366 while (it.hasNext() && i < size) { 1367 Map.Entry<String, ArrayList<String>> ent = it.next(); 1368 packages[i] = ent.getKey(); 1369 components[i] = ent.getValue(); 1370 PackageSetting ps = mSettings.mPackages.get(ent.getKey()); 1371 uids[i] = (ps != null) 1372 ? UserHandle.getUid(packageUserId, ps.appId) 1373 : -1; 1374 i++; 1375 } 1376 } 1377 size = i; 1378 mPendingBroadcasts.clear(); 1379 } 1380 // Send broadcasts 1381 for (int i = 0; i < size; i++) { 1382 sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]); 1383 } 1384 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1385 break; 1386 } 1387 case START_CLEANING_PACKAGE: { 1388 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1389 final String packageName = (String)msg.obj; 1390 final int userId = msg.arg1; 1391 final boolean andCode = msg.arg2 != 0; 1392 synchronized (mPackages) { 1393 if (userId == UserHandle.USER_ALL) { 1394 int[] users = sUserManager.getUserIds(); 1395 for (int user : users) { 1396 mSettings.addPackageToCleanLPw( 1397 new PackageCleanItem(user, packageName, andCode)); 1398 } 1399 } else { 1400 mSettings.addPackageToCleanLPw( 1401 new PackageCleanItem(userId, packageName, andCode)); 1402 } 1403 } 1404 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1405 startCleaningPackages(); 1406 } break; 1407 case POST_INSTALL: { 1408 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1); 1409 1410 PostInstallData data = mRunningInstalls.get(msg.arg1); 1411 final boolean didRestore = (msg.arg2 != 0); 1412 mRunningInstalls.delete(msg.arg1); 1413 1414 if (data != null) { 1415 InstallArgs args = data.args; 1416 PackageInstalledInfo parentRes = data.res; 1417 1418 final boolean grantPermissions = (args.installFlags 1419 & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0; 1420 final boolean killApp = (args.installFlags 1421 & PackageManager.INSTALL_DONT_KILL_APP) == 0; 1422 final String[] grantedPermissions = args.installGrantPermissions; 1423 1424 // Handle the parent package 1425 handlePackagePostInstall(parentRes, grantPermissions, killApp, 1426 grantedPermissions, didRestore, args.installerPackageName, 1427 args.observer); 1428 1429 // Handle the child packages 1430 final int childCount = (parentRes.addedChildPackages != null) 1431 ? parentRes.addedChildPackages.size() : 0; 1432 for (int i = 0; i < childCount; i++) { 1433 PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i); 1434 handlePackagePostInstall(childRes, grantPermissions, killApp, 1435 grantedPermissions, false, args.installerPackageName, 1436 args.observer); 1437 } 1438 1439 // Log tracing if needed 1440 if (args.traceMethod != null) { 1441 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod, 1442 args.traceCookie); 1443 } 1444 } else { 1445 Slog.e(TAG, "Bogus post-install token " + msg.arg1); 1446 } 1447 1448 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1); 1449 } break; 1450 case UPDATED_MEDIA_STATUS: { 1451 if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS"); 1452 boolean reportStatus = msg.arg1 == 1; 1453 boolean doGc = msg.arg2 == 1; 1454 if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc); 1455 if (doGc) { 1456 // Force a gc to clear up stale containers. 1457 Runtime.getRuntime().gc(); 1458 } 1459 if (msg.obj != null) { 1460 @SuppressWarnings("unchecked") 1461 Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj; 1462 if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers"); 1463 // Unload containers 1464 unloadAllContainers(args); 1465 } 1466 if (reportStatus) { 1467 try { 1468 if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back"); 1469 PackageHelper.getMountService().finishMediaUpdate(); 1470 } catch (RemoteException e) { 1471 Log.e(TAG, "MountService not running?"); 1472 } 1473 } 1474 } break; 1475 case WRITE_SETTINGS: { 1476 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1477 synchronized (mPackages) { 1478 removeMessages(WRITE_SETTINGS); 1479 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1480 mSettings.writeLPr(); 1481 mDirtyUsers.clear(); 1482 } 1483 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1484 } break; 1485 case WRITE_PACKAGE_RESTRICTIONS: { 1486 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1487 synchronized (mPackages) { 1488 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1489 for (int userId : mDirtyUsers) { 1490 mSettings.writePackageRestrictionsLPr(userId); 1491 } 1492 mDirtyUsers.clear(); 1493 } 1494 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1495 } break; 1496 case WRITE_PACKAGE_LIST: { 1497 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1498 synchronized (mPackages) { 1499 removeMessages(WRITE_PACKAGE_LIST); 1500 mSettings.writePackageListLPr(msg.arg1); 1501 } 1502 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1503 } break; 1504 case CHECK_PENDING_VERIFICATION: { 1505 final int verificationId = msg.arg1; 1506 final PackageVerificationState state = mPendingVerification.get(verificationId); 1507 1508 if ((state != null) && !state.timeoutExtended()) { 1509 final InstallArgs args = state.getInstallArgs(); 1510 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1511 1512 Slog.i(TAG, "Verification timed out for " + originUri); 1513 mPendingVerification.remove(verificationId); 1514 1515 int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1516 1517 if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) { 1518 Slog.i(TAG, "Continuing with installation of " + originUri); 1519 state.setVerifierResponse(Binder.getCallingUid(), 1520 PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT); 1521 broadcastPackageVerified(verificationId, originUri, 1522 PackageManager.VERIFICATION_ALLOW, 1523 state.getInstallArgs().getUser()); 1524 try { 1525 ret = args.copyApk(mContainerService, true); 1526 } catch (RemoteException e) { 1527 Slog.e(TAG, "Could not contact the ContainerService"); 1528 } 1529 } else { 1530 broadcastPackageVerified(verificationId, originUri, 1531 PackageManager.VERIFICATION_REJECT, 1532 state.getInstallArgs().getUser()); 1533 } 1534 1535 Trace.asyncTraceEnd( 1536 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 1537 1538 processPendingInstall(args, ret); 1539 mHandler.sendEmptyMessage(MCS_UNBIND); 1540 } 1541 break; 1542 } 1543 case PACKAGE_VERIFIED: { 1544 final int verificationId = msg.arg1; 1545 1546 final PackageVerificationState state = mPendingVerification.get(verificationId); 1547 if (state == null) { 1548 Slog.w(TAG, "Invalid verification token " + verificationId + " received"); 1549 break; 1550 } 1551 1552 final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj; 1553 1554 state.setVerifierResponse(response.callerUid, response.code); 1555 1556 if (state.isVerificationComplete()) { 1557 mPendingVerification.remove(verificationId); 1558 1559 final InstallArgs args = state.getInstallArgs(); 1560 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1561 1562 int ret; 1563 if (state.isInstallAllowed()) { 1564 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 1565 broadcastPackageVerified(verificationId, originUri, 1566 response.code, state.getInstallArgs().getUser()); 1567 try { 1568 ret = args.copyApk(mContainerService, true); 1569 } catch (RemoteException e) { 1570 Slog.e(TAG, "Could not contact the ContainerService"); 1571 } 1572 } else { 1573 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1574 } 1575 1576 Trace.asyncTraceEnd( 1577 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 1578 1579 processPendingInstall(args, ret); 1580 mHandler.sendEmptyMessage(MCS_UNBIND); 1581 } 1582 1583 break; 1584 } 1585 case START_INTENT_FILTER_VERIFICATIONS: { 1586 IFVerificationParams params = (IFVerificationParams) msg.obj; 1587 verifyIntentFiltersIfNeeded(params.userId, params.verifierUid, 1588 params.replacing, params.pkg); 1589 break; 1590 } 1591 case INTENT_FILTER_VERIFIED: { 1592 final int verificationId = msg.arg1; 1593 1594 final IntentFilterVerificationState state = mIntentFilterVerificationStates.get( 1595 verificationId); 1596 if (state == null) { 1597 Slog.w(TAG, "Invalid IntentFilter verification token " 1598 + verificationId + " received"); 1599 break; 1600 } 1601 1602 final int userId = state.getUserId(); 1603 1604 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1605 "Processing IntentFilter verification with token:" 1606 + verificationId + " and userId:" + userId); 1607 1608 final IntentFilterVerificationResponse response = 1609 (IntentFilterVerificationResponse) msg.obj; 1610 1611 state.setVerifierResponse(response.callerUid, response.code); 1612 1613 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1614 "IntentFilter verification with token:" + verificationId 1615 + " and userId:" + userId 1616 + " is settings verifier response with response code:" 1617 + response.code); 1618 1619 if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) { 1620 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: " 1621 + response.getFailedDomainsString()); 1622 } 1623 1624 if (state.isVerificationComplete()) { 1625 mIntentFilterVerifier.receiveVerificationResponse(verificationId); 1626 } else { 1627 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1628 "IntentFilter verification with token:" + verificationId 1629 + " was not said to be complete"); 1630 } 1631 1632 break; 1633 } 1634 } 1635 } 1636 } 1637 1638 private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions, 1639 boolean killApp, String[] grantedPermissions, 1640 boolean launchedForRestore, String installerPackage, 1641 IPackageInstallObserver2 installObserver) { 1642 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 1643 // Send the removed broadcasts 1644 if (res.removedInfo != null) { 1645 res.removedInfo.sendPackageRemovedBroadcasts(killApp); 1646 } 1647 1648 // Now that we successfully installed the package, grant runtime 1649 // permissions if requested before broadcasting the install. 1650 if (grantPermissions && res.pkg.applicationInfo.targetSdkVersion 1651 >= Build.VERSION_CODES.M) { 1652 grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions); 1653 } 1654 1655 final boolean update = res.removedInfo != null 1656 && res.removedInfo.removedPackage != null; 1657 1658 // If this is the first time we have child packages for a disabled privileged 1659 // app that had no children, we grant requested runtime permissions to the new 1660 // children if the parent on the system image had them already granted. 1661 if (res.pkg.parentPackage != null) { 1662 synchronized (mPackages) { 1663 grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg); 1664 } 1665 } 1666 1667 synchronized (mPackages) { 1668 mEphemeralApplicationRegistry.onPackageInstalledLPw(res.pkg); 1669 } 1670 1671 final String packageName = res.pkg.applicationInfo.packageName; 1672 Bundle extras = new Bundle(1); 1673 extras.putInt(Intent.EXTRA_UID, res.uid); 1674 1675 // Determine the set of users who are adding this package for 1676 // the first time vs. those who are seeing an update. 1677 int[] firstUsers = EMPTY_INT_ARRAY; 1678 int[] updateUsers = EMPTY_INT_ARRAY; 1679 if (res.origUsers == null || res.origUsers.length == 0) { 1680 firstUsers = res.newUsers; 1681 } else { 1682 for (int newUser : res.newUsers) { 1683 boolean isNew = true; 1684 for (int origUser : res.origUsers) { 1685 if (origUser == newUser) { 1686 isNew = false; 1687 break; 1688 } 1689 } 1690 if (isNew) { 1691 firstUsers = ArrayUtils.appendInt(firstUsers, newUser); 1692 } else { 1693 updateUsers = ArrayUtils.appendInt(updateUsers, newUser); 1694 } 1695 } 1696 } 1697 1698 // Send installed broadcasts if the install/update is not ephemeral 1699 if (!isEphemeral(res.pkg)) { 1700 mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath); 1701 1702 // Send added for users that see the package for the first time 1703 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, 1704 extras, 0 /*flags*/, null /*targetPackage*/, 1705 null /*finishedReceiver*/, firstUsers); 1706 1707 // Send added for users that don't see the package for the first time 1708 if (update) { 1709 extras.putBoolean(Intent.EXTRA_REPLACING, true); 1710 } 1711 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, 1712 extras, 0 /*flags*/, null /*targetPackage*/, 1713 null /*finishedReceiver*/, updateUsers); 1714 1715 // Send replaced for users that don't see the package for the first time 1716 if (update) { 1717 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, 1718 packageName, extras, 0 /*flags*/, 1719 null /*targetPackage*/, null /*finishedReceiver*/, 1720 updateUsers); 1721 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, 1722 null /*package*/, null /*extras*/, 0 /*flags*/, 1723 packageName /*targetPackage*/, 1724 null /*finishedReceiver*/, updateUsers); 1725 } else if (launchedForRestore && !isSystemApp(res.pkg)) { 1726 // First-install and we did a restore, so we're responsible for the 1727 // first-launch broadcast. 1728 if (DEBUG_BACKUP) { 1729 Slog.i(TAG, "Post-restore of " + packageName 1730 + " sending FIRST_LAUNCH in " + Arrays.toString(firstUsers)); 1731 } 1732 sendFirstLaunchBroadcast(packageName, installerPackage, firstUsers); 1733 } 1734 1735 // Send broadcast package appeared if forward locked/external for all users 1736 // treat asec-hosted packages like removable media on upgrade 1737 if (res.pkg.isForwardLocked() || isExternal(res.pkg)) { 1738 if (DEBUG_INSTALL) { 1739 Slog.i(TAG, "upgrading pkg " + res.pkg 1740 + " is ASEC-hosted -> AVAILABLE"); 1741 } 1742 final int[] uidArray = new int[]{res.pkg.applicationInfo.uid}; 1743 ArrayList<String> pkgList = new ArrayList<>(1); 1744 pkgList.add(packageName); 1745 sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null); 1746 } 1747 } 1748 1749 // Work that needs to happen on first install within each user 1750 if (firstUsers != null && firstUsers.length > 0) { 1751 synchronized (mPackages) { 1752 for (int userId : firstUsers) { 1753 // If this app is a browser and it's newly-installed for some 1754 // users, clear any default-browser state in those users. The 1755 // app's nature doesn't depend on the user, so we can just check 1756 // its browser nature in any user and generalize. 1757 if (packageIsBrowser(packageName, userId)) { 1758 mSettings.setDefaultBrowserPackageNameLPw(null, userId); 1759 } 1760 1761 // We may also need to apply pending (restored) runtime 1762 // permission grants within these users. 1763 mSettings.applyPendingPermissionGrantsLPw(packageName, userId); 1764 } 1765 } 1766 } 1767 1768 // Log current value of "unknown sources" setting 1769 EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED, 1770 getUnknownSourcesSettings()); 1771 1772 // Force a gc to clear up things 1773 Runtime.getRuntime().gc(); 1774 1775 // Remove the replaced package's older resources safely now 1776 // We delete after a gc for applications on sdcard. 1777 if (res.removedInfo != null && res.removedInfo.args != null) { 1778 synchronized (mInstallLock) { 1779 res.removedInfo.args.doPostDeleteLI(true); 1780 } 1781 } 1782 } 1783 1784 // If someone is watching installs - notify them 1785 if (installObserver != null) { 1786 try { 1787 Bundle extras = extrasForInstallResult(res); 1788 installObserver.onPackageInstalled(res.name, res.returnCode, 1789 res.returnMsg, extras); 1790 } catch (RemoteException e) { 1791 Slog.i(TAG, "Observer no longer exists."); 1792 } 1793 } 1794 } 1795 1796 private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw( 1797 PackageParser.Package pkg) { 1798 if (pkg.parentPackage == null) { 1799 return; 1800 } 1801 if (pkg.requestedPermissions == null) { 1802 return; 1803 } 1804 final PackageSetting disabledSysParentPs = mSettings 1805 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName); 1806 if (disabledSysParentPs == null || disabledSysParentPs.pkg == null 1807 || !disabledSysParentPs.isPrivileged() 1808 || (disabledSysParentPs.childPackageNames != null 1809 && !disabledSysParentPs.childPackageNames.isEmpty())) { 1810 return; 1811 } 1812 final int[] allUserIds = sUserManager.getUserIds(); 1813 final int permCount = pkg.requestedPermissions.size(); 1814 for (int i = 0; i < permCount; i++) { 1815 String permission = pkg.requestedPermissions.get(i); 1816 BasePermission bp = mSettings.mPermissions.get(permission); 1817 if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) { 1818 continue; 1819 } 1820 for (int userId : allUserIds) { 1821 if (disabledSysParentPs.getPermissionsState().hasRuntimePermission( 1822 permission, userId)) { 1823 grantRuntimePermission(pkg.packageName, permission, userId); 1824 } 1825 } 1826 } 1827 } 1828 1829 private StorageEventListener mStorageListener = new StorageEventListener() { 1830 @Override 1831 public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) { 1832 if (vol.type == VolumeInfo.TYPE_PRIVATE) { 1833 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1834 final String volumeUuid = vol.getFsUuid(); 1835 1836 // Clean up any users or apps that were removed or recreated 1837 // while this volume was missing 1838 reconcileUsers(volumeUuid); 1839 reconcileApps(volumeUuid); 1840 1841 // Clean up any install sessions that expired or were 1842 // cancelled while this volume was missing 1843 mInstallerService.onPrivateVolumeMounted(volumeUuid); 1844 1845 loadPrivatePackages(vol); 1846 1847 } else if (vol.state == VolumeInfo.STATE_EJECTING) { 1848 unloadPrivatePackages(vol); 1849 } 1850 } 1851 1852 if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) { 1853 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1854 updateExternalMediaStatus(true, false); 1855 } else if (vol.state == VolumeInfo.STATE_EJECTING) { 1856 updateExternalMediaStatus(false, false); 1857 } 1858 } 1859 } 1860 1861 @Override 1862 public void onVolumeForgotten(String fsUuid) { 1863 if (TextUtils.isEmpty(fsUuid)) { 1864 Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring"); 1865 return; 1866 } 1867 1868 // Remove any apps installed on the forgotten volume 1869 synchronized (mPackages) { 1870 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid); 1871 for (PackageSetting ps : packages) { 1872 Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten"); 1873 deletePackage(ps.name, new LegacyPackageDeleteObserver(null).getBinder(), 1874 UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS); 1875 } 1876 1877 mSettings.onVolumeForgotten(fsUuid); 1878 mSettings.writeLPr(); 1879 } 1880 } 1881 }; 1882 1883 private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds, 1884 String[] grantedPermissions) { 1885 for (int userId : userIds) { 1886 grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions); 1887 } 1888 1889 // We could have touched GID membership, so flush out packages.list 1890 synchronized (mPackages) { 1891 mSettings.writePackageListLPr(); 1892 } 1893 } 1894 1895 private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId, 1896 String[] grantedPermissions) { 1897 SettingBase sb = (SettingBase) pkg.mExtras; 1898 if (sb == null) { 1899 return; 1900 } 1901 1902 PermissionsState permissionsState = sb.getPermissionsState(); 1903 1904 final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 1905 | PackageManager.FLAG_PERMISSION_POLICY_FIXED; 1906 1907 for (String permission : pkg.requestedPermissions) { 1908 final BasePermission bp; 1909 synchronized (mPackages) { 1910 bp = mSettings.mPermissions.get(permission); 1911 } 1912 if (bp != null && (bp.isRuntime() || bp.isDevelopment()) 1913 && (grantedPermissions == null 1914 || ArrayUtils.contains(grantedPermissions, permission))) { 1915 final int flags = permissionsState.getPermissionFlags(permission, userId); 1916 // Installer cannot change immutable permissions. 1917 if ((flags & immutableFlags) == 0) { 1918 grantRuntimePermission(pkg.packageName, permission, userId); 1919 } 1920 } 1921 } 1922 } 1923 1924 Bundle extrasForInstallResult(PackageInstalledInfo res) { 1925 Bundle extras = null; 1926 switch (res.returnCode) { 1927 case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: { 1928 extras = new Bundle(); 1929 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION, 1930 res.origPermission); 1931 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE, 1932 res.origPackage); 1933 break; 1934 } 1935 case PackageManager.INSTALL_SUCCEEDED: { 1936 extras = new Bundle(); 1937 extras.putBoolean(Intent.EXTRA_REPLACING, 1938 res.removedInfo != null && res.removedInfo.removedPackage != null); 1939 break; 1940 } 1941 } 1942 return extras; 1943 } 1944 1945 void scheduleWriteSettingsLocked() { 1946 if (!mHandler.hasMessages(WRITE_SETTINGS)) { 1947 mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY); 1948 } 1949 } 1950 1951 void scheduleWritePackageListLocked(int userId) { 1952 if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) { 1953 Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST); 1954 msg.arg1 = userId; 1955 mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY); 1956 } 1957 } 1958 1959 void scheduleWritePackageRestrictionsLocked(UserHandle user) { 1960 final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier(); 1961 scheduleWritePackageRestrictionsLocked(userId); 1962 } 1963 1964 void scheduleWritePackageRestrictionsLocked(int userId) { 1965 final int[] userIds = (userId == UserHandle.USER_ALL) 1966 ? sUserManager.getUserIds() : new int[]{userId}; 1967 for (int nextUserId : userIds) { 1968 if (!sUserManager.exists(nextUserId)) return; 1969 mDirtyUsers.add(nextUserId); 1970 if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) { 1971 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY); 1972 } 1973 } 1974 } 1975 1976 public static PackageManagerService main(Context context, Installer installer, 1977 boolean factoryTest, boolean onlyCore) { 1978 // Self-check for initial settings. 1979 PackageManagerServiceCompilerMapping.checkProperties(); 1980 1981 PackageManagerService m = new PackageManagerService(context, installer, 1982 factoryTest, onlyCore); 1983 m.enableSystemUserPackages(); 1984 ServiceManager.addService("package", m); 1985 return m; 1986 } 1987 1988 private void enableSystemUserPackages() { 1989 if (!UserManager.isSplitSystemUser()) { 1990 return; 1991 } 1992 // For system user, enable apps based on the following conditions: 1993 // - app is whitelisted or belong to one of these groups: 1994 // -- system app which has no launcher icons 1995 // -- system app which has INTERACT_ACROSS_USERS permission 1996 // -- system IME app 1997 // - app is not in the blacklist 1998 AppsQueryHelper queryHelper = new AppsQueryHelper(this); 1999 Set<String> enableApps = new ArraySet<>(); 2000 enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS 2001 | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM 2002 | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM)); 2003 ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps(); 2004 enableApps.addAll(wlApps); 2005 enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER, 2006 /* systemAppsOnly */ false, UserHandle.SYSTEM)); 2007 ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps(); 2008 enableApps.removeAll(blApps); 2009 Log.i(TAG, "Applications installed for system user: " + enableApps); 2010 List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false, 2011 UserHandle.SYSTEM); 2012 final int allAppsSize = allAps.size(); 2013 synchronized (mPackages) { 2014 for (int i = 0; i < allAppsSize; i++) { 2015 String pName = allAps.get(i); 2016 PackageSetting pkgSetting = mSettings.mPackages.get(pName); 2017 // Should not happen, but we shouldn't be failing if it does 2018 if (pkgSetting == null) { 2019 continue; 2020 } 2021 boolean install = enableApps.contains(pName); 2022 if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) { 2023 Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName 2024 + " for system user"); 2025 pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM); 2026 } 2027 } 2028 } 2029 } 2030 2031 private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) { 2032 DisplayManager displayManager = (DisplayManager) context.getSystemService( 2033 Context.DISPLAY_SERVICE); 2034 displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics); 2035 } 2036 2037 /** 2038 * Requests that files preopted on a secondary system partition be copied to the data partition 2039 * if possible. Note that the actual copying of the files is accomplished by init for security 2040 * reasons. This simply requests that the copy takes place and awaits confirmation of its 2041 * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy. 2042 */ 2043 private static void requestCopyPreoptedFiles() { 2044 final int WAIT_TIME_MS = 100; 2045 final String CP_PREOPT_PROPERTY = "sys.cppreopt"; 2046 if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) { 2047 SystemProperties.set(CP_PREOPT_PROPERTY, "requested"); 2048 // We will wait for up to 100 seconds. 2049 final long timeEnd = SystemClock.uptimeMillis() + 100 * 1000; 2050 while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) { 2051 try { 2052 Thread.sleep(WAIT_TIME_MS); 2053 } catch (InterruptedException e) { 2054 // Do nothing 2055 } 2056 if (SystemClock.uptimeMillis() > timeEnd) { 2057 SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out"); 2058 Slog.wtf(TAG, "cppreopt did not finish!"); 2059 break; 2060 } 2061 } 2062 } 2063 } 2064 2065 public PackageManagerService(Context context, Installer installer, 2066 boolean factoryTest, boolean onlyCore) { 2067 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START, 2068 SystemClock.uptimeMillis()); 2069 2070 if (mSdkVersion <= 0) { 2071 Slog.w(TAG, "**** ro.build.version.sdk not set!"); 2072 } 2073 2074 mContext = context; 2075 2076 mPermissionReviewRequired = context.getResources().getBoolean( 2077 R.bool.config_permissionReviewRequired); 2078 2079 mFactoryTest = factoryTest; 2080 mOnlyCore = onlyCore; 2081 mMetrics = new DisplayMetrics(); 2082 mSettings = new Settings(mPackages); 2083 mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID, 2084 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2085 mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, 2086 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2087 mSettings.addSharedUserLPw("android.uid.log", LOG_UID, 2088 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2089 mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, 2090 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2091 mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID, 2092 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2093 mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID, 2094 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2095 2096 String separateProcesses = SystemProperties.get("debug.separate_processes"); 2097 if (separateProcesses != null && separateProcesses.length() > 0) { 2098 if ("*".equals(separateProcesses)) { 2099 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES; 2100 mSeparateProcesses = null; 2101 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)"); 2102 } else { 2103 mDefParseFlags = 0; 2104 mSeparateProcesses = separateProcesses.split(","); 2105 Slog.w(TAG, "Running with debug.separate_processes: " 2106 + separateProcesses); 2107 } 2108 } else { 2109 mDefParseFlags = 0; 2110 mSeparateProcesses = null; 2111 } 2112 2113 mInstaller = installer; 2114 mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context, 2115 "*dexopt*"); 2116 mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper()); 2117 2118 mOnPermissionChangeListeners = new OnPermissionChangeListeners( 2119 FgThread.get().getLooper()); 2120 2121 getDefaultDisplayMetrics(context, mMetrics); 2122 2123 SystemConfig systemConfig = SystemConfig.getInstance(); 2124 mGlobalGids = systemConfig.getGlobalGids(); 2125 mSystemPermissions = systemConfig.getSystemPermissions(); 2126 mAvailableFeatures = systemConfig.getAvailableFeatures(); 2127 2128 mProtectedPackages = new ProtectedPackages(mContext); 2129 2130 synchronized (mInstallLock) { 2131 // writer 2132 synchronized (mPackages) { 2133 mHandlerThread = new ServiceThread(TAG, 2134 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/); 2135 mHandlerThread.start(); 2136 mHandler = new PackageHandler(mHandlerThread.getLooper()); 2137 mProcessLoggingHandler = new ProcessLoggingHandler(); 2138 Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT); 2139 2140 mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(this); 2141 2142 File dataDir = Environment.getDataDirectory(); 2143 mAppInstallDir = new File(dataDir, "app"); 2144 mAppLib32InstallDir = new File(dataDir, "app-lib"); 2145 mEphemeralInstallDir = new File(dataDir, "app-ephemeral"); 2146 mAsecInternalPath = new File(dataDir, "app-asec").getPath(); 2147 mDrmAppPrivateInstallDir = new File(dataDir, "app-private"); 2148 2149 sUserManager = new UserManagerService(context, this, mPackages); 2150 2151 // Propagate permission configuration in to package manager. 2152 ArrayMap<String, SystemConfig.PermissionEntry> permConfig 2153 = systemConfig.getPermissions(); 2154 for (int i=0; i<permConfig.size(); i++) { 2155 SystemConfig.PermissionEntry perm = permConfig.valueAt(i); 2156 BasePermission bp = mSettings.mPermissions.get(perm.name); 2157 if (bp == null) { 2158 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN); 2159 mSettings.mPermissions.put(perm.name, bp); 2160 } 2161 if (perm.gids != null) { 2162 bp.setGids(perm.gids, perm.perUser); 2163 } 2164 } 2165 2166 ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries(); 2167 for (int i=0; i<libConfig.size(); i++) { 2168 mSharedLibraries.put(libConfig.keyAt(i), 2169 new SharedLibraryEntry(libConfig.valueAt(i), null)); 2170 } 2171 2172 mFoundPolicyFile = SELinuxMMAC.readInstallPolicy(); 2173 2174 mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false)); 2175 2176 if (mFirstBoot) { 2177 requestCopyPreoptedFiles(); 2178 } 2179 2180 String customResolverActivity = Resources.getSystem().getString( 2181 R.string.config_customResolverActivity); 2182 if (TextUtils.isEmpty(customResolverActivity)) { 2183 customResolverActivity = null; 2184 } else { 2185 mCustomResolverComponentName = ComponentName.unflattenFromString( 2186 customResolverActivity); 2187 } 2188 2189 long startTime = SystemClock.uptimeMillis(); 2190 2191 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START, 2192 startTime); 2193 2194 // Set flag to monitor and not change apk file paths when 2195 // scanning install directories. 2196 final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING | SCAN_INITIAL; 2197 2198 final String bootClassPath = System.getenv("BOOTCLASSPATH"); 2199 final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH"); 2200 2201 if (bootClassPath == null) { 2202 Slog.w(TAG, "No BOOTCLASSPATH found!"); 2203 } 2204 2205 if (systemServerClassPath == null) { 2206 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!"); 2207 } 2208 2209 final List<String> allInstructionSets = InstructionSets.getAllInstructionSets(); 2210 final String[] dexCodeInstructionSets = 2211 getDexCodeInstructionSets( 2212 allInstructionSets.toArray(new String[allInstructionSets.size()])); 2213 2214 /** 2215 * Ensure all external libraries have had dexopt run on them. 2216 */ 2217 if (mSharedLibraries.size() > 0) { 2218 // NOTE: For now, we're compiling these system "shared libraries" 2219 // (and framework jars) into all available architectures. It's possible 2220 // to compile them only when we come across an app that uses them (there's 2221 // already logic for that in scanPackageLI) but that adds some complexity. 2222 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 2223 for (SharedLibraryEntry libEntry : mSharedLibraries.values()) { 2224 final String lib = libEntry.path; 2225 if (lib == null) { 2226 continue; 2227 } 2228 2229 try { 2230 // Shared libraries do not have profiles so we perform a full 2231 // AOT compilation (if needed). 2232 int dexoptNeeded = DexFile.getDexOptNeeded( 2233 lib, dexCodeInstructionSet, 2234 getCompilerFilterForReason(REASON_SHARED_APK), 2235 false /* newProfile */); 2236 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { 2237 mInstaller.dexopt(lib, Process.SYSTEM_UID, "*", 2238 dexCodeInstructionSet, dexoptNeeded, null, 2239 DEXOPT_PUBLIC, 2240 getCompilerFilterForReason(REASON_SHARED_APK), 2241 StorageManager.UUID_PRIVATE_INTERNAL, 2242 SKIP_SHARED_LIBRARY_CHECK); 2243 } 2244 } catch (FileNotFoundException e) { 2245 Slog.w(TAG, "Library not found: " + lib); 2246 } catch (IOException | InstallerException e) { 2247 Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? " 2248 + e.getMessage()); 2249 } 2250 } 2251 } 2252 } 2253 2254 File frameworkDir = new File(Environment.getRootDirectory(), "framework"); 2255 2256 final VersionInfo ver = mSettings.getInternalVersion(); 2257 mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint); 2258 2259 // when upgrading from pre-M, promote system app permissions from install to runtime 2260 mPromoteSystemApps = 2261 mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1; 2262 2263 // When upgrading from pre-N, we need to handle package extraction like first boot, 2264 // as there is no profiling data available. 2265 mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N; 2266 2267 mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1; 2268 2269 // save off the names of pre-existing system packages prior to scanning; we don't 2270 // want to automatically grant runtime permissions for new system apps 2271 if (mPromoteSystemApps) { 2272 Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator(); 2273 while (pkgSettingIter.hasNext()) { 2274 PackageSetting ps = pkgSettingIter.next(); 2275 if (isSystemApp(ps)) { 2276 mExistingSystemPackages.add(ps.name); 2277 } 2278 } 2279 } 2280 2281 // Collect vendor overlay packages. 2282 // (Do this before scanning any apps.) 2283 // For security and version matching reason, only consider 2284 // overlay packages if they reside in the right directory. 2285 File vendorOverlayDir; 2286 String overlaySkuDir = SystemProperties.get(VENDOR_OVERLAY_SKU_PROPERTY); 2287 if (!overlaySkuDir.isEmpty()) { 2288 vendorOverlayDir = new File(VENDOR_OVERLAY_DIR, overlaySkuDir); 2289 } else { 2290 vendorOverlayDir = new File(VENDOR_OVERLAY_DIR); 2291 } 2292 scanDirTracedLI(vendorOverlayDir, mDefParseFlags 2293 | PackageParser.PARSE_IS_SYSTEM 2294 | PackageParser.PARSE_IS_SYSTEM_DIR 2295 | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0); 2296 2297 // Find base frameworks (resource packages without code). 2298 scanDirTracedLI(frameworkDir, mDefParseFlags 2299 | PackageParser.PARSE_IS_SYSTEM 2300 | PackageParser.PARSE_IS_SYSTEM_DIR 2301 | PackageParser.PARSE_IS_PRIVILEGED, 2302 scanFlags | SCAN_NO_DEX, 0); 2303 2304 // Collected privileged system packages. 2305 final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app"); 2306 scanDirTracedLI(privilegedAppDir, mDefParseFlags 2307 | PackageParser.PARSE_IS_SYSTEM 2308 | PackageParser.PARSE_IS_SYSTEM_DIR 2309 | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0); 2310 2311 // Collect ordinary system packages. 2312 final File systemAppDir = new File(Environment.getRootDirectory(), "app"); 2313 scanDirTracedLI(systemAppDir, mDefParseFlags 2314 | PackageParser.PARSE_IS_SYSTEM 2315 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2316 2317 // Collect all vendor packages. 2318 File vendorAppDir = new File("/vendor/app"); 2319 try { 2320 vendorAppDir = vendorAppDir.getCanonicalFile(); 2321 } catch (IOException e) { 2322 // failed to look up canonical path, continue with original one 2323 } 2324 scanDirTracedLI(vendorAppDir, mDefParseFlags 2325 | PackageParser.PARSE_IS_SYSTEM 2326 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2327 2328 // Collect all OEM packages. 2329 final File oemAppDir = new File(Environment.getOemDirectory(), "app"); 2330 scanDirTracedLI(oemAppDir, mDefParseFlags 2331 | PackageParser.PARSE_IS_SYSTEM 2332 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2333 2334 // Prune any system packages that no longer exist. 2335 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>(); 2336 if (!mOnlyCore) { 2337 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 2338 while (psit.hasNext()) { 2339 PackageSetting ps = psit.next(); 2340 2341 /* 2342 * If this is not a system app, it can't be a 2343 * disable system app. 2344 */ 2345 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) { 2346 continue; 2347 } 2348 2349 /* 2350 * If the package is scanned, it's not erased. 2351 */ 2352 final PackageParser.Package scannedPkg = mPackages.get(ps.name); 2353 if (scannedPkg != null) { 2354 /* 2355 * If the system app is both scanned and in the 2356 * disabled packages list, then it must have been 2357 * added via OTA. Remove it from the currently 2358 * scanned package so the previously user-installed 2359 * application can be scanned. 2360 */ 2361 if (mSettings.isDisabledSystemPackageLPr(ps.name)) { 2362 logCriticalInfo(Log.WARN, "Expecting better updated system app for " 2363 + ps.name + "; removing system app. Last known codePath=" 2364 + ps.codePathString + ", installStatus=" + ps.installStatus 2365 + ", versionCode=" + ps.versionCode + "; scanned versionCode=" 2366 + scannedPkg.mVersionCode); 2367 removePackageLI(scannedPkg, true); 2368 mExpectingBetter.put(ps.name, ps.codePath); 2369 } 2370 2371 continue; 2372 } 2373 2374 if (!mSettings.isDisabledSystemPackageLPr(ps.name)) { 2375 psit.remove(); 2376 logCriticalInfo(Log.WARN, "System package " + ps.name 2377 + " no longer exists; it's data will be wiped"); 2378 // Actual deletion of code and data will be handled by later 2379 // reconciliation step 2380 } else { 2381 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name); 2382 if (disabledPs.codePath == null || !disabledPs.codePath.exists()) { 2383 possiblyDeletedUpdatedSystemApps.add(ps.name); 2384 } 2385 } 2386 } 2387 } 2388 2389 //look for any incomplete package installations 2390 ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr(); 2391 for (int i = 0; i < deletePkgsList.size(); i++) { 2392 // Actual deletion of code and data will be handled by later 2393 // reconciliation step 2394 final String packageName = deletePkgsList.get(i).name; 2395 logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName); 2396 synchronized (mPackages) { 2397 mSettings.removePackageLPw(packageName); 2398 } 2399 } 2400 2401 //delete tmp files 2402 deleteTempPackageFiles(); 2403 2404 // Remove any shared userIDs that have no associated packages 2405 mSettings.pruneSharedUsersLPw(); 2406 2407 if (!mOnlyCore) { 2408 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START, 2409 SystemClock.uptimeMillis()); 2410 scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0); 2411 2412 scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags 2413 | PackageParser.PARSE_FORWARD_LOCK, 2414 scanFlags | SCAN_REQUIRE_KNOWN, 0); 2415 2416 scanDirLI(mEphemeralInstallDir, mDefParseFlags 2417 | PackageParser.PARSE_IS_EPHEMERAL, 2418 scanFlags | SCAN_REQUIRE_KNOWN, 0); 2419 2420 /** 2421 * Remove disable package settings for any updated system 2422 * apps that were removed via an OTA. If they're not a 2423 * previously-updated app, remove them completely. 2424 * Otherwise, just revoke their system-level permissions. 2425 */ 2426 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) { 2427 PackageParser.Package deletedPkg = mPackages.get(deletedAppName); 2428 mSettings.removeDisabledSystemPackageLPw(deletedAppName); 2429 2430 String msg; 2431 if (deletedPkg == null) { 2432 msg = "Updated system package " + deletedAppName 2433 + " no longer exists; it's data will be wiped"; 2434 // Actual deletion of code and data will be handled by later 2435 // reconciliation step 2436 } else { 2437 msg = "Updated system app + " + deletedAppName 2438 + " no longer present; removing system privileges for " 2439 + deletedAppName; 2440 2441 deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM; 2442 2443 PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName); 2444 deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM; 2445 } 2446 logCriticalInfo(Log.WARN, msg); 2447 } 2448 2449 /** 2450 * Make sure all system apps that we expected to appear on 2451 * the userdata partition actually showed up. If they never 2452 * appeared, crawl back and revive the system version. 2453 */ 2454 for (int i = 0; i < mExpectingBetter.size(); i++) { 2455 final String packageName = mExpectingBetter.keyAt(i); 2456 if (!mPackages.containsKey(packageName)) { 2457 final File scanFile = mExpectingBetter.valueAt(i); 2458 2459 logCriticalInfo(Log.WARN, "Expected better " + packageName 2460 + " but never showed up; reverting to system"); 2461 2462 int reparseFlags = mDefParseFlags; 2463 if (FileUtils.contains(privilegedAppDir, scanFile)) { 2464 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2465 | PackageParser.PARSE_IS_SYSTEM_DIR 2466 | PackageParser.PARSE_IS_PRIVILEGED; 2467 } else if (FileUtils.contains(systemAppDir, scanFile)) { 2468 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2469 | PackageParser.PARSE_IS_SYSTEM_DIR; 2470 } else if (FileUtils.contains(vendorAppDir, scanFile)) { 2471 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2472 | PackageParser.PARSE_IS_SYSTEM_DIR; 2473 } else if (FileUtils.contains(oemAppDir, scanFile)) { 2474 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2475 | PackageParser.PARSE_IS_SYSTEM_DIR; 2476 } else { 2477 Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile); 2478 continue; 2479 } 2480 2481 mSettings.enableSystemPackageLPw(packageName); 2482 2483 try { 2484 scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null); 2485 } catch (PackageManagerException e) { 2486 Slog.e(TAG, "Failed to parse original system package: " 2487 + e.getMessage()); 2488 } 2489 } 2490 } 2491 } 2492 mExpectingBetter.clear(); 2493 2494 // Resolve the storage manager. 2495 mStorageManagerPackage = getStorageManagerPackageName(); 2496 2497 // Resolve protected action filters. Only the setup wizard is allowed to 2498 // have a high priority filter for these actions. 2499 mSetupWizardPackage = getSetupWizardPackageName(); 2500 if (mProtectedFilters.size() > 0) { 2501 if (DEBUG_FILTERS && mSetupWizardPackage == null) { 2502 Slog.i(TAG, "No setup wizard;" 2503 + " All protected intents capped to priority 0"); 2504 } 2505 for (ActivityIntentInfo filter : mProtectedFilters) { 2506 if (filter.activity.info.packageName.equals(mSetupWizardPackage)) { 2507 if (DEBUG_FILTERS) { 2508 Slog.i(TAG, "Found setup wizard;" 2509 + " allow priority " + filter.getPriority() + ";" 2510 + " package: " + filter.activity.info.packageName 2511 + " activity: " + filter.activity.className 2512 + " priority: " + filter.getPriority()); 2513 } 2514 // skip setup wizard; allow it to keep the high priority filter 2515 continue; 2516 } 2517 Slog.w(TAG, "Protected action; cap priority to 0;" 2518 + " package: " + filter.activity.info.packageName 2519 + " activity: " + filter.activity.className 2520 + " origPrio: " + filter.getPriority()); 2521 filter.setPriority(0); 2522 } 2523 } 2524 mDeferProtectedFilters = false; 2525 mProtectedFilters.clear(); 2526 2527 // Now that we know all of the shared libraries, update all clients to have 2528 // the correct library paths. 2529 updateAllSharedLibrariesLPw(); 2530 2531 for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) { 2532 // NOTE: We ignore potential failures here during a system scan (like 2533 // the rest of the commands above) because there's precious little we 2534 // can do about it. A settings error is reported, though. 2535 adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */, 2536 false /* boot complete */); 2537 } 2538 2539 // Now that we know all the packages we are keeping, 2540 // read and update their last usage times. 2541 mPackageUsage.read(mPackages); 2542 mCompilerStats.read(); 2543 2544 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END, 2545 SystemClock.uptimeMillis()); 2546 Slog.i(TAG, "Time to scan packages: " 2547 + ((SystemClock.uptimeMillis()-startTime)/1000f) 2548 + " seconds"); 2549 2550 // If the platform SDK has changed since the last time we booted, 2551 // we need to re-grant app permission to catch any new ones that 2552 // appear. This is really a hack, and means that apps can in some 2553 // cases get permissions that the user didn't initially explicitly 2554 // allow... it would be nice to have some better way to handle 2555 // this situation. 2556 int updateFlags = UPDATE_PERMISSIONS_ALL; 2557 if (ver.sdkVersion != mSdkVersion) { 2558 Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to " 2559 + mSdkVersion + "; regranting permissions for internal storage"); 2560 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 2561 } 2562 updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags); 2563 ver.sdkVersion = mSdkVersion; 2564 2565 // If this is the first boot or an update from pre-M, and it is a normal 2566 // boot, then we need to initialize the default preferred apps across 2567 // all defined users. 2568 if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) { 2569 for (UserInfo user : sUserManager.getUsers(true)) { 2570 mSettings.applyDefaultPreferredAppsLPw(this, user.id); 2571 applyFactoryDefaultBrowserLPw(user.id); 2572 primeDomainVerificationsLPw(user.id); 2573 } 2574 } 2575 2576 // Prepare storage for system user really early during boot, 2577 // since core system apps like SettingsProvider and SystemUI 2578 // can't wait for user to start 2579 final int storageFlags; 2580 if (StorageManager.isFileEncryptedNativeOrEmulated()) { 2581 storageFlags = StorageManager.FLAG_STORAGE_DE; 2582 } else { 2583 storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 2584 } 2585 reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL, UserHandle.USER_SYSTEM, 2586 storageFlags); 2587 2588 // If this is first boot after an OTA, and a normal boot, then 2589 // we need to clear code cache directories. 2590 // Note that we do *not* clear the application profiles. These remain valid 2591 // across OTAs and are used to drive profile verification (post OTA) and 2592 // profile compilation (without waiting to collect a fresh set of profiles). 2593 if (mIsUpgrade && !onlyCore) { 2594 Slog.i(TAG, "Build fingerprint changed; clearing code caches"); 2595 for (int i = 0; i < mSettings.mPackages.size(); i++) { 2596 final PackageSetting ps = mSettings.mPackages.valueAt(i); 2597 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) { 2598 // No apps are running this early, so no need to freeze 2599 clearAppDataLIF(ps.pkg, UserHandle.USER_ALL, 2600 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE 2601 | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 2602 } 2603 } 2604 ver.fingerprint = Build.FINGERPRINT; 2605 } 2606 2607 checkDefaultBrowser(); 2608 2609 // clear only after permissions and other defaults have been updated 2610 mExistingSystemPackages.clear(); 2611 mPromoteSystemApps = false; 2612 2613 // All the changes are done during package scanning. 2614 ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION; 2615 2616 // can downgrade to reader 2617 mSettings.writeLPr(); 2618 2619 // Perform dexopt on all apps that mark themselves as coreApps. We do this pretty 2620 // early on (before the package manager declares itself as early) because other 2621 // components in the system server might ask for package contexts for these apps. 2622 // 2623 // Note that "onlyCore" in this context means the system is encrypted or encrypting 2624 // (i.e, that the data partition is unavailable). 2625 if ((isFirstBoot() || isUpgrade() || VMRuntime.didPruneDalvikCache()) && !onlyCore) { 2626 long start = System.nanoTime(); 2627 List<PackageParser.Package> coreApps = new ArrayList<>(); 2628 for (PackageParser.Package pkg : mPackages.values()) { 2629 if (pkg.coreApp) { 2630 coreApps.add(pkg); 2631 } 2632 } 2633 2634 int[] stats = performDexOptUpgrade(coreApps, false, 2635 getCompilerFilterForReason(REASON_CORE_APP)); 2636 2637 final int elapsedTimeSeconds = 2638 (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start); 2639 MetricsLogger.histogram(mContext, "opt_coreapps_time_s", elapsedTimeSeconds); 2640 2641 if (DEBUG_DEXOPT) { 2642 Slog.i(TAG, "Dex-opt core apps took : " + elapsedTimeSeconds + " seconds (" + 2643 stats[0] + ", " + stats[1] + ", " + stats[2] + ")"); 2644 } 2645 2646 2647 // TODO: Should we log these stats to tron too ? 2648 // MetricsLogger.histogram(mContext, "opt_coreapps_num_dexopted", stats[0]); 2649 // MetricsLogger.histogram(mContext, "opt_coreapps_num_skipped", stats[1]); 2650 // MetricsLogger.histogram(mContext, "opt_coreapps_num_failed", stats[2]); 2651 // MetricsLogger.histogram(mContext, "opt_coreapps_num_total", coreApps.size()); 2652 } 2653 2654 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY, 2655 SystemClock.uptimeMillis()); 2656 2657 if (!mOnlyCore) { 2658 mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr(); 2659 mRequiredInstallerPackage = getRequiredInstallerLPr(); 2660 mRequiredUninstallerPackage = getRequiredUninstallerLPr(); 2661 mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr(); 2662 mIntentFilterVerifier = new IntentVerifierProxy(mContext, 2663 mIntentFilterVerifierComponent); 2664 mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr( 2665 PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES); 2666 mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr( 2667 PackageManager.SYSTEM_SHARED_LIBRARY_SHARED); 2668 } else { 2669 mRequiredVerifierPackage = null; 2670 mRequiredInstallerPackage = null; 2671 mRequiredUninstallerPackage = null; 2672 mIntentFilterVerifierComponent = null; 2673 mIntentFilterVerifier = null; 2674 mServicesSystemSharedLibraryPackageName = null; 2675 mSharedSystemSharedLibraryPackageName = null; 2676 } 2677 2678 mInstallerService = new PackageInstallerService(context, this); 2679 2680 final ComponentName ephemeralResolverComponent = getEphemeralResolverLPr(); 2681 final ComponentName ephemeralInstallerComponent = getEphemeralInstallerLPr(); 2682 // both the installer and resolver must be present to enable ephemeral 2683 if (ephemeralInstallerComponent != null && ephemeralResolverComponent != null) { 2684 if (DEBUG_EPHEMERAL) { 2685 Slog.i(TAG, "Ephemeral activated; resolver: " + ephemeralResolverComponent 2686 + " installer:" + ephemeralInstallerComponent); 2687 } 2688 mEphemeralResolverComponent = ephemeralResolverComponent; 2689 mEphemeralInstallerComponent = ephemeralInstallerComponent; 2690 setUpEphemeralInstallerActivityLP(mEphemeralInstallerComponent); 2691 mEphemeralResolverConnection = 2692 new EphemeralResolverConnection(mContext, mEphemeralResolverComponent); 2693 } else { 2694 if (DEBUG_EPHEMERAL) { 2695 final String missingComponent = 2696 (ephemeralResolverComponent == null) 2697 ? (ephemeralInstallerComponent == null) 2698 ? "resolver and installer" 2699 : "resolver" 2700 : "installer"; 2701 Slog.i(TAG, "Ephemeral deactivated; missing " + missingComponent); 2702 } 2703 mEphemeralResolverComponent = null; 2704 mEphemeralInstallerComponent = null; 2705 mEphemeralResolverConnection = null; 2706 } 2707 2708 mEphemeralApplicationRegistry = new EphemeralApplicationRegistry(this); 2709 } // synchronized (mPackages) 2710 } // synchronized (mInstallLock) 2711 2712 // Now after opening every single application zip, make sure they 2713 // are all flushed. Not really needed, but keeps things nice and 2714 // tidy. 2715 Runtime.getRuntime().gc(); 2716 2717 // The initial scanning above does many calls into installd while 2718 // holding the mPackages lock, but we're mostly interested in yelling 2719 // once we have a booted system. 2720 mInstaller.setWarnIfHeld(mPackages); 2721 2722 // Expose private service for system components to use. 2723 LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl()); 2724 } 2725 2726 @Override 2727 public boolean isFirstBoot() { 2728 return mFirstBoot; 2729 } 2730 2731 @Override 2732 public boolean isOnlyCoreApps() { 2733 return mOnlyCore; 2734 } 2735 2736 @Override 2737 public boolean isUpgrade() { 2738 return mIsUpgrade; 2739 } 2740 2741 private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() { 2742 final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 2743 2744 final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE, 2745 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 2746 UserHandle.USER_SYSTEM); 2747 if (matches.size() == 1) { 2748 return matches.get(0).getComponentInfo().packageName; 2749 } else if (matches.size() == 0) { 2750 Log.e(TAG, "There should probably be a verifier, but, none were found"); 2751 return null; 2752 } 2753 throw new RuntimeException("There must be exactly one verifier; found " + matches); 2754 } 2755 2756 private @NonNull String getRequiredSharedLibraryLPr(String libraryName) { 2757 synchronized (mPackages) { 2758 SharedLibraryEntry libraryEntry = mSharedLibraries.get(libraryName); 2759 if (libraryEntry == null) { 2760 throw new IllegalStateException("Missing required shared library:" + libraryName); 2761 } 2762 return libraryEntry.apk; 2763 } 2764 } 2765 2766 private @NonNull String getRequiredInstallerLPr() { 2767 final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE); 2768 intent.addCategory(Intent.CATEGORY_DEFAULT); 2769 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE); 2770 2771 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE, 2772 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 2773 UserHandle.USER_SYSTEM); 2774 if (matches.size() == 1) { 2775 ResolveInfo resolveInfo = matches.get(0); 2776 if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) { 2777 throw new RuntimeException("The installer must be a privileged app"); 2778 } 2779 return matches.get(0).getComponentInfo().packageName; 2780 } else { 2781 throw new RuntimeException("There must be exactly one installer; found " + matches); 2782 } 2783 } 2784 2785 private @NonNull String getRequiredUninstallerLPr() { 2786 final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE); 2787 intent.addCategory(Intent.CATEGORY_DEFAULT); 2788 intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null)); 2789 2790 final ResolveInfo resolveInfo = resolveIntent(intent, null, 2791 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 2792 UserHandle.USER_SYSTEM); 2793 if (resolveInfo == null || 2794 mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) { 2795 throw new RuntimeException("There must be exactly one uninstaller; found " 2796 + resolveInfo); 2797 } 2798 return resolveInfo.getComponentInfo().packageName; 2799 } 2800 2801 private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() { 2802 final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 2803 2804 final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE, 2805 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 2806 UserHandle.USER_SYSTEM); 2807 ResolveInfo best = null; 2808 final int N = matches.size(); 2809 for (int i = 0; i < N; i++) { 2810 final ResolveInfo cur = matches.get(i); 2811 final String packageName = cur.getComponentInfo().packageName; 2812 if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 2813 packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) { 2814 continue; 2815 } 2816 2817 if (best == null || cur.priority > best.priority) { 2818 best = cur; 2819 } 2820 } 2821 2822 if (best != null) { 2823 return best.getComponentInfo().getComponentName(); 2824 } else { 2825 throw new RuntimeException("There must be at least one intent filter verifier"); 2826 } 2827 } 2828 2829 private @Nullable ComponentName getEphemeralResolverLPr() { 2830 final String[] packageArray = 2831 mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage); 2832 if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) { 2833 if (DEBUG_EPHEMERAL) { 2834 Slog.d(TAG, "Ephemeral resolver NOT found; empty package list"); 2835 } 2836 return null; 2837 } 2838 2839 final int resolveFlags = 2840 MATCH_DIRECT_BOOT_AWARE 2841 | MATCH_DIRECT_BOOT_UNAWARE 2842 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0); 2843 final Intent resolverIntent = new Intent(Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE); 2844 final List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null, 2845 resolveFlags, UserHandle.USER_SYSTEM); 2846 2847 final int N = resolvers.size(); 2848 if (N == 0) { 2849 if (DEBUG_EPHEMERAL) { 2850 Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters"); 2851 } 2852 return null; 2853 } 2854 2855 final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray)); 2856 for (int i = 0; i < N; i++) { 2857 final ResolveInfo info = resolvers.get(i); 2858 2859 if (info.serviceInfo == null) { 2860 continue; 2861 } 2862 2863 final String packageName = info.serviceInfo.packageName; 2864 if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) { 2865 if (DEBUG_EPHEMERAL) { 2866 Slog.d(TAG, "Ephemeral resolver not in allowed package list;" 2867 + " pkg: " + packageName + ", info:" + info); 2868 } 2869 continue; 2870 } 2871 2872 if (DEBUG_EPHEMERAL) { 2873 Slog.v(TAG, "Ephemeral resolver found;" 2874 + " pkg: " + packageName + ", info:" + info); 2875 } 2876 return new ComponentName(packageName, info.serviceInfo.name); 2877 } 2878 if (DEBUG_EPHEMERAL) { 2879 Slog.v(TAG, "Ephemeral resolver NOT found"); 2880 } 2881 return null; 2882 } 2883 2884 private @Nullable ComponentName getEphemeralInstallerLPr() { 2885 final Intent intent = new Intent(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE); 2886 intent.addCategory(Intent.CATEGORY_DEFAULT); 2887 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE); 2888 2889 final int resolveFlags = 2890 MATCH_DIRECT_BOOT_AWARE 2891 | MATCH_DIRECT_BOOT_UNAWARE 2892 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0); 2893 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE, 2894 resolveFlags, UserHandle.USER_SYSTEM); 2895 if (matches.size() == 0) { 2896 return null; 2897 } else if (matches.size() == 1) { 2898 return matches.get(0).getComponentInfo().getComponentName(); 2899 } else { 2900 throw new RuntimeException( 2901 "There must be at most one ephemeral installer; found " + matches); 2902 } 2903 } 2904 2905 private void primeDomainVerificationsLPw(int userId) { 2906 if (DEBUG_DOMAIN_VERIFICATION) { 2907 Slog.d(TAG, "Priming domain verifications in user " + userId); 2908 } 2909 2910 SystemConfig systemConfig = SystemConfig.getInstance(); 2911 ArraySet<String> packages = systemConfig.getLinkedApps(); 2912 ArraySet<String> domains = new ArraySet<String>(); 2913 2914 for (String packageName : packages) { 2915 PackageParser.Package pkg = mPackages.get(packageName); 2916 if (pkg != null) { 2917 if (!pkg.isSystemApp()) { 2918 Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>"); 2919 continue; 2920 } 2921 2922 domains.clear(); 2923 for (PackageParser.Activity a : pkg.activities) { 2924 for (ActivityIntentInfo filter : a.intents) { 2925 if (hasValidDomains(filter)) { 2926 domains.addAll(filter.getHostsList()); 2927 } 2928 } 2929 } 2930 2931 if (domains.size() > 0) { 2932 if (DEBUG_DOMAIN_VERIFICATION) { 2933 Slog.v(TAG, " + " + packageName); 2934 } 2935 // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual 2936 // state w.r.t. the formal app-linkage "no verification attempted" state; 2937 // and then 'always' in the per-user state actually used for intent resolution. 2938 final IntentFilterVerificationInfo ivi; 2939 ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, 2940 new ArrayList<String>(domains)); 2941 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED); 2942 mSettings.updateIntentFilterVerificationStatusLPw(packageName, 2943 INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId); 2944 } else { 2945 Slog.w(TAG, "Sysconfig <app-link> package '" + packageName 2946 + "' does not handle web links"); 2947 } 2948 } else { 2949 Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>"); 2950 } 2951 } 2952 2953 scheduleWritePackageRestrictionsLocked(userId); 2954 scheduleWriteSettingsLocked(); 2955 } 2956 2957 private void applyFactoryDefaultBrowserLPw(int userId) { 2958 // The default browser app's package name is stored in a string resource, 2959 // with a product-specific overlay used for vendor customization. 2960 String browserPkg = mContext.getResources().getString( 2961 com.android.internal.R.string.default_browser); 2962 if (!TextUtils.isEmpty(browserPkg)) { 2963 // non-empty string => required to be a known package 2964 PackageSetting ps = mSettings.mPackages.get(browserPkg); 2965 if (ps == null) { 2966 Slog.e(TAG, "Product default browser app does not exist: " + browserPkg); 2967 browserPkg = null; 2968 } else { 2969 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId); 2970 } 2971 } 2972 2973 // Nothing valid explicitly set? Make the factory-installed browser the explicit 2974 // default. If there's more than one, just leave everything alone. 2975 if (browserPkg == null) { 2976 calculateDefaultBrowserLPw(userId); 2977 } 2978 } 2979 2980 private void calculateDefaultBrowserLPw(int userId) { 2981 List<String> allBrowsers = resolveAllBrowserApps(userId); 2982 final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null; 2983 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId); 2984 } 2985 2986 private List<String> resolveAllBrowserApps(int userId) { 2987 // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set 2988 List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null, 2989 PackageManager.MATCH_ALL, userId); 2990 2991 final int count = list.size(); 2992 List<String> result = new ArrayList<String>(count); 2993 for (int i=0; i<count; i++) { 2994 ResolveInfo info = list.get(i); 2995 if (info.activityInfo == null 2996 || !info.handleAllWebDataURI 2997 || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0 2998 || result.contains(info.activityInfo.packageName)) { 2999 continue; 3000 } 3001 result.add(info.activityInfo.packageName); 3002 } 3003 3004 return result; 3005 } 3006 3007 private boolean packageIsBrowser(String packageName, int userId) { 3008 List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null, 3009 PackageManager.MATCH_ALL, userId); 3010 final int N = list.size(); 3011 for (int i = 0; i < N; i++) { 3012 ResolveInfo info = list.get(i); 3013 if (packageName.equals(info.activityInfo.packageName)) { 3014 return true; 3015 } 3016 } 3017 return false; 3018 } 3019 3020 private void checkDefaultBrowser() { 3021 final int myUserId = UserHandle.myUserId(); 3022 final String packageName = getDefaultBrowserPackageName(myUserId); 3023 if (packageName != null) { 3024 PackageInfo info = getPackageInfo(packageName, 0, myUserId); 3025 if (info == null) { 3026 Slog.w(TAG, "Default browser no longer installed: " + packageName); 3027 synchronized (mPackages) { 3028 applyFactoryDefaultBrowserLPw(myUserId); // leaves ambiguous when > 1 3029 } 3030 } 3031 } 3032 } 3033 3034 @Override 3035 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 3036 throws RemoteException { 3037 try { 3038 return super.onTransact(code, data, reply, flags); 3039 } catch (RuntimeException e) { 3040 if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) { 3041 Slog.wtf(TAG, "Package Manager Crash", e); 3042 } 3043 throw e; 3044 } 3045 } 3046 3047 static int[] appendInts(int[] cur, int[] add) { 3048 if (add == null) return cur; 3049 if (cur == null) return add; 3050 final int N = add.length; 3051 for (int i=0; i<N; i++) { 3052 cur = appendInt(cur, add[i]); 3053 } 3054 return cur; 3055 } 3056 3057 private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) { 3058 if (!sUserManager.exists(userId)) return null; 3059 if (ps == null) { 3060 return null; 3061 } 3062 final PackageParser.Package p = ps.pkg; 3063 if (p == null) { 3064 return null; 3065 } 3066 3067 final PermissionsState permissionsState = ps.getPermissionsState(); 3068 3069 // Compute GIDs only if requested 3070 final int[] gids = (flags & PackageManager.GET_GIDS) == 0 3071 ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId); 3072 // Compute granted permissions only if package has requested permissions 3073 final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions) 3074 ? Collections.<String>emptySet() : permissionsState.getPermissions(userId); 3075 final PackageUserState state = ps.readUserState(userId); 3076 3077 return PackageParser.generatePackageInfo(p, gids, flags, 3078 ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId); 3079 } 3080 3081 @Override 3082 public void checkPackageStartable(String packageName, int userId) { 3083 final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId); 3084 3085 synchronized (mPackages) { 3086 final PackageSetting ps = mSettings.mPackages.get(packageName); 3087 if (ps == null) { 3088 throw new SecurityException("Package " + packageName + " was not found!"); 3089 } 3090 3091 if (!ps.getInstalled(userId)) { 3092 throw new SecurityException( 3093 "Package " + packageName + " was not installed for user " + userId + "!"); 3094 } 3095 3096 if (mSafeMode && !ps.isSystem()) { 3097 throw new SecurityException("Package " + packageName + " not a system app!"); 3098 } 3099 3100 if (mFrozenPackages.contains(packageName)) { 3101 throw new SecurityException("Package " + packageName + " is currently frozen!"); 3102 } 3103 3104 if (!userKeyUnlocked && !(ps.pkg.applicationInfo.isDirectBootAware() 3105 || ps.pkg.applicationInfo.isPartiallyDirectBootAware())) { 3106 throw new SecurityException("Package " + packageName + " is not encryption aware!"); 3107 } 3108 } 3109 } 3110 3111 @Override 3112 public boolean isPackageAvailable(String packageName, int userId) { 3113 if (!sUserManager.exists(userId)) return false; 3114 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3115 false /* requireFullPermission */, false /* checkShell */, "is package available"); 3116 synchronized (mPackages) { 3117 PackageParser.Package p = mPackages.get(packageName); 3118 if (p != null) { 3119 final PackageSetting ps = (PackageSetting) p.mExtras; 3120 if (ps != null) { 3121 final PackageUserState state = ps.readUserState(userId); 3122 if (state != null) { 3123 return PackageParser.isAvailable(state); 3124 } 3125 } 3126 } 3127 } 3128 return false; 3129 } 3130 3131 @Override 3132 public PackageInfo getPackageInfo(String packageName, int flags, int userId) { 3133 if (!sUserManager.exists(userId)) return null; 3134 flags = updateFlagsForPackage(flags, userId, packageName); 3135 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3136 false /* requireFullPermission */, false /* checkShell */, "get package info"); 3137 // reader 3138 synchronized (mPackages) { 3139 final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0; 3140 PackageParser.Package p = null; 3141 if (matchFactoryOnly) { 3142 final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName); 3143 if (ps != null) { 3144 return generatePackageInfo(ps, flags, userId); 3145 } 3146 } 3147 if (p == null) { 3148 p = mPackages.get(packageName); 3149 if (matchFactoryOnly && p != null && !isSystemApp(p)) { 3150 return null; 3151 } 3152 } 3153 if (DEBUG_PACKAGE_INFO) 3154 Log.v(TAG, "getPackageInfo " + packageName + ": " + p); 3155 if (p != null) { 3156 return generatePackageInfo((PackageSetting)p.mExtras, flags, userId); 3157 } 3158 if (!matchFactoryOnly && (flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 3159 final PackageSetting ps = mSettings.mPackages.get(packageName); 3160 return generatePackageInfo(ps, flags, userId); 3161 } 3162 } 3163 return null; 3164 } 3165 3166 @Override 3167 public String[] currentToCanonicalPackageNames(String[] names) { 3168 String[] out = new String[names.length]; 3169 // reader 3170 synchronized (mPackages) { 3171 for (int i=names.length-1; i>=0; i--) { 3172 PackageSetting ps = mSettings.mPackages.get(names[i]); 3173 out[i] = ps != null && ps.realName != null ? ps.realName : names[i]; 3174 } 3175 } 3176 return out; 3177 } 3178 3179 @Override 3180 public String[] canonicalToCurrentPackageNames(String[] names) { 3181 String[] out = new String[names.length]; 3182 // reader 3183 synchronized (mPackages) { 3184 for (int i=names.length-1; i>=0; i--) { 3185 String cur = mSettings.mRenamedPackages.get(names[i]); 3186 out[i] = cur != null ? cur : names[i]; 3187 } 3188 } 3189 return out; 3190 } 3191 3192 @Override 3193 public int getPackageUid(String packageName, int flags, int userId) { 3194 if (!sUserManager.exists(userId)) return -1; 3195 flags = updateFlagsForPackage(flags, userId, packageName); 3196 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3197 false /* requireFullPermission */, false /* checkShell */, "get package uid"); 3198 3199 // reader 3200 synchronized (mPackages) { 3201 final PackageParser.Package p = mPackages.get(packageName); 3202 if (p != null && p.isMatch(flags)) { 3203 return UserHandle.getUid(userId, p.applicationInfo.uid); 3204 } 3205 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 3206 final PackageSetting ps = mSettings.mPackages.get(packageName); 3207 if (ps != null && ps.isMatch(flags)) { 3208 return UserHandle.getUid(userId, ps.appId); 3209 } 3210 } 3211 } 3212 3213 return -1; 3214 } 3215 3216 @Override 3217 public int[] getPackageGids(String packageName, int flags, int userId) { 3218 if (!sUserManager.exists(userId)) return null; 3219 flags = updateFlagsForPackage(flags, userId, packageName); 3220 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3221 false /* requireFullPermission */, false /* checkShell */, 3222 "getPackageGids"); 3223 3224 // reader 3225 synchronized (mPackages) { 3226 final PackageParser.Package p = mPackages.get(packageName); 3227 if (p != null && p.isMatch(flags)) { 3228 PackageSetting ps = (PackageSetting) p.mExtras; 3229 return ps.getPermissionsState().computeGids(userId); 3230 } 3231 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 3232 final PackageSetting ps = mSettings.mPackages.get(packageName); 3233 if (ps != null && ps.isMatch(flags)) { 3234 return ps.getPermissionsState().computeGids(userId); 3235 } 3236 } 3237 } 3238 3239 return null; 3240 } 3241 3242 static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) { 3243 if (bp.perm != null) { 3244 return PackageParser.generatePermissionInfo(bp.perm, flags); 3245 } 3246 PermissionInfo pi = new PermissionInfo(); 3247 pi.name = bp.name; 3248 pi.packageName = bp.sourcePackage; 3249 pi.nonLocalizedLabel = bp.name; 3250 pi.protectionLevel = bp.protectionLevel; 3251 return pi; 3252 } 3253 3254 @Override 3255 public PermissionInfo getPermissionInfo(String name, int flags) { 3256 // reader 3257 synchronized (mPackages) { 3258 final BasePermission p = mSettings.mPermissions.get(name); 3259 if (p != null) { 3260 return generatePermissionInfo(p, flags); 3261 } 3262 return null; 3263 } 3264 } 3265 3266 @Override 3267 public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group, 3268 int flags) { 3269 // reader 3270 synchronized (mPackages) { 3271 if (group != null && !mPermissionGroups.containsKey(group)) { 3272 // This is thrown as NameNotFoundException 3273 return null; 3274 } 3275 3276 ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10); 3277 for (BasePermission p : mSettings.mPermissions.values()) { 3278 if (group == null) { 3279 if (p.perm == null || p.perm.info.group == null) { 3280 out.add(generatePermissionInfo(p, flags)); 3281 } 3282 } else { 3283 if (p.perm != null && group.equals(p.perm.info.group)) { 3284 out.add(PackageParser.generatePermissionInfo(p.perm, flags)); 3285 } 3286 } 3287 } 3288 return new ParceledListSlice<>(out); 3289 } 3290 } 3291 3292 @Override 3293 public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) { 3294 // reader 3295 synchronized (mPackages) { 3296 return PackageParser.generatePermissionGroupInfo( 3297 mPermissionGroups.get(name), flags); 3298 } 3299 } 3300 3301 @Override 3302 public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) { 3303 // reader 3304 synchronized (mPackages) { 3305 final int N = mPermissionGroups.size(); 3306 ArrayList<PermissionGroupInfo> out 3307 = new ArrayList<PermissionGroupInfo>(N); 3308 for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) { 3309 out.add(PackageParser.generatePermissionGroupInfo(pg, flags)); 3310 } 3311 return new ParceledListSlice<>(out); 3312 } 3313 } 3314 3315 private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags, 3316 int userId) { 3317 if (!sUserManager.exists(userId)) return null; 3318 PackageSetting ps = mSettings.mPackages.get(packageName); 3319 if (ps != null) { 3320 if (ps.pkg == null) { 3321 final PackageInfo pInfo = generatePackageInfo(ps, flags, userId); 3322 if (pInfo != null) { 3323 return pInfo.applicationInfo; 3324 } 3325 return null; 3326 } 3327 return PackageParser.generateApplicationInfo(ps.pkg, flags, 3328 ps.readUserState(userId), userId); 3329 } 3330 return null; 3331 } 3332 3333 @Override 3334 public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) { 3335 if (!sUserManager.exists(userId)) return null; 3336 flags = updateFlagsForApplication(flags, userId, packageName); 3337 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3338 false /* requireFullPermission */, false /* checkShell */, "get application info"); 3339 // writer 3340 synchronized (mPackages) { 3341 PackageParser.Package p = mPackages.get(packageName); 3342 if (DEBUG_PACKAGE_INFO) Log.v( 3343 TAG, "getApplicationInfo " + packageName 3344 + ": " + p); 3345 if (p != null) { 3346 PackageSetting ps = mSettings.mPackages.get(packageName); 3347 if (ps == null) return null; 3348 // Note: isEnabledLP() does not apply here - always return info 3349 return PackageParser.generateApplicationInfo( 3350 p, flags, ps.readUserState(userId), userId); 3351 } 3352 if ("android".equals(packageName)||"system".equals(packageName)) { 3353 return mAndroidApplication; 3354 } 3355 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 3356 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId); 3357 } 3358 } 3359 return null; 3360 } 3361 3362 @Override 3363 public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize, 3364 final IPackageDataObserver observer) { 3365 mContext.enforceCallingOrSelfPermission( 3366 android.Manifest.permission.CLEAR_APP_CACHE, null); 3367 // Queue up an async operation since clearing cache may take a little while. 3368 mHandler.post(new Runnable() { 3369 public void run() { 3370 mHandler.removeCallbacks(this); 3371 boolean success = true; 3372 synchronized (mInstallLock) { 3373 try { 3374 mInstaller.freeCache(volumeUuid, freeStorageSize); 3375 } catch (InstallerException e) { 3376 Slog.w(TAG, "Couldn't clear application caches: " + e); 3377 success = false; 3378 } 3379 } 3380 if (observer != null) { 3381 try { 3382 observer.onRemoveCompleted(null, success); 3383 } catch (RemoteException e) { 3384 Slog.w(TAG, "RemoveException when invoking call back"); 3385 } 3386 } 3387 } 3388 }); 3389 } 3390 3391 @Override 3392 public void freeStorage(final String volumeUuid, final long freeStorageSize, 3393 final IntentSender pi) { 3394 mContext.enforceCallingOrSelfPermission( 3395 android.Manifest.permission.CLEAR_APP_CACHE, null); 3396 // Queue up an async operation since clearing cache may take a little while. 3397 mHandler.post(new Runnable() { 3398 public void run() { 3399 mHandler.removeCallbacks(this); 3400 boolean success = true; 3401 synchronized (mInstallLock) { 3402 try { 3403 mInstaller.freeCache(volumeUuid, freeStorageSize); 3404 } catch (InstallerException e) { 3405 Slog.w(TAG, "Couldn't clear application caches: " + e); 3406 success = false; 3407 } 3408 } 3409 if(pi != null) { 3410 try { 3411 // Callback via pending intent 3412 int code = success ? 1 : 0; 3413 pi.sendIntent(null, code, null, 3414 null, null); 3415 } catch (SendIntentException e1) { 3416 Slog.i(TAG, "Failed to send pending intent"); 3417 } 3418 } 3419 } 3420 }); 3421 } 3422 3423 void freeStorage(String volumeUuid, long freeStorageSize) throws IOException { 3424 synchronized (mInstallLock) { 3425 try { 3426 mInstaller.freeCache(volumeUuid, freeStorageSize); 3427 } catch (InstallerException e) { 3428 throw new IOException("Failed to free enough space", e); 3429 } 3430 } 3431 } 3432 3433 /** 3434 * Update given flags based on encryption status of current user. 3435 */ 3436 private int updateFlags(int flags, int userId) { 3437 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE 3438 | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) { 3439 // Caller expressed an explicit opinion about what encryption 3440 // aware/unaware components they want to see, so fall through and 3441 // give them what they want 3442 } else { 3443 // Caller expressed no opinion, so match based on user state 3444 if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) { 3445 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE; 3446 } else { 3447 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE; 3448 } 3449 } 3450 return flags; 3451 } 3452 3453 private UserManagerInternal getUserManagerInternal() { 3454 if (mUserManagerInternal == null) { 3455 mUserManagerInternal = LocalServices.getService(UserManagerInternal.class); 3456 } 3457 return mUserManagerInternal; 3458 } 3459 3460 /** 3461 * Update given flags when being used to request {@link PackageInfo}. 3462 */ 3463 private int updateFlagsForPackage(int flags, int userId, Object cookie) { 3464 boolean triaged = true; 3465 if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS 3466 | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) { 3467 // Caller is asking for component details, so they'd better be 3468 // asking for specific encryption matching behavior, or be triaged 3469 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE 3470 | PackageManager.MATCH_DIRECT_BOOT_AWARE 3471 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3472 triaged = false; 3473 } 3474 } 3475 if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES 3476 | PackageManager.MATCH_SYSTEM_ONLY 3477 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3478 triaged = false; 3479 } 3480 if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) { 3481 Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie 3482 + " with flags 0x" + Integer.toHexString(flags), new Throwable()); 3483 } 3484 return updateFlags(flags, userId); 3485 } 3486 3487 /** 3488 * Update given flags when being used to request {@link ApplicationInfo}. 3489 */ 3490 private int updateFlagsForApplication(int flags, int userId, Object cookie) { 3491 return updateFlagsForPackage(flags, userId, cookie); 3492 } 3493 3494 /** 3495 * Update given flags when being used to request {@link ComponentInfo}. 3496 */ 3497 private int updateFlagsForComponent(int flags, int userId, Object cookie) { 3498 if (cookie instanceof Intent) { 3499 if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) { 3500 flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING; 3501 } 3502 } 3503 3504 boolean triaged = true; 3505 // Caller is asking for component details, so they'd better be 3506 // asking for specific encryption matching behavior, or be triaged 3507 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE 3508 | PackageManager.MATCH_DIRECT_BOOT_AWARE 3509 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3510 triaged = false; 3511 } 3512 if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) { 3513 Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie 3514 + " with flags 0x" + Integer.toHexString(flags), new Throwable()); 3515 } 3516 3517 return updateFlags(flags, userId); 3518 } 3519 3520 /** 3521 * Update given flags when being used to request {@link ResolveInfo}. 3522 */ 3523 int updateFlagsForResolve(int flags, int userId, Object cookie) { 3524 // Safe mode means we shouldn't match any third-party components 3525 if (mSafeMode) { 3526 flags |= PackageManager.MATCH_SYSTEM_ONLY; 3527 } 3528 3529 return updateFlagsForComponent(flags, userId, cookie); 3530 } 3531 3532 @Override 3533 public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) { 3534 if (!sUserManager.exists(userId)) return null; 3535 flags = updateFlagsForComponent(flags, userId, component); 3536 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3537 false /* requireFullPermission */, false /* checkShell */, "get activity info"); 3538 synchronized (mPackages) { 3539 PackageParser.Activity a = mActivities.mActivities.get(component); 3540 3541 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a); 3542 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) { 3543 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3544 if (ps == null) return null; 3545 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 3546 userId); 3547 } 3548 if (mResolveComponentName.equals(component)) { 3549 return PackageParser.generateActivityInfo(mResolveActivity, flags, 3550 new PackageUserState(), userId); 3551 } 3552 } 3553 return null; 3554 } 3555 3556 @Override 3557 public boolean activitySupportsIntent(ComponentName component, Intent intent, 3558 String resolvedType) { 3559 synchronized (mPackages) { 3560 if (component.equals(mResolveComponentName)) { 3561 // The resolver supports EVERYTHING! 3562 return true; 3563 } 3564 PackageParser.Activity a = mActivities.mActivities.get(component); 3565 if (a == null) { 3566 return false; 3567 } 3568 for (int i=0; i<a.intents.size(); i++) { 3569 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(), 3570 intent.getData(), intent.getCategories(), TAG) >= 0) { 3571 return true; 3572 } 3573 } 3574 return false; 3575 } 3576 } 3577 3578 @Override 3579 public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) { 3580 if (!sUserManager.exists(userId)) return null; 3581 flags = updateFlagsForComponent(flags, userId, component); 3582 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3583 false /* requireFullPermission */, false /* checkShell */, "get receiver info"); 3584 synchronized (mPackages) { 3585 PackageParser.Activity a = mReceivers.mActivities.get(component); 3586 if (DEBUG_PACKAGE_INFO) Log.v( 3587 TAG, "getReceiverInfo " + component + ": " + a); 3588 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) { 3589 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3590 if (ps == null) return null; 3591 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 3592 userId); 3593 } 3594 } 3595 return null; 3596 } 3597 3598 @Override 3599 public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) { 3600 if (!sUserManager.exists(userId)) return null; 3601 flags = updateFlagsForComponent(flags, userId, component); 3602 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3603 false /* requireFullPermission */, false /* checkShell */, "get service info"); 3604 synchronized (mPackages) { 3605 PackageParser.Service s = mServices.mServices.get(component); 3606 if (DEBUG_PACKAGE_INFO) Log.v( 3607 TAG, "getServiceInfo " + component + ": " + s); 3608 if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) { 3609 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3610 if (ps == null) return null; 3611 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId), 3612 userId); 3613 } 3614 } 3615 return null; 3616 } 3617 3618 @Override 3619 public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) { 3620 if (!sUserManager.exists(userId)) return null; 3621 flags = updateFlagsForComponent(flags, userId, component); 3622 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3623 false /* requireFullPermission */, false /* checkShell */, "get provider info"); 3624 synchronized (mPackages) { 3625 PackageParser.Provider p = mProviders.mProviders.get(component); 3626 if (DEBUG_PACKAGE_INFO) Log.v( 3627 TAG, "getProviderInfo " + component + ": " + p); 3628 if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) { 3629 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3630 if (ps == null) return null; 3631 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId), 3632 userId); 3633 } 3634 } 3635 return null; 3636 } 3637 3638 @Override 3639 public String[] getSystemSharedLibraryNames() { 3640 Set<String> libSet; 3641 synchronized (mPackages) { 3642 libSet = mSharedLibraries.keySet(); 3643 int size = libSet.size(); 3644 if (size > 0) { 3645 String[] libs = new String[size]; 3646 libSet.toArray(libs); 3647 return libs; 3648 } 3649 } 3650 return null; 3651 } 3652 3653 @Override 3654 public @NonNull String getServicesSystemSharedLibraryPackageName() { 3655 synchronized (mPackages) { 3656 return mServicesSystemSharedLibraryPackageName; 3657 } 3658 } 3659 3660 @Override 3661 public @NonNull String getSharedSystemSharedLibraryPackageName() { 3662 synchronized (mPackages) { 3663 return mSharedSystemSharedLibraryPackageName; 3664 } 3665 } 3666 3667 @Override 3668 public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() { 3669 synchronized (mPackages) { 3670 final ArrayList<FeatureInfo> res = new ArrayList<>(mAvailableFeatures.values()); 3671 3672 final FeatureInfo fi = new FeatureInfo(); 3673 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version", 3674 FeatureInfo.GL_ES_VERSION_UNDEFINED); 3675 res.add(fi); 3676 3677 return new ParceledListSlice<>(res); 3678 } 3679 } 3680 3681 @Override 3682 public boolean hasSystemFeature(String name, int version) { 3683 synchronized (mPackages) { 3684 final FeatureInfo feat = mAvailableFeatures.get(name); 3685 if (feat == null) { 3686 return false; 3687 } else { 3688 return feat.version >= version; 3689 } 3690 } 3691 } 3692 3693 @Override 3694 public int checkPermission(String permName, String pkgName, int userId) { 3695 if (!sUserManager.exists(userId)) { 3696 return PackageManager.PERMISSION_DENIED; 3697 } 3698 3699 synchronized (mPackages) { 3700 final PackageParser.Package p = mPackages.get(pkgName); 3701 if (p != null && p.mExtras != null) { 3702 final PackageSetting ps = (PackageSetting) p.mExtras; 3703 final PermissionsState permissionsState = ps.getPermissionsState(); 3704 if (permissionsState.hasPermission(permName, userId)) { 3705 return PackageManager.PERMISSION_GRANTED; 3706 } 3707 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION 3708 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState 3709 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { 3710 return PackageManager.PERMISSION_GRANTED; 3711 } 3712 } 3713 } 3714 3715 return PackageManager.PERMISSION_DENIED; 3716 } 3717 3718 @Override 3719 public int checkUidPermission(String permName, int uid) { 3720 final int userId = UserHandle.getUserId(uid); 3721 3722 if (!sUserManager.exists(userId)) { 3723 return PackageManager.PERMISSION_DENIED; 3724 } 3725 3726 synchronized (mPackages) { 3727 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 3728 if (obj != null) { 3729 final SettingBase ps = (SettingBase) obj; 3730 final PermissionsState permissionsState = ps.getPermissionsState(); 3731 if (permissionsState.hasPermission(permName, userId)) { 3732 return PackageManager.PERMISSION_GRANTED; 3733 } 3734 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION 3735 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState 3736 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { 3737 return PackageManager.PERMISSION_GRANTED; 3738 } 3739 } else { 3740 ArraySet<String> perms = mSystemPermissions.get(uid); 3741 if (perms != null) { 3742 if (perms.contains(permName)) { 3743 return PackageManager.PERMISSION_GRANTED; 3744 } 3745 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms 3746 .contains(Manifest.permission.ACCESS_FINE_LOCATION)) { 3747 return PackageManager.PERMISSION_GRANTED; 3748 } 3749 } 3750 } 3751 } 3752 3753 return PackageManager.PERMISSION_DENIED; 3754 } 3755 3756 @Override 3757 public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) { 3758 if (UserHandle.getCallingUserId() != userId) { 3759 mContext.enforceCallingPermission( 3760 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 3761 "isPermissionRevokedByPolicy for user " + userId); 3762 } 3763 3764 if (checkPermission(permission, packageName, userId) 3765 == PackageManager.PERMISSION_GRANTED) { 3766 return false; 3767 } 3768 3769 final long identity = Binder.clearCallingIdentity(); 3770 try { 3771 final int flags = getPermissionFlags(permission, packageName, userId); 3772 return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0; 3773 } finally { 3774 Binder.restoreCallingIdentity(identity); 3775 } 3776 } 3777 3778 @Override 3779 public String getPermissionControllerPackageName() { 3780 synchronized (mPackages) { 3781 return mRequiredInstallerPackage; 3782 } 3783 } 3784 3785 /** 3786 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS 3787 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller. 3788 * @param checkShell whether to prevent shell from access if there's a debugging restriction 3789 * @param message the message to log on security exception 3790 */ 3791 void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, 3792 boolean checkShell, String message) { 3793 if (userId < 0) { 3794 throw new IllegalArgumentException("Invalid userId " + userId); 3795 } 3796 if (checkShell) { 3797 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); 3798 } 3799 if (userId == UserHandle.getUserId(callingUid)) return; 3800 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 3801 if (requireFullPermission) { 3802 mContext.enforceCallingOrSelfPermission( 3803 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 3804 } else { 3805 try { 3806 mContext.enforceCallingOrSelfPermission( 3807 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 3808 } catch (SecurityException se) { 3809 mContext.enforceCallingOrSelfPermission( 3810 android.Manifest.permission.INTERACT_ACROSS_USERS, message); 3811 } 3812 } 3813 } 3814 } 3815 3816 void enforceShellRestriction(String restriction, int callingUid, int userHandle) { 3817 if (callingUid == Process.SHELL_UID) { 3818 if (userHandle >= 0 3819 && sUserManager.hasUserRestriction(restriction, userHandle)) { 3820 throw new SecurityException("Shell does not have permission to access user " 3821 + userHandle); 3822 } else if (userHandle < 0) { 3823 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t" 3824 + Debug.getCallers(3)); 3825 } 3826 } 3827 } 3828 3829 private BasePermission findPermissionTreeLP(String permName) { 3830 for(BasePermission bp : mSettings.mPermissionTrees.values()) { 3831 if (permName.startsWith(bp.name) && 3832 permName.length() > bp.name.length() && 3833 permName.charAt(bp.name.length()) == '.') { 3834 return bp; 3835 } 3836 } 3837 return null; 3838 } 3839 3840 private BasePermission checkPermissionTreeLP(String permName) { 3841 if (permName != null) { 3842 BasePermission bp = findPermissionTreeLP(permName); 3843 if (bp != null) { 3844 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) { 3845 return bp; 3846 } 3847 throw new SecurityException("Calling uid " 3848 + Binder.getCallingUid() 3849 + " is not allowed to add to permission tree " 3850 + bp.name + " owned by uid " + bp.uid); 3851 } 3852 } 3853 throw new SecurityException("No permission tree found for " + permName); 3854 } 3855 3856 static boolean compareStrings(CharSequence s1, CharSequence s2) { 3857 if (s1 == null) { 3858 return s2 == null; 3859 } 3860 if (s2 == null) { 3861 return false; 3862 } 3863 if (s1.getClass() != s2.getClass()) { 3864 return false; 3865 } 3866 return s1.equals(s2); 3867 } 3868 3869 static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) { 3870 if (pi1.icon != pi2.icon) return false; 3871 if (pi1.logo != pi2.logo) return false; 3872 if (pi1.protectionLevel != pi2.protectionLevel) return false; 3873 if (!compareStrings(pi1.name, pi2.name)) return false; 3874 if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false; 3875 // We'll take care of setting this one. 3876 if (!compareStrings(pi1.packageName, pi2.packageName)) return false; 3877 // These are not currently stored in settings. 3878 //if (!compareStrings(pi1.group, pi2.group)) return false; 3879 //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false; 3880 //if (pi1.labelRes != pi2.labelRes) return false; 3881 //if (pi1.descriptionRes != pi2.descriptionRes) return false; 3882 return true; 3883 } 3884 3885 int permissionInfoFootprint(PermissionInfo info) { 3886 int size = info.name.length(); 3887 if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length(); 3888 if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length(); 3889 return size; 3890 } 3891 3892 int calculateCurrentPermissionFootprintLocked(BasePermission tree) { 3893 int size = 0; 3894 for (BasePermission perm : mSettings.mPermissions.values()) { 3895 if (perm.uid == tree.uid) { 3896 size += perm.name.length() + permissionInfoFootprint(perm.perm.info); 3897 } 3898 } 3899 return size; 3900 } 3901 3902 void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) { 3903 // We calculate the max size of permissions defined by this uid and throw 3904 // if that plus the size of 'info' would exceed our stated maximum. 3905 if (tree.uid != Process.SYSTEM_UID) { 3906 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree); 3907 if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) { 3908 throw new SecurityException("Permission tree size cap exceeded"); 3909 } 3910 } 3911 } 3912 3913 boolean addPermissionLocked(PermissionInfo info, boolean async) { 3914 if (info.labelRes == 0 && info.nonLocalizedLabel == null) { 3915 throw new SecurityException("Label must be specified in permission"); 3916 } 3917 BasePermission tree = checkPermissionTreeLP(info.name); 3918 BasePermission bp = mSettings.mPermissions.get(info.name); 3919 boolean added = bp == null; 3920 boolean changed = true; 3921 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel); 3922 if (added) { 3923 enforcePermissionCapLocked(info, tree); 3924 bp = new BasePermission(info.name, tree.sourcePackage, 3925 BasePermission.TYPE_DYNAMIC); 3926 } else if (bp.type != BasePermission.TYPE_DYNAMIC) { 3927 throw new SecurityException( 3928 "Not allowed to modify non-dynamic permission " 3929 + info.name); 3930 } else { 3931 if (bp.protectionLevel == fixedLevel 3932 && bp.perm.owner.equals(tree.perm.owner) 3933 && bp.uid == tree.uid 3934 && comparePermissionInfos(bp.perm.info, info)) { 3935 changed = false; 3936 } 3937 } 3938 bp.protectionLevel = fixedLevel; 3939 info = new PermissionInfo(info); 3940 info.protectionLevel = fixedLevel; 3941 bp.perm = new PackageParser.Permission(tree.perm.owner, info); 3942 bp.perm.info.packageName = tree.perm.info.packageName; 3943 bp.uid = tree.uid; 3944 if (added) { 3945 mSettings.mPermissions.put(info.name, bp); 3946 } 3947 if (changed) { 3948 if (!async) { 3949 mSettings.writeLPr(); 3950 } else { 3951 scheduleWriteSettingsLocked(); 3952 } 3953 } 3954 return added; 3955 } 3956 3957 @Override 3958 public boolean addPermission(PermissionInfo info) { 3959 synchronized (mPackages) { 3960 return addPermissionLocked(info, false); 3961 } 3962 } 3963 3964 @Override 3965 public boolean addPermissionAsync(PermissionInfo info) { 3966 synchronized (mPackages) { 3967 return addPermissionLocked(info, true); 3968 } 3969 } 3970 3971 @Override 3972 public void removePermission(String name) { 3973 synchronized (mPackages) { 3974 checkPermissionTreeLP(name); 3975 BasePermission bp = mSettings.mPermissions.get(name); 3976 if (bp != null) { 3977 if (bp.type != BasePermission.TYPE_DYNAMIC) { 3978 throw new SecurityException( 3979 "Not allowed to modify non-dynamic permission " 3980 + name); 3981 } 3982 mSettings.mPermissions.remove(name); 3983 mSettings.writeLPr(); 3984 } 3985 } 3986 } 3987 3988 private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg, 3989 BasePermission bp) { 3990 int index = pkg.requestedPermissions.indexOf(bp.name); 3991 if (index == -1) { 3992 throw new SecurityException("Package " + pkg.packageName 3993 + " has not requested permission " + bp.name); 3994 } 3995 if (!bp.isRuntime() && !bp.isDevelopment()) { 3996 throw new SecurityException("Permission " + bp.name 3997 + " is not a changeable permission type"); 3998 } 3999 } 4000 4001 @Override 4002 public void grantRuntimePermission(String packageName, String name, final int userId) { 4003 if (!sUserManager.exists(userId)) { 4004 Log.e(TAG, "No such user:" + userId); 4005 return; 4006 } 4007 4008 mContext.enforceCallingOrSelfPermission( 4009 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 4010 "grantRuntimePermission"); 4011 4012 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4013 true /* requireFullPermission */, true /* checkShell */, 4014 "grantRuntimePermission"); 4015 4016 final int uid; 4017 final SettingBase sb; 4018 4019 synchronized (mPackages) { 4020 final PackageParser.Package pkg = mPackages.get(packageName); 4021 if (pkg == null) { 4022 throw new IllegalArgumentException("Unknown package: " + packageName); 4023 } 4024 4025 final BasePermission bp = mSettings.mPermissions.get(name); 4026 if (bp == null) { 4027 throw new IllegalArgumentException("Unknown permission: " + name); 4028 } 4029 4030 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp); 4031 4032 // If a permission review is required for legacy apps we represent 4033 // their permissions as always granted runtime ones since we need 4034 // to keep the review required permission flag per user while an 4035 // install permission's state is shared across all users. 4036 if ((mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED) 4037 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M 4038 && bp.isRuntime()) { 4039 return; 4040 } 4041 4042 uid = UserHandle.getUid(userId, pkg.applicationInfo.uid); 4043 sb = (SettingBase) pkg.mExtras; 4044 if (sb == null) { 4045 throw new IllegalArgumentException("Unknown package: " + packageName); 4046 } 4047 4048 final PermissionsState permissionsState = sb.getPermissionsState(); 4049 4050 final int flags = permissionsState.getPermissionFlags(name, userId); 4051 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 4052 throw new SecurityException("Cannot grant system fixed permission " 4053 + name + " for package " + packageName); 4054 } 4055 4056 if (bp.isDevelopment()) { 4057 // Development permissions must be handled specially, since they are not 4058 // normal runtime permissions. For now they apply to all users. 4059 if (permissionsState.grantInstallPermission(bp) != 4060 PermissionsState.PERMISSION_OPERATION_FAILURE) { 4061 scheduleWriteSettingsLocked(); 4062 } 4063 return; 4064 } 4065 4066 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 4067 Slog.w(TAG, "Cannot grant runtime permission to a legacy app"); 4068 return; 4069 } 4070 4071 final int result = permissionsState.grantRuntimePermission(bp, userId); 4072 switch (result) { 4073 case PermissionsState.PERMISSION_OPERATION_FAILURE: { 4074 return; 4075 } 4076 4077 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 4078 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); 4079 mHandler.post(new Runnable() { 4080 @Override 4081 public void run() { 4082 killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED); 4083 } 4084 }); 4085 } 4086 break; 4087 } 4088 4089 mOnPermissionChangeListeners.onPermissionsChanged(uid); 4090 4091 // Not critical if that is lost - app has to request again. 4092 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 4093 } 4094 4095 // Only need to do this if user is initialized. Otherwise it's a new user 4096 // and there are no processes running as the user yet and there's no need 4097 // to make an expensive call to remount processes for the changed permissions. 4098 if (READ_EXTERNAL_STORAGE.equals(name) 4099 || WRITE_EXTERNAL_STORAGE.equals(name)) { 4100 final long token = Binder.clearCallingIdentity(); 4101 try { 4102 if (sUserManager.isInitialized(userId)) { 4103 MountServiceInternal mountServiceInternal = LocalServices.getService( 4104 MountServiceInternal.class); 4105 mountServiceInternal.onExternalStoragePolicyChanged(uid, packageName); 4106 } 4107 } finally { 4108 Binder.restoreCallingIdentity(token); 4109 } 4110 } 4111 } 4112 4113 @Override 4114 public void revokeRuntimePermission(String packageName, String name, int userId) { 4115 if (!sUserManager.exists(userId)) { 4116 Log.e(TAG, "No such user:" + userId); 4117 return; 4118 } 4119 4120 mContext.enforceCallingOrSelfPermission( 4121 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 4122 "revokeRuntimePermission"); 4123 4124 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4125 true /* requireFullPermission */, true /* checkShell */, 4126 "revokeRuntimePermission"); 4127 4128 final int appId; 4129 4130 synchronized (mPackages) { 4131 final PackageParser.Package pkg = mPackages.get(packageName); 4132 if (pkg == null) { 4133 throw new IllegalArgumentException("Unknown package: " + packageName); 4134 } 4135 4136 final BasePermission bp = mSettings.mPermissions.get(name); 4137 if (bp == null) { 4138 throw new IllegalArgumentException("Unknown permission: " + name); 4139 } 4140 4141 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp); 4142 4143 // If a permission review is required for legacy apps we represent 4144 // their permissions as always granted runtime ones since we need 4145 // to keep the review required permission flag per user while an 4146 // install permission's state is shared across all users. 4147 if ((mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED) 4148 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M 4149 && bp.isRuntime()) { 4150 return; 4151 } 4152 4153 SettingBase sb = (SettingBase) pkg.mExtras; 4154 if (sb == null) { 4155 throw new IllegalArgumentException("Unknown package: " + packageName); 4156 } 4157 4158 final PermissionsState permissionsState = sb.getPermissionsState(); 4159 4160 final int flags = permissionsState.getPermissionFlags(name, userId); 4161 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 4162 throw new SecurityException("Cannot revoke system fixed permission " 4163 + name + " for package " + packageName); 4164 } 4165 4166 if (bp.isDevelopment()) { 4167 // Development permissions must be handled specially, since they are not 4168 // normal runtime permissions. For now they apply to all users. 4169 if (permissionsState.revokeInstallPermission(bp) != 4170 PermissionsState.PERMISSION_OPERATION_FAILURE) { 4171 scheduleWriteSettingsLocked(); 4172 } 4173 return; 4174 } 4175 4176 if (permissionsState.revokeRuntimePermission(bp, userId) == 4177 PermissionsState.PERMISSION_OPERATION_FAILURE) { 4178 return; 4179 } 4180 4181 mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid); 4182 4183 // Critical, after this call app should never have the permission. 4184 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 4185 4186 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 4187 } 4188 4189 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED); 4190 } 4191 4192 @Override 4193 public void resetRuntimePermissions() { 4194 mContext.enforceCallingOrSelfPermission( 4195 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 4196 "revokeRuntimePermission"); 4197 4198 int callingUid = Binder.getCallingUid(); 4199 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 4200 mContext.enforceCallingOrSelfPermission( 4201 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 4202 "resetRuntimePermissions"); 4203 } 4204 4205 synchronized (mPackages) { 4206 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL); 4207 for (int userId : UserManagerService.getInstance().getUserIds()) { 4208 final int packageCount = mPackages.size(); 4209 for (int i = 0; i < packageCount; i++) { 4210 PackageParser.Package pkg = mPackages.valueAt(i); 4211 if (!(pkg.mExtras instanceof PackageSetting)) { 4212 continue; 4213 } 4214 PackageSetting ps = (PackageSetting) pkg.mExtras; 4215 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 4216 } 4217 } 4218 } 4219 } 4220 4221 @Override 4222 public int getPermissionFlags(String name, String packageName, int userId) { 4223 if (!sUserManager.exists(userId)) { 4224 return 0; 4225 } 4226 4227 enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags"); 4228 4229 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4230 true /* requireFullPermission */, false /* checkShell */, 4231 "getPermissionFlags"); 4232 4233 synchronized (mPackages) { 4234 final PackageParser.Package pkg = mPackages.get(packageName); 4235 if (pkg == null) { 4236 return 0; 4237 } 4238 4239 final BasePermission bp = mSettings.mPermissions.get(name); 4240 if (bp == null) { 4241 return 0; 4242 } 4243 4244 SettingBase sb = (SettingBase) pkg.mExtras; 4245 if (sb == null) { 4246 return 0; 4247 } 4248 4249 PermissionsState permissionsState = sb.getPermissionsState(); 4250 return permissionsState.getPermissionFlags(name, userId); 4251 } 4252 } 4253 4254 @Override 4255 public void updatePermissionFlags(String name, String packageName, int flagMask, 4256 int flagValues, int userId) { 4257 if (!sUserManager.exists(userId)) { 4258 return; 4259 } 4260 4261 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags"); 4262 4263 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4264 true /* requireFullPermission */, true /* checkShell */, 4265 "updatePermissionFlags"); 4266 4267 // Only the system can change these flags and nothing else. 4268 if (getCallingUid() != Process.SYSTEM_UID) { 4269 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4270 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4271 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 4272 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 4273 flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 4274 } 4275 4276 synchronized (mPackages) { 4277 final PackageParser.Package pkg = mPackages.get(packageName); 4278 if (pkg == null) { 4279 throw new IllegalArgumentException("Unknown package: " + packageName); 4280 } 4281 4282 final BasePermission bp = mSettings.mPermissions.get(name); 4283 if (bp == null) { 4284 throw new IllegalArgumentException("Unknown permission: " + name); 4285 } 4286 4287 SettingBase sb = (SettingBase) pkg.mExtras; 4288 if (sb == null) { 4289 throw new IllegalArgumentException("Unknown package: " + packageName); 4290 } 4291 4292 PermissionsState permissionsState = sb.getPermissionsState(); 4293 4294 boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null; 4295 4296 if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) { 4297 // Install and runtime permissions are stored in different places, 4298 // so figure out what permission changed and persist the change. 4299 if (permissionsState.getInstallPermissionState(name) != null) { 4300 scheduleWriteSettingsLocked(); 4301 } else if (permissionsState.getRuntimePermissionState(name, userId) != null 4302 || hadState) { 4303 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 4304 } 4305 } 4306 } 4307 } 4308 4309 /** 4310 * Update the permission flags for all packages and runtime permissions of a user in order 4311 * to allow device or profile owner to remove POLICY_FIXED. 4312 */ 4313 @Override 4314 public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) { 4315 if (!sUserManager.exists(userId)) { 4316 return; 4317 } 4318 4319 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps"); 4320 4321 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4322 true /* requireFullPermission */, true /* checkShell */, 4323 "updatePermissionFlagsForAllApps"); 4324 4325 // Only the system can change system fixed flags. 4326 if (getCallingUid() != Process.SYSTEM_UID) { 4327 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4328 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4329 } 4330 4331 synchronized (mPackages) { 4332 boolean changed = false; 4333 final int packageCount = mPackages.size(); 4334 for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) { 4335 final PackageParser.Package pkg = mPackages.valueAt(pkgIndex); 4336 SettingBase sb = (SettingBase) pkg.mExtras; 4337 if (sb == null) { 4338 continue; 4339 } 4340 PermissionsState permissionsState = sb.getPermissionsState(); 4341 changed |= permissionsState.updatePermissionFlagsForAllPermissions( 4342 userId, flagMask, flagValues); 4343 } 4344 if (changed) { 4345 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 4346 } 4347 } 4348 } 4349 4350 private void enforceGrantRevokeRuntimePermissionPermissions(String message) { 4351 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS) 4352 != PackageManager.PERMISSION_GRANTED 4353 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) 4354 != PackageManager.PERMISSION_GRANTED) { 4355 throw new SecurityException(message + " requires " 4356 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or " 4357 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS); 4358 } 4359 } 4360 4361 @Override 4362 public boolean shouldShowRequestPermissionRationale(String permissionName, 4363 String packageName, int userId) { 4364 if (UserHandle.getCallingUserId() != userId) { 4365 mContext.enforceCallingPermission( 4366 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 4367 "canShowRequestPermissionRationale for user " + userId); 4368 } 4369 4370 final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId); 4371 if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) { 4372 return false; 4373 } 4374 4375 if (checkPermission(permissionName, packageName, userId) 4376 == PackageManager.PERMISSION_GRANTED) { 4377 return false; 4378 } 4379 4380 final int flags; 4381 4382 final long identity = Binder.clearCallingIdentity(); 4383 try { 4384 flags = getPermissionFlags(permissionName, 4385 packageName, userId); 4386 } finally { 4387 Binder.restoreCallingIdentity(identity); 4388 } 4389 4390 final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 4391 | PackageManager.FLAG_PERMISSION_POLICY_FIXED 4392 | PackageManager.FLAG_PERMISSION_USER_FIXED; 4393 4394 if ((flags & fixedFlags) != 0) { 4395 return false; 4396 } 4397 4398 return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0; 4399 } 4400 4401 @Override 4402 public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 4403 mContext.enforceCallingOrSelfPermission( 4404 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS, 4405 "addOnPermissionsChangeListener"); 4406 4407 synchronized (mPackages) { 4408 mOnPermissionChangeListeners.addListenerLocked(listener); 4409 } 4410 } 4411 4412 @Override 4413 public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 4414 synchronized (mPackages) { 4415 mOnPermissionChangeListeners.removeListenerLocked(listener); 4416 } 4417 } 4418 4419 @Override 4420 public boolean isProtectedBroadcast(String actionName) { 4421 synchronized (mPackages) { 4422 if (mProtectedBroadcasts.contains(actionName)) { 4423 return true; 4424 } else if (actionName != null) { 4425 // TODO: remove these terrible hacks 4426 if (actionName.startsWith("android.net.netmon.lingerExpired") 4427 || actionName.startsWith("com.android.server.sip.SipWakeupTimer") 4428 || actionName.startsWith("com.android.internal.telephony.data-reconnect") 4429 || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) { 4430 return true; 4431 } 4432 } 4433 } 4434 return false; 4435 } 4436 4437 @Override 4438 public int checkSignatures(String pkg1, String pkg2) { 4439 synchronized (mPackages) { 4440 final PackageParser.Package p1 = mPackages.get(pkg1); 4441 final PackageParser.Package p2 = mPackages.get(pkg2); 4442 if (p1 == null || p1.mExtras == null 4443 || p2 == null || p2.mExtras == null) { 4444 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4445 } 4446 return compareSignatures(p1.mSignatures, p2.mSignatures); 4447 } 4448 } 4449 4450 @Override 4451 public int checkUidSignatures(int uid1, int uid2) { 4452 // Map to base uids. 4453 uid1 = UserHandle.getAppId(uid1); 4454 uid2 = UserHandle.getAppId(uid2); 4455 // reader 4456 synchronized (mPackages) { 4457 Signature[] s1; 4458 Signature[] s2; 4459 Object obj = mSettings.getUserIdLPr(uid1); 4460 if (obj != null) { 4461 if (obj instanceof SharedUserSetting) { 4462 s1 = ((SharedUserSetting)obj).signatures.mSignatures; 4463 } else if (obj instanceof PackageSetting) { 4464 s1 = ((PackageSetting)obj).signatures.mSignatures; 4465 } else { 4466 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4467 } 4468 } else { 4469 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4470 } 4471 obj = mSettings.getUserIdLPr(uid2); 4472 if (obj != null) { 4473 if (obj instanceof SharedUserSetting) { 4474 s2 = ((SharedUserSetting)obj).signatures.mSignatures; 4475 } else if (obj instanceof PackageSetting) { 4476 s2 = ((PackageSetting)obj).signatures.mSignatures; 4477 } else { 4478 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4479 } 4480 } else { 4481 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4482 } 4483 return compareSignatures(s1, s2); 4484 } 4485 } 4486 4487 /** 4488 * This method should typically only be used when granting or revoking 4489 * permissions, since the app may immediately restart after this call. 4490 * <p> 4491 * If you're doing surgery on app code/data, use {@link PackageFreezer} to 4492 * guard your work against the app being relaunched. 4493 */ 4494 private void killUid(int appId, int userId, String reason) { 4495 final long identity = Binder.clearCallingIdentity(); 4496 try { 4497 IActivityManager am = ActivityManagerNative.getDefault(); 4498 if (am != null) { 4499 try { 4500 am.killUid(appId, userId, reason); 4501 } catch (RemoteException e) { 4502 /* ignore - same process */ 4503 } 4504 } 4505 } finally { 4506 Binder.restoreCallingIdentity(identity); 4507 } 4508 } 4509 4510 /** 4511 * Compares two sets of signatures. Returns: 4512 * <br /> 4513 * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null, 4514 * <br /> 4515 * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null, 4516 * <br /> 4517 * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null, 4518 * <br /> 4519 * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical, 4520 * <br /> 4521 * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ. 4522 */ 4523 static int compareSignatures(Signature[] s1, Signature[] s2) { 4524 if (s1 == null) { 4525 return s2 == null 4526 ? PackageManager.SIGNATURE_NEITHER_SIGNED 4527 : PackageManager.SIGNATURE_FIRST_NOT_SIGNED; 4528 } 4529 4530 if (s2 == null) { 4531 return PackageManager.SIGNATURE_SECOND_NOT_SIGNED; 4532 } 4533 4534 if (s1.length != s2.length) { 4535 return PackageManager.SIGNATURE_NO_MATCH; 4536 } 4537 4538 // Since both signature sets are of size 1, we can compare without HashSets. 4539 if (s1.length == 1) { 4540 return s1[0].equals(s2[0]) ? 4541 PackageManager.SIGNATURE_MATCH : 4542 PackageManager.SIGNATURE_NO_MATCH; 4543 } 4544 4545 ArraySet<Signature> set1 = new ArraySet<Signature>(); 4546 for (Signature sig : s1) { 4547 set1.add(sig); 4548 } 4549 ArraySet<Signature> set2 = new ArraySet<Signature>(); 4550 for (Signature sig : s2) { 4551 set2.add(sig); 4552 } 4553 // Make sure s2 contains all signatures in s1. 4554 if (set1.equals(set2)) { 4555 return PackageManager.SIGNATURE_MATCH; 4556 } 4557 return PackageManager.SIGNATURE_NO_MATCH; 4558 } 4559 4560 /** 4561 * If the database version for this type of package (internal storage or 4562 * external storage) is less than the version where package signatures 4563 * were updated, return true. 4564 */ 4565 private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 4566 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); 4567 return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY; 4568 } 4569 4570 /** 4571 * Used for backward compatibility to make sure any packages with 4572 * certificate chains get upgraded to the new style. {@code existingSigs} 4573 * will be in the old format (since they were stored on disk from before the 4574 * system upgrade) and {@code scannedSigs} will be in the newer format. 4575 */ 4576 private int compareSignaturesCompat(PackageSignatures existingSigs, 4577 PackageParser.Package scannedPkg) { 4578 if (!isCompatSignatureUpdateNeeded(scannedPkg)) { 4579 return PackageManager.SIGNATURE_NO_MATCH; 4580 } 4581 4582 ArraySet<Signature> existingSet = new ArraySet<Signature>(); 4583 for (Signature sig : existingSigs.mSignatures) { 4584 existingSet.add(sig); 4585 } 4586 ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>(); 4587 for (Signature sig : scannedPkg.mSignatures) { 4588 try { 4589 Signature[] chainSignatures = sig.getChainSignatures(); 4590 for (Signature chainSig : chainSignatures) { 4591 scannedCompatSet.add(chainSig); 4592 } 4593 } catch (CertificateEncodingException e) { 4594 scannedCompatSet.add(sig); 4595 } 4596 } 4597 /* 4598 * Make sure the expanded scanned set contains all signatures in the 4599 * existing one. 4600 */ 4601 if (scannedCompatSet.equals(existingSet)) { 4602 // Migrate the old signatures to the new scheme. 4603 existingSigs.assignSignatures(scannedPkg.mSignatures); 4604 // The new KeySets will be re-added later in the scanning process. 4605 synchronized (mPackages) { 4606 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName); 4607 } 4608 return PackageManager.SIGNATURE_MATCH; 4609 } 4610 return PackageManager.SIGNATURE_NO_MATCH; 4611 } 4612 4613 private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 4614 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); 4615 return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER; 4616 } 4617 4618 private int compareSignaturesRecover(PackageSignatures existingSigs, 4619 PackageParser.Package scannedPkg) { 4620 if (!isRecoverSignatureUpdateNeeded(scannedPkg)) { 4621 return PackageManager.SIGNATURE_NO_MATCH; 4622 } 4623 4624 String msg = null; 4625 try { 4626 if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) { 4627 logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for " 4628 + scannedPkg.packageName); 4629 return PackageManager.SIGNATURE_MATCH; 4630 } 4631 } catch (CertificateException e) { 4632 msg = e.getMessage(); 4633 } 4634 4635 logCriticalInfo(Log.INFO, 4636 "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg); 4637 return PackageManager.SIGNATURE_NO_MATCH; 4638 } 4639 4640 @Override 4641 public List<String> getAllPackages() { 4642 synchronized (mPackages) { 4643 return new ArrayList<String>(mPackages.keySet()); 4644 } 4645 } 4646 4647 @Override 4648 public String[] getPackagesForUid(int uid) { 4649 final int userId = UserHandle.getUserId(uid); 4650 uid = UserHandle.getAppId(uid); 4651 // reader 4652 synchronized (mPackages) { 4653 Object obj = mSettings.getUserIdLPr(uid); 4654 if (obj instanceof SharedUserSetting) { 4655 final SharedUserSetting sus = (SharedUserSetting) obj; 4656 final int N = sus.packages.size(); 4657 String[] res = new String[N]; 4658 final Iterator<PackageSetting> it = sus.packages.iterator(); 4659 int i = 0; 4660 while (it.hasNext()) { 4661 PackageSetting ps = it.next(); 4662 if (ps.getInstalled(userId)) { 4663 res[i++] = ps.name; 4664 } else { 4665 res = ArrayUtils.removeElement(String.class, res, res[i]); 4666 } 4667 } 4668 return res; 4669 } else if (obj instanceof PackageSetting) { 4670 final PackageSetting ps = (PackageSetting) obj; 4671 return new String[] { ps.name }; 4672 } 4673 } 4674 return null; 4675 } 4676 4677 @Override 4678 public String getNameForUid(int uid) { 4679 // reader 4680 synchronized (mPackages) { 4681 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4682 if (obj instanceof SharedUserSetting) { 4683 final SharedUserSetting sus = (SharedUserSetting) obj; 4684 return sus.name + ":" + sus.userId; 4685 } else if (obj instanceof PackageSetting) { 4686 final PackageSetting ps = (PackageSetting) obj; 4687 return ps.name; 4688 } 4689 } 4690 return null; 4691 } 4692 4693 @Override 4694 public int getUidForSharedUser(String sharedUserName) { 4695 if(sharedUserName == null) { 4696 return -1; 4697 } 4698 // reader 4699 synchronized (mPackages) { 4700 final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false); 4701 if (suid == null) { 4702 return -1; 4703 } 4704 return suid.userId; 4705 } 4706 } 4707 4708 @Override 4709 public int getFlagsForUid(int uid) { 4710 synchronized (mPackages) { 4711 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4712 if (obj instanceof SharedUserSetting) { 4713 final SharedUserSetting sus = (SharedUserSetting) obj; 4714 return sus.pkgFlags; 4715 } else if (obj instanceof PackageSetting) { 4716 final PackageSetting ps = (PackageSetting) obj; 4717 return ps.pkgFlags; 4718 } 4719 } 4720 return 0; 4721 } 4722 4723 @Override 4724 public int getPrivateFlagsForUid(int uid) { 4725 synchronized (mPackages) { 4726 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4727 if (obj instanceof SharedUserSetting) { 4728 final SharedUserSetting sus = (SharedUserSetting) obj; 4729 return sus.pkgPrivateFlags; 4730 } else if (obj instanceof PackageSetting) { 4731 final PackageSetting ps = (PackageSetting) obj; 4732 return ps.pkgPrivateFlags; 4733 } 4734 } 4735 return 0; 4736 } 4737 4738 @Override 4739 public boolean isUidPrivileged(int uid) { 4740 uid = UserHandle.getAppId(uid); 4741 // reader 4742 synchronized (mPackages) { 4743 Object obj = mSettings.getUserIdLPr(uid); 4744 if (obj instanceof SharedUserSetting) { 4745 final SharedUserSetting sus = (SharedUserSetting) obj; 4746 final Iterator<PackageSetting> it = sus.packages.iterator(); 4747 while (it.hasNext()) { 4748 if (it.next().isPrivileged()) { 4749 return true; 4750 } 4751 } 4752 } else if (obj instanceof PackageSetting) { 4753 final PackageSetting ps = (PackageSetting) obj; 4754 return ps.isPrivileged(); 4755 } 4756 } 4757 return false; 4758 } 4759 4760 @Override 4761 public String[] getAppOpPermissionPackages(String permissionName) { 4762 synchronized (mPackages) { 4763 ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName); 4764 if (pkgs == null) { 4765 return null; 4766 } 4767 return pkgs.toArray(new String[pkgs.size()]); 4768 } 4769 } 4770 4771 @Override 4772 public ResolveInfo resolveIntent(Intent intent, String resolvedType, 4773 int flags, int userId) { 4774 try { 4775 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent"); 4776 4777 if (!sUserManager.exists(userId)) return null; 4778 flags = updateFlagsForResolve(flags, userId, intent); 4779 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4780 false /*requireFullPermission*/, false /*checkShell*/, "resolve intent"); 4781 4782 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities"); 4783 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, 4784 flags, userId); 4785 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 4786 4787 final ResolveInfo bestChoice = 4788 chooseBestActivity(intent, resolvedType, flags, query, userId); 4789 return bestChoice; 4790 } finally { 4791 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 4792 } 4793 } 4794 4795 @Override 4796 public void setLastChosenActivity(Intent intent, String resolvedType, int flags, 4797 IntentFilter filter, int match, ComponentName activity) { 4798 final int userId = UserHandle.getCallingUserId(); 4799 if (DEBUG_PREFERRED) { 4800 Log.v(TAG, "setLastChosenActivity intent=" + intent 4801 + " resolvedType=" + resolvedType 4802 + " flags=" + flags 4803 + " filter=" + filter 4804 + " match=" + match 4805 + " activity=" + activity); 4806 filter.dump(new PrintStreamPrinter(System.out), " "); 4807 } 4808 intent.setComponent(null); 4809 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags, 4810 userId); 4811 // Find any earlier preferred or last chosen entries and nuke them 4812 findPreferredActivity(intent, resolvedType, 4813 flags, query, 0, false, true, false, userId); 4814 // Add the new activity as the last chosen for this filter 4815 addPreferredActivityInternal(filter, match, null, activity, false, userId, 4816 "Setting last chosen"); 4817 } 4818 4819 @Override 4820 public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) { 4821 final int userId = UserHandle.getCallingUserId(); 4822 if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent); 4823 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags, 4824 userId); 4825 return findPreferredActivity(intent, resolvedType, flags, query, 0, 4826 false, false, false, userId); 4827 } 4828 4829 private boolean isEphemeralDisabled() { 4830 // ephemeral apps have been disabled across the board 4831 if (DISABLE_EPHEMERAL_APPS) { 4832 return true; 4833 } 4834 // system isn't up yet; can't read settings, so, assume no ephemeral apps 4835 if (!mSystemReady) { 4836 return true; 4837 } 4838 // we can't get a content resolver until the system is ready; these checks must happen last 4839 final ContentResolver resolver = mContext.getContentResolver(); 4840 if (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) { 4841 return true; 4842 } 4843 return Secure.getInt(resolver, Secure.WEB_ACTION_ENABLED, 1) == 0; 4844 } 4845 4846 private boolean isEphemeralAllowed( 4847 Intent intent, List<ResolveInfo> resolvedActivities, int userId, 4848 boolean skipPackageCheck) { 4849 // Short circuit and return early if possible. 4850 if (isEphemeralDisabled()) { 4851 return false; 4852 } 4853 final int callingUser = UserHandle.getCallingUserId(); 4854 if (callingUser != UserHandle.USER_SYSTEM) { 4855 return false; 4856 } 4857 if (mEphemeralResolverConnection == null) { 4858 return false; 4859 } 4860 if (intent.getComponent() != null) { 4861 return false; 4862 } 4863 if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) { 4864 return false; 4865 } 4866 if (!skipPackageCheck && intent.getPackage() != null) { 4867 return false; 4868 } 4869 final boolean isWebUri = hasWebURI(intent); 4870 if (!isWebUri || intent.getData().getHost() == null) { 4871 return false; 4872 } 4873 // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution. 4874 synchronized (mPackages) { 4875 final int count = (resolvedActivities == null ? 0 : resolvedActivities.size()); 4876 for (int n = 0; n < count; n++) { 4877 ResolveInfo info = resolvedActivities.get(n); 4878 String packageName = info.activityInfo.packageName; 4879 PackageSetting ps = mSettings.mPackages.get(packageName); 4880 if (ps != null) { 4881 // Try to get the status from User settings first 4882 long packedStatus = getDomainVerificationStatusLPr(ps, userId); 4883 int status = (int) (packedStatus >> 32); 4884 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS 4885 || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) { 4886 if (DEBUG_EPHEMERAL) { 4887 Slog.v(TAG, "DENY ephemeral apps;" 4888 + " pkg: " + packageName + ", status: " + status); 4889 } 4890 return false; 4891 } 4892 } 4893 } 4894 } 4895 // We've exhausted all ways to deny ephemeral application; let the system look for them. 4896 return true; 4897 } 4898 4899 private static EphemeralResolveInfo getEphemeralResolveInfo( 4900 Context context, EphemeralResolverConnection resolverConnection, Intent intent, 4901 String resolvedType, int userId, String packageName) { 4902 final int ephemeralPrefixMask = Global.getInt(context.getContentResolver(), 4903 Global.EPHEMERAL_HASH_PREFIX_MASK, DEFAULT_EPHEMERAL_HASH_PREFIX_MASK); 4904 final int ephemeralPrefixCount = Global.getInt(context.getContentResolver(), 4905 Global.EPHEMERAL_HASH_PREFIX_COUNT, DEFAULT_EPHEMERAL_HASH_PREFIX_COUNT); 4906 final EphemeralDigest digest = new EphemeralDigest(intent.getData(), ephemeralPrefixMask, 4907 ephemeralPrefixCount); 4908 final int[] shaPrefix = digest.getDigestPrefix(); 4909 final byte[][] digestBytes = digest.getDigestBytes(); 4910 final List<EphemeralResolveInfo> ephemeralResolveInfoList = 4911 resolverConnection.getEphemeralResolveInfoList(shaPrefix, ephemeralPrefixMask); 4912 if (ephemeralResolveInfoList == null || ephemeralResolveInfoList.size() == 0) { 4913 // No hash prefix match; there are no ephemeral apps for this domain. 4914 return null; 4915 } 4916 4917 // Go in reverse order so we match the narrowest scope first. 4918 for (int i = shaPrefix.length - 1; i >= 0 ; --i) { 4919 for (EphemeralResolveInfo ephemeralApplication : ephemeralResolveInfoList) { 4920 if (!Arrays.equals(digestBytes[i], ephemeralApplication.getDigestBytes())) { 4921 continue; 4922 } 4923 final List<IntentFilter> filters = ephemeralApplication.getFilters(); 4924 // No filters; this should never happen. 4925 if (filters.isEmpty()) { 4926 continue; 4927 } 4928 if (packageName != null 4929 && !packageName.equals(ephemeralApplication.getPackageName())) { 4930 continue; 4931 } 4932 // We have a domain match; resolve the filters to see if anything matches. 4933 final EphemeralIntentResolver ephemeralResolver = new EphemeralIntentResolver(); 4934 for (int j = filters.size() - 1; j >= 0; --j) { 4935 final EphemeralResolveIntentInfo intentInfo = 4936 new EphemeralResolveIntentInfo(filters.get(j), ephemeralApplication); 4937 ephemeralResolver.addFilter(intentInfo); 4938 } 4939 List<EphemeralResolveInfo> matchedResolveInfoList = ephemeralResolver.queryIntent( 4940 intent, resolvedType, false /*defaultOnly*/, userId); 4941 if (!matchedResolveInfoList.isEmpty()) { 4942 return matchedResolveInfoList.get(0); 4943 } 4944 } 4945 } 4946 // Hash or filter mis-match; no ephemeral apps for this domain. 4947 return null; 4948 } 4949 4950 private ResolveInfo chooseBestActivity(Intent intent, String resolvedType, 4951 int flags, List<ResolveInfo> query, int userId) { 4952 if (query != null) { 4953 final int N = query.size(); 4954 if (N == 1) { 4955 return query.get(0); 4956 } else if (N > 1) { 4957 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 4958 // If there is more than one activity with the same priority, 4959 // then let the user decide between them. 4960 ResolveInfo r0 = query.get(0); 4961 ResolveInfo r1 = query.get(1); 4962 if (DEBUG_INTENT_MATCHING || debug) { 4963 Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs " 4964 + r1.activityInfo.name + "=" + r1.priority); 4965 } 4966 // If the first activity has a higher priority, or a different 4967 // default, then it is always desirable to pick it. 4968 if (r0.priority != r1.priority 4969 || r0.preferredOrder != r1.preferredOrder 4970 || r0.isDefault != r1.isDefault) { 4971 return query.get(0); 4972 } 4973 // If we have saved a preference for a preferred activity for 4974 // this Intent, use that. 4975 ResolveInfo ri = findPreferredActivity(intent, resolvedType, 4976 flags, query, r0.priority, true, false, debug, userId); 4977 if (ri != null) { 4978 return ri; 4979 } 4980 ri = new ResolveInfo(mResolveInfo); 4981 ri.activityInfo = new ActivityInfo(ri.activityInfo); 4982 ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction()); 4983 // If all of the options come from the same package, show the application's 4984 // label and icon instead of the generic resolver's. 4985 // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here 4986 // and then throw away the ResolveInfo itself, meaning that the caller loses 4987 // the resolvePackageName. Therefore the activityInfo.labelRes above provides 4988 // a fallback for this case; we only set the target package's resources on 4989 // the ResolveInfo, not the ActivityInfo. 4990 final String intentPackage = intent.getPackage(); 4991 if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) { 4992 final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo; 4993 ri.resolvePackageName = intentPackage; 4994 if (userNeedsBadging(userId)) { 4995 ri.noResourceId = true; 4996 } else { 4997 ri.icon = appi.icon; 4998 } 4999 ri.iconResourceId = appi.icon; 5000 ri.labelRes = appi.labelRes; 5001 } 5002 ri.activityInfo.applicationInfo = new ApplicationInfo( 5003 ri.activityInfo.applicationInfo); 5004 if (userId != 0) { 5005 ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId, 5006 UserHandle.getAppId(ri.activityInfo.applicationInfo.uid)); 5007 } 5008 // Make sure that the resolver is displayable in car mode 5009 if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle(); 5010 ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true); 5011 return ri; 5012 } 5013 } 5014 return null; 5015 } 5016 5017 /** 5018 * Return true if the given list is not empty and all of its contents have 5019 * an activityInfo with the given package name. 5020 */ 5021 private boolean allHavePackage(List<ResolveInfo> list, String packageName) { 5022 if (ArrayUtils.isEmpty(list)) { 5023 return false; 5024 } 5025 for (int i = 0, N = list.size(); i < N; i++) { 5026 final ResolveInfo ri = list.get(i); 5027 final ActivityInfo ai = ri != null ? ri.activityInfo : null; 5028 if (ai == null || !packageName.equals(ai.packageName)) { 5029 return false; 5030 } 5031 } 5032 return true; 5033 } 5034 5035 private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType, 5036 int flags, List<ResolveInfo> query, boolean debug, int userId) { 5037 final int N = query.size(); 5038 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 5039 .get(userId); 5040 // Get the list of persistent preferred activities that handle the intent 5041 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities..."); 5042 List<PersistentPreferredActivity> pprefs = ppir != null 5043 ? ppir.queryIntent(intent, resolvedType, 5044 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 5045 : null; 5046 if (pprefs != null && pprefs.size() > 0) { 5047 final int M = pprefs.size(); 5048 for (int i=0; i<M; i++) { 5049 final PersistentPreferredActivity ppa = pprefs.get(i); 5050 if (DEBUG_PREFERRED || debug) { 5051 Slog.v(TAG, "Checking PersistentPreferredActivity ds=" 5052 + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>") 5053 + "\n component=" + ppa.mComponent); 5054 ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 5055 } 5056 final ActivityInfo ai = getActivityInfo(ppa.mComponent, 5057 flags | MATCH_DISABLED_COMPONENTS, userId); 5058 if (DEBUG_PREFERRED || debug) { 5059 Slog.v(TAG, "Found persistent preferred activity:"); 5060 if (ai != null) { 5061 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 5062 } else { 5063 Slog.v(TAG, " null"); 5064 } 5065 } 5066 if (ai == null) { 5067 // This previously registered persistent preferred activity 5068 // component is no longer known. Ignore it and do NOT remove it. 5069 continue; 5070 } 5071 for (int j=0; j<N; j++) { 5072 final ResolveInfo ri = query.get(j); 5073 if (!ri.activityInfo.applicationInfo.packageName 5074 .equals(ai.applicationInfo.packageName)) { 5075 continue; 5076 } 5077 if (!ri.activityInfo.name.equals(ai.name)) { 5078 continue; 5079 } 5080 // Found a persistent preference that can handle the intent. 5081 if (DEBUG_PREFERRED || debug) { 5082 Slog.v(TAG, "Returning persistent preferred activity: " + 5083 ri.activityInfo.packageName + "/" + ri.activityInfo.name); 5084 } 5085 return ri; 5086 } 5087 } 5088 } 5089 return null; 5090 } 5091 5092 // TODO: handle preferred activities missing while user has amnesia 5093 ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags, 5094 List<ResolveInfo> query, int priority, boolean always, 5095 boolean removeMatches, boolean debug, int userId) { 5096 if (!sUserManager.exists(userId)) return null; 5097 flags = updateFlagsForResolve(flags, userId, intent); 5098 // writer 5099 synchronized (mPackages) { 5100 if (intent.getSelector() != null) { 5101 intent = intent.getSelector(); 5102 } 5103 if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION); 5104 5105 // Try to find a matching persistent preferred activity. 5106 ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query, 5107 debug, userId); 5108 5109 // If a persistent preferred activity matched, use it. 5110 if (pri != null) { 5111 return pri; 5112 } 5113 5114 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 5115 // Get the list of preferred activities that handle the intent 5116 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities..."); 5117 List<PreferredActivity> prefs = pir != null 5118 ? pir.queryIntent(intent, resolvedType, 5119 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 5120 : null; 5121 if (prefs != null && prefs.size() > 0) { 5122 boolean changed = false; 5123 try { 5124 // First figure out how good the original match set is. 5125 // We will only allow preferred activities that came 5126 // from the same match quality. 5127 int match = 0; 5128 5129 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match..."); 5130 5131 final int N = query.size(); 5132 for (int j=0; j<N; j++) { 5133 final ResolveInfo ri = query.get(j); 5134 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo 5135 + ": 0x" + Integer.toHexString(match)); 5136 if (ri.match > match) { 5137 match = ri.match; 5138 } 5139 } 5140 5141 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x" 5142 + Integer.toHexString(match)); 5143 5144 match &= IntentFilter.MATCH_CATEGORY_MASK; 5145 final int M = prefs.size(); 5146 for (int i=0; i<M; i++) { 5147 final PreferredActivity pa = prefs.get(i); 5148 if (DEBUG_PREFERRED || debug) { 5149 Slog.v(TAG, "Checking PreferredActivity ds=" 5150 + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>") 5151 + "\n component=" + pa.mPref.mComponent); 5152 pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 5153 } 5154 if (pa.mPref.mMatch != match) { 5155 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match " 5156 + Integer.toHexString(pa.mPref.mMatch)); 5157 continue; 5158 } 5159 // If it's not an "always" type preferred activity and that's what we're 5160 // looking for, skip it. 5161 if (always && !pa.mPref.mAlways) { 5162 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry"); 5163 continue; 5164 } 5165 final ActivityInfo ai = getActivityInfo( 5166 pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS 5167 | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 5168 userId); 5169 if (DEBUG_PREFERRED || debug) { 5170 Slog.v(TAG, "Found preferred activity:"); 5171 if (ai != null) { 5172 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 5173 } else { 5174 Slog.v(TAG, " null"); 5175 } 5176 } 5177 if (ai == null) { 5178 // This previously registered preferred activity 5179 // component is no longer known. Most likely an update 5180 // to the app was installed and in the new version this 5181 // component no longer exists. Clean it up by removing 5182 // it from the preferred activities list, and skip it. 5183 Slog.w(TAG, "Removing dangling preferred activity: " 5184 + pa.mPref.mComponent); 5185 pir.removeFilter(pa); 5186 changed = true; 5187 continue; 5188 } 5189 for (int j=0; j<N; j++) { 5190 final ResolveInfo ri = query.get(j); 5191 if (!ri.activityInfo.applicationInfo.packageName 5192 .equals(ai.applicationInfo.packageName)) { 5193 continue; 5194 } 5195 if (!ri.activityInfo.name.equals(ai.name)) { 5196 continue; 5197 } 5198 5199 if (removeMatches) { 5200 pir.removeFilter(pa); 5201 changed = true; 5202 if (DEBUG_PREFERRED) { 5203 Slog.v(TAG, "Removing match " + pa.mPref.mComponent); 5204 } 5205 break; 5206 } 5207 5208 // Okay we found a previously set preferred or last chosen app. 5209 // If the result set is different from when this 5210 // was created, we need to clear it and re-ask the 5211 // user their preference, if we're looking for an "always" type entry. 5212 if (always && !pa.mPref.sameSet(query)) { 5213 Slog.i(TAG, "Result set changed, dropping preferred activity for " 5214 + intent + " type " + resolvedType); 5215 if (DEBUG_PREFERRED) { 5216 Slog.v(TAG, "Removing preferred activity since set changed " 5217 + pa.mPref.mComponent); 5218 } 5219 pir.removeFilter(pa); 5220 // Re-add the filter as a "last chosen" entry (!always) 5221 PreferredActivity lastChosen = new PreferredActivity( 5222 pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false); 5223 pir.addFilter(lastChosen); 5224 changed = true; 5225 return null; 5226 } 5227 5228 // Yay! Either the set matched or we're looking for the last chosen 5229 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: " 5230 + ri.activityInfo.packageName + "/" + ri.activityInfo.name); 5231 return ri; 5232 } 5233 } 5234 } finally { 5235 if (changed) { 5236 if (DEBUG_PREFERRED) { 5237 Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions"); 5238 } 5239 scheduleWritePackageRestrictionsLocked(userId); 5240 } 5241 } 5242 } 5243 } 5244 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return"); 5245 return null; 5246 } 5247 5248 /* 5249 * Returns if intent can be forwarded from the sourceUserId to the targetUserId 5250 */ 5251 @Override 5252 public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId, 5253 int targetUserId) { 5254 mContext.enforceCallingOrSelfPermission( 5255 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 5256 List<CrossProfileIntentFilter> matches = 5257 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId); 5258 if (matches != null) { 5259 int size = matches.size(); 5260 for (int i = 0; i < size; i++) { 5261 if (matches.get(i).getTargetUserId() == targetUserId) return true; 5262 } 5263 } 5264 if (hasWebURI(intent)) { 5265 // cross-profile app linking works only towards the parent. 5266 final UserInfo parent = getProfileParent(sourceUserId); 5267 synchronized(mPackages) { 5268 int flags = updateFlagsForResolve(0, parent.id, intent); 5269 CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr( 5270 intent, resolvedType, flags, sourceUserId, parent.id); 5271 return xpDomainInfo != null; 5272 } 5273 } 5274 return false; 5275 } 5276 5277 private UserInfo getProfileParent(int userId) { 5278 final long identity = Binder.clearCallingIdentity(); 5279 try { 5280 return sUserManager.getProfileParent(userId); 5281 } finally { 5282 Binder.restoreCallingIdentity(identity); 5283 } 5284 } 5285 5286 private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent, 5287 String resolvedType, int userId) { 5288 CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId); 5289 if (resolver != null) { 5290 return resolver.queryIntent(intent, resolvedType, false, userId); 5291 } 5292 return null; 5293 } 5294 5295 @Override 5296 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent, 5297 String resolvedType, int flags, int userId) { 5298 try { 5299 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities"); 5300 5301 return new ParceledListSlice<>( 5302 queryIntentActivitiesInternal(intent, resolvedType, flags, userId)); 5303 } finally { 5304 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 5305 } 5306 } 5307 5308 private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, 5309 String resolvedType, int flags, int userId) { 5310 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5311 flags = updateFlagsForResolve(flags, userId, intent); 5312 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5313 false /* requireFullPermission */, false /* checkShell */, 5314 "query intent activities"); 5315 ComponentName comp = intent.getComponent(); 5316 if (comp == null) { 5317 if (intent.getSelector() != null) { 5318 intent = intent.getSelector(); 5319 comp = intent.getComponent(); 5320 } 5321 } 5322 5323 if (comp != null) { 5324 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5325 final ActivityInfo ai = getActivityInfo(comp, flags, userId); 5326 if (ai != null) { 5327 final ResolveInfo ri = new ResolveInfo(); 5328 ri.activityInfo = ai; 5329 list.add(ri); 5330 } 5331 return list; 5332 } 5333 5334 // reader 5335 boolean sortResult = false; 5336 boolean addEphemeral = false; 5337 boolean matchEphemeralPackage = false; 5338 List<ResolveInfo> result; 5339 final String pkgName = intent.getPackage(); 5340 synchronized (mPackages) { 5341 if (pkgName == null) { 5342 List<CrossProfileIntentFilter> matchingFilters = 5343 getMatchingCrossProfileIntentFilters(intent, resolvedType, userId); 5344 // Check for results that need to skip the current profile. 5345 ResolveInfo xpResolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent, 5346 resolvedType, flags, userId); 5347 if (xpResolveInfo != null) { 5348 List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1); 5349 xpResult.add(xpResolveInfo); 5350 return filterIfNotSystemUser(xpResult, userId); 5351 } 5352 5353 // Check for results in the current profile. 5354 result = filterIfNotSystemUser(mActivities.queryIntent( 5355 intent, resolvedType, flags, userId), userId); 5356 addEphemeral = 5357 isEphemeralAllowed(intent, result, userId, false /*skipPackageCheck*/); 5358 5359 // Check for cross profile results. 5360 boolean hasNonNegativePriorityResult = hasNonNegativePriority(result); 5361 xpResolveInfo = queryCrossProfileIntents( 5362 matchingFilters, intent, resolvedType, flags, userId, 5363 hasNonNegativePriorityResult); 5364 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) { 5365 boolean isVisibleToUser = filterIfNotSystemUser( 5366 Collections.singletonList(xpResolveInfo), userId).size() > 0; 5367 if (isVisibleToUser) { 5368 result.add(xpResolveInfo); 5369 sortResult = true; 5370 } 5371 } 5372 if (hasWebURI(intent)) { 5373 CrossProfileDomainInfo xpDomainInfo = null; 5374 final UserInfo parent = getProfileParent(userId); 5375 if (parent != null) { 5376 xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType, 5377 flags, userId, parent.id); 5378 } 5379 if (xpDomainInfo != null) { 5380 if (xpResolveInfo != null) { 5381 // If we didn't remove it, the cross-profile ResolveInfo would be twice 5382 // in the result. 5383 result.remove(xpResolveInfo); 5384 } 5385 if (result.size() == 0 && !addEphemeral) { 5386 result.add(xpDomainInfo.resolveInfo); 5387 return result; 5388 } 5389 } 5390 if (result.size() > 1 || addEphemeral) { 5391 result = filterCandidatesWithDomainPreferredActivitiesLPr( 5392 intent, flags, result, xpDomainInfo, userId); 5393 sortResult = true; 5394 } 5395 } 5396 } else { 5397 final PackageParser.Package pkg = mPackages.get(pkgName); 5398 if (pkg != null) { 5399 result = filterIfNotSystemUser( 5400 mActivities.queryIntentForPackage( 5401 intent, resolvedType, flags, pkg.activities, userId), 5402 userId); 5403 } else { 5404 // the caller wants to resolve for a particular package; however, there 5405 // were no installed results, so, try to find an ephemeral result 5406 addEphemeral = isEphemeralAllowed( 5407 intent, null /*result*/, userId, true /*skipPackageCheck*/); 5408 matchEphemeralPackage = true; 5409 result = new ArrayList<ResolveInfo>(); 5410 } 5411 } 5412 } 5413 if (addEphemeral) { 5414 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral"); 5415 final EphemeralResolveInfo ai = getEphemeralResolveInfo( 5416 mContext, mEphemeralResolverConnection, intent, resolvedType, userId, 5417 matchEphemeralPackage ? pkgName : null); 5418 if (ai != null) { 5419 if (DEBUG_EPHEMERAL) { 5420 Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list"); 5421 } 5422 final ResolveInfo ephemeralInstaller = new ResolveInfo(mEphemeralInstallerInfo); 5423 ephemeralInstaller.ephemeralResolveInfo = ai; 5424 // make sure this resolver is the default 5425 ephemeralInstaller.isDefault = true; 5426 ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART 5427 | IntentFilter.MATCH_ADJUSTMENT_NORMAL; 5428 // add a non-generic filter 5429 ephemeralInstaller.filter = new IntentFilter(intent.getAction()); 5430 ephemeralInstaller.filter.addDataPath( 5431 intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL); 5432 result.add(ephemeralInstaller); 5433 } 5434 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 5435 } 5436 if (sortResult) { 5437 Collections.sort(result, mResolvePrioritySorter); 5438 } 5439 return result; 5440 } 5441 5442 private static class CrossProfileDomainInfo { 5443 /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */ 5444 ResolveInfo resolveInfo; 5445 /* Best domain verification status of the activities found in the other profile */ 5446 int bestDomainVerificationStatus; 5447 } 5448 5449 private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent, 5450 String resolvedType, int flags, int sourceUserId, int parentUserId) { 5451 if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING, 5452 sourceUserId)) { 5453 return null; 5454 } 5455 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 5456 resolvedType, flags, parentUserId); 5457 5458 if (resultTargetUser == null || resultTargetUser.isEmpty()) { 5459 return null; 5460 } 5461 CrossProfileDomainInfo result = null; 5462 int size = resultTargetUser.size(); 5463 for (int i = 0; i < size; i++) { 5464 ResolveInfo riTargetUser = resultTargetUser.get(i); 5465 // Intent filter verification is only for filters that specify a host. So don't return 5466 // those that handle all web uris. 5467 if (riTargetUser.handleAllWebDataURI) { 5468 continue; 5469 } 5470 String packageName = riTargetUser.activityInfo.packageName; 5471 PackageSetting ps = mSettings.mPackages.get(packageName); 5472 if (ps == null) { 5473 continue; 5474 } 5475 long verificationState = getDomainVerificationStatusLPr(ps, parentUserId); 5476 int status = (int)(verificationState >> 32); 5477 if (result == null) { 5478 result = new CrossProfileDomainInfo(); 5479 result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(), 5480 sourceUserId, parentUserId); 5481 result.bestDomainVerificationStatus = status; 5482 } else { 5483 result.bestDomainVerificationStatus = bestDomainVerificationStatus(status, 5484 result.bestDomainVerificationStatus); 5485 } 5486 } 5487 // Don't consider matches with status NEVER across profiles. 5488 if (result != null && result.bestDomainVerificationStatus 5489 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5490 return null; 5491 } 5492 return result; 5493 } 5494 5495 /** 5496 * Verification statuses are ordered from the worse to the best, except for 5497 * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse. 5498 */ 5499 private int bestDomainVerificationStatus(int status1, int status2) { 5500 if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5501 return status2; 5502 } 5503 if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5504 return status1; 5505 } 5506 return (int) MathUtils.max(status1, status2); 5507 } 5508 5509 private boolean isUserEnabled(int userId) { 5510 long callingId = Binder.clearCallingIdentity(); 5511 try { 5512 UserInfo userInfo = sUserManager.getUserInfo(userId); 5513 return userInfo != null && userInfo.isEnabled(); 5514 } finally { 5515 Binder.restoreCallingIdentity(callingId); 5516 } 5517 } 5518 5519 /** 5520 * Filter out activities with systemUserOnly flag set, when current user is not System. 5521 * 5522 * @return filtered list 5523 */ 5524 private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) { 5525 if (userId == UserHandle.USER_SYSTEM) { 5526 return resolveInfos; 5527 } 5528 for (int i = resolveInfos.size() - 1; i >= 0; i--) { 5529 ResolveInfo info = resolveInfos.get(i); 5530 if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) { 5531 resolveInfos.remove(i); 5532 } 5533 } 5534 return resolveInfos; 5535 } 5536 5537 /** 5538 * @param resolveInfos list of resolve infos in descending priority order 5539 * @return if the list contains a resolve info with non-negative priority 5540 */ 5541 private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) { 5542 return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0; 5543 } 5544 5545 private static boolean hasWebURI(Intent intent) { 5546 if (intent.getData() == null) { 5547 return false; 5548 } 5549 final String scheme = intent.getScheme(); 5550 if (TextUtils.isEmpty(scheme)) { 5551 return false; 5552 } 5553 return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS); 5554 } 5555 5556 private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent, 5557 int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo, 5558 int userId) { 5559 final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0; 5560 5561 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) { 5562 Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " + 5563 candidates.size()); 5564 } 5565 5566 ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>(); 5567 ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>(); 5568 ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>(); 5569 ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>(); 5570 ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>(); 5571 ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>(); 5572 5573 synchronized (mPackages) { 5574 final int count = candidates.size(); 5575 // First, try to use linked apps. Partition the candidates into four lists: 5576 // one for the final results, one for the "do not use ever", one for "undefined status" 5577 // and finally one for "browser app type". 5578 for (int n=0; n<count; n++) { 5579 ResolveInfo info = candidates.get(n); 5580 String packageName = info.activityInfo.packageName; 5581 PackageSetting ps = mSettings.mPackages.get(packageName); 5582 if (ps != null) { 5583 // Add to the special match all list (Browser use case) 5584 if (info.handleAllWebDataURI) { 5585 matchAllList.add(info); 5586 continue; 5587 } 5588 // Try to get the status from User settings first 5589 long packedStatus = getDomainVerificationStatusLPr(ps, userId); 5590 int status = (int)(packedStatus >> 32); 5591 int linkGeneration = (int)(packedStatus & 0xFFFFFFFF); 5592 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) { 5593 if (DEBUG_DOMAIN_VERIFICATION) { 5594 Slog.i(TAG, " + always: " + info.activityInfo.packageName 5595 + " : linkgen=" + linkGeneration); 5596 } 5597 // Use link-enabled generation as preferredOrder, i.e. 5598 // prefer newly-enabled over earlier-enabled. 5599 info.preferredOrder = linkGeneration; 5600 alwaysList.add(info); 5601 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5602 if (DEBUG_DOMAIN_VERIFICATION) { 5603 Slog.i(TAG, " + never: " + info.activityInfo.packageName); 5604 } 5605 neverList.add(info); 5606 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) { 5607 if (DEBUG_DOMAIN_VERIFICATION) { 5608 Slog.i(TAG, " + always-ask: " + info.activityInfo.packageName); 5609 } 5610 alwaysAskList.add(info); 5611 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED || 5612 status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) { 5613 if (DEBUG_DOMAIN_VERIFICATION) { 5614 Slog.i(TAG, " + ask: " + info.activityInfo.packageName); 5615 } 5616 undefinedList.add(info); 5617 } 5618 } 5619 } 5620 5621 // We'll want to include browser possibilities in a few cases 5622 boolean includeBrowser = false; 5623 5624 // First try to add the "always" resolution(s) for the current user, if any 5625 if (alwaysList.size() > 0) { 5626 result.addAll(alwaysList); 5627 } else { 5628 // Add all undefined apps as we want them to appear in the disambiguation dialog. 5629 result.addAll(undefinedList); 5630 // Maybe add one for the other profile. 5631 if (xpDomainInfo != null && ( 5632 xpDomainInfo.bestDomainVerificationStatus 5633 != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) { 5634 result.add(xpDomainInfo.resolveInfo); 5635 } 5636 includeBrowser = true; 5637 } 5638 5639 // The presence of any 'always ask' alternatives means we'll also offer browsers. 5640 // If there were 'always' entries their preferred order has been set, so we also 5641 // back that off to make the alternatives equivalent 5642 if (alwaysAskList.size() > 0) { 5643 for (ResolveInfo i : result) { 5644 i.preferredOrder = 0; 5645 } 5646 result.addAll(alwaysAskList); 5647 includeBrowser = true; 5648 } 5649 5650 if (includeBrowser) { 5651 // Also add browsers (all of them or only the default one) 5652 if (DEBUG_DOMAIN_VERIFICATION) { 5653 Slog.v(TAG, " ...including browsers in candidate set"); 5654 } 5655 if ((matchFlags & MATCH_ALL) != 0) { 5656 result.addAll(matchAllList); 5657 } else { 5658 // Browser/generic handling case. If there's a default browser, go straight 5659 // to that (but only if there is no other higher-priority match). 5660 final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId); 5661 int maxMatchPrio = 0; 5662 ResolveInfo defaultBrowserMatch = null; 5663 final int numCandidates = matchAllList.size(); 5664 for (int n = 0; n < numCandidates; n++) { 5665 ResolveInfo info = matchAllList.get(n); 5666 // track the highest overall match priority... 5667 if (info.priority > maxMatchPrio) { 5668 maxMatchPrio = info.priority; 5669 } 5670 // ...and the highest-priority default browser match 5671 if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) { 5672 if (defaultBrowserMatch == null 5673 || (defaultBrowserMatch.priority < info.priority)) { 5674 if (debug) { 5675 Slog.v(TAG, "Considering default browser match " + info); 5676 } 5677 defaultBrowserMatch = info; 5678 } 5679 } 5680 } 5681 if (defaultBrowserMatch != null 5682 && defaultBrowserMatch.priority >= maxMatchPrio 5683 && !TextUtils.isEmpty(defaultBrowserPackageName)) 5684 { 5685 if (debug) { 5686 Slog.v(TAG, "Default browser match " + defaultBrowserMatch); 5687 } 5688 result.add(defaultBrowserMatch); 5689 } else { 5690 result.addAll(matchAllList); 5691 } 5692 } 5693 5694 // If there is nothing selected, add all candidates and remove the ones that the user 5695 // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state 5696 if (result.size() == 0) { 5697 result.addAll(candidates); 5698 result.removeAll(neverList); 5699 } 5700 } 5701 } 5702 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) { 5703 Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " + 5704 result.size()); 5705 for (ResolveInfo info : result) { 5706 Slog.v(TAG, " + " + info.activityInfo); 5707 } 5708 } 5709 return result; 5710 } 5711 5712 // Returns a packed value as a long: 5713 // 5714 // high 'int'-sized word: link status: undefined/ask/never/always. 5715 // low 'int'-sized word: relative priority among 'always' results. 5716 private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) { 5717 long result = ps.getDomainVerificationStatusForUser(userId); 5718 // if none available, get the master status 5719 if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 5720 if (ps.getIntentFilterVerificationInfo() != null) { 5721 result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32; 5722 } 5723 } 5724 return result; 5725 } 5726 5727 private ResolveInfo querySkipCurrentProfileIntents( 5728 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 5729 int flags, int sourceUserId) { 5730 if (matchingFilters != null) { 5731 int size = matchingFilters.size(); 5732 for (int i = 0; i < size; i ++) { 5733 CrossProfileIntentFilter filter = matchingFilters.get(i); 5734 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) { 5735 // Checking if there are activities in the target user that can handle the 5736 // intent. 5737 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent, 5738 resolvedType, flags, sourceUserId); 5739 if (resolveInfo != null) { 5740 return resolveInfo; 5741 } 5742 } 5743 } 5744 } 5745 return null; 5746 } 5747 5748 // Return matching ResolveInfo in target user if any. 5749 private ResolveInfo queryCrossProfileIntents( 5750 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 5751 int flags, int sourceUserId, boolean matchInCurrentProfile) { 5752 if (matchingFilters != null) { 5753 // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and 5754 // match the same intent. For performance reasons, it is better not to 5755 // run queryIntent twice for the same userId 5756 SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray(); 5757 int size = matchingFilters.size(); 5758 for (int i = 0; i < size; i++) { 5759 CrossProfileIntentFilter filter = matchingFilters.get(i); 5760 int targetUserId = filter.getTargetUserId(); 5761 boolean skipCurrentProfile = 5762 (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0; 5763 boolean skipCurrentProfileIfNoMatchFound = 5764 (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0; 5765 if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId) 5766 && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) { 5767 // Checking if there are activities in the target user that can handle the 5768 // intent. 5769 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent, 5770 resolvedType, flags, sourceUserId); 5771 if (resolveInfo != null) return resolveInfo; 5772 alreadyTriedUserIds.put(targetUserId, true); 5773 } 5774 } 5775 } 5776 return null; 5777 } 5778 5779 /** 5780 * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that 5781 * will forward the intent to the filter's target user. 5782 * Otherwise, returns null. 5783 */ 5784 private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent, 5785 String resolvedType, int flags, int sourceUserId) { 5786 int targetUserId = filter.getTargetUserId(); 5787 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 5788 resolvedType, flags, targetUserId); 5789 if (resultTargetUser != null && isUserEnabled(targetUserId)) { 5790 // If all the matches in the target profile are suspended, return null. 5791 for (int i = resultTargetUser.size() - 1; i >= 0; i--) { 5792 if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags 5793 & ApplicationInfo.FLAG_SUSPENDED) == 0) { 5794 return createForwardingResolveInfoUnchecked(filter, sourceUserId, 5795 targetUserId); 5796 } 5797 } 5798 } 5799 return null; 5800 } 5801 5802 private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter, 5803 int sourceUserId, int targetUserId) { 5804 ResolveInfo forwardingResolveInfo = new ResolveInfo(); 5805 long ident = Binder.clearCallingIdentity(); 5806 boolean targetIsProfile; 5807 try { 5808 targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile(); 5809 } finally { 5810 Binder.restoreCallingIdentity(ident); 5811 } 5812 String className; 5813 if (targetIsProfile) { 5814 className = FORWARD_INTENT_TO_MANAGED_PROFILE; 5815 } else { 5816 className = FORWARD_INTENT_TO_PARENT; 5817 } 5818 ComponentName forwardingActivityComponentName = new ComponentName( 5819 mAndroidApplication.packageName, className); 5820 ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0, 5821 sourceUserId); 5822 if (!targetIsProfile) { 5823 forwardingActivityInfo.showUserIcon = targetUserId; 5824 forwardingResolveInfo.noResourceId = true; 5825 } 5826 forwardingResolveInfo.activityInfo = forwardingActivityInfo; 5827 forwardingResolveInfo.priority = 0; 5828 forwardingResolveInfo.preferredOrder = 0; 5829 forwardingResolveInfo.match = 0; 5830 forwardingResolveInfo.isDefault = true; 5831 forwardingResolveInfo.filter = filter; 5832 forwardingResolveInfo.targetUserId = targetUserId; 5833 return forwardingResolveInfo; 5834 } 5835 5836 @Override 5837 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller, 5838 Intent[] specifics, String[] specificTypes, Intent intent, 5839 String resolvedType, int flags, int userId) { 5840 return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics, 5841 specificTypes, intent, resolvedType, flags, userId)); 5842 } 5843 5844 private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller, 5845 Intent[] specifics, String[] specificTypes, Intent intent, 5846 String resolvedType, int flags, int userId) { 5847 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5848 flags = updateFlagsForResolve(flags, userId, intent); 5849 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5850 false /* requireFullPermission */, false /* checkShell */, 5851 "query intent activity options"); 5852 final String resultsAction = intent.getAction(); 5853 5854 final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags 5855 | PackageManager.GET_RESOLVED_FILTER, userId); 5856 5857 if (DEBUG_INTENT_MATCHING) { 5858 Log.v(TAG, "Query " + intent + ": " + results); 5859 } 5860 5861 int specificsPos = 0; 5862 int N; 5863 5864 // todo: note that the algorithm used here is O(N^2). This 5865 // isn't a problem in our current environment, but if we start running 5866 // into situations where we have more than 5 or 10 matches then this 5867 // should probably be changed to something smarter... 5868 5869 // First we go through and resolve each of the specific items 5870 // that were supplied, taking care of removing any corresponding 5871 // duplicate items in the generic resolve list. 5872 if (specifics != null) { 5873 for (int i=0; i<specifics.length; i++) { 5874 final Intent sintent = specifics[i]; 5875 if (sintent == null) { 5876 continue; 5877 } 5878 5879 if (DEBUG_INTENT_MATCHING) { 5880 Log.v(TAG, "Specific #" + i + ": " + sintent); 5881 } 5882 5883 String action = sintent.getAction(); 5884 if (resultsAction != null && resultsAction.equals(action)) { 5885 // If this action was explicitly requested, then don't 5886 // remove things that have it. 5887 action = null; 5888 } 5889 5890 ResolveInfo ri = null; 5891 ActivityInfo ai = null; 5892 5893 ComponentName comp = sintent.getComponent(); 5894 if (comp == null) { 5895 ri = resolveIntent( 5896 sintent, 5897 specificTypes != null ? specificTypes[i] : null, 5898 flags, userId); 5899 if (ri == null) { 5900 continue; 5901 } 5902 if (ri == mResolveInfo) { 5903 // ACK! Must do something better with this. 5904 } 5905 ai = ri.activityInfo; 5906 comp = new ComponentName(ai.applicationInfo.packageName, 5907 ai.name); 5908 } else { 5909 ai = getActivityInfo(comp, flags, userId); 5910 if (ai == null) { 5911 continue; 5912 } 5913 } 5914 5915 // Look for any generic query activities that are duplicates 5916 // of this specific one, and remove them from the results. 5917 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai); 5918 N = results.size(); 5919 int j; 5920 for (j=specificsPos; j<N; j++) { 5921 ResolveInfo sri = results.get(j); 5922 if ((sri.activityInfo.name.equals(comp.getClassName()) 5923 && sri.activityInfo.applicationInfo.packageName.equals( 5924 comp.getPackageName())) 5925 || (action != null && sri.filter.matchAction(action))) { 5926 results.remove(j); 5927 if (DEBUG_INTENT_MATCHING) Log.v( 5928 TAG, "Removing duplicate item from " + j 5929 + " due to specific " + specificsPos); 5930 if (ri == null) { 5931 ri = sri; 5932 } 5933 j--; 5934 N--; 5935 } 5936 } 5937 5938 // Add this specific item to its proper place. 5939 if (ri == null) { 5940 ri = new ResolveInfo(); 5941 ri.activityInfo = ai; 5942 } 5943 results.add(specificsPos, ri); 5944 ri.specificIndex = i; 5945 specificsPos++; 5946 } 5947 } 5948 5949 // Now we go through the remaining generic results and remove any 5950 // duplicate actions that are found here. 5951 N = results.size(); 5952 for (int i=specificsPos; i<N-1; i++) { 5953 final ResolveInfo rii = results.get(i); 5954 if (rii.filter == null) { 5955 continue; 5956 } 5957 5958 // Iterate over all of the actions of this result's intent 5959 // filter... typically this should be just one. 5960 final Iterator<String> it = rii.filter.actionsIterator(); 5961 if (it == null) { 5962 continue; 5963 } 5964 while (it.hasNext()) { 5965 final String action = it.next(); 5966 if (resultsAction != null && resultsAction.equals(action)) { 5967 // If this action was explicitly requested, then don't 5968 // remove things that have it. 5969 continue; 5970 } 5971 for (int j=i+1; j<N; j++) { 5972 final ResolveInfo rij = results.get(j); 5973 if (rij.filter != null && rij.filter.hasAction(action)) { 5974 results.remove(j); 5975 if (DEBUG_INTENT_MATCHING) Log.v( 5976 TAG, "Removing duplicate item from " + j 5977 + " due to action " + action + " at " + i); 5978 j--; 5979 N--; 5980 } 5981 } 5982 } 5983 5984 // If the caller didn't request filter information, drop it now 5985 // so we don't have to marshall/unmarshall it. 5986 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 5987 rii.filter = null; 5988 } 5989 } 5990 5991 // Filter out the caller activity if so requested. 5992 if (caller != null) { 5993 N = results.size(); 5994 for (int i=0; i<N; i++) { 5995 ActivityInfo ainfo = results.get(i).activityInfo; 5996 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName) 5997 && caller.getClassName().equals(ainfo.name)) { 5998 results.remove(i); 5999 break; 6000 } 6001 } 6002 } 6003 6004 // If the caller didn't request filter information, 6005 // drop them now so we don't have to 6006 // marshall/unmarshall it. 6007 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 6008 N = results.size(); 6009 for (int i=0; i<N; i++) { 6010 results.get(i).filter = null; 6011 } 6012 } 6013 6014 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results); 6015 return results; 6016 } 6017 6018 @Override 6019 public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent, 6020 String resolvedType, int flags, int userId) { 6021 return new ParceledListSlice<>( 6022 queryIntentReceiversInternal(intent, resolvedType, flags, userId)); 6023 } 6024 6025 private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent, 6026 String resolvedType, int flags, int userId) { 6027 if (!sUserManager.exists(userId)) return Collections.emptyList(); 6028 flags = updateFlagsForResolve(flags, userId, intent); 6029 ComponentName comp = intent.getComponent(); 6030 if (comp == null) { 6031 if (intent.getSelector() != null) { 6032 intent = intent.getSelector(); 6033 comp = intent.getComponent(); 6034 } 6035 } 6036 if (comp != null) { 6037 List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 6038 ActivityInfo ai = getReceiverInfo(comp, flags, userId); 6039 if (ai != null) { 6040 ResolveInfo ri = new ResolveInfo(); 6041 ri.activityInfo = ai; 6042 list.add(ri); 6043 } 6044 return list; 6045 } 6046 6047 // reader 6048 synchronized (mPackages) { 6049 String pkgName = intent.getPackage(); 6050 if (pkgName == null) { 6051 return mReceivers.queryIntent(intent, resolvedType, flags, userId); 6052 } 6053 final PackageParser.Package pkg = mPackages.get(pkgName); 6054 if (pkg != null) { 6055 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers, 6056 userId); 6057 } 6058 return Collections.emptyList(); 6059 } 6060 } 6061 6062 @Override 6063 public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) { 6064 if (!sUserManager.exists(userId)) return null; 6065 flags = updateFlagsForResolve(flags, userId, intent); 6066 List<ResolveInfo> query = queryIntentServicesInternal(intent, resolvedType, flags, userId); 6067 if (query != null) { 6068 if (query.size() >= 1) { 6069 // If there is more than one service with the same priority, 6070 // just arbitrarily pick the first one. 6071 return query.get(0); 6072 } 6073 } 6074 return null; 6075 } 6076 6077 @Override 6078 public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent, 6079 String resolvedType, int flags, int userId) { 6080 return new ParceledListSlice<>( 6081 queryIntentServicesInternal(intent, resolvedType, flags, userId)); 6082 } 6083 6084 private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent, 6085 String resolvedType, int flags, int userId) { 6086 if (!sUserManager.exists(userId)) return Collections.emptyList(); 6087 flags = updateFlagsForResolve(flags, userId, intent); 6088 ComponentName comp = intent.getComponent(); 6089 if (comp == null) { 6090 if (intent.getSelector() != null) { 6091 intent = intent.getSelector(); 6092 comp = intent.getComponent(); 6093 } 6094 } 6095 if (comp != null) { 6096 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 6097 final ServiceInfo si = getServiceInfo(comp, flags, userId); 6098 if (si != null) { 6099 final ResolveInfo ri = new ResolveInfo(); 6100 ri.serviceInfo = si; 6101 list.add(ri); 6102 } 6103 return list; 6104 } 6105 6106 // reader 6107 synchronized (mPackages) { 6108 String pkgName = intent.getPackage(); 6109 if (pkgName == null) { 6110 return mServices.queryIntent(intent, resolvedType, flags, userId); 6111 } 6112 final PackageParser.Package pkg = mPackages.get(pkgName); 6113 if (pkg != null) { 6114 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services, 6115 userId); 6116 } 6117 return Collections.emptyList(); 6118 } 6119 } 6120 6121 @Override 6122 public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent, 6123 String resolvedType, int flags, int userId) { 6124 return new ParceledListSlice<>( 6125 queryIntentContentProvidersInternal(intent, resolvedType, flags, userId)); 6126 } 6127 6128 private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal( 6129 Intent intent, String resolvedType, int flags, int userId) { 6130 if (!sUserManager.exists(userId)) return Collections.emptyList(); 6131 flags = updateFlagsForResolve(flags, userId, intent); 6132 ComponentName comp = intent.getComponent(); 6133 if (comp == null) { 6134 if (intent.getSelector() != null) { 6135 intent = intent.getSelector(); 6136 comp = intent.getComponent(); 6137 } 6138 } 6139 if (comp != null) { 6140 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 6141 final ProviderInfo pi = getProviderInfo(comp, flags, userId); 6142 if (pi != null) { 6143 final ResolveInfo ri = new ResolveInfo(); 6144 ri.providerInfo = pi; 6145 list.add(ri); 6146 } 6147 return list; 6148 } 6149 6150 // reader 6151 synchronized (mPackages) { 6152 String pkgName = intent.getPackage(); 6153 if (pkgName == null) { 6154 return mProviders.queryIntent(intent, resolvedType, flags, userId); 6155 } 6156 final PackageParser.Package pkg = mPackages.get(pkgName); 6157 if (pkg != null) { 6158 return mProviders.queryIntentForPackage( 6159 intent, resolvedType, flags, pkg.providers, userId); 6160 } 6161 return Collections.emptyList(); 6162 } 6163 } 6164 6165 @Override 6166 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) { 6167 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 6168 flags = updateFlagsForPackage(flags, userId, null); 6169 final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0; 6170 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6171 true /* requireFullPermission */, false /* checkShell */, 6172 "get installed packages"); 6173 6174 // writer 6175 synchronized (mPackages) { 6176 ArrayList<PackageInfo> list; 6177 if (listUninstalled) { 6178 list = new ArrayList<PackageInfo>(mSettings.mPackages.size()); 6179 for (PackageSetting ps : mSettings.mPackages.values()) { 6180 final PackageInfo pi; 6181 if (ps.pkg != null) { 6182 pi = generatePackageInfo(ps, flags, userId); 6183 } else { 6184 pi = generatePackageInfo(ps, flags, userId); 6185 } 6186 if (pi != null) { 6187 list.add(pi); 6188 } 6189 } 6190 } else { 6191 list = new ArrayList<PackageInfo>(mPackages.size()); 6192 for (PackageParser.Package p : mPackages.values()) { 6193 final PackageInfo pi = 6194 generatePackageInfo((PackageSetting)p.mExtras, flags, userId); 6195 if (pi != null) { 6196 list.add(pi); 6197 } 6198 } 6199 } 6200 6201 return new ParceledListSlice<PackageInfo>(list); 6202 } 6203 } 6204 6205 private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps, 6206 String[] permissions, boolean[] tmp, int flags, int userId) { 6207 int numMatch = 0; 6208 final PermissionsState permissionsState = ps.getPermissionsState(); 6209 for (int i=0; i<permissions.length; i++) { 6210 final String permission = permissions[i]; 6211 if (permissionsState.hasPermission(permission, userId)) { 6212 tmp[i] = true; 6213 numMatch++; 6214 } else { 6215 tmp[i] = false; 6216 } 6217 } 6218 if (numMatch == 0) { 6219 return; 6220 } 6221 final PackageInfo pi; 6222 if (ps.pkg != null) { 6223 pi = generatePackageInfo(ps, flags, userId); 6224 } else { 6225 pi = generatePackageInfo(ps, flags, userId); 6226 } 6227 // The above might return null in cases of uninstalled apps or install-state 6228 // skew across users/profiles. 6229 if (pi != null) { 6230 if ((flags&PackageManager.GET_PERMISSIONS) == 0) { 6231 if (numMatch == permissions.length) { 6232 pi.requestedPermissions = permissions; 6233 } else { 6234 pi.requestedPermissions = new String[numMatch]; 6235 numMatch = 0; 6236 for (int i=0; i<permissions.length; i++) { 6237 if (tmp[i]) { 6238 pi.requestedPermissions[numMatch] = permissions[i]; 6239 numMatch++; 6240 } 6241 } 6242 } 6243 } 6244 list.add(pi); 6245 } 6246 } 6247 6248 @Override 6249 public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions( 6250 String[] permissions, int flags, int userId) { 6251 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 6252 flags = updateFlagsForPackage(flags, userId, permissions); 6253 final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0; 6254 6255 // writer 6256 synchronized (mPackages) { 6257 ArrayList<PackageInfo> list = new ArrayList<PackageInfo>(); 6258 boolean[] tmpBools = new boolean[permissions.length]; 6259 if (listUninstalled) { 6260 for (PackageSetting ps : mSettings.mPackages.values()) { 6261 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId); 6262 } 6263 } else { 6264 for (PackageParser.Package pkg : mPackages.values()) { 6265 PackageSetting ps = (PackageSetting)pkg.mExtras; 6266 if (ps != null) { 6267 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, 6268 userId); 6269 } 6270 } 6271 } 6272 6273 return new ParceledListSlice<PackageInfo>(list); 6274 } 6275 } 6276 6277 @Override 6278 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) { 6279 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 6280 flags = updateFlagsForApplication(flags, userId, null); 6281 final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0; 6282 6283 // writer 6284 synchronized (mPackages) { 6285 ArrayList<ApplicationInfo> list; 6286 if (listUninstalled) { 6287 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size()); 6288 for (PackageSetting ps : mSettings.mPackages.values()) { 6289 ApplicationInfo ai; 6290 if (ps.pkg != null) { 6291 ai = PackageParser.generateApplicationInfo(ps.pkg, flags, 6292 ps.readUserState(userId), userId); 6293 } else { 6294 ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId); 6295 } 6296 if (ai != null) { 6297 list.add(ai); 6298 } 6299 } 6300 } else { 6301 list = new ArrayList<ApplicationInfo>(mPackages.size()); 6302 for (PackageParser.Package p : mPackages.values()) { 6303 if (p.mExtras != null) { 6304 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 6305 ((PackageSetting)p.mExtras).readUserState(userId), userId); 6306 if (ai != null) { 6307 list.add(ai); 6308 } 6309 } 6310 } 6311 } 6312 6313 return new ParceledListSlice<ApplicationInfo>(list); 6314 } 6315 } 6316 6317 @Override 6318 public ParceledListSlice<EphemeralApplicationInfo> getEphemeralApplications(int userId) { 6319 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) { 6320 return null; 6321 } 6322 6323 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS, 6324 "getEphemeralApplications"); 6325 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6326 true /* requireFullPermission */, false /* checkShell */, 6327 "getEphemeralApplications"); 6328 synchronized (mPackages) { 6329 List<EphemeralApplicationInfo> ephemeralApps = mEphemeralApplicationRegistry 6330 .getEphemeralApplicationsLPw(userId); 6331 if (ephemeralApps != null) { 6332 return new ParceledListSlice<>(ephemeralApps); 6333 } 6334 } 6335 return null; 6336 } 6337 6338 @Override 6339 public boolean isEphemeralApplication(String packageName, int userId) { 6340 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6341 true /* requireFullPermission */, false /* checkShell */, 6342 "isEphemeral"); 6343 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) { 6344 return false; 6345 } 6346 6347 if (!isCallerSameApp(packageName)) { 6348 return false; 6349 } 6350 synchronized (mPackages) { 6351 PackageParser.Package pkg = mPackages.get(packageName); 6352 if (pkg != null) { 6353 return pkg.applicationInfo.isEphemeralApp(); 6354 } 6355 } 6356 return false; 6357 } 6358 6359 @Override 6360 public byte[] getEphemeralApplicationCookie(String packageName, int userId) { 6361 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) { 6362 return null; 6363 } 6364 6365 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6366 true /* requireFullPermission */, false /* checkShell */, 6367 "getCookie"); 6368 if (!isCallerSameApp(packageName)) { 6369 return null; 6370 } 6371 synchronized (mPackages) { 6372 return mEphemeralApplicationRegistry.getEphemeralApplicationCookieLPw( 6373 packageName, userId); 6374 } 6375 } 6376 6377 @Override 6378 public boolean setEphemeralApplicationCookie(String packageName, byte[] cookie, int userId) { 6379 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) { 6380 return true; 6381 } 6382 6383 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6384 true /* requireFullPermission */, true /* checkShell */, 6385 "setCookie"); 6386 if (!isCallerSameApp(packageName)) { 6387 return false; 6388 } 6389 synchronized (mPackages) { 6390 return mEphemeralApplicationRegistry.setEphemeralApplicationCookieLPw( 6391 packageName, cookie, userId); 6392 } 6393 } 6394 6395 @Override 6396 public Bitmap getEphemeralApplicationIcon(String packageName, int userId) { 6397 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) { 6398 return null; 6399 } 6400 6401 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS, 6402 "getEphemeralApplicationIcon"); 6403 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6404 true /* requireFullPermission */, false /* checkShell */, 6405 "getEphemeralApplicationIcon"); 6406 synchronized (mPackages) { 6407 return mEphemeralApplicationRegistry.getEphemeralApplicationIconLPw( 6408 packageName, userId); 6409 } 6410 } 6411 6412 private boolean isCallerSameApp(String packageName) { 6413 PackageParser.Package pkg = mPackages.get(packageName); 6414 return pkg != null 6415 && UserHandle.getAppId(Binder.getCallingUid()) == pkg.applicationInfo.uid; 6416 } 6417 6418 @Override 6419 public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) { 6420 return new ParceledListSlice<>(getPersistentApplicationsInternal(flags)); 6421 } 6422 6423 private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) { 6424 final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>(); 6425 6426 // reader 6427 synchronized (mPackages) { 6428 final Iterator<PackageParser.Package> i = mPackages.values().iterator(); 6429 final int userId = UserHandle.getCallingUserId(); 6430 while (i.hasNext()) { 6431 final PackageParser.Package p = i.next(); 6432 if (p.applicationInfo == null) continue; 6433 6434 final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0) 6435 && !p.applicationInfo.isDirectBootAware(); 6436 final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0) 6437 && p.applicationInfo.isDirectBootAware(); 6438 6439 if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0 6440 && (!mSafeMode || isSystemApp(p)) 6441 && (matchesUnaware || matchesAware)) { 6442 PackageSetting ps = mSettings.mPackages.get(p.packageName); 6443 if (ps != null) { 6444 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 6445 ps.readUserState(userId), userId); 6446 if (ai != null) { 6447 finalList.add(ai); 6448 } 6449 } 6450 } 6451 } 6452 } 6453 6454 return finalList; 6455 } 6456 6457 @Override 6458 public ProviderInfo resolveContentProvider(String name, int flags, int userId) { 6459 if (!sUserManager.exists(userId)) return null; 6460 flags = updateFlagsForComponent(flags, userId, name); 6461 // reader 6462 synchronized (mPackages) { 6463 final PackageParser.Provider provider = mProvidersByAuthority.get(name); 6464 PackageSetting ps = provider != null 6465 ? mSettings.mPackages.get(provider.owner.packageName) 6466 : null; 6467 return ps != null 6468 && mSettings.isEnabledAndMatchLPr(provider.info, flags, userId) 6469 ? PackageParser.generateProviderInfo(provider, flags, 6470 ps.readUserState(userId), userId) 6471 : null; 6472 } 6473 } 6474 6475 /** 6476 * @deprecated 6477 */ 6478 @Deprecated 6479 public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) { 6480 // reader 6481 synchronized (mPackages) { 6482 final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority 6483 .entrySet().iterator(); 6484 final int userId = UserHandle.getCallingUserId(); 6485 while (i.hasNext()) { 6486 Map.Entry<String, PackageParser.Provider> entry = i.next(); 6487 PackageParser.Provider p = entry.getValue(); 6488 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 6489 6490 if (ps != null && p.syncable 6491 && (!mSafeMode || (p.info.applicationInfo.flags 6492 &ApplicationInfo.FLAG_SYSTEM) != 0)) { 6493 ProviderInfo info = PackageParser.generateProviderInfo(p, 0, 6494 ps.readUserState(userId), userId); 6495 if (info != null) { 6496 outNames.add(entry.getKey()); 6497 outInfo.add(info); 6498 } 6499 } 6500 } 6501 } 6502 } 6503 6504 @Override 6505 public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName, 6506 int uid, int flags) { 6507 final int userId = processName != null ? UserHandle.getUserId(uid) 6508 : UserHandle.getCallingUserId(); 6509 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 6510 flags = updateFlagsForComponent(flags, userId, processName); 6511 6512 ArrayList<ProviderInfo> finalList = null; 6513 // reader 6514 synchronized (mPackages) { 6515 final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator(); 6516 while (i.hasNext()) { 6517 final PackageParser.Provider p = i.next(); 6518 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 6519 if (ps != null && p.info.authority != null 6520 && (processName == null 6521 || (p.info.processName.equals(processName) 6522 && UserHandle.isSameApp(p.info.applicationInfo.uid, uid))) 6523 && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) { 6524 if (finalList == null) { 6525 finalList = new ArrayList<ProviderInfo>(3); 6526 } 6527 ProviderInfo info = PackageParser.generateProviderInfo(p, flags, 6528 ps.readUserState(userId), userId); 6529 if (info != null) { 6530 finalList.add(info); 6531 } 6532 } 6533 } 6534 } 6535 6536 if (finalList != null) { 6537 Collections.sort(finalList, mProviderInitOrderSorter); 6538 return new ParceledListSlice<ProviderInfo>(finalList); 6539 } 6540 6541 return ParceledListSlice.emptyList(); 6542 } 6543 6544 @Override 6545 public InstrumentationInfo getInstrumentationInfo(ComponentName name, int flags) { 6546 // reader 6547 synchronized (mPackages) { 6548 final PackageParser.Instrumentation i = mInstrumentation.get(name); 6549 return PackageParser.generateInstrumentationInfo(i, flags); 6550 } 6551 } 6552 6553 @Override 6554 public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation( 6555 String targetPackage, int flags) { 6556 return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags)); 6557 } 6558 6559 private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage, 6560 int flags) { 6561 ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>(); 6562 6563 // reader 6564 synchronized (mPackages) { 6565 final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator(); 6566 while (i.hasNext()) { 6567 final PackageParser.Instrumentation p = i.next(); 6568 if (targetPackage == null 6569 || targetPackage.equals(p.info.targetPackage)) { 6570 InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p, 6571 flags); 6572 if (ii != null) { 6573 finalList.add(ii); 6574 } 6575 } 6576 } 6577 } 6578 6579 return finalList; 6580 } 6581 6582 private void createIdmapsForPackageLI(PackageParser.Package pkg) { 6583 ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName); 6584 if (overlays == null) { 6585 Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages"); 6586 return; 6587 } 6588 for (PackageParser.Package opkg : overlays.values()) { 6589 // Not much to do if idmap fails: we already logged the error 6590 // and we certainly don't want to abort installation of pkg simply 6591 // because an overlay didn't fit properly. For these reasons, 6592 // ignore the return value of createIdmapForPackagePairLI. 6593 createIdmapForPackagePairLI(pkg, opkg); 6594 } 6595 } 6596 6597 private boolean createIdmapForPackagePairLI(PackageParser.Package pkg, 6598 PackageParser.Package opkg) { 6599 if (!opkg.mTrustedOverlay) { 6600 Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " + 6601 opkg.baseCodePath + ": overlay not trusted"); 6602 return false; 6603 } 6604 ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName); 6605 if (overlaySet == null) { 6606 Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " + 6607 opkg.baseCodePath + " but target package has no known overlays"); 6608 return false; 6609 } 6610 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 6611 // TODO: generate idmap for split APKs 6612 try { 6613 mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid); 6614 } catch (InstallerException e) { 6615 Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and " 6616 + opkg.baseCodePath); 6617 return false; 6618 } 6619 PackageParser.Package[] overlayArray = 6620 overlaySet.values().toArray(new PackageParser.Package[0]); 6621 Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() { 6622 public int compare(PackageParser.Package p1, PackageParser.Package p2) { 6623 return p1.mOverlayPriority - p2.mOverlayPriority; 6624 } 6625 }; 6626 Arrays.sort(overlayArray, cmp); 6627 6628 pkg.applicationInfo.resourceDirs = new String[overlayArray.length]; 6629 int i = 0; 6630 for (PackageParser.Package p : overlayArray) { 6631 pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath; 6632 } 6633 return true; 6634 } 6635 6636 private void scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime) { 6637 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir"); 6638 try { 6639 scanDirLI(dir, parseFlags, scanFlags, currentTime); 6640 } finally { 6641 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6642 } 6643 } 6644 6645 private void scanDirLI(File dir, final int parseFlags, int scanFlags, long currentTime) { 6646 final File[] files = dir.listFiles(); 6647 if (ArrayUtils.isEmpty(files)) { 6648 Log.d(TAG, "No files in app dir " + dir); 6649 return; 6650 } 6651 6652 if (DEBUG_PACKAGE_SCANNING) { 6653 Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags 6654 + " flags=0x" + Integer.toHexString(parseFlags)); 6655 } 6656 6657 for (File file : files) { 6658 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 6659 && !PackageInstallerService.isStageName(file.getName()); 6660 if (!isPackage) { 6661 // Ignore entries which are not packages 6662 continue; 6663 } 6664 try { 6665 scanPackageTracedLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK, 6666 scanFlags, currentTime, null); 6667 } catch (PackageManagerException e) { 6668 Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage()); 6669 6670 // Delete invalid userdata apps 6671 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 && 6672 e.error == PackageManager.INSTALL_FAILED_INVALID_APK) { 6673 logCriticalInfo(Log.WARN, "Deleting invalid package at " + file); 6674 removeCodePathLI(file); 6675 } 6676 } 6677 } 6678 } 6679 6680 private static File getSettingsProblemFile() { 6681 File dataDir = Environment.getDataDirectory(); 6682 File systemDir = new File(dataDir, "system"); 6683 File fname = new File(systemDir, "uiderrors.txt"); 6684 return fname; 6685 } 6686 6687 static void reportSettingsProblem(int priority, String msg) { 6688 logCriticalInfo(priority, msg); 6689 } 6690 6691 static void logCriticalInfo(int priority, String msg) { 6692 Slog.println(priority, TAG, msg); 6693 EventLogTags.writePmCriticalInfo(msg); 6694 try { 6695 File fname = getSettingsProblemFile(); 6696 FileOutputStream out = new FileOutputStream(fname, true); 6697 PrintWriter pw = new FastPrintWriter(out); 6698 SimpleDateFormat formatter = new SimpleDateFormat(); 6699 String dateString = formatter.format(new Date(System.currentTimeMillis())); 6700 pw.println(dateString + ": " + msg); 6701 pw.close(); 6702 FileUtils.setPermissions( 6703 fname.toString(), 6704 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH, 6705 -1, -1); 6706 } catch (java.io.IOException e) { 6707 } 6708 } 6709 6710 private long getLastModifiedTime(PackageParser.Package pkg, File srcFile) { 6711 if (srcFile.isDirectory()) { 6712 final File baseFile = new File(pkg.baseCodePath); 6713 long maxModifiedTime = baseFile.lastModified(); 6714 if (pkg.splitCodePaths != null) { 6715 for (int i = pkg.splitCodePaths.length - 1; i >=0; --i) { 6716 final File splitFile = new File(pkg.splitCodePaths[i]); 6717 maxModifiedTime = Math.max(maxModifiedTime, splitFile.lastModified()); 6718 } 6719 } 6720 return maxModifiedTime; 6721 } 6722 return srcFile.lastModified(); 6723 } 6724 6725 private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile, 6726 final int policyFlags) throws PackageManagerException { 6727 // When upgrading from pre-N MR1, verify the package time stamp using the package 6728 // directory and not the APK file. 6729 final long lastModifiedTime = mIsPreNMR1Upgrade 6730 ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg, srcFile); 6731 if (ps != null 6732 && ps.codePath.equals(srcFile) 6733 && ps.timeStamp == lastModifiedTime 6734 && !isCompatSignatureUpdateNeeded(pkg) 6735 && !isRecoverSignatureUpdateNeeded(pkg)) { 6736 long mSigningKeySetId = ps.keySetData.getProperSigningKeySet(); 6737 KeySetManagerService ksms = mSettings.mKeySetManagerService; 6738 ArraySet<PublicKey> signingKs; 6739 synchronized (mPackages) { 6740 signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId); 6741 } 6742 if (ps.signatures.mSignatures != null 6743 && ps.signatures.mSignatures.length != 0 6744 && signingKs != null) { 6745 // Optimization: reuse the existing cached certificates 6746 // if the package appears to be unchanged. 6747 pkg.mSignatures = ps.signatures.mSignatures; 6748 pkg.mSigningKeys = signingKs; 6749 return; 6750 } 6751 6752 Slog.w(TAG, "PackageSetting for " + ps.name 6753 + " is missing signatures. Collecting certs again to recover them."); 6754 } else { 6755 Slog.i(TAG, srcFile.toString() + " changed; collecting certs"); 6756 } 6757 6758 try { 6759 PackageParser.collectCertificates(pkg, policyFlags); 6760 } catch (PackageParserException e) { 6761 throw PackageManagerException.from(e); 6762 } 6763 } 6764 6765 /** 6766 * Traces a package scan. 6767 * @see #scanPackageLI(File, int, int, long, UserHandle) 6768 */ 6769 private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags, 6770 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 6771 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage"); 6772 try { 6773 return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user); 6774 } finally { 6775 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6776 } 6777 } 6778 6779 /** 6780 * Scans a package and returns the newly parsed package. 6781 * Returns {@code null} in case of errors and the error code is stored in mLastScanError 6782 */ 6783 private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags, 6784 long currentTime, UserHandle user) throws PackageManagerException { 6785 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile); 6786 PackageParser pp = new PackageParser(); 6787 pp.setSeparateProcesses(mSeparateProcesses); 6788 pp.setOnlyCoreApps(mOnlyCore); 6789 pp.setDisplayMetrics(mMetrics); 6790 6791 if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) { 6792 parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY; 6793 } 6794 6795 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage"); 6796 final PackageParser.Package pkg; 6797 try { 6798 pkg = pp.parsePackage(scanFile, parseFlags); 6799 } catch (PackageParserException e) { 6800 throw PackageManagerException.from(e); 6801 } finally { 6802 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6803 } 6804 6805 return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user); 6806 } 6807 6808 /** 6809 * Scans a package and returns the newly parsed package. 6810 * @throws PackageManagerException on a parse error. 6811 */ 6812 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile, 6813 final int policyFlags, int scanFlags, long currentTime, UserHandle user) 6814 throws PackageManagerException { 6815 // If the package has children and this is the first dive in the function 6816 // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all 6817 // packages (parent and children) would be successfully scanned before the 6818 // actual scan since scanning mutates internal state and we want to atomically 6819 // install the package and its children. 6820 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 6821 if (pkg.childPackages != null && pkg.childPackages.size() > 0) { 6822 scanFlags |= SCAN_CHECK_ONLY; 6823 } 6824 } else { 6825 scanFlags &= ~SCAN_CHECK_ONLY; 6826 } 6827 6828 // Scan the parent 6829 PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, policyFlags, 6830 scanFlags, currentTime, user); 6831 6832 // Scan the children 6833 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 6834 for (int i = 0; i < childCount; i++) { 6835 PackageParser.Package childPackage = pkg.childPackages.get(i); 6836 scanPackageInternalLI(childPackage, scanFile, policyFlags, scanFlags, 6837 currentTime, user); 6838 } 6839 6840 6841 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 6842 return scanPackageLI(pkg, scanFile, policyFlags, scanFlags, currentTime, user); 6843 } 6844 6845 return scannedPkg; 6846 } 6847 6848 /** 6849 * Scans a package and returns the newly parsed package. 6850 * @throws PackageManagerException on a parse error. 6851 */ 6852 private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile, 6853 int policyFlags, int scanFlags, long currentTime, UserHandle user) 6854 throws PackageManagerException { 6855 PackageSetting ps = null; 6856 PackageSetting updatedPkg; 6857 // reader 6858 synchronized (mPackages) { 6859 // Look to see if we already know about this package. 6860 String oldName = mSettings.mRenamedPackages.get(pkg.packageName); 6861 if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) { 6862 // This package has been renamed to its original name. Let's 6863 // use that. 6864 ps = mSettings.peekPackageLPr(oldName); 6865 } 6866 // If there was no original package, see one for the real package name. 6867 if (ps == null) { 6868 ps = mSettings.peekPackageLPr(pkg.packageName); 6869 } 6870 // Check to see if this package could be hiding/updating a system 6871 // package. Must look for it either under the original or real 6872 // package name depending on our state. 6873 updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName); 6874 if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg); 6875 6876 // If this is a package we don't know about on the system partition, we 6877 // may need to remove disabled child packages on the system partition 6878 // or may need to not add child packages if the parent apk is updated 6879 // on the data partition and no longer defines this child package. 6880 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) { 6881 // If this is a parent package for an updated system app and this system 6882 // app got an OTA update which no longer defines some of the child packages 6883 // we have to prune them from the disabled system packages. 6884 PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName); 6885 if (disabledPs != null) { 6886 final int scannedChildCount = (pkg.childPackages != null) 6887 ? pkg.childPackages.size() : 0; 6888 final int disabledChildCount = disabledPs.childPackageNames != null 6889 ? disabledPs.childPackageNames.size() : 0; 6890 for (int i = 0; i < disabledChildCount; i++) { 6891 String disabledChildPackageName = disabledPs.childPackageNames.get(i); 6892 boolean disabledPackageAvailable = false; 6893 for (int j = 0; j < scannedChildCount; j++) { 6894 PackageParser.Package childPkg = pkg.childPackages.get(j); 6895 if (childPkg.packageName.equals(disabledChildPackageName)) { 6896 disabledPackageAvailable = true; 6897 break; 6898 } 6899 } 6900 if (!disabledPackageAvailable) { 6901 mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName); 6902 } 6903 } 6904 } 6905 } 6906 } 6907 6908 boolean updatedPkgBetter = false; 6909 // First check if this is a system package that may involve an update 6910 if (updatedPkg != null && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) { 6911 // If new package is not located in "/system/priv-app" (e.g. due to an OTA), 6912 // it needs to drop FLAG_PRIVILEGED. 6913 if (locationIsPrivileged(scanFile)) { 6914 updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 6915 } else { 6916 updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 6917 } 6918 6919 if (ps != null && !ps.codePath.equals(scanFile)) { 6920 // The path has changed from what was last scanned... check the 6921 // version of the new path against what we have stored to determine 6922 // what to do. 6923 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath); 6924 if (pkg.mVersionCode <= ps.versionCode) { 6925 // The system package has been updated and the code path does not match 6926 // Ignore entry. Skip it. 6927 if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile 6928 + " ignored: updated version " + ps.versionCode 6929 + " better than this " + pkg.mVersionCode); 6930 if (!updatedPkg.codePath.equals(scanFile)) { 6931 Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg " 6932 + ps.name + " changing from " + updatedPkg.codePathString 6933 + " to " + scanFile); 6934 updatedPkg.codePath = scanFile; 6935 updatedPkg.codePathString = scanFile.toString(); 6936 updatedPkg.resourcePath = scanFile; 6937 updatedPkg.resourcePathString = scanFile.toString(); 6938 } 6939 updatedPkg.pkg = pkg; 6940 updatedPkg.versionCode = pkg.mVersionCode; 6941 6942 // Update the disabled system child packages to point to the package too. 6943 final int childCount = updatedPkg.childPackageNames != null 6944 ? updatedPkg.childPackageNames.size() : 0; 6945 for (int i = 0; i < childCount; i++) { 6946 String childPackageName = updatedPkg.childPackageNames.get(i); 6947 PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr( 6948 childPackageName); 6949 if (updatedChildPkg != null) { 6950 updatedChildPkg.pkg = pkg; 6951 updatedChildPkg.versionCode = pkg.mVersionCode; 6952 } 6953 } 6954 6955 throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at " 6956 + scanFile + " ignored: updated version " + ps.versionCode 6957 + " better than this " + pkg.mVersionCode); 6958 } else { 6959 // The current app on the system partition is better than 6960 // what we have updated to on the data partition; switch 6961 // back to the system partition version. 6962 // At this point, its safely assumed that package installation for 6963 // apps in system partition will go through. If not there won't be a working 6964 // version of the app 6965 // writer 6966 synchronized (mPackages) { 6967 // Just remove the loaded entries from package lists. 6968 mPackages.remove(ps.name); 6969 } 6970 6971 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 6972 + " reverting from " + ps.codePathString 6973 + ": new version " + pkg.mVersionCode 6974 + " better than installed " + ps.versionCode); 6975 6976 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 6977 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 6978 synchronized (mInstallLock) { 6979 args.cleanUpResourcesLI(); 6980 } 6981 synchronized (mPackages) { 6982 mSettings.enableSystemPackageLPw(ps.name); 6983 } 6984 updatedPkgBetter = true; 6985 } 6986 } 6987 } 6988 6989 if (updatedPkg != null) { 6990 // An updated system app will not have the PARSE_IS_SYSTEM flag set 6991 // initially 6992 policyFlags |= PackageParser.PARSE_IS_SYSTEM; 6993 6994 // An updated privileged app will not have the PARSE_IS_PRIVILEGED 6995 // flag set initially 6996 if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) { 6997 policyFlags |= PackageParser.PARSE_IS_PRIVILEGED; 6998 } 6999 } 7000 7001 // Verify certificates against what was last scanned 7002 collectCertificatesLI(ps, pkg, scanFile, policyFlags); 7003 7004 /* 7005 * A new system app appeared, but we already had a non-system one of the 7006 * same name installed earlier. 7007 */ 7008 boolean shouldHideSystemApp = false; 7009 if (updatedPkg == null && ps != null 7010 && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) { 7011 /* 7012 * Check to make sure the signatures match first. If they don't, 7013 * wipe the installed application and its data. 7014 */ 7015 if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures) 7016 != PackageManager.SIGNATURE_MATCH) { 7017 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but" 7018 + " signatures don't match existing userdata copy; removing"); 7019 try (PackageFreezer freezer = freezePackage(pkg.packageName, 7020 "scanPackageInternalLI")) { 7021 deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null); 7022 } 7023 ps = null; 7024 } else { 7025 /* 7026 * If the newly-added system app is an older version than the 7027 * already installed version, hide it. It will be scanned later 7028 * and re-added like an update. 7029 */ 7030 if (pkg.mVersionCode <= ps.versionCode) { 7031 shouldHideSystemApp = true; 7032 logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile 7033 + " but new version " + pkg.mVersionCode + " better than installed " 7034 + ps.versionCode + "; hiding system"); 7035 } else { 7036 /* 7037 * The newly found system app is a newer version that the 7038 * one previously installed. Simply remove the 7039 * already-installed application and replace it with our own 7040 * while keeping the application data. 7041 */ 7042 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 7043 + " reverting from " + ps.codePathString + ": new version " 7044 + pkg.mVersionCode + " better than installed " + ps.versionCode); 7045 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 7046 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 7047 synchronized (mInstallLock) { 7048 args.cleanUpResourcesLI(); 7049 } 7050 } 7051 } 7052 } 7053 7054 // The apk is forward locked (not public) if its code and resources 7055 // are kept in different files. (except for app in either system or 7056 // vendor path). 7057 // TODO grab this value from PackageSettings 7058 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 7059 if (ps != null && !ps.codePath.equals(ps.resourcePath)) { 7060 policyFlags |= PackageParser.PARSE_FORWARD_LOCK; 7061 } 7062 } 7063 7064 // TODO: extend to support forward-locked splits 7065 String resourcePath = null; 7066 String baseResourcePath = null; 7067 if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) { 7068 if (ps != null && ps.resourcePathString != null) { 7069 resourcePath = ps.resourcePathString; 7070 baseResourcePath = ps.resourcePathString; 7071 } else { 7072 // Should not happen at all. Just log an error. 7073 Slog.e(TAG, "Resource path not set for package " + pkg.packageName); 7074 } 7075 } else { 7076 resourcePath = pkg.codePath; 7077 baseResourcePath = pkg.baseCodePath; 7078 } 7079 7080 // Set application objects path explicitly. 7081 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 7082 pkg.setApplicationInfoCodePath(pkg.codePath); 7083 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 7084 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 7085 pkg.setApplicationInfoResourcePath(resourcePath); 7086 pkg.setApplicationInfoBaseResourcePath(baseResourcePath); 7087 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 7088 7089 // Note that we invoke the following method only if we are about to unpack an application 7090 PackageParser.Package scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags 7091 | SCAN_UPDATE_SIGNATURE, currentTime, user); 7092 7093 /* 7094 * If the system app should be overridden by a previously installed 7095 * data, hide the system app now and let the /data/app scan pick it up 7096 * again. 7097 */ 7098 if (shouldHideSystemApp) { 7099 synchronized (mPackages) { 7100 mSettings.disableSystemPackageLPw(pkg.packageName, true); 7101 } 7102 } 7103 7104 return scannedPkg; 7105 } 7106 7107 private static String fixProcessName(String defProcessName, 7108 String processName, int uid) { 7109 if (processName == null) { 7110 return defProcessName; 7111 } 7112 return processName; 7113 } 7114 7115 private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg) 7116 throws PackageManagerException { 7117 if (pkgSetting.signatures.mSignatures != null) { 7118 // Already existing package. Make sure signatures match 7119 boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures) 7120 == PackageManager.SIGNATURE_MATCH; 7121 if (!match) { 7122 match = compareSignaturesCompat(pkgSetting.signatures, pkg) 7123 == PackageManager.SIGNATURE_MATCH; 7124 } 7125 if (!match) { 7126 match = compareSignaturesRecover(pkgSetting.signatures, pkg) 7127 == PackageManager.SIGNATURE_MATCH; 7128 } 7129 if (!match) { 7130 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 7131 + pkg.packageName + " signatures do not match the " 7132 + "previously installed version; ignoring!"); 7133 } 7134 } 7135 7136 // Check for shared user signatures 7137 if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) { 7138 // Already existing package. Make sure signatures match 7139 boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 7140 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 7141 if (!match) { 7142 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg) 7143 == PackageManager.SIGNATURE_MATCH; 7144 } 7145 if (!match) { 7146 match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg) 7147 == PackageManager.SIGNATURE_MATCH; 7148 } 7149 if (!match) { 7150 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 7151 "Package " + pkg.packageName 7152 + " has no signatures that match those in shared user " 7153 + pkgSetting.sharedUser.name + "; ignoring!"); 7154 } 7155 } 7156 } 7157 7158 /** 7159 * Enforces that only the system UID or root's UID can call a method exposed 7160 * via Binder. 7161 * 7162 * @param message used as message if SecurityException is thrown 7163 * @throws SecurityException if the caller is not system or root 7164 */ 7165 private static final void enforceSystemOrRoot(String message) { 7166 final int uid = Binder.getCallingUid(); 7167 if (uid != Process.SYSTEM_UID && uid != 0) { 7168 throw new SecurityException(message); 7169 } 7170 } 7171 7172 @Override 7173 public void performFstrimIfNeeded() { 7174 enforceSystemOrRoot("Only the system can request fstrim"); 7175 7176 // Before everything else, see whether we need to fstrim. 7177 try { 7178 IMountService ms = PackageHelper.getMountService(); 7179 if (ms != null) { 7180 boolean doTrim = false; 7181 final long interval = android.provider.Settings.Global.getLong( 7182 mContext.getContentResolver(), 7183 android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL, 7184 DEFAULT_MANDATORY_FSTRIM_INTERVAL); 7185 if (interval > 0) { 7186 final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance(); 7187 if (timeSinceLast > interval) { 7188 doTrim = true; 7189 Slog.w(TAG, "No disk maintenance in " + timeSinceLast 7190 + "; running immediately"); 7191 } 7192 } 7193 if (doTrim) { 7194 final boolean dexOptDialogShown; 7195 synchronized (mPackages) { 7196 dexOptDialogShown = mDexOptDialogShown; 7197 } 7198 if (!isFirstBoot() && dexOptDialogShown) { 7199 try { 7200 ActivityManagerNative.getDefault().showBootMessage( 7201 mContext.getResources().getString( 7202 R.string.android_upgrading_fstrim), true); 7203 } catch (RemoteException e) { 7204 } 7205 } 7206 ms.runMaintenance(); 7207 } 7208 } else { 7209 Slog.e(TAG, "Mount service unavailable!"); 7210 } 7211 } catch (RemoteException e) { 7212 // Can't happen; MountService is local 7213 } 7214 } 7215 7216 @Override 7217 public void updatePackagesIfNeeded() { 7218 enforceSystemOrRoot("Only the system can request package update"); 7219 7220 // We need to re-extract after an OTA. 7221 boolean causeUpgrade = isUpgrade(); 7222 7223 // First boot or factory reset. 7224 // Note: we also handle devices that are upgrading to N right now as if it is their 7225 // first boot, as they do not have profile data. 7226 boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade; 7227 7228 // We need to re-extract after a pruned cache, as AoT-ed files will be out of date. 7229 boolean causePrunedCache = VMRuntime.didPruneDalvikCache(); 7230 7231 if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) { 7232 return; 7233 } 7234 7235 List<PackageParser.Package> pkgs; 7236 synchronized (mPackages) { 7237 pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this); 7238 } 7239 7240 final long startTime = System.nanoTime(); 7241 final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */, 7242 getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT)); 7243 7244 final int elapsedTimeSeconds = 7245 (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime); 7246 7247 MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]); 7248 MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]); 7249 MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]); 7250 MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size()); 7251 MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds); 7252 } 7253 7254 /** 7255 * Performs dexopt on the set of packages in {@code packages} and returns an int array 7256 * containing statistics about the invocation. The array consists of three elements, 7257 * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped} 7258 * and {@code numberOfPackagesFailed}. 7259 */ 7260 private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog, 7261 String compilerFilter) { 7262 7263 int numberOfPackagesVisited = 0; 7264 int numberOfPackagesOptimized = 0; 7265 int numberOfPackagesSkipped = 0; 7266 int numberOfPackagesFailed = 0; 7267 final int numberOfPackagesToDexopt = pkgs.size(); 7268 7269 for (PackageParser.Package pkg : pkgs) { 7270 numberOfPackagesVisited++; 7271 7272 if (!PackageDexOptimizer.canOptimizePackage(pkg)) { 7273 if (DEBUG_DEXOPT) { 7274 Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName); 7275 } 7276 numberOfPackagesSkipped++; 7277 continue; 7278 } 7279 7280 if (DEBUG_DEXOPT) { 7281 Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " + 7282 numberOfPackagesToDexopt + ": " + pkg.packageName); 7283 } 7284 7285 if (showDialog) { 7286 try { 7287 ActivityManagerNative.getDefault().showBootMessage( 7288 mContext.getResources().getString(R.string.android_upgrading_apk, 7289 numberOfPackagesVisited, numberOfPackagesToDexopt), true); 7290 } catch (RemoteException e) { 7291 } 7292 synchronized (mPackages) { 7293 mDexOptDialogShown = true; 7294 } 7295 } 7296 7297 // If the OTA updates a system app which was previously preopted to a non-preopted state 7298 // the app might end up being verified at runtime. That's because by default the apps 7299 // are verify-profile but for preopted apps there's no profile. 7300 // Do a hacky check to ensure that if we have no profiles (a reasonable indication 7301 // that before the OTA the app was preopted) the app gets compiled with a non-profile 7302 // filter (by default interpret-only). 7303 // Note that at this stage unused apps are already filtered. 7304 if (isSystemApp(pkg) && 7305 DexFile.isProfileGuidedCompilerFilter(compilerFilter) && 7306 !Environment.getReferenceProfile(pkg.packageName).exists()) { 7307 compilerFilter = getNonProfileGuidedCompilerFilter(compilerFilter); 7308 } 7309 7310 // If the OTA updates a system app which was previously preopted to a non-preopted state 7311 // the app might end up being verified at runtime. That's because by default the apps 7312 // are verify-profile but for preopted apps there's no profile. 7313 // Do a hacky check to ensure that if we have no profiles (a reasonable indication 7314 // that before the OTA the app was preopted) the app gets compiled with a non-profile 7315 // filter (by default interpret-only). 7316 // Note that at this stage unused apps are already filtered. 7317 if (isSystemApp(pkg) && 7318 DexFile.isProfileGuidedCompilerFilter(compilerFilter) && 7319 !Environment.getReferenceProfile(pkg.packageName).exists()) { 7320 compilerFilter = getNonProfileGuidedCompilerFilter(compilerFilter); 7321 } 7322 7323 // checkProfiles is false to avoid merging profiles during boot which 7324 // might interfere with background compilation (b/28612421). 7325 // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will 7326 // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a 7327 // trade-off worth doing to save boot time work. 7328 int dexOptStatus = performDexOptTraced(pkg.packageName, 7329 false /* checkProfiles */, 7330 compilerFilter, 7331 false /* force */); 7332 switch (dexOptStatus) { 7333 case PackageDexOptimizer.DEX_OPT_PERFORMED: 7334 numberOfPackagesOptimized++; 7335 break; 7336 case PackageDexOptimizer.DEX_OPT_SKIPPED: 7337 numberOfPackagesSkipped++; 7338 break; 7339 case PackageDexOptimizer.DEX_OPT_FAILED: 7340 numberOfPackagesFailed++; 7341 break; 7342 default: 7343 Log.e(TAG, "Unexpected dexopt return code " + dexOptStatus); 7344 break; 7345 } 7346 } 7347 7348 return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped, 7349 numberOfPackagesFailed }; 7350 } 7351 7352 @Override 7353 public void notifyPackageUse(String packageName, int reason) { 7354 synchronized (mPackages) { 7355 PackageParser.Package p = mPackages.get(packageName); 7356 if (p == null) { 7357 return; 7358 } 7359 p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis(); 7360 } 7361 } 7362 7363 // TODO: this is not used nor needed. Delete it. 7364 @Override 7365 public boolean performDexOptIfNeeded(String packageName) { 7366 int dexOptStatus = performDexOptTraced(packageName, 7367 false /* checkProfiles */, getFullCompilerFilter(), false /* force */); 7368 return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED; 7369 } 7370 7371 @Override 7372 public boolean performDexOpt(String packageName, 7373 boolean checkProfiles, int compileReason, boolean force) { 7374 int dexOptStatus = performDexOptTraced(packageName, checkProfiles, 7375 getCompilerFilterForReason(compileReason), force); 7376 return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED; 7377 } 7378 7379 @Override 7380 public boolean performDexOptMode(String packageName, 7381 boolean checkProfiles, String targetCompilerFilter, boolean force) { 7382 int dexOptStatus = performDexOptTraced(packageName, checkProfiles, 7383 targetCompilerFilter, force); 7384 return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED; 7385 } 7386 7387 private int performDexOptTraced(String packageName, 7388 boolean checkProfiles, String targetCompilerFilter, boolean force) { 7389 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 7390 try { 7391 return performDexOptInternal(packageName, checkProfiles, 7392 targetCompilerFilter, force); 7393 } finally { 7394 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7395 } 7396 } 7397 7398 // Run dexopt on a given package. Returns true if dexopt did not fail, i.e. 7399 // if the package can now be considered up to date for the given filter. 7400 private int performDexOptInternal(String packageName, 7401 boolean checkProfiles, String targetCompilerFilter, boolean force) { 7402 PackageParser.Package p; 7403 synchronized (mPackages) { 7404 p = mPackages.get(packageName); 7405 if (p == null) { 7406 // Package could not be found. Report failure. 7407 return PackageDexOptimizer.DEX_OPT_FAILED; 7408 } 7409 mPackageUsage.maybeWriteAsync(mPackages); 7410 mCompilerStats.maybeWriteAsync(); 7411 } 7412 long callingId = Binder.clearCallingIdentity(); 7413 try { 7414 synchronized (mInstallLock) { 7415 return performDexOptInternalWithDependenciesLI(p, checkProfiles, 7416 targetCompilerFilter, force); 7417 } 7418 } finally { 7419 Binder.restoreCallingIdentity(callingId); 7420 } 7421 } 7422 7423 public ArraySet<String> getOptimizablePackages() { 7424 ArraySet<String> pkgs = new ArraySet<String>(); 7425 synchronized (mPackages) { 7426 for (PackageParser.Package p : mPackages.values()) { 7427 if (PackageDexOptimizer.canOptimizePackage(p)) { 7428 pkgs.add(p.packageName); 7429 } 7430 } 7431 } 7432 return pkgs; 7433 } 7434 7435 private int performDexOptInternalWithDependenciesLI(PackageParser.Package p, 7436 boolean checkProfiles, String targetCompilerFilter, 7437 boolean force) { 7438 // Select the dex optimizer based on the force parameter. 7439 // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to 7440 // allocate an object here. 7441 PackageDexOptimizer pdo = force 7442 ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer) 7443 : mPackageDexOptimizer; 7444 7445 // Optimize all dependencies first. Note: we ignore the return value and march on 7446 // on errors. 7447 Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p); 7448 final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo); 7449 if (!deps.isEmpty()) { 7450 for (PackageParser.Package depPackage : deps) { 7451 // TODO: Analyze and investigate if we (should) profile libraries. 7452 // Currently this will do a full compilation of the library by default. 7453 pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets, 7454 false /* checkProfiles */, 7455 getCompilerFilterForReason(REASON_NON_SYSTEM_LIBRARY), 7456 getOrCreateCompilerPackageStats(depPackage)); 7457 } 7458 } 7459 return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles, 7460 targetCompilerFilter, getOrCreateCompilerPackageStats(p)); 7461 } 7462 7463 Collection<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) { 7464 if (p.usesLibraries != null || p.usesOptionalLibraries != null) { 7465 ArrayList<PackageParser.Package> retValue = new ArrayList<>(); 7466 Set<String> collectedNames = new HashSet<>(); 7467 findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames); 7468 7469 retValue.remove(p); 7470 7471 return retValue; 7472 } else { 7473 return Collections.emptyList(); 7474 } 7475 } 7476 7477 private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p, 7478 Collection<PackageParser.Package> collected, Set<String> collectedNames) { 7479 if (!collectedNames.contains(p.packageName)) { 7480 collectedNames.add(p.packageName); 7481 collected.add(p); 7482 7483 if (p.usesLibraries != null) { 7484 findSharedNonSystemLibrariesRecursive(p.usesLibraries, collected, collectedNames); 7485 } 7486 if (p.usesOptionalLibraries != null) { 7487 findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries, collected, 7488 collectedNames); 7489 } 7490 } 7491 } 7492 7493 private void findSharedNonSystemLibrariesRecursive(Collection<String> libs, 7494 Collection<PackageParser.Package> collected, Set<String> collectedNames) { 7495 for (String libName : libs) { 7496 PackageParser.Package libPkg = findSharedNonSystemLibrary(libName); 7497 if (libPkg != null) { 7498 findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames); 7499 } 7500 } 7501 } 7502 7503 private PackageParser.Package findSharedNonSystemLibrary(String libName) { 7504 synchronized (mPackages) { 7505 PackageManagerService.SharedLibraryEntry lib = mSharedLibraries.get(libName); 7506 if (lib != null && lib.apk != null) { 7507 return mPackages.get(lib.apk); 7508 } 7509 } 7510 return null; 7511 } 7512 7513 public void shutdown() { 7514 mPackageUsage.writeNow(mPackages); 7515 mCompilerStats.writeNow(); 7516 } 7517 7518 @Override 7519 public void dumpProfiles(String packageName) { 7520 PackageParser.Package pkg; 7521 synchronized (mPackages) { 7522 pkg = mPackages.get(packageName); 7523 if (pkg == null) { 7524 throw new IllegalArgumentException("Unknown package: " + packageName); 7525 } 7526 } 7527 /* Only the shell, root, or the app user should be able to dump profiles. */ 7528 int callingUid = Binder.getCallingUid(); 7529 if (callingUid != Process.SHELL_UID && 7530 callingUid != Process.ROOT_UID && 7531 callingUid != pkg.applicationInfo.uid) { 7532 throw new SecurityException("dumpProfiles"); 7533 } 7534 7535 synchronized (mInstallLock) { 7536 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles"); 7537 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 7538 try { 7539 List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly(); 7540 String codePaths = TextUtils.join(";", allCodePaths); 7541 mInstaller.dumpProfiles(sharedGid, packageName, codePaths); 7542 } catch (InstallerException e) { 7543 Slog.w(TAG, "Failed to dump profiles", e); 7544 } 7545 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7546 } 7547 } 7548 7549 @Override 7550 public void forceDexOpt(String packageName) { 7551 enforceSystemOrRoot("forceDexOpt"); 7552 7553 PackageParser.Package pkg; 7554 synchronized (mPackages) { 7555 pkg = mPackages.get(packageName); 7556 if (pkg == null) { 7557 throw new IllegalArgumentException("Unknown package: " + packageName); 7558 } 7559 } 7560 7561 synchronized (mInstallLock) { 7562 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 7563 7564 // Whoever is calling forceDexOpt wants a fully compiled package. 7565 // Don't use profiles since that may cause compilation to be skipped. 7566 final int res = performDexOptInternalWithDependenciesLI(pkg, 7567 false /* checkProfiles */, getCompilerFilterForReason(REASON_FORCED_DEXOPT), 7568 true /* force */); 7569 7570 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7571 if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) { 7572 throw new IllegalStateException("Failed to dexopt: " + res); 7573 } 7574 } 7575 } 7576 7577 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) { 7578 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) { 7579 Slog.w(TAG, "Unable to update from " + oldPkg.name 7580 + " to " + newPkg.packageName 7581 + ": old package not in system partition"); 7582 return false; 7583 } else if (mPackages.get(oldPkg.name) != null) { 7584 Slog.w(TAG, "Unable to update from " + oldPkg.name 7585 + " to " + newPkg.packageName 7586 + ": old package still exists"); 7587 return false; 7588 } 7589 return true; 7590 } 7591 7592 void removeCodePathLI(File codePath) { 7593 if (codePath.isDirectory()) { 7594 try { 7595 mInstaller.rmPackageDir(codePath.getAbsolutePath()); 7596 } catch (InstallerException e) { 7597 Slog.w(TAG, "Failed to remove code path", e); 7598 } 7599 } else { 7600 codePath.delete(); 7601 } 7602 } 7603 7604 private int[] resolveUserIds(int userId) { 7605 return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId }; 7606 } 7607 7608 private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) { 7609 if (pkg == null) { 7610 Slog.wtf(TAG, "Package was null!", new Throwable()); 7611 return; 7612 } 7613 clearAppDataLeafLIF(pkg, userId, flags); 7614 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7615 for (int i = 0; i < childCount; i++) { 7616 clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags); 7617 } 7618 } 7619 7620 private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) { 7621 final PackageSetting ps; 7622 synchronized (mPackages) { 7623 ps = mSettings.mPackages.get(pkg.packageName); 7624 } 7625 for (int realUserId : resolveUserIds(userId)) { 7626 final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0; 7627 try { 7628 mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags, 7629 ceDataInode); 7630 } catch (InstallerException e) { 7631 Slog.w(TAG, String.valueOf(e)); 7632 } 7633 } 7634 } 7635 7636 private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) { 7637 if (pkg == null) { 7638 Slog.wtf(TAG, "Package was null!", new Throwable()); 7639 return; 7640 } 7641 destroyAppDataLeafLIF(pkg, userId, flags); 7642 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7643 for (int i = 0; i < childCount; i++) { 7644 destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags); 7645 } 7646 } 7647 7648 private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) { 7649 final PackageSetting ps; 7650 synchronized (mPackages) { 7651 ps = mSettings.mPackages.get(pkg.packageName); 7652 } 7653 for (int realUserId : resolveUserIds(userId)) { 7654 final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0; 7655 try { 7656 mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags, 7657 ceDataInode); 7658 } catch (InstallerException e) { 7659 Slog.w(TAG, String.valueOf(e)); 7660 } 7661 } 7662 } 7663 7664 private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) { 7665 if (pkg == null) { 7666 Slog.wtf(TAG, "Package was null!", new Throwable()); 7667 return; 7668 } 7669 destroyAppProfilesLeafLIF(pkg); 7670 destroyAppReferenceProfileLeafLIF(pkg, userId, true /* removeBaseMarker */); 7671 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7672 for (int i = 0; i < childCount; i++) { 7673 destroyAppProfilesLeafLIF(pkg.childPackages.get(i)); 7674 destroyAppReferenceProfileLeafLIF(pkg.childPackages.get(i), userId, 7675 true /* removeBaseMarker */); 7676 } 7677 } 7678 7679 private void destroyAppReferenceProfileLeafLIF(PackageParser.Package pkg, int userId, 7680 boolean removeBaseMarker) { 7681 if (pkg.isForwardLocked()) { 7682 return; 7683 } 7684 7685 for (String path : pkg.getAllCodePathsExcludingResourceOnly()) { 7686 try { 7687 path = PackageManagerServiceUtils.realpath(new File(path)); 7688 } catch (IOException e) { 7689 // TODO: Should we return early here ? 7690 Slog.w(TAG, "Failed to get canonical path", e); 7691 continue; 7692 } 7693 7694 final String useMarker = path.replace('/', '@'); 7695 for (int realUserId : resolveUserIds(userId)) { 7696 File profileDir = Environment.getDataProfilesDeForeignDexDirectory(realUserId); 7697 if (removeBaseMarker) { 7698 File foreignUseMark = new File(profileDir, useMarker); 7699 if (foreignUseMark.exists()) { 7700 if (!foreignUseMark.delete()) { 7701 Slog.w(TAG, "Unable to delete foreign user mark for package: " 7702 + pkg.packageName); 7703 } 7704 } 7705 } 7706 7707 File[] markers = profileDir.listFiles(); 7708 if (markers != null) { 7709 final String searchString = "@" + pkg.packageName + "@"; 7710 // We also delete all markers that contain the package name we're 7711 // uninstalling. These are associated with secondary dex-files belonging 7712 // to the package. Reconstructing the path of these dex files is messy 7713 // in general. 7714 for (File marker : markers) { 7715 if (marker.getName().indexOf(searchString) > 0) { 7716 if (!marker.delete()) { 7717 Slog.w(TAG, "Unable to delete foreign user mark for package: " 7718 + pkg.packageName); 7719 } 7720 } 7721 } 7722 } 7723 } 7724 } 7725 } 7726 7727 private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) { 7728 try { 7729 mInstaller.destroyAppProfiles(pkg.packageName); 7730 } catch (InstallerException e) { 7731 Slog.w(TAG, String.valueOf(e)); 7732 } 7733 } 7734 7735 private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) { 7736 if (pkg == null) { 7737 Slog.wtf(TAG, "Package was null!", new Throwable()); 7738 return; 7739 } 7740 clearAppProfilesLeafLIF(pkg); 7741 // We don't remove the base foreign use marker when clearing profiles because 7742 // we will rename it when the app is updated. Unlike the actual profile contents, 7743 // the foreign use marker is good across installs. 7744 destroyAppReferenceProfileLeafLIF(pkg, userId, false /* removeBaseMarker */); 7745 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7746 for (int i = 0; i < childCount; i++) { 7747 clearAppProfilesLeafLIF(pkg.childPackages.get(i)); 7748 } 7749 } 7750 7751 private void clearAppProfilesLeafLIF(PackageParser.Package pkg) { 7752 try { 7753 mInstaller.clearAppProfiles(pkg.packageName); 7754 } catch (InstallerException e) { 7755 Slog.w(TAG, String.valueOf(e)); 7756 } 7757 } 7758 7759 private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime, 7760 long lastUpdateTime) { 7761 // Set parent install/update time 7762 PackageSetting ps = (PackageSetting) pkg.mExtras; 7763 if (ps != null) { 7764 ps.firstInstallTime = firstInstallTime; 7765 ps.lastUpdateTime = lastUpdateTime; 7766 } 7767 // Set children install/update time 7768 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7769 for (int i = 0; i < childCount; i++) { 7770 PackageParser.Package childPkg = pkg.childPackages.get(i); 7771 ps = (PackageSetting) childPkg.mExtras; 7772 if (ps != null) { 7773 ps.firstInstallTime = firstInstallTime; 7774 ps.lastUpdateTime = lastUpdateTime; 7775 } 7776 } 7777 } 7778 7779 private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file, 7780 PackageParser.Package changingLib) { 7781 if (file.path != null) { 7782 usesLibraryFiles.add(file.path); 7783 return; 7784 } 7785 PackageParser.Package p = mPackages.get(file.apk); 7786 if (changingLib != null && changingLib.packageName.equals(file.apk)) { 7787 // If we are doing this while in the middle of updating a library apk, 7788 // then we need to make sure to use that new apk for determining the 7789 // dependencies here. (We haven't yet finished committing the new apk 7790 // to the package manager state.) 7791 if (p == null || p.packageName.equals(changingLib.packageName)) { 7792 p = changingLib; 7793 } 7794 } 7795 if (p != null) { 7796 usesLibraryFiles.addAll(p.getAllCodePaths()); 7797 } 7798 } 7799 7800 private void updateSharedLibrariesLPw(PackageParser.Package pkg, 7801 PackageParser.Package changingLib) throws PackageManagerException { 7802 if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) { 7803 final ArraySet<String> usesLibraryFiles = new ArraySet<>(); 7804 int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0; 7805 for (int i=0; i<N; i++) { 7806 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i)); 7807 if (file == null) { 7808 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, 7809 "Package " + pkg.packageName + " requires unavailable shared library " 7810 + pkg.usesLibraries.get(i) + "; failing!"); 7811 } 7812 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 7813 } 7814 N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0; 7815 for (int i=0; i<N; i++) { 7816 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i)); 7817 if (file == null) { 7818 Slog.w(TAG, "Package " + pkg.packageName 7819 + " desires unavailable shared library " 7820 + pkg.usesOptionalLibraries.get(i) + "; ignoring!"); 7821 } else { 7822 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 7823 } 7824 } 7825 N = usesLibraryFiles.size(); 7826 if (N > 0) { 7827 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]); 7828 } else { 7829 pkg.usesLibraryFiles = null; 7830 } 7831 } 7832 } 7833 7834 private static boolean hasString(List<String> list, List<String> which) { 7835 if (list == null) { 7836 return false; 7837 } 7838 for (int i=list.size()-1; i>=0; i--) { 7839 for (int j=which.size()-1; j>=0; j--) { 7840 if (which.get(j).equals(list.get(i))) { 7841 return true; 7842 } 7843 } 7844 } 7845 return false; 7846 } 7847 7848 private void updateAllSharedLibrariesLPw() { 7849 for (PackageParser.Package pkg : mPackages.values()) { 7850 try { 7851 updateSharedLibrariesLPw(pkg, null); 7852 } catch (PackageManagerException e) { 7853 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 7854 } 7855 } 7856 } 7857 7858 private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw( 7859 PackageParser.Package changingPkg) { 7860 ArrayList<PackageParser.Package> res = null; 7861 for (PackageParser.Package pkg : mPackages.values()) { 7862 if (hasString(pkg.usesLibraries, changingPkg.libraryNames) 7863 || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) { 7864 if (res == null) { 7865 res = new ArrayList<PackageParser.Package>(); 7866 } 7867 res.add(pkg); 7868 try { 7869 updateSharedLibrariesLPw(pkg, changingPkg); 7870 } catch (PackageManagerException e) { 7871 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 7872 } 7873 } 7874 } 7875 return res; 7876 } 7877 7878 /** 7879 * Derive the value of the {@code cpuAbiOverride} based on the provided 7880 * value and an optional stored value from the package settings. 7881 */ 7882 private static String deriveAbiOverride(String abiOverride, PackageSetting settings) { 7883 String cpuAbiOverride = null; 7884 7885 if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) { 7886 cpuAbiOverride = null; 7887 } else if (abiOverride != null) { 7888 cpuAbiOverride = abiOverride; 7889 } else if (settings != null) { 7890 cpuAbiOverride = settings.cpuAbiOverrideString; 7891 } 7892 7893 return cpuAbiOverride; 7894 } 7895 7896 private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg, 7897 final int policyFlags, int scanFlags, long currentTime, UserHandle user) 7898 throws PackageManagerException { 7899 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage"); 7900 // If the package has children and this is the first dive in the function 7901 // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see 7902 // whether all packages (parent and children) would be successfully scanned 7903 // before the actual scan since scanning mutates internal state and we want 7904 // to atomically install the package and its children. 7905 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 7906 if (pkg.childPackages != null && pkg.childPackages.size() > 0) { 7907 scanFlags |= SCAN_CHECK_ONLY; 7908 } 7909 } else { 7910 scanFlags &= ~SCAN_CHECK_ONLY; 7911 } 7912 7913 final PackageParser.Package scannedPkg; 7914 try { 7915 // Scan the parent 7916 scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags, currentTime, user); 7917 // Scan the children 7918 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7919 for (int i = 0; i < childCount; i++) { 7920 PackageParser.Package childPkg = pkg.childPackages.get(i); 7921 scanPackageLI(childPkg, policyFlags, 7922 scanFlags, currentTime, user); 7923 } 7924 } finally { 7925 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7926 } 7927 7928 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 7929 return scanPackageTracedLI(pkg, policyFlags, scanFlags, currentTime, user); 7930 } 7931 7932 return scannedPkg; 7933 } 7934 7935 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags, 7936 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 7937 boolean success = false; 7938 try { 7939 final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags, 7940 currentTime, user); 7941 success = true; 7942 return res; 7943 } finally { 7944 if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) { 7945 // DELETE_DATA_ON_FAILURES is only used by frozen paths 7946 destroyAppDataLIF(pkg, UserHandle.USER_ALL, 7947 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 7948 destroyAppProfilesLIF(pkg, UserHandle.USER_ALL); 7949 } 7950 } 7951 } 7952 7953 /** 7954 * Returns {@code true} if the given file contains code. Otherwise {@code false}. 7955 */ 7956 private static boolean apkHasCode(String fileName) { 7957 StrictJarFile jarFile = null; 7958 try { 7959 jarFile = new StrictJarFile(fileName, 7960 false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/); 7961 return jarFile.findEntry("classes.dex") != null; 7962 } catch (IOException ignore) { 7963 } finally { 7964 try { 7965 if (jarFile != null) { 7966 jarFile.close(); 7967 } 7968 } catch (IOException ignore) {} 7969 } 7970 return false; 7971 } 7972 7973 /** 7974 * Enforces code policy for the package. This ensures that if an APK has 7975 * declared hasCode="true" in its manifest that the APK actually contains 7976 * code. 7977 * 7978 * @throws PackageManagerException If bytecode could not be found when it should exist 7979 */ 7980 private static void enforceCodePolicy(PackageParser.Package pkg) 7981 throws PackageManagerException { 7982 final boolean shouldHaveCode = 7983 (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0; 7984 if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) { 7985 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 7986 "Package " + pkg.baseCodePath + " code is missing"); 7987 } 7988 7989 if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) { 7990 for (int i = 0; i < pkg.splitCodePaths.length; i++) { 7991 final boolean splitShouldHaveCode = 7992 (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0; 7993 if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) { 7994 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 7995 "Package " + pkg.splitCodePaths[i] + " code is missing"); 7996 } 7997 } 7998 } 7999 } 8000 8001 private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, 8002 final int policyFlags, final int scanFlags, long currentTime, UserHandle user) 8003 throws PackageManagerException { 8004 final File scanFile = new File(pkg.codePath); 8005 if (pkg.applicationInfo.getCodePath() == null || 8006 pkg.applicationInfo.getResourcePath() == null) { 8007 // Bail out. The resource and code paths haven't been set. 8008 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 8009 "Code and resource paths haven't been set correctly"); 8010 } 8011 8012 // Apply policy 8013 if ((policyFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 8014 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; 8015 if (pkg.applicationInfo.isDirectBootAware()) { 8016 // we're direct boot aware; set for all components 8017 for (PackageParser.Service s : pkg.services) { 8018 s.info.encryptionAware = s.info.directBootAware = true; 8019 } 8020 for (PackageParser.Provider p : pkg.providers) { 8021 p.info.encryptionAware = p.info.directBootAware = true; 8022 } 8023 for (PackageParser.Activity a : pkg.activities) { 8024 a.info.encryptionAware = a.info.directBootAware = true; 8025 } 8026 for (PackageParser.Activity r : pkg.receivers) { 8027 r.info.encryptionAware = r.info.directBootAware = true; 8028 } 8029 } 8030 } else { 8031 // Only allow system apps to be flagged as core apps. 8032 pkg.coreApp = false; 8033 // clear flags not applicable to regular apps 8034 pkg.applicationInfo.privateFlags &= 8035 ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE; 8036 pkg.applicationInfo.privateFlags &= 8037 ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE; 8038 } 8039 pkg.mTrustedOverlay = (policyFlags&PackageParser.PARSE_TRUSTED_OVERLAY) != 0; 8040 8041 if ((policyFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) { 8042 pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 8043 } 8044 8045 if ((policyFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) { 8046 enforceCodePolicy(pkg); 8047 } 8048 8049 if (mCustomResolverComponentName != null && 8050 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) { 8051 setUpCustomResolverActivity(pkg); 8052 } 8053 8054 if (pkg.packageName.equals("android")) { 8055 synchronized (mPackages) { 8056 if (mAndroidApplication != null) { 8057 Slog.w(TAG, "*************************************************"); 8058 Slog.w(TAG, "Core android package being redefined. Skipping."); 8059 Slog.w(TAG, " file=" + scanFile); 8060 Slog.w(TAG, "*************************************************"); 8061 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 8062 "Core android package being redefined. Skipping."); 8063 } 8064 8065 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 8066 // Set up information for our fall-back user intent resolution activity. 8067 mPlatformPackage = pkg; 8068 pkg.mVersionCode = mSdkVersion; 8069 mAndroidApplication = pkg.applicationInfo; 8070 8071 if (!mResolverReplaced) { 8072 mResolveActivity.applicationInfo = mAndroidApplication; 8073 mResolveActivity.name = ResolverActivity.class.getName(); 8074 mResolveActivity.packageName = mAndroidApplication.packageName; 8075 mResolveActivity.processName = "system:ui"; 8076 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 8077 mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER; 8078 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS; 8079 mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert; 8080 mResolveActivity.exported = true; 8081 mResolveActivity.enabled = true; 8082 mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE; 8083 mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE 8084 | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE 8085 | ActivityInfo.CONFIG_SCREEN_LAYOUT 8086 | ActivityInfo.CONFIG_ORIENTATION 8087 | ActivityInfo.CONFIG_KEYBOARD 8088 | ActivityInfo.CONFIG_KEYBOARD_HIDDEN; 8089 mResolveInfo.activityInfo = mResolveActivity; 8090 mResolveInfo.priority = 0; 8091 mResolveInfo.preferredOrder = 0; 8092 mResolveInfo.match = 0; 8093 mResolveComponentName = new ComponentName( 8094 mAndroidApplication.packageName, mResolveActivity.name); 8095 } 8096 } 8097 } 8098 } 8099 8100 if (DEBUG_PACKAGE_SCANNING) { 8101 if ((policyFlags & PackageParser.PARSE_CHATTY) != 0) 8102 Log.d(TAG, "Scanning package " + pkg.packageName); 8103 } 8104 8105 synchronized (mPackages) { 8106 if (mPackages.containsKey(pkg.packageName) 8107 || mSharedLibraries.containsKey(pkg.packageName)) { 8108 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 8109 "Application package " + pkg.packageName 8110 + " already installed. Skipping duplicate."); 8111 } 8112 8113 // If we're only installing presumed-existing packages, require that the 8114 // scanned APK is both already known and at the path previously established 8115 // for it. Previously unknown packages we pick up normally, but if we have an 8116 // a priori expectation about this package's install presence, enforce it. 8117 // With a singular exception for new system packages. When an OTA contains 8118 // a new system package, we allow the codepath to change from a system location 8119 // to the user-installed location. If we don't allow this change, any newer, 8120 // user-installed version of the application will be ignored. 8121 if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) { 8122 if (mExpectingBetter.containsKey(pkg.packageName)) { 8123 logCriticalInfo(Log.WARN, 8124 "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName); 8125 } else { 8126 PackageSetting known = mSettings.peekPackageLPr(pkg.packageName); 8127 if (known != null) { 8128 if (DEBUG_PACKAGE_SCANNING) { 8129 Log.d(TAG, "Examining " + pkg.codePath 8130 + " and requiring known paths " + known.codePathString 8131 + " & " + known.resourcePathString); 8132 } 8133 if (!pkg.applicationInfo.getCodePath().equals(known.codePathString) 8134 || !pkg.applicationInfo.getResourcePath().equals( 8135 known.resourcePathString)) { 8136 throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED, 8137 "Application package " + pkg.packageName 8138 + " found at " + pkg.applicationInfo.getCodePath() 8139 + " but expected at " + known.codePathString 8140 + "; ignoring."); 8141 } 8142 } 8143 } 8144 } 8145 } 8146 8147 // Initialize package source and resource directories 8148 File destCodeFile = new File(pkg.applicationInfo.getCodePath()); 8149 File destResourceFile = new File(pkg.applicationInfo.getResourcePath()); 8150 8151 SharedUserSetting suid = null; 8152 PackageSetting pkgSetting = null; 8153 8154 if (!isSystemApp(pkg)) { 8155 // Only system apps can use these features. 8156 pkg.mOriginalPackages = null; 8157 pkg.mRealPackage = null; 8158 pkg.mAdoptPermissions = null; 8159 } 8160 8161 // Getting the package setting may have a side-effect, so if we 8162 // are only checking if scan would succeed, stash a copy of the 8163 // old setting to restore at the end. 8164 PackageSetting nonMutatedPs = null; 8165 8166 // writer 8167 synchronized (mPackages) { 8168 if (pkg.mSharedUserId != null) { 8169 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, true); 8170 if (suid == null) { 8171 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 8172 "Creating application package " + pkg.packageName 8173 + " for shared user failed"); 8174 } 8175 if (DEBUG_PACKAGE_SCANNING) { 8176 if ((policyFlags & PackageParser.PARSE_CHATTY) != 0) 8177 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId 8178 + "): packages=" + suid.packages); 8179 } 8180 } 8181 8182 // Check if we are renaming from an original package name. 8183 PackageSetting origPackage = null; 8184 String realName = null; 8185 if (pkg.mOriginalPackages != null) { 8186 // This package may need to be renamed to a previously 8187 // installed name. Let's check on that... 8188 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage); 8189 if (pkg.mOriginalPackages.contains(renamed)) { 8190 // This package had originally been installed as the 8191 // original name, and we have already taken care of 8192 // transitioning to the new one. Just update the new 8193 // one to continue using the old name. 8194 realName = pkg.mRealPackage; 8195 if (!pkg.packageName.equals(renamed)) { 8196 // Callers into this function may have already taken 8197 // care of renaming the package; only do it here if 8198 // it is not already done. 8199 pkg.setPackageName(renamed); 8200 } 8201 8202 } else { 8203 for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) { 8204 if ((origPackage = mSettings.peekPackageLPr( 8205 pkg.mOriginalPackages.get(i))) != null) { 8206 // We do have the package already installed under its 8207 // original name... should we use it? 8208 if (!verifyPackageUpdateLPr(origPackage, pkg)) { 8209 // New package is not compatible with original. 8210 origPackage = null; 8211 continue; 8212 } else if (origPackage.sharedUser != null) { 8213 // Make sure uid is compatible between packages. 8214 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) { 8215 Slog.w(TAG, "Unable to migrate data from " + origPackage.name 8216 + " to " + pkg.packageName + ": old uid " 8217 + origPackage.sharedUser.name 8218 + " differs from " + pkg.mSharedUserId); 8219 origPackage = null; 8220 continue; 8221 } 8222 // TODO: Add case when shared user id is added [b/28144775] 8223 } else { 8224 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package " 8225 + pkg.packageName + " to old name " + origPackage.name); 8226 } 8227 break; 8228 } 8229 } 8230 } 8231 } 8232 8233 if (mTransferedPackages.contains(pkg.packageName)) { 8234 Slog.w(TAG, "Package " + pkg.packageName 8235 + " was transferred to another, but its .apk remains"); 8236 } 8237 8238 // See comments in nonMutatedPs declaration 8239 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 8240 PackageSetting foundPs = mSettings.peekPackageLPr(pkg.packageName); 8241 if (foundPs != null) { 8242 nonMutatedPs = new PackageSetting(foundPs); 8243 } 8244 } 8245 8246 // Just create the setting, don't add it yet. For already existing packages 8247 // the PkgSetting exists already and doesn't have to be created. 8248 pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile, 8249 destResourceFile, pkg.applicationInfo.nativeLibraryRootDir, 8250 pkg.applicationInfo.primaryCpuAbi, 8251 pkg.applicationInfo.secondaryCpuAbi, 8252 pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, 8253 user, false); 8254 if (pkgSetting == null) { 8255 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 8256 "Creating application package " + pkg.packageName + " failed"); 8257 } 8258 8259 if (pkgSetting.origPackage != null) { 8260 // If we are first transitioning from an original package, 8261 // fix up the new package's name now. We need to do this after 8262 // looking up the package under its new name, so getPackageLP 8263 // can take care of fiddling things correctly. 8264 pkg.setPackageName(origPackage.name); 8265 8266 // File a report about this. 8267 String msg = "New package " + pkgSetting.realName 8268 + " renamed to replace old package " + pkgSetting.name; 8269 reportSettingsProblem(Log.WARN, msg); 8270 8271 // Make a note of it. 8272 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 8273 mTransferedPackages.add(origPackage.name); 8274 } 8275 8276 // No longer need to retain this. 8277 pkgSetting.origPackage = null; 8278 } 8279 8280 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) { 8281 // Make a note of it. 8282 mTransferedPackages.add(pkg.packageName); 8283 } 8284 8285 if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) { 8286 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 8287 } 8288 8289 if ((policyFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 8290 // Check all shared libraries and map to their actual file path. 8291 // We only do this here for apps not on a system dir, because those 8292 // are the only ones that can fail an install due to this. We 8293 // will take care of the system apps by updating all of their 8294 // library paths after the scan is done. 8295 updateSharedLibrariesLPw(pkg, null); 8296 } 8297 8298 if (mFoundPolicyFile) { 8299 SELinuxMMAC.assignSeinfoValue(pkg); 8300 } 8301 8302 pkg.applicationInfo.uid = pkgSetting.appId; 8303 pkg.mExtras = pkgSetting; 8304 if (shouldCheckUpgradeKeySetLP(pkgSetting, scanFlags)) { 8305 if (checkUpgradeKeySetLP(pkgSetting, pkg)) { 8306 // We just determined the app is signed correctly, so bring 8307 // over the latest parsed certs. 8308 pkgSetting.signatures.mSignatures = pkg.mSignatures; 8309 } else { 8310 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 8311 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 8312 "Package " + pkg.packageName + " upgrade keys do not match the " 8313 + "previously installed version"); 8314 } else { 8315 pkgSetting.signatures.mSignatures = pkg.mSignatures; 8316 String msg = "System package " + pkg.packageName 8317 + " signature changed; retaining data."; 8318 reportSettingsProblem(Log.WARN, msg); 8319 } 8320 } 8321 } else { 8322 try { 8323 verifySignaturesLP(pkgSetting, pkg); 8324 // We just determined the app is signed correctly, so bring 8325 // over the latest parsed certs. 8326 pkgSetting.signatures.mSignatures = pkg.mSignatures; 8327 } catch (PackageManagerException e) { 8328 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 8329 throw e; 8330 } 8331 // The signature has changed, but this package is in the system 8332 // image... let's recover! 8333 pkgSetting.signatures.mSignatures = pkg.mSignatures; 8334 // However... if this package is part of a shared user, but it 8335 // doesn't match the signature of the shared user, let's fail. 8336 // What this means is that you can't change the signatures 8337 // associated with an overall shared user, which doesn't seem all 8338 // that unreasonable. 8339 if (pkgSetting.sharedUser != null) { 8340 if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 8341 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { 8342 throw new PackageManagerException( 8343 INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES, 8344 "Signature mismatch for shared user: " 8345 + pkgSetting.sharedUser); 8346 } 8347 } 8348 // File a report about this. 8349 String msg = "System package " + pkg.packageName 8350 + " signature changed; retaining data."; 8351 reportSettingsProblem(Log.WARN, msg); 8352 } 8353 } 8354 // Verify that this new package doesn't have any content providers 8355 // that conflict with existing packages. Only do this if the 8356 // package isn't already installed, since we don't want to break 8357 // things that are installed. 8358 if ((scanFlags & SCAN_NEW_INSTALL) != 0) { 8359 final int N = pkg.providers.size(); 8360 int i; 8361 for (i=0; i<N; i++) { 8362 PackageParser.Provider p = pkg.providers.get(i); 8363 if (p.info.authority != null) { 8364 String names[] = p.info.authority.split(";"); 8365 for (int j = 0; j < names.length; j++) { 8366 if (mProvidersByAuthority.containsKey(names[j])) { 8367 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 8368 final String otherPackageName = 8369 ((other != null && other.getComponentName() != null) ? 8370 other.getComponentName().getPackageName() : "?"); 8371 throw new PackageManagerException( 8372 INSTALL_FAILED_CONFLICTING_PROVIDER, 8373 "Can't install because provider name " + names[j] 8374 + " (in package " + pkg.applicationInfo.packageName 8375 + ") is already used by " + otherPackageName); 8376 } 8377 } 8378 } 8379 } 8380 } 8381 8382 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) { 8383 // This package wants to adopt ownership of permissions from 8384 // another package. 8385 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) { 8386 final String origName = pkg.mAdoptPermissions.get(i); 8387 final PackageSetting orig = mSettings.peekPackageLPr(origName); 8388 if (orig != null) { 8389 if (verifyPackageUpdateLPr(orig, pkg)) { 8390 Slog.i(TAG, "Adopting permissions from " + origName + " to " 8391 + pkg.packageName); 8392 mSettings.transferPermissionsLPw(origName, pkg.packageName); 8393 } 8394 } 8395 } 8396 } 8397 } 8398 8399 final String pkgName = pkg.packageName; 8400 8401 final long scanFileTime = getLastModifiedTime(pkg, scanFile); 8402 final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0; 8403 pkg.applicationInfo.processName = fixProcessName( 8404 pkg.applicationInfo.packageName, 8405 pkg.applicationInfo.processName, 8406 pkg.applicationInfo.uid); 8407 8408 if (pkg != mPlatformPackage) { 8409 // Get all of our default paths setup 8410 pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM); 8411 } 8412 8413 final String path = scanFile.getPath(); 8414 final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting); 8415 8416 if ((scanFlags & SCAN_NEW_INSTALL) == 0) { 8417 derivePackageAbi(pkg, scanFile, cpuAbiOverride, true /* extract libs */); 8418 8419 // Some system apps still use directory structure for native libraries 8420 // in which case we might end up not detecting abi solely based on apk 8421 // structure. Try to detect abi based on directory structure. 8422 if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() && 8423 pkg.applicationInfo.primaryCpuAbi == null) { 8424 setBundledAppAbisAndRoots(pkg, pkgSetting); 8425 setNativeLibraryPaths(pkg); 8426 } 8427 8428 } else { 8429 if ((scanFlags & SCAN_MOVE) != 0) { 8430 // We haven't run dex-opt for this move (since we've moved the compiled output too) 8431 // but we already have this packages package info in the PackageSetting. We just 8432 // use that and derive the native library path based on the new codepath. 8433 pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString; 8434 pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString; 8435 } 8436 8437 // Set native library paths again. For moves, the path will be updated based on the 8438 // ABIs we've determined above. For non-moves, the path will be updated based on the 8439 // ABIs we determined during compilation, but the path will depend on the final 8440 // package path (after the rename away from the stage path). 8441 setNativeLibraryPaths(pkg); 8442 } 8443 8444 // This is a special case for the "system" package, where the ABI is 8445 // dictated by the zygote configuration (and init.rc). We should keep track 8446 // of this ABI so that we can deal with "normal" applications that run under 8447 // the same UID correctly. 8448 if (mPlatformPackage == pkg) { 8449 pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ? 8450 Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]; 8451 } 8452 8453 // If there's a mismatch between the abi-override in the package setting 8454 // and the abiOverride specified for the install. Warn about this because we 8455 // would've already compiled the app without taking the package setting into 8456 // account. 8457 if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) { 8458 if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) { 8459 Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride + 8460 " for package " + pkg.packageName); 8461 } 8462 } 8463 8464 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 8465 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 8466 pkgSetting.cpuAbiOverrideString = cpuAbiOverride; 8467 8468 // Copy the derived override back to the parsed package, so that we can 8469 // update the package settings accordingly. 8470 pkg.cpuAbiOverride = cpuAbiOverride; 8471 8472 if (DEBUG_ABI_SELECTION) { 8473 Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName 8474 + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa=" 8475 + pkg.applicationInfo.nativeLibraryRootRequiresIsa); 8476 } 8477 8478 // Push the derived path down into PackageSettings so we know what to 8479 // clean up at uninstall time. 8480 pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir; 8481 8482 if (DEBUG_ABI_SELECTION) { 8483 Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" + 8484 " primary=" + pkg.applicationInfo.primaryCpuAbi + 8485 " secondary=" + pkg.applicationInfo.secondaryCpuAbi); 8486 } 8487 8488 if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) { 8489 // We don't do this here during boot because we can do it all 8490 // at once after scanning all existing packages. 8491 // 8492 // We also do this *before* we perform dexopt on this package, so that 8493 // we can avoid redundant dexopts, and also to make sure we've got the 8494 // code and package path correct. 8495 adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, 8496 pkg, true /* boot complete */); 8497 } 8498 8499 if (mFactoryTest && pkg.requestedPermissions.contains( 8500 android.Manifest.permission.FACTORY_TEST)) { 8501 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST; 8502 } 8503 8504 if (isSystemApp(pkg)) { 8505 pkgSetting.isOrphaned = true; 8506 } 8507 8508 ArrayList<PackageParser.Package> clientLibPkgs = null; 8509 8510 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 8511 if (nonMutatedPs != null) { 8512 synchronized (mPackages) { 8513 mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs); 8514 } 8515 } 8516 return pkg; 8517 } 8518 8519 // Only privileged apps and updated privileged apps can add child packages. 8520 if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) { 8521 if ((policyFlags & PARSE_IS_PRIVILEGED) == 0) { 8522 throw new PackageManagerException("Only privileged apps and updated " 8523 + "privileged apps can add child packages. Ignoring package " 8524 + pkg.packageName); 8525 } 8526 final int childCount = pkg.childPackages.size(); 8527 for (int i = 0; i < childCount; i++) { 8528 PackageParser.Package childPkg = pkg.childPackages.get(i); 8529 if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName, 8530 childPkg.packageName)) { 8531 throw new PackageManagerException("Cannot override a child package of " 8532 + "another disabled system app. Ignoring package " + pkg.packageName); 8533 } 8534 } 8535 } 8536 8537 // writer 8538 synchronized (mPackages) { 8539 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 8540 // Only system apps can add new shared libraries. 8541 if (pkg.libraryNames != null) { 8542 for (int i=0; i<pkg.libraryNames.size(); i++) { 8543 String name = pkg.libraryNames.get(i); 8544 boolean allowed = false; 8545 if (pkg.isUpdatedSystemApp()) { 8546 // New library entries can only be added through the 8547 // system image. This is important to get rid of a lot 8548 // of nasty edge cases: for example if we allowed a non- 8549 // system update of the app to add a library, then uninstalling 8550 // the update would make the library go away, and assumptions 8551 // we made such as through app install filtering would now 8552 // have allowed apps on the device which aren't compatible 8553 // with it. Better to just have the restriction here, be 8554 // conservative, and create many fewer cases that can negatively 8555 // impact the user experience. 8556 final PackageSetting sysPs = mSettings 8557 .getDisabledSystemPkgLPr(pkg.packageName); 8558 if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) { 8559 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) { 8560 if (name.equals(sysPs.pkg.libraryNames.get(j))) { 8561 allowed = true; 8562 break; 8563 } 8564 } 8565 } 8566 } else { 8567 allowed = true; 8568 } 8569 if (allowed) { 8570 if (!mSharedLibraries.containsKey(name)) { 8571 mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName)); 8572 } else if (!name.equals(pkg.packageName)) { 8573 Slog.w(TAG, "Package " + pkg.packageName + " library " 8574 + name + " already exists; skipping"); 8575 } 8576 } else { 8577 Slog.w(TAG, "Package " + pkg.packageName + " declares lib " 8578 + name + " that is not declared on system image; skipping"); 8579 } 8580 } 8581 if ((scanFlags & SCAN_BOOTING) == 0) { 8582 // If we are not booting, we need to update any applications 8583 // that are clients of our shared library. If we are booting, 8584 // this will all be done once the scan is complete. 8585 clientLibPkgs = updateAllSharedLibrariesLPw(pkg); 8586 } 8587 } 8588 } 8589 } 8590 8591 if ((scanFlags & SCAN_BOOTING) != 0) { 8592 // No apps can run during boot scan, so they don't need to be frozen 8593 } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) { 8594 // Caller asked to not kill app, so it's probably not frozen 8595 } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) { 8596 // Caller asked us to ignore frozen check for some reason; they 8597 // probably didn't know the package name 8598 } else { 8599 // We're doing major surgery on this package, so it better be frozen 8600 // right now to keep it from launching 8601 checkPackageFrozen(pkgName); 8602 } 8603 8604 // Also need to kill any apps that are dependent on the library. 8605 if (clientLibPkgs != null) { 8606 for (int i=0; i<clientLibPkgs.size(); i++) { 8607 PackageParser.Package clientPkg = clientLibPkgs.get(i); 8608 killApplication(clientPkg.applicationInfo.packageName, 8609 clientPkg.applicationInfo.uid, "update lib"); 8610 } 8611 } 8612 8613 // Make sure we're not adding any bogus keyset info 8614 KeySetManagerService ksms = mSettings.mKeySetManagerService; 8615 ksms.assertScannedPackageValid(pkg); 8616 8617 // writer 8618 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 8619 8620 boolean createIdmapFailed = false; 8621 synchronized (mPackages) { 8622 // We don't expect installation to fail beyond this point 8623 8624 if (pkgSetting.pkg != null) { 8625 // Note that |user| might be null during the initial boot scan. If a codePath 8626 // for an app has changed during a boot scan, it's due to an app update that's 8627 // part of the system partition and marker changes must be applied to all users. 8628 maybeRenameForeignDexMarkers(pkgSetting.pkg, pkg, 8629 (user != null) ? user : UserHandle.ALL); 8630 } 8631 8632 // Add the new setting to mSettings 8633 mSettings.insertPackageSettingLPw(pkgSetting, pkg); 8634 // Add the new setting to mPackages 8635 mPackages.put(pkg.applicationInfo.packageName, pkg); 8636 // Make sure we don't accidentally delete its data. 8637 final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator(); 8638 while (iter.hasNext()) { 8639 PackageCleanItem item = iter.next(); 8640 if (pkgName.equals(item.packageName)) { 8641 iter.remove(); 8642 } 8643 } 8644 8645 // Take care of first install / last update times. 8646 if (currentTime != 0) { 8647 if (pkgSetting.firstInstallTime == 0) { 8648 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime; 8649 } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) { 8650 pkgSetting.lastUpdateTime = currentTime; 8651 } 8652 } else if (pkgSetting.firstInstallTime == 0) { 8653 // We need *something*. Take time time stamp of the file. 8654 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime; 8655 } else if ((policyFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) { 8656 if (scanFileTime != pkgSetting.timeStamp) { 8657 // A package on the system image has changed; consider this 8658 // to be an update. 8659 pkgSetting.lastUpdateTime = scanFileTime; 8660 } 8661 } 8662 8663 // Add the package's KeySets to the global KeySetManagerService 8664 ksms.addScannedPackageLPw(pkg); 8665 8666 int N = pkg.providers.size(); 8667 StringBuilder r = null; 8668 int i; 8669 for (i=0; i<N; i++) { 8670 PackageParser.Provider p = pkg.providers.get(i); 8671 p.info.processName = fixProcessName(pkg.applicationInfo.processName, 8672 p.info.processName, pkg.applicationInfo.uid); 8673 mProviders.addProvider(p); 8674 p.syncable = p.info.isSyncable; 8675 if (p.info.authority != null) { 8676 String names[] = p.info.authority.split(";"); 8677 p.info.authority = null; 8678 for (int j = 0; j < names.length; j++) { 8679 if (j == 1 && p.syncable) { 8680 // We only want the first authority for a provider to possibly be 8681 // syncable, so if we already added this provider using a different 8682 // authority clear the syncable flag. We copy the provider before 8683 // changing it because the mProviders object contains a reference 8684 // to a provider that we don't want to change. 8685 // Only do this for the second authority since the resulting provider 8686 // object can be the same for all future authorities for this provider. 8687 p = new PackageParser.Provider(p); 8688 p.syncable = false; 8689 } 8690 if (!mProvidersByAuthority.containsKey(names[j])) { 8691 mProvidersByAuthority.put(names[j], p); 8692 if (p.info.authority == null) { 8693 p.info.authority = names[j]; 8694 } else { 8695 p.info.authority = p.info.authority + ";" + names[j]; 8696 } 8697 if (DEBUG_PACKAGE_SCANNING) { 8698 if ((policyFlags & PackageParser.PARSE_CHATTY) != 0) 8699 Log.d(TAG, "Registered content provider: " + names[j] 8700 + ", className = " + p.info.name + ", isSyncable = " 8701 + p.info.isSyncable); 8702 } 8703 } else { 8704 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 8705 Slog.w(TAG, "Skipping provider name " + names[j] + 8706 " (in package " + pkg.applicationInfo.packageName + 8707 "): name already used by " 8708 + ((other != null && other.getComponentName() != null) 8709 ? other.getComponentName().getPackageName() : "?")); 8710 } 8711 } 8712 } 8713 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) { 8714 if (r == null) { 8715 r = new StringBuilder(256); 8716 } else { 8717 r.append(' '); 8718 } 8719 r.append(p.info.name); 8720 } 8721 } 8722 if (r != null) { 8723 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r); 8724 } 8725 8726 N = pkg.services.size(); 8727 r = null; 8728 for (i=0; i<N; i++) { 8729 PackageParser.Service s = pkg.services.get(i); 8730 s.info.processName = fixProcessName(pkg.applicationInfo.processName, 8731 s.info.processName, pkg.applicationInfo.uid); 8732 mServices.addService(s); 8733 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) { 8734 if (r == null) { 8735 r = new StringBuilder(256); 8736 } else { 8737 r.append(' '); 8738 } 8739 r.append(s.info.name); 8740 } 8741 } 8742 if (r != null) { 8743 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r); 8744 } 8745 8746 N = pkg.receivers.size(); 8747 r = null; 8748 for (i=0; i<N; i++) { 8749 PackageParser.Activity a = pkg.receivers.get(i); 8750 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 8751 a.info.processName, pkg.applicationInfo.uid); 8752 mReceivers.addActivity(a, "receiver"); 8753 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) { 8754 if (r == null) { 8755 r = new StringBuilder(256); 8756 } else { 8757 r.append(' '); 8758 } 8759 r.append(a.info.name); 8760 } 8761 } 8762 if (r != null) { 8763 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r); 8764 } 8765 8766 N = pkg.activities.size(); 8767 r = null; 8768 for (i=0; i<N; i++) { 8769 PackageParser.Activity a = pkg.activities.get(i); 8770 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 8771 a.info.processName, pkg.applicationInfo.uid); 8772 mActivities.addActivity(a, "activity"); 8773 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) { 8774 if (r == null) { 8775 r = new StringBuilder(256); 8776 } else { 8777 r.append(' '); 8778 } 8779 r.append(a.info.name); 8780 } 8781 } 8782 if (r != null) { 8783 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r); 8784 } 8785 8786 N = pkg.permissionGroups.size(); 8787 r = null; 8788 for (i=0; i<N; i++) { 8789 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i); 8790 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name); 8791 final String curPackageName = cur == null ? null : cur.info.packageName; 8792 final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName); 8793 if (cur == null || isPackageUpdate) { 8794 mPermissionGroups.put(pg.info.name, pg); 8795 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) { 8796 if (r == null) { 8797 r = new StringBuilder(256); 8798 } else { 8799 r.append(' '); 8800 } 8801 if (isPackageUpdate) { 8802 r.append("UPD:"); 8803 } 8804 r.append(pg.info.name); 8805 } 8806 } else { 8807 Slog.w(TAG, "Permission group " + pg.info.name + " from package " 8808 + pg.info.packageName + " ignored: original from " 8809 + cur.info.packageName); 8810 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) { 8811 if (r == null) { 8812 r = new StringBuilder(256); 8813 } else { 8814 r.append(' '); 8815 } 8816 r.append("DUP:"); 8817 r.append(pg.info.name); 8818 } 8819 } 8820 } 8821 if (r != null) { 8822 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permission Groups: " + r); 8823 } 8824 8825 N = pkg.permissions.size(); 8826 r = null; 8827 for (i=0; i<N; i++) { 8828 PackageParser.Permission p = pkg.permissions.get(i); 8829 8830 // Assume by default that we did not install this permission into the system. 8831 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED; 8832 8833 // Now that permission groups have a special meaning, we ignore permission 8834 // groups for legacy apps to prevent unexpected behavior. In particular, 8835 // permissions for one app being granted to someone just becase they happen 8836 // to be in a group defined by another app (before this had no implications). 8837 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) { 8838 p.group = mPermissionGroups.get(p.info.group); 8839 // Warn for a permission in an unknown group. 8840 if (p.info.group != null && p.group == null) { 8841 Slog.w(TAG, "Permission " + p.info.name + " from package " 8842 + p.info.packageName + " in an unknown group " + p.info.group); 8843 } 8844 } 8845 8846 ArrayMap<String, BasePermission> permissionMap = 8847 p.tree ? mSettings.mPermissionTrees 8848 : mSettings.mPermissions; 8849 BasePermission bp = permissionMap.get(p.info.name); 8850 8851 // Allow system apps to redefine non-system permissions 8852 if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) { 8853 final boolean currentOwnerIsSystem = (bp.perm != null 8854 && isSystemApp(bp.perm.owner)); 8855 if (isSystemApp(p.owner)) { 8856 if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) { 8857 // It's a built-in permission and no owner, take ownership now 8858 bp.packageSetting = pkgSetting; 8859 bp.perm = p; 8860 bp.uid = pkg.applicationInfo.uid; 8861 bp.sourcePackage = p.info.packageName; 8862 p.info.flags |= PermissionInfo.FLAG_INSTALLED; 8863 } else if (!currentOwnerIsSystem) { 8864 String msg = "New decl " + p.owner + " of permission " 8865 + p.info.name + " is system; overriding " + bp.sourcePackage; 8866 reportSettingsProblem(Log.WARN, msg); 8867 bp = null; 8868 } 8869 } 8870 } 8871 8872 if (bp == null) { 8873 bp = new BasePermission(p.info.name, p.info.packageName, 8874 BasePermission.TYPE_NORMAL); 8875 permissionMap.put(p.info.name, bp); 8876 } 8877 8878 if (bp.perm == null) { 8879 if (bp.sourcePackage == null 8880 || bp.sourcePackage.equals(p.info.packageName)) { 8881 BasePermission tree = findPermissionTreeLP(p.info.name); 8882 if (tree == null 8883 || tree.sourcePackage.equals(p.info.packageName)) { 8884 bp.packageSetting = pkgSetting; 8885 bp.perm = p; 8886 bp.uid = pkg.applicationInfo.uid; 8887 bp.sourcePackage = p.info.packageName; 8888 p.info.flags |= PermissionInfo.FLAG_INSTALLED; 8889 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) { 8890 if (r == null) { 8891 r = new StringBuilder(256); 8892 } else { 8893 r.append(' '); 8894 } 8895 r.append(p.info.name); 8896 } 8897 } else { 8898 Slog.w(TAG, "Permission " + p.info.name + " from package " 8899 + p.info.packageName + " ignored: base tree " 8900 + tree.name + " is from package " 8901 + tree.sourcePackage); 8902 } 8903 } else { 8904 Slog.w(TAG, "Permission " + p.info.name + " from package " 8905 + p.info.packageName + " ignored: original from " 8906 + bp.sourcePackage); 8907 } 8908 } else if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) { 8909 if (r == null) { 8910 r = new StringBuilder(256); 8911 } else { 8912 r.append(' '); 8913 } 8914 r.append("DUP:"); 8915 r.append(p.info.name); 8916 } 8917 if (bp.perm == p) { 8918 bp.protectionLevel = p.info.protectionLevel; 8919 } 8920 } 8921 8922 if (r != null) { 8923 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permissions: " + r); 8924 } 8925 8926 N = pkg.instrumentation.size(); 8927 r = null; 8928 for (i=0; i<N; i++) { 8929 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 8930 a.info.packageName = pkg.applicationInfo.packageName; 8931 a.info.sourceDir = pkg.applicationInfo.sourceDir; 8932 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir; 8933 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs; 8934 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs; 8935 a.info.dataDir = pkg.applicationInfo.dataDir; 8936 a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir; 8937 a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir; 8938 8939 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir; 8940 a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir; 8941 mInstrumentation.put(a.getComponentName(), a); 8942 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) { 8943 if (r == null) { 8944 r = new StringBuilder(256); 8945 } else { 8946 r.append(' '); 8947 } 8948 r.append(a.info.name); 8949 } 8950 } 8951 if (r != null) { 8952 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r); 8953 } 8954 8955 if (pkg.protectedBroadcasts != null) { 8956 N = pkg.protectedBroadcasts.size(); 8957 for (i=0; i<N; i++) { 8958 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i)); 8959 } 8960 } 8961 8962 pkgSetting.setTimeStamp(scanFileTime); 8963 8964 // Create idmap files for pairs of (packages, overlay packages). 8965 // Note: "android", ie framework-res.apk, is handled by native layers. 8966 if (pkg.mOverlayTarget != null) { 8967 // This is an overlay package. 8968 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) { 8969 if (!mOverlays.containsKey(pkg.mOverlayTarget)) { 8970 mOverlays.put(pkg.mOverlayTarget, 8971 new ArrayMap<String, PackageParser.Package>()); 8972 } 8973 ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget); 8974 map.put(pkg.packageName, pkg); 8975 PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget); 8976 if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) { 8977 createIdmapFailed = true; 8978 } 8979 } 8980 } else if (mOverlays.containsKey(pkg.packageName) && 8981 !pkg.packageName.equals("android")) { 8982 // This is a regular package, with one or more known overlay packages. 8983 createIdmapsForPackageLI(pkg); 8984 } 8985 } 8986 8987 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 8988 8989 if (createIdmapFailed) { 8990 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 8991 "scanPackageLI failed to createIdmap"); 8992 } 8993 return pkg; 8994 } 8995 8996 private void maybeRenameForeignDexMarkers(PackageParser.Package existing, 8997 PackageParser.Package update, UserHandle user) { 8998 if (existing.applicationInfo == null || update.applicationInfo == null) { 8999 // This isn't due to an app installation. 9000 return; 9001 } 9002 9003 final File oldCodePath = new File(existing.applicationInfo.getCodePath()); 9004 final File newCodePath = new File(update.applicationInfo.getCodePath()); 9005 9006 // The codePath hasn't changed, so there's nothing for us to do. 9007 if (Objects.equals(oldCodePath, newCodePath)) { 9008 return; 9009 } 9010 9011 File canonicalNewCodePath; 9012 try { 9013 canonicalNewCodePath = new File(PackageManagerServiceUtils.realpath(newCodePath)); 9014 } catch (IOException e) { 9015 Slog.w(TAG, "Failed to get canonical path.", e); 9016 return; 9017 } 9018 9019 // This is a bit of a hack. The oldCodePath doesn't exist at this point (because 9020 // we've already renamed / deleted it) so we cannot call realpath on it. Here we assume 9021 // that the last component of the path (i.e, the name) doesn't need canonicalization 9022 // (i.e, that it isn't ".", ".." or a symbolic link). This is a valid assumption for now 9023 // but may change in the future. Hopefully this function won't exist at that point. 9024 final File canonicalOldCodePath = new File(canonicalNewCodePath.getParentFile(), 9025 oldCodePath.getName()); 9026 9027 // Calculate the prefixes of the markers. These are just the paths with "/" replaced 9028 // with "@". 9029 String oldMarkerPrefix = canonicalOldCodePath.getAbsolutePath().replace('/', '@'); 9030 if (!oldMarkerPrefix.endsWith("@")) { 9031 oldMarkerPrefix += "@"; 9032 } 9033 String newMarkerPrefix = canonicalNewCodePath.getAbsolutePath().replace('/', '@'); 9034 if (!newMarkerPrefix.endsWith("@")) { 9035 newMarkerPrefix += "@"; 9036 } 9037 9038 List<String> updatedPaths = update.getAllCodePathsExcludingResourceOnly(); 9039 List<String> markerSuffixes = new ArrayList<String>(updatedPaths.size()); 9040 for (String updatedPath : updatedPaths) { 9041 String updatedPathName = new File(updatedPath).getName(); 9042 markerSuffixes.add(updatedPathName.replace('/', '@')); 9043 } 9044 9045 for (int userId : resolveUserIds(user.getIdentifier())) { 9046 File profileDir = Environment.getDataProfilesDeForeignDexDirectory(userId); 9047 9048 for (String markerSuffix : markerSuffixes) { 9049 File oldForeignUseMark = new File(profileDir, oldMarkerPrefix + markerSuffix); 9050 File newForeignUseMark = new File(profileDir, newMarkerPrefix + markerSuffix); 9051 if (oldForeignUseMark.exists()) { 9052 try { 9053 Os.rename(oldForeignUseMark.getAbsolutePath(), 9054 newForeignUseMark.getAbsolutePath()); 9055 } catch (ErrnoException e) { 9056 Slog.w(TAG, "Failed to rename foreign use marker", e); 9057 oldForeignUseMark.delete(); 9058 } 9059 } 9060 } 9061 } 9062 } 9063 9064 /** 9065 * Derive the ABI of a non-system package located at {@code scanFile}. This information 9066 * is derived purely on the basis of the contents of {@code scanFile} and 9067 * {@code cpuAbiOverride}. 9068 * 9069 * If {@code extractLibs} is true, native libraries are extracted from the app if required. 9070 */ 9071 private void derivePackageAbi(PackageParser.Package pkg, File scanFile, 9072 String cpuAbiOverride, boolean extractLibs) 9073 throws PackageManagerException { 9074 // TODO: We can probably be smarter about this stuff. For installed apps, 9075 // we can calculate this information at install time once and for all. For 9076 // system apps, we can probably assume that this information doesn't change 9077 // after the first boot scan. As things stand, we do lots of unnecessary work. 9078 9079 // Give ourselves some initial paths; we'll come back for another 9080 // pass once we've determined ABI below. 9081 setNativeLibraryPaths(pkg); 9082 9083 // We would never need to extract libs for forward-locked and external packages, 9084 // since the container service will do it for us. We shouldn't attempt to 9085 // extract libs from system app when it was not updated. 9086 if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() || 9087 (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) { 9088 extractLibs = false; 9089 } 9090 9091 final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir; 9092 final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa; 9093 9094 NativeLibraryHelper.Handle handle = null; 9095 try { 9096 handle = NativeLibraryHelper.Handle.create(pkg); 9097 // TODO(multiArch): This can be null for apps that didn't go through the 9098 // usual installation process. We can calculate it again, like we 9099 // do during install time. 9100 // 9101 // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally 9102 // unnecessary. 9103 final File nativeLibraryRoot = new File(nativeLibraryRootStr); 9104 9105 // Null out the abis so that they can be recalculated. 9106 pkg.applicationInfo.primaryCpuAbi = null; 9107 pkg.applicationInfo.secondaryCpuAbi = null; 9108 if (isMultiArch(pkg.applicationInfo)) { 9109 // Warn if we've set an abiOverride for multi-lib packages.. 9110 // By definition, we need to copy both 32 and 64 bit libraries for 9111 // such packages. 9112 if (pkg.cpuAbiOverride != null 9113 && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) { 9114 Slog.w(TAG, "Ignoring abiOverride for multi arch application."); 9115 } 9116 9117 int abi32 = PackageManager.NO_NATIVE_LIBRARIES; 9118 int abi64 = PackageManager.NO_NATIVE_LIBRARIES; 9119 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) { 9120 if (extractLibs) { 9121 abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 9122 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS, 9123 useIsaSpecificSubdirs); 9124 } else { 9125 abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS); 9126 } 9127 } 9128 9129 maybeThrowExceptionForMultiArchCopy( 9130 "Error unpackaging 32 bit native libs for multiarch app.", abi32); 9131 9132 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) { 9133 if (extractLibs) { 9134 abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 9135 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS, 9136 useIsaSpecificSubdirs); 9137 } else { 9138 abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS); 9139 } 9140 } 9141 9142 maybeThrowExceptionForMultiArchCopy( 9143 "Error unpackaging 64 bit native libs for multiarch app.", abi64); 9144 9145 if (abi64 >= 0) { 9146 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64]; 9147 } 9148 9149 if (abi32 >= 0) { 9150 final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32]; 9151 if (abi64 >= 0) { 9152 if (pkg.use32bitAbi) { 9153 pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi; 9154 pkg.applicationInfo.primaryCpuAbi = abi; 9155 } else { 9156 pkg.applicationInfo.secondaryCpuAbi = abi; 9157 } 9158 } else { 9159 pkg.applicationInfo.primaryCpuAbi = abi; 9160 } 9161 } 9162 9163 } else { 9164 String[] abiList = (cpuAbiOverride != null) ? 9165 new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS; 9166 9167 // Enable gross and lame hacks for apps that are built with old 9168 // SDK tools. We must scan their APKs for renderscript bitcode and 9169 // not launch them if it's present. Don't bother checking on devices 9170 // that don't have 64 bit support. 9171 boolean needsRenderScriptOverride = false; 9172 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null && 9173 NativeLibraryHelper.hasRenderscriptBitcode(handle)) { 9174 abiList = Build.SUPPORTED_32_BIT_ABIS; 9175 needsRenderScriptOverride = true; 9176 } 9177 9178 final int copyRet; 9179 if (extractLibs) { 9180 copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 9181 nativeLibraryRoot, abiList, useIsaSpecificSubdirs); 9182 } else { 9183 copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList); 9184 } 9185 9186 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { 9187 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, 9188 "Error unpackaging native libs for app, errorCode=" + copyRet); 9189 } 9190 9191 if (copyRet >= 0) { 9192 pkg.applicationInfo.primaryCpuAbi = abiList[copyRet]; 9193 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) { 9194 pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride; 9195 } else if (needsRenderScriptOverride) { 9196 pkg.applicationInfo.primaryCpuAbi = abiList[0]; 9197 } 9198 } 9199 } catch (IOException ioe) { 9200 Slog.e(TAG, "Unable to get canonical file " + ioe.toString()); 9201 } finally { 9202 IoUtils.closeQuietly(handle); 9203 } 9204 9205 // Now that we've calculated the ABIs and determined if it's an internal app, 9206 // we will go ahead and populate the nativeLibraryPath. 9207 setNativeLibraryPaths(pkg); 9208 } 9209 9210 /** 9211 * Adjusts ABIs for a set of packages belonging to a shared user so that they all match. 9212 * i.e, so that all packages can be run inside a single process if required. 9213 * 9214 * Optionally, callers can pass in a parsed package via {@code newPackage} in which case 9215 * this function will either try and make the ABI for all packages in {@code packagesForUser} 9216 * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match 9217 * the ABI selected for {@code packagesForUser}. This variant is used when installing or 9218 * updating a package that belongs to a shared user. 9219 * 9220 * NOTE: We currently only match for the primary CPU abi string. Matching the secondary 9221 * adds unnecessary complexity. 9222 */ 9223 private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser, 9224 PackageParser.Package scannedPackage, boolean bootComplete) { 9225 String requiredInstructionSet = null; 9226 if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) { 9227 requiredInstructionSet = VMRuntime.getInstructionSet( 9228 scannedPackage.applicationInfo.primaryCpuAbi); 9229 } 9230 9231 PackageSetting requirer = null; 9232 for (PackageSetting ps : packagesForUser) { 9233 // If packagesForUser contains scannedPackage, we skip it. This will happen 9234 // when scannedPackage is an update of an existing package. Without this check, 9235 // we will never be able to change the ABI of any package belonging to a shared 9236 // user, even if it's compatible with other packages. 9237 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 9238 if (ps.primaryCpuAbiString == null) { 9239 continue; 9240 } 9241 9242 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString); 9243 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) { 9244 // We have a mismatch between instruction sets (say arm vs arm64) warn about 9245 // this but there's not much we can do. 9246 String errorMessage = "Instruction set mismatch, " 9247 + ((requirer == null) ? "[caller]" : requirer) 9248 + " requires " + requiredInstructionSet + " whereas " + ps 9249 + " requires " + instructionSet; 9250 Slog.w(TAG, errorMessage); 9251 } 9252 9253 if (requiredInstructionSet == null) { 9254 requiredInstructionSet = instructionSet; 9255 requirer = ps; 9256 } 9257 } 9258 } 9259 9260 if (requiredInstructionSet != null) { 9261 String adjustedAbi; 9262 if (requirer != null) { 9263 // requirer != null implies that either scannedPackage was null or that scannedPackage 9264 // did not require an ABI, in which case we have to adjust scannedPackage to match 9265 // the ABI of the set (which is the same as requirer's ABI) 9266 adjustedAbi = requirer.primaryCpuAbiString; 9267 if (scannedPackage != null) { 9268 scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi; 9269 } 9270 } else { 9271 // requirer == null implies that we're updating all ABIs in the set to 9272 // match scannedPackage. 9273 adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi; 9274 } 9275 9276 for (PackageSetting ps : packagesForUser) { 9277 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 9278 if (ps.primaryCpuAbiString != null) { 9279 continue; 9280 } 9281 9282 ps.primaryCpuAbiString = adjustedAbi; 9283 if (ps.pkg != null && ps.pkg.applicationInfo != null && 9284 !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) { 9285 ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi; 9286 Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi 9287 + " (requirer=" 9288 + (requirer == null ? "null" : requirer.pkg.packageName) 9289 + ", scannedPackage=" 9290 + (scannedPackage != null ? scannedPackage.packageName : "null") 9291 + ")"); 9292 try { 9293 mInstaller.rmdex(ps.codePathString, 9294 getDexCodeInstructionSet(getPreferredInstructionSet())); 9295 } catch (InstallerException ignored) { 9296 } 9297 } 9298 } 9299 } 9300 } 9301 } 9302 9303 private void setUpCustomResolverActivity(PackageParser.Package pkg) { 9304 synchronized (mPackages) { 9305 mResolverReplaced = true; 9306 // Set up information for custom user intent resolution activity. 9307 mResolveActivity.applicationInfo = pkg.applicationInfo; 9308 mResolveActivity.name = mCustomResolverComponentName.getClassName(); 9309 mResolveActivity.packageName = pkg.applicationInfo.packageName; 9310 mResolveActivity.processName = pkg.applicationInfo.packageName; 9311 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 9312 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS | 9313 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 9314 mResolveActivity.theme = 0; 9315 mResolveActivity.exported = true; 9316 mResolveActivity.enabled = true; 9317 mResolveInfo.activityInfo = mResolveActivity; 9318 mResolveInfo.priority = 0; 9319 mResolveInfo.preferredOrder = 0; 9320 mResolveInfo.match = 0; 9321 mResolveComponentName = mCustomResolverComponentName; 9322 Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " + 9323 mResolveComponentName); 9324 } 9325 } 9326 9327 private void setUpEphemeralInstallerActivityLP(ComponentName installerComponent) { 9328 final PackageParser.Package pkg = mPackages.get(installerComponent.getPackageName()); 9329 9330 // Set up information for ephemeral installer activity 9331 mEphemeralInstallerActivity.applicationInfo = pkg.applicationInfo; 9332 mEphemeralInstallerActivity.name = mEphemeralInstallerComponent.getClassName(); 9333 mEphemeralInstallerActivity.packageName = pkg.applicationInfo.packageName; 9334 mEphemeralInstallerActivity.processName = pkg.applicationInfo.packageName; 9335 mEphemeralInstallerActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 9336 mEphemeralInstallerActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS 9337 | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 9338 mEphemeralInstallerActivity.theme = 0; 9339 mEphemeralInstallerActivity.exported = true; 9340 mEphemeralInstallerActivity.enabled = true; 9341 mEphemeralInstallerInfo.activityInfo = mEphemeralInstallerActivity; 9342 mEphemeralInstallerInfo.priority = 0; 9343 mEphemeralInstallerInfo.preferredOrder = 1; 9344 mEphemeralInstallerInfo.isDefault = true; 9345 mEphemeralInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART 9346 | IntentFilter.MATCH_ADJUSTMENT_NORMAL; 9347 9348 if (DEBUG_EPHEMERAL) { 9349 Slog.d(TAG, "Set ephemeral installer activity: " + mEphemeralInstallerComponent); 9350 } 9351 } 9352 9353 private static String calculateBundledApkRoot(final String codePathString) { 9354 final File codePath = new File(codePathString); 9355 final File codeRoot; 9356 if (FileUtils.contains(Environment.getRootDirectory(), codePath)) { 9357 codeRoot = Environment.getRootDirectory(); 9358 } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) { 9359 codeRoot = Environment.getOemDirectory(); 9360 } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) { 9361 codeRoot = Environment.getVendorDirectory(); 9362 } else { 9363 // Unrecognized code path; take its top real segment as the apk root: 9364 // e.g. /something/app/blah.apk => /something 9365 try { 9366 File f = codePath.getCanonicalFile(); 9367 File parent = f.getParentFile(); // non-null because codePath is a file 9368 File tmp; 9369 while ((tmp = parent.getParentFile()) != null) { 9370 f = parent; 9371 parent = tmp; 9372 } 9373 codeRoot = f; 9374 Slog.w(TAG, "Unrecognized code path " 9375 + codePath + " - using " + codeRoot); 9376 } catch (IOException e) { 9377 // Can't canonicalize the code path -- shenanigans? 9378 Slog.w(TAG, "Can't canonicalize code path " + codePath); 9379 return Environment.getRootDirectory().getPath(); 9380 } 9381 } 9382 return codeRoot.getPath(); 9383 } 9384 9385 /** 9386 * Derive and set the location of native libraries for the given package, 9387 * which varies depending on where and how the package was installed. 9388 */ 9389 private void setNativeLibraryPaths(PackageParser.Package pkg) { 9390 final ApplicationInfo info = pkg.applicationInfo; 9391 final String codePath = pkg.codePath; 9392 final File codeFile = new File(codePath); 9393 final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp(); 9394 final boolean asecApp = info.isForwardLocked() || info.isExternalAsec(); 9395 9396 info.nativeLibraryRootDir = null; 9397 info.nativeLibraryRootRequiresIsa = false; 9398 info.nativeLibraryDir = null; 9399 info.secondaryNativeLibraryDir = null; 9400 9401 if (isApkFile(codeFile)) { 9402 // Monolithic install 9403 if (bundledApp) { 9404 // If "/system/lib64/apkname" exists, assume that is the per-package 9405 // native library directory to use; otherwise use "/system/lib/apkname". 9406 final String apkRoot = calculateBundledApkRoot(info.sourceDir); 9407 final boolean is64Bit = VMRuntime.is64BitInstructionSet( 9408 getPrimaryInstructionSet(info)); 9409 9410 // This is a bundled system app so choose the path based on the ABI. 9411 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this 9412 // is just the default path. 9413 final String apkName = deriveCodePathName(codePath); 9414 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME; 9415 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir, 9416 apkName).getAbsolutePath(); 9417 9418 if (info.secondaryCpuAbi != null) { 9419 final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME; 9420 info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot), 9421 secondaryLibDir, apkName).getAbsolutePath(); 9422 } 9423 } else if (asecApp) { 9424 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME) 9425 .getAbsolutePath(); 9426 } else { 9427 final String apkName = deriveCodePathName(codePath); 9428 info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName) 9429 .getAbsolutePath(); 9430 } 9431 9432 info.nativeLibraryRootRequiresIsa = false; 9433 info.nativeLibraryDir = info.nativeLibraryRootDir; 9434 } else { 9435 // Cluster install 9436 info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath(); 9437 info.nativeLibraryRootRequiresIsa = true; 9438 9439 info.nativeLibraryDir = new File(info.nativeLibraryRootDir, 9440 getPrimaryInstructionSet(info)).getAbsolutePath(); 9441 9442 if (info.secondaryCpuAbi != null) { 9443 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir, 9444 VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath(); 9445 } 9446 } 9447 } 9448 9449 /** 9450 * Calculate the abis and roots for a bundled app. These can uniquely 9451 * be determined from the contents of the system partition, i.e whether 9452 * it contains 64 or 32 bit shared libraries etc. We do not validate any 9453 * of this information, and instead assume that the system was built 9454 * sensibly. 9455 */ 9456 private void setBundledAppAbisAndRoots(PackageParser.Package pkg, 9457 PackageSetting pkgSetting) { 9458 final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath()); 9459 9460 // If "/system/lib64/apkname" exists, assume that is the per-package 9461 // native library directory to use; otherwise use "/system/lib/apkname". 9462 final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir); 9463 setBundledAppAbi(pkg, apkRoot, apkName); 9464 // pkgSetting might be null during rescan following uninstall of updates 9465 // to a bundled app, so accommodate that possibility. The settings in 9466 // that case will be established later from the parsed package. 9467 // 9468 // If the settings aren't null, sync them up with what we've just derived. 9469 // note that apkRoot isn't stored in the package settings. 9470 if (pkgSetting != null) { 9471 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 9472 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 9473 } 9474 } 9475 9476 /** 9477 * Deduces the ABI of a bundled app and sets the relevant fields on the 9478 * parsed pkg object. 9479 * 9480 * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem} 9481 * under which system libraries are installed. 9482 * @param apkName the name of the installed package. 9483 */ 9484 private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) { 9485 final File codeFile = new File(pkg.codePath); 9486 9487 final boolean has64BitLibs; 9488 final boolean has32BitLibs; 9489 if (isApkFile(codeFile)) { 9490 // Monolithic install 9491 has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists(); 9492 has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists(); 9493 } else { 9494 // Cluster install 9495 final File rootDir = new File(codeFile, LIB_DIR_NAME); 9496 if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS) 9497 && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) { 9498 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]); 9499 has64BitLibs = (new File(rootDir, isa)).exists(); 9500 } else { 9501 has64BitLibs = false; 9502 } 9503 if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS) 9504 && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) { 9505 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]); 9506 has32BitLibs = (new File(rootDir, isa)).exists(); 9507 } else { 9508 has32BitLibs = false; 9509 } 9510 } 9511 9512 if (has64BitLibs && !has32BitLibs) { 9513 // The package has 64 bit libs, but not 32 bit libs. Its primary 9514 // ABI should be 64 bit. We can safely assume here that the bundled 9515 // native libraries correspond to the most preferred ABI in the list. 9516 9517 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 9518 pkg.applicationInfo.secondaryCpuAbi = null; 9519 } else if (has32BitLibs && !has64BitLibs) { 9520 // The package has 32 bit libs but not 64 bit libs. Its primary 9521 // ABI should be 32 bit. 9522 9523 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 9524 pkg.applicationInfo.secondaryCpuAbi = null; 9525 } else if (has32BitLibs && has64BitLibs) { 9526 // The application has both 64 and 32 bit bundled libraries. We check 9527 // here that the app declares multiArch support, and warn if it doesn't. 9528 // 9529 // We will be lenient here and record both ABIs. The primary will be the 9530 // ABI that's higher on the list, i.e, a device that's configured to prefer 9531 // 64 bit apps will see a 64 bit primary ABI, 9532 9533 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) { 9534 Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch."); 9535 } 9536 9537 if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) { 9538 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 9539 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 9540 } else { 9541 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 9542 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 9543 } 9544 } else { 9545 pkg.applicationInfo.primaryCpuAbi = null; 9546 pkg.applicationInfo.secondaryCpuAbi = null; 9547 } 9548 } 9549 9550 private void killApplication(String pkgName, int appId, String reason) { 9551 killApplication(pkgName, appId, UserHandle.USER_ALL, reason); 9552 } 9553 9554 private void killApplication(String pkgName, int appId, int userId, String reason) { 9555 // Request the ActivityManager to kill the process(only for existing packages) 9556 // so that we do not end up in a confused state while the user is still using the older 9557 // version of the application while the new one gets installed. 9558 final long token = Binder.clearCallingIdentity(); 9559 try { 9560 IActivityManager am = ActivityManagerNative.getDefault(); 9561 if (am != null) { 9562 try { 9563 am.killApplication(pkgName, appId, userId, reason); 9564 } catch (RemoteException e) { 9565 } 9566 } 9567 } finally { 9568 Binder.restoreCallingIdentity(token); 9569 } 9570 } 9571 9572 private void removePackageLI(PackageParser.Package pkg, boolean chatty) { 9573 // Remove the parent package setting 9574 PackageSetting ps = (PackageSetting) pkg.mExtras; 9575 if (ps != null) { 9576 removePackageLI(ps, chatty); 9577 } 9578 // Remove the child package setting 9579 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 9580 for (int i = 0; i < childCount; i++) { 9581 PackageParser.Package childPkg = pkg.childPackages.get(i); 9582 ps = (PackageSetting) childPkg.mExtras; 9583 if (ps != null) { 9584 removePackageLI(ps, chatty); 9585 } 9586 } 9587 } 9588 9589 void removePackageLI(PackageSetting ps, boolean chatty) { 9590 if (DEBUG_INSTALL) { 9591 if (chatty) 9592 Log.d(TAG, "Removing package " + ps.name); 9593 } 9594 9595 // writer 9596 synchronized (mPackages) { 9597 mPackages.remove(ps.name); 9598 final PackageParser.Package pkg = ps.pkg; 9599 if (pkg != null) { 9600 cleanPackageDataStructuresLILPw(pkg, chatty); 9601 } 9602 } 9603 } 9604 9605 void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) { 9606 if (DEBUG_INSTALL) { 9607 if (chatty) 9608 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName); 9609 } 9610 9611 // writer 9612 synchronized (mPackages) { 9613 // Remove the parent package 9614 mPackages.remove(pkg.applicationInfo.packageName); 9615 cleanPackageDataStructuresLILPw(pkg, chatty); 9616 9617 // Remove the child packages 9618 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 9619 for (int i = 0; i < childCount; i++) { 9620 PackageParser.Package childPkg = pkg.childPackages.get(i); 9621 mPackages.remove(childPkg.applicationInfo.packageName); 9622 cleanPackageDataStructuresLILPw(childPkg, chatty); 9623 } 9624 } 9625 } 9626 9627 void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) { 9628 int N = pkg.providers.size(); 9629 StringBuilder r = null; 9630 int i; 9631 for (i=0; i<N; i++) { 9632 PackageParser.Provider p = pkg.providers.get(i); 9633 mProviders.removeProvider(p); 9634 if (p.info.authority == null) { 9635 9636 /* There was another ContentProvider with this authority when 9637 * this app was installed so this authority is null, 9638 * Ignore it as we don't have to unregister the provider. 9639 */ 9640 continue; 9641 } 9642 String names[] = p.info.authority.split(";"); 9643 for (int j = 0; j < names.length; j++) { 9644 if (mProvidersByAuthority.get(names[j]) == p) { 9645 mProvidersByAuthority.remove(names[j]); 9646 if (DEBUG_REMOVE) { 9647 if (chatty) 9648 Log.d(TAG, "Unregistered content provider: " + names[j] 9649 + ", className = " + p.info.name + ", isSyncable = " 9650 + p.info.isSyncable); 9651 } 9652 } 9653 } 9654 if (DEBUG_REMOVE && chatty) { 9655 if (r == null) { 9656 r = new StringBuilder(256); 9657 } else { 9658 r.append(' '); 9659 } 9660 r.append(p.info.name); 9661 } 9662 } 9663 if (r != null) { 9664 if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r); 9665 } 9666 9667 N = pkg.services.size(); 9668 r = null; 9669 for (i=0; i<N; i++) { 9670 PackageParser.Service s = pkg.services.get(i); 9671 mServices.removeService(s); 9672 if (chatty) { 9673 if (r == null) { 9674 r = new StringBuilder(256); 9675 } else { 9676 r.append(' '); 9677 } 9678 r.append(s.info.name); 9679 } 9680 } 9681 if (r != null) { 9682 if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r); 9683 } 9684 9685 N = pkg.receivers.size(); 9686 r = null; 9687 for (i=0; i<N; i++) { 9688 PackageParser.Activity a = pkg.receivers.get(i); 9689 mReceivers.removeActivity(a, "receiver"); 9690 if (DEBUG_REMOVE && chatty) { 9691 if (r == null) { 9692 r = new StringBuilder(256); 9693 } else { 9694 r.append(' '); 9695 } 9696 r.append(a.info.name); 9697 } 9698 } 9699 if (r != null) { 9700 if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r); 9701 } 9702 9703 N = pkg.activities.size(); 9704 r = null; 9705 for (i=0; i<N; i++) { 9706 PackageParser.Activity a = pkg.activities.get(i); 9707 mActivities.removeActivity(a, "activity"); 9708 if (DEBUG_REMOVE && chatty) { 9709 if (r == null) { 9710 r = new StringBuilder(256); 9711 } else { 9712 r.append(' '); 9713 } 9714 r.append(a.info.name); 9715 } 9716 } 9717 if (r != null) { 9718 if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r); 9719 } 9720 9721 N = pkg.permissions.size(); 9722 r = null; 9723 for (i=0; i<N; i++) { 9724 PackageParser.Permission p = pkg.permissions.get(i); 9725 BasePermission bp = mSettings.mPermissions.get(p.info.name); 9726 if (bp == null) { 9727 bp = mSettings.mPermissionTrees.get(p.info.name); 9728 } 9729 if (bp != null && bp.perm == p) { 9730 bp.perm = null; 9731 if (DEBUG_REMOVE && chatty) { 9732 if (r == null) { 9733 r = new StringBuilder(256); 9734 } else { 9735 r.append(' '); 9736 } 9737 r.append(p.info.name); 9738 } 9739 } 9740 if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 9741 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name); 9742 if (appOpPkgs != null) { 9743 appOpPkgs.remove(pkg.packageName); 9744 } 9745 } 9746 } 9747 if (r != null) { 9748 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 9749 } 9750 9751 N = pkg.requestedPermissions.size(); 9752 r = null; 9753 for (i=0; i<N; i++) { 9754 String perm = pkg.requestedPermissions.get(i); 9755 BasePermission bp = mSettings.mPermissions.get(perm); 9756 if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 9757 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm); 9758 if (appOpPkgs != null) { 9759 appOpPkgs.remove(pkg.packageName); 9760 if (appOpPkgs.isEmpty()) { 9761 mAppOpPermissionPackages.remove(perm); 9762 } 9763 } 9764 } 9765 } 9766 if (r != null) { 9767 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 9768 } 9769 9770 N = pkg.instrumentation.size(); 9771 r = null; 9772 for (i=0; i<N; i++) { 9773 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 9774 mInstrumentation.remove(a.getComponentName()); 9775 if (DEBUG_REMOVE && chatty) { 9776 if (r == null) { 9777 r = new StringBuilder(256); 9778 } else { 9779 r.append(' '); 9780 } 9781 r.append(a.info.name); 9782 } 9783 } 9784 if (r != null) { 9785 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r); 9786 } 9787 9788 r = null; 9789 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9790 // Only system apps can hold shared libraries. 9791 if (pkg.libraryNames != null) { 9792 for (i=0; i<pkg.libraryNames.size(); i++) { 9793 String name = pkg.libraryNames.get(i); 9794 SharedLibraryEntry cur = mSharedLibraries.get(name); 9795 if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) { 9796 mSharedLibraries.remove(name); 9797 if (DEBUG_REMOVE && chatty) { 9798 if (r == null) { 9799 r = new StringBuilder(256); 9800 } else { 9801 r.append(' '); 9802 } 9803 r.append(name); 9804 } 9805 } 9806 } 9807 } 9808 } 9809 if (r != null) { 9810 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r); 9811 } 9812 } 9813 9814 private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) { 9815 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) { 9816 if (pkgInfo.permissions.get(i).info.name.equals(perm)) { 9817 return true; 9818 } 9819 } 9820 return false; 9821 } 9822 9823 static final int UPDATE_PERMISSIONS_ALL = 1<<0; 9824 static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1; 9825 static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2; 9826 9827 private void updatePermissionsLPw(PackageParser.Package pkg, int flags) { 9828 // Update the parent permissions 9829 updatePermissionsLPw(pkg.packageName, pkg, flags); 9830 // Update the child permissions 9831 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 9832 for (int i = 0; i < childCount; i++) { 9833 PackageParser.Package childPkg = pkg.childPackages.get(i); 9834 updatePermissionsLPw(childPkg.packageName, childPkg, flags); 9835 } 9836 } 9837 9838 private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo, 9839 int flags) { 9840 final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null; 9841 updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags); 9842 } 9843 9844 private void updatePermissionsLPw(String changingPkg, 9845 PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) { 9846 // Make sure there are no dangling permission trees. 9847 Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator(); 9848 while (it.hasNext()) { 9849 final BasePermission bp = it.next(); 9850 if (bp.packageSetting == null) { 9851 // We may not yet have parsed the package, so just see if 9852 // we still know about its settings. 9853 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 9854 } 9855 if (bp.packageSetting == null) { 9856 Slog.w(TAG, "Removing dangling permission tree: " + bp.name 9857 + " from package " + bp.sourcePackage); 9858 it.remove(); 9859 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 9860 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 9861 Slog.i(TAG, "Removing old permission tree: " + bp.name 9862 + " from package " + bp.sourcePackage); 9863 flags |= UPDATE_PERMISSIONS_ALL; 9864 it.remove(); 9865 } 9866 } 9867 } 9868 9869 // Make sure all dynamic permissions have been assigned to a package, 9870 // and make sure there are no dangling permissions. 9871 it = mSettings.mPermissions.values().iterator(); 9872 while (it.hasNext()) { 9873 final BasePermission bp = it.next(); 9874 if (bp.type == BasePermission.TYPE_DYNAMIC) { 9875 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name=" 9876 + bp.name + " pkg=" + bp.sourcePackage 9877 + " info=" + bp.pendingInfo); 9878 if (bp.packageSetting == null && bp.pendingInfo != null) { 9879 final BasePermission tree = findPermissionTreeLP(bp.name); 9880 if (tree != null && tree.perm != null) { 9881 bp.packageSetting = tree.packageSetting; 9882 bp.perm = new PackageParser.Permission(tree.perm.owner, 9883 new PermissionInfo(bp.pendingInfo)); 9884 bp.perm.info.packageName = tree.perm.info.packageName; 9885 bp.perm.info.name = bp.name; 9886 bp.uid = tree.uid; 9887 } 9888 } 9889 } 9890 if (bp.packageSetting == null) { 9891 // We may not yet have parsed the package, so just see if 9892 // we still know about its settings. 9893 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 9894 } 9895 if (bp.packageSetting == null) { 9896 Slog.w(TAG, "Removing dangling permission: " + bp.name 9897 + " from package " + bp.sourcePackage); 9898 it.remove(); 9899 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 9900 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 9901 Slog.i(TAG, "Removing old permission: " + bp.name 9902 + " from package " + bp.sourcePackage); 9903 flags |= UPDATE_PERMISSIONS_ALL; 9904 it.remove(); 9905 } 9906 } 9907 } 9908 9909 // Now update the permissions for all packages, in particular 9910 // replace the granted permissions of the system packages. 9911 if ((flags&UPDATE_PERMISSIONS_ALL) != 0) { 9912 for (PackageParser.Package pkg : mPackages.values()) { 9913 if (pkg != pkgInfo) { 9914 // Only replace for packages on requested volume 9915 final String volumeUuid = getVolumeUuidForPackage(pkg); 9916 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0) 9917 && Objects.equals(replaceVolumeUuid, volumeUuid); 9918 grantPermissionsLPw(pkg, replace, changingPkg); 9919 } 9920 } 9921 } 9922 9923 if (pkgInfo != null) { 9924 // Only replace for packages on requested volume 9925 final String volumeUuid = getVolumeUuidForPackage(pkgInfo); 9926 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0) 9927 && Objects.equals(replaceVolumeUuid, volumeUuid); 9928 grantPermissionsLPw(pkgInfo, replace, changingPkg); 9929 } 9930 } 9931 9932 private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace, 9933 String packageOfInterest) { 9934 // IMPORTANT: There are two types of permissions: install and runtime. 9935 // Install time permissions are granted when the app is installed to 9936 // all device users and users added in the future. Runtime permissions 9937 // are granted at runtime explicitly to specific users. Normal and signature 9938 // protected permissions are install time permissions. Dangerous permissions 9939 // are install permissions if the app's target SDK is Lollipop MR1 or older, 9940 // otherwise they are runtime permissions. This function does not manage 9941 // runtime permissions except for the case an app targeting Lollipop MR1 9942 // being upgraded to target a newer SDK, in which case dangerous permissions 9943 // are transformed from install time to runtime ones. 9944 9945 final PackageSetting ps = (PackageSetting) pkg.mExtras; 9946 if (ps == null) { 9947 return; 9948 } 9949 9950 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions"); 9951 9952 PermissionsState permissionsState = ps.getPermissionsState(); 9953 PermissionsState origPermissions = permissionsState; 9954 9955 final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); 9956 9957 boolean runtimePermissionsRevoked = false; 9958 int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY; 9959 9960 boolean changedInstallPermission = false; 9961 9962 if (replace) { 9963 ps.installPermissionsFixed = false; 9964 if (!ps.isSharedUser()) { 9965 origPermissions = new PermissionsState(permissionsState); 9966 permissionsState.reset(); 9967 } else { 9968 // We need to know only about runtime permission changes since the 9969 // calling code always writes the install permissions state but 9970 // the runtime ones are written only if changed. The only cases of 9971 // changed runtime permissions here are promotion of an install to 9972 // runtime and revocation of a runtime from a shared user. 9973 changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw( 9974 ps.sharedUser, UserManagerService.getInstance().getUserIds()); 9975 if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) { 9976 runtimePermissionsRevoked = true; 9977 } 9978 } 9979 } 9980 9981 permissionsState.setGlobalGids(mGlobalGids); 9982 9983 final int N = pkg.requestedPermissions.size(); 9984 for (int i=0; i<N; i++) { 9985 final String name = pkg.requestedPermissions.get(i); 9986 final BasePermission bp = mSettings.mPermissions.get(name); 9987 9988 if (DEBUG_INSTALL) { 9989 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp); 9990 } 9991 9992 if (bp == null || bp.packageSetting == null) { 9993 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 9994 Slog.w(TAG, "Unknown permission " + name 9995 + " in package " + pkg.packageName); 9996 } 9997 continue; 9998 } 9999 10000 final String perm = bp.name; 10001 boolean allowedSig = false; 10002 int grant = GRANT_DENIED; 10003 10004 // Keep track of app op permissions. 10005 if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 10006 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name); 10007 if (pkgs == null) { 10008 pkgs = new ArraySet<>(); 10009 mAppOpPermissionPackages.put(bp.name, pkgs); 10010 } 10011 pkgs.add(pkg.packageName); 10012 } 10013 10014 final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; 10015 final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion 10016 >= Build.VERSION_CODES.M; 10017 switch (level) { 10018 case PermissionInfo.PROTECTION_NORMAL: { 10019 // For all apps normal permissions are install time ones. 10020 grant = GRANT_INSTALL; 10021 } break; 10022 10023 case PermissionInfo.PROTECTION_DANGEROUS: { 10024 // If a permission review is required for legacy apps we represent 10025 // their permissions as always granted runtime ones since we need 10026 // to keep the review required permission flag per user while an 10027 // install permission's state is shared across all users. 10028 if (!appSupportsRuntimePermissions && !mPermissionReviewRequired 10029 && !Build.PERMISSIONS_REVIEW_REQUIRED) { 10030 // For legacy apps dangerous permissions are install time ones. 10031 grant = GRANT_INSTALL; 10032 } else if (origPermissions.hasInstallPermission(bp.name)) { 10033 // For legacy apps that became modern, install becomes runtime. 10034 grant = GRANT_UPGRADE; 10035 } else if (mPromoteSystemApps 10036 && isSystemApp(ps) 10037 && mExistingSystemPackages.contains(ps.name)) { 10038 // For legacy system apps, install becomes runtime. 10039 // We cannot check hasInstallPermission() for system apps since those 10040 // permissions were granted implicitly and not persisted pre-M. 10041 grant = GRANT_UPGRADE; 10042 } else { 10043 // For modern apps keep runtime permissions unchanged. 10044 grant = GRANT_RUNTIME; 10045 } 10046 } break; 10047 10048 case PermissionInfo.PROTECTION_SIGNATURE: { 10049 // For all apps signature permissions are install time ones. 10050 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions); 10051 if (allowedSig) { 10052 grant = GRANT_INSTALL; 10053 } 10054 } break; 10055 } 10056 10057 if (DEBUG_INSTALL) { 10058 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm); 10059 } 10060 10061 if (grant != GRANT_DENIED) { 10062 if (!isSystemApp(ps) && ps.installPermissionsFixed) { 10063 // If this is an existing, non-system package, then 10064 // we can't add any new permissions to it. 10065 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) { 10066 // Except... if this is a permission that was added 10067 // to the platform (note: need to only do this when 10068 // updating the platform). 10069 if (!isNewPlatformPermissionForPackage(perm, pkg)) { 10070 grant = GRANT_DENIED; 10071 } 10072 } 10073 } 10074 10075 switch (grant) { 10076 case GRANT_INSTALL: { 10077 // Revoke this as runtime permission to handle the case of 10078 // a runtime permission being downgraded to an install one. 10079 // Also in permission review mode we keep dangerous permissions 10080 // for legacy apps 10081 for (int userId : UserManagerService.getInstance().getUserIds()) { 10082 if (origPermissions.getRuntimePermissionState( 10083 bp.name, userId) != null) { 10084 // Revoke the runtime permission and clear the flags. 10085 origPermissions.revokeRuntimePermission(bp, userId); 10086 origPermissions.updatePermissionFlags(bp, userId, 10087 PackageManager.MASK_PERMISSION_FLAGS, 0); 10088 // If we revoked a permission permission, we have to write. 10089 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 10090 changedRuntimePermissionUserIds, userId); 10091 } 10092 } 10093 // Grant an install permission. 10094 if (permissionsState.grantInstallPermission(bp) != 10095 PermissionsState.PERMISSION_OPERATION_FAILURE) { 10096 changedInstallPermission = true; 10097 } 10098 } break; 10099 10100 case GRANT_RUNTIME: { 10101 // Grant previously granted runtime permissions. 10102 for (int userId : UserManagerService.getInstance().getUserIds()) { 10103 PermissionState permissionState = origPermissions 10104 .getRuntimePermissionState(bp.name, userId); 10105 int flags = permissionState != null 10106 ? permissionState.getFlags() : 0; 10107 if (origPermissions.hasRuntimePermission(bp.name, userId)) { 10108 if (permissionsState.grantRuntimePermission(bp, userId) == 10109 PermissionsState.PERMISSION_OPERATION_FAILURE) { 10110 // If we cannot put the permission as it was, we have to write. 10111 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 10112 changedRuntimePermissionUserIds, userId); 10113 } 10114 // If the app supports runtime permissions no need for a review. 10115 if ((mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED) 10116 && appSupportsRuntimePermissions 10117 && (flags & PackageManager 10118 .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) { 10119 flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 10120 // Since we changed the flags, we have to write. 10121 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 10122 changedRuntimePermissionUserIds, userId); 10123 } 10124 } else if ((mPermissionReviewRequired 10125 || Build.PERMISSIONS_REVIEW_REQUIRED) 10126 && !appSupportsRuntimePermissions) { 10127 // For legacy apps that need a permission review, every new 10128 // runtime permission is granted but it is pending a review. 10129 // We also need to review only platform defined runtime 10130 // permissions as these are the only ones the platform knows 10131 // how to disable the API to simulate revocation as legacy 10132 // apps don't expect to run with revoked permissions. 10133 if (PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage)) { 10134 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) { 10135 flags |= FLAG_PERMISSION_REVIEW_REQUIRED; 10136 // We changed the flags, hence have to write. 10137 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 10138 changedRuntimePermissionUserIds, userId); 10139 } 10140 } 10141 if (permissionsState.grantRuntimePermission(bp, userId) 10142 != PermissionsState.PERMISSION_OPERATION_FAILURE) { 10143 // We changed the permission, hence have to write. 10144 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 10145 changedRuntimePermissionUserIds, userId); 10146 } 10147 } 10148 // Propagate the permission flags. 10149 permissionsState.updatePermissionFlags(bp, userId, flags, flags); 10150 } 10151 } break; 10152 10153 case GRANT_UPGRADE: { 10154 // Grant runtime permissions for a previously held install permission. 10155 PermissionState permissionState = origPermissions 10156 .getInstallPermissionState(bp.name); 10157 final int flags = permissionState != null ? permissionState.getFlags() : 0; 10158 10159 if (origPermissions.revokeInstallPermission(bp) 10160 != PermissionsState.PERMISSION_OPERATION_FAILURE) { 10161 // We will be transferring the permission flags, so clear them. 10162 origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL, 10163 PackageManager.MASK_PERMISSION_FLAGS, 0); 10164 changedInstallPermission = true; 10165 } 10166 10167 // If the permission is not to be promoted to runtime we ignore it and 10168 // also its other flags as they are not applicable to install permissions. 10169 if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) { 10170 for (int userId : currentUserIds) { 10171 if (permissionsState.grantRuntimePermission(bp, userId) != 10172 PermissionsState.PERMISSION_OPERATION_FAILURE) { 10173 // Transfer the permission flags. 10174 permissionsState.updatePermissionFlags(bp, userId, 10175 flags, flags); 10176 // If we granted the permission, we have to write. 10177 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 10178 changedRuntimePermissionUserIds, userId); 10179 } 10180 } 10181 } 10182 } break; 10183 10184 default: { 10185 if (packageOfInterest == null 10186 || packageOfInterest.equals(pkg.packageName)) { 10187 Slog.w(TAG, "Not granting permission " + perm 10188 + " to package " + pkg.packageName 10189 + " because it was previously installed without"); 10190 } 10191 } break; 10192 } 10193 } else { 10194 if (permissionsState.revokeInstallPermission(bp) != 10195 PermissionsState.PERMISSION_OPERATION_FAILURE) { 10196 // Also drop the permission flags. 10197 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 10198 PackageManager.MASK_PERMISSION_FLAGS, 0); 10199 changedInstallPermission = true; 10200 Slog.i(TAG, "Un-granting permission " + perm 10201 + " from package " + pkg.packageName 10202 + " (protectionLevel=" + bp.protectionLevel 10203 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 10204 + ")"); 10205 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) { 10206 // Don't print warning for app op permissions, since it is fine for them 10207 // not to be granted, there is a UI for the user to decide. 10208 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 10209 Slog.w(TAG, "Not granting permission " + perm 10210 + " to package " + pkg.packageName 10211 + " (protectionLevel=" + bp.protectionLevel 10212 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 10213 + ")"); 10214 } 10215 } 10216 } 10217 } 10218 10219 if ((changedInstallPermission || replace) && !ps.installPermissionsFixed && 10220 !isSystemApp(ps) || isUpdatedSystemApp(ps)){ 10221 // This is the first that we have heard about this package, so the 10222 // permissions we have now selected are fixed until explicitly 10223 // changed. 10224 ps.installPermissionsFixed = true; 10225 } 10226 10227 // Persist the runtime permissions state for users with changes. If permissions 10228 // were revoked because no app in the shared user declares them we have to 10229 // write synchronously to avoid losing runtime permissions state. 10230 for (int userId : changedRuntimePermissionUserIds) { 10231 mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked); 10232 } 10233 10234 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 10235 } 10236 10237 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) { 10238 boolean allowed = false; 10239 final int NP = PackageParser.NEW_PERMISSIONS.length; 10240 for (int ip=0; ip<NP; ip++) { 10241 final PackageParser.NewPermissionInfo npi 10242 = PackageParser.NEW_PERMISSIONS[ip]; 10243 if (npi.name.equals(perm) 10244 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) { 10245 allowed = true; 10246 Log.i(TAG, "Auto-granting " + perm + " to old pkg " 10247 + pkg.packageName); 10248 break; 10249 } 10250 } 10251 return allowed; 10252 } 10253 10254 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg, 10255 BasePermission bp, PermissionsState origPermissions) { 10256 boolean allowed; 10257 allowed = (compareSignatures( 10258 bp.packageSetting.signatures.mSignatures, pkg.mSignatures) 10259 == PackageManager.SIGNATURE_MATCH) 10260 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures) 10261 == PackageManager.SIGNATURE_MATCH); 10262 if (!allowed && (bp.protectionLevel 10263 & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) { 10264 if (isSystemApp(pkg)) { 10265 // For updated system applications, a system permission 10266 // is granted only if it had been defined by the original application. 10267 if (pkg.isUpdatedSystemApp()) { 10268 final PackageSetting sysPs = mSettings 10269 .getDisabledSystemPkgLPr(pkg.packageName); 10270 if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) { 10271 // If the original was granted this permission, we take 10272 // that grant decision as read and propagate it to the 10273 // update. 10274 if (sysPs.isPrivileged()) { 10275 allowed = true; 10276 } 10277 } else { 10278 // The system apk may have been updated with an older 10279 // version of the one on the data partition, but which 10280 // granted a new system permission that it didn't have 10281 // before. In this case we do want to allow the app to 10282 // now get the new permission if the ancestral apk is 10283 // privileged to get it. 10284 if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) { 10285 for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) { 10286 if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) { 10287 allowed = true; 10288 break; 10289 } 10290 } 10291 } 10292 // Also if a privileged parent package on the system image or any of 10293 // its children requested a privileged permission, the updated child 10294 // packages can also get the permission. 10295 if (pkg.parentPackage != null) { 10296 final PackageSetting disabledSysParentPs = mSettings 10297 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName); 10298 if (disabledSysParentPs != null && disabledSysParentPs.pkg != null 10299 && disabledSysParentPs.isPrivileged()) { 10300 if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) { 10301 allowed = true; 10302 } else if (disabledSysParentPs.pkg.childPackages != null) { 10303 final int count = disabledSysParentPs.pkg.childPackages.size(); 10304 for (int i = 0; i < count; i++) { 10305 PackageParser.Package disabledSysChildPkg = 10306 disabledSysParentPs.pkg.childPackages.get(i); 10307 if (isPackageRequestingPermission(disabledSysChildPkg, 10308 perm)) { 10309 allowed = true; 10310 break; 10311 } 10312 } 10313 } 10314 } 10315 } 10316 } 10317 } else { 10318 allowed = isPrivilegedApp(pkg); 10319 } 10320 } 10321 } 10322 if (!allowed) { 10323 if (!allowed && (bp.protectionLevel 10324 & PermissionInfo.PROTECTION_FLAG_PRE23) != 0 10325 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 10326 // If this was a previously normal/dangerous permission that got moved 10327 // to a system permission as part of the runtime permission redesign, then 10328 // we still want to blindly grant it to old apps. 10329 allowed = true; 10330 } 10331 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0 10332 && pkg.packageName.equals(mRequiredInstallerPackage)) { 10333 // If this permission is to be granted to the system installer and 10334 // this app is an installer, then it gets the permission. 10335 allowed = true; 10336 } 10337 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0 10338 && pkg.packageName.equals(mRequiredVerifierPackage)) { 10339 // If this permission is to be granted to the system verifier and 10340 // this app is a verifier, then it gets the permission. 10341 allowed = true; 10342 } 10343 if (!allowed && (bp.protectionLevel 10344 & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0 10345 && isSystemApp(pkg)) { 10346 // Any pre-installed system app is allowed to get this permission. 10347 allowed = true; 10348 } 10349 if (!allowed && (bp.protectionLevel 10350 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) { 10351 // For development permissions, a development permission 10352 // is granted only if it was already granted. 10353 allowed = origPermissions.hasInstallPermission(perm); 10354 } 10355 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0 10356 && pkg.packageName.equals(mSetupWizardPackage)) { 10357 // If this permission is to be granted to the system setup wizard and 10358 // this app is a setup wizard, then it gets the permission. 10359 allowed = true; 10360 } 10361 } 10362 return allowed; 10363 } 10364 10365 private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) { 10366 final int permCount = pkg.requestedPermissions.size(); 10367 for (int j = 0; j < permCount; j++) { 10368 String requestedPermission = pkg.requestedPermissions.get(j); 10369 if (permission.equals(requestedPermission)) { 10370 return true; 10371 } 10372 } 10373 return false; 10374 } 10375 10376 final class ActivityIntentResolver 10377 extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> { 10378 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 10379 boolean defaultOnly, int userId) { 10380 if (!sUserManager.exists(userId)) return null; 10381 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 10382 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 10383 } 10384 10385 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 10386 int userId) { 10387 if (!sUserManager.exists(userId)) return null; 10388 mFlags = flags; 10389 return super.queryIntent(intent, resolvedType, 10390 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 10391 } 10392 10393 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 10394 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) { 10395 if (!sUserManager.exists(userId)) return null; 10396 if (packageActivities == null) { 10397 return null; 10398 } 10399 mFlags = flags; 10400 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 10401 final int N = packageActivities.size(); 10402 ArrayList<PackageParser.ActivityIntentInfo[]> listCut = 10403 new ArrayList<PackageParser.ActivityIntentInfo[]>(N); 10404 10405 ArrayList<PackageParser.ActivityIntentInfo> intentFilters; 10406 for (int i = 0; i < N; ++i) { 10407 intentFilters = packageActivities.get(i).intents; 10408 if (intentFilters != null && intentFilters.size() > 0) { 10409 PackageParser.ActivityIntentInfo[] array = 10410 new PackageParser.ActivityIntentInfo[intentFilters.size()]; 10411 intentFilters.toArray(array); 10412 listCut.add(array); 10413 } 10414 } 10415 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 10416 } 10417 10418 /** 10419 * Finds a privileged activity that matches the specified activity names. 10420 */ 10421 private PackageParser.Activity findMatchingActivity( 10422 List<PackageParser.Activity> activityList, ActivityInfo activityInfo) { 10423 for (PackageParser.Activity sysActivity : activityList) { 10424 if (sysActivity.info.name.equals(activityInfo.name)) { 10425 return sysActivity; 10426 } 10427 if (sysActivity.info.name.equals(activityInfo.targetActivity)) { 10428 return sysActivity; 10429 } 10430 if (sysActivity.info.targetActivity != null) { 10431 if (sysActivity.info.targetActivity.equals(activityInfo.name)) { 10432 return sysActivity; 10433 } 10434 if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) { 10435 return sysActivity; 10436 } 10437 } 10438 } 10439 return null; 10440 } 10441 10442 public class IterGenerator<E> { 10443 public Iterator<E> generate(ActivityIntentInfo info) { 10444 return null; 10445 } 10446 } 10447 10448 public class ActionIterGenerator extends IterGenerator<String> { 10449 @Override 10450 public Iterator<String> generate(ActivityIntentInfo info) { 10451 return info.actionsIterator(); 10452 } 10453 } 10454 10455 public class CategoriesIterGenerator extends IterGenerator<String> { 10456 @Override 10457 public Iterator<String> generate(ActivityIntentInfo info) { 10458 return info.categoriesIterator(); 10459 } 10460 } 10461 10462 public class SchemesIterGenerator extends IterGenerator<String> { 10463 @Override 10464 public Iterator<String> generate(ActivityIntentInfo info) { 10465 return info.schemesIterator(); 10466 } 10467 } 10468 10469 public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> { 10470 @Override 10471 public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) { 10472 return info.authoritiesIterator(); 10473 } 10474 } 10475 10476 /** 10477 * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE 10478 * MODIFIED. Do not pass in a list that should not be changed. 10479 */ 10480 private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList, 10481 IterGenerator<T> generator, Iterator<T> searchIterator) { 10482 // loop through the set of actions; every one must be found in the intent filter 10483 while (searchIterator.hasNext()) { 10484 // we must have at least one filter in the list to consider a match 10485 if (intentList.size() == 0) { 10486 break; 10487 } 10488 10489 final T searchAction = searchIterator.next(); 10490 10491 // loop through the set of intent filters 10492 final Iterator<ActivityIntentInfo> intentIter = intentList.iterator(); 10493 while (intentIter.hasNext()) { 10494 final ActivityIntentInfo intentInfo = intentIter.next(); 10495 boolean selectionFound = false; 10496 10497 // loop through the intent filter's selection criteria; at least one 10498 // of them must match the searched criteria 10499 final Iterator<T> intentSelectionIter = generator.generate(intentInfo); 10500 while (intentSelectionIter != null && intentSelectionIter.hasNext()) { 10501 final T intentSelection = intentSelectionIter.next(); 10502 if (intentSelection != null && intentSelection.equals(searchAction)) { 10503 selectionFound = true; 10504 break; 10505 } 10506 } 10507 10508 // the selection criteria wasn't found in this filter's set; this filter 10509 // is not a potential match 10510 if (!selectionFound) { 10511 intentIter.remove(); 10512 } 10513 } 10514 } 10515 } 10516 10517 private boolean isProtectedAction(ActivityIntentInfo filter) { 10518 final Iterator<String> actionsIter = filter.actionsIterator(); 10519 while (actionsIter != null && actionsIter.hasNext()) { 10520 final String filterAction = actionsIter.next(); 10521 if (PROTECTED_ACTIONS.contains(filterAction)) { 10522 return true; 10523 } 10524 } 10525 return false; 10526 } 10527 10528 /** 10529 * Adjusts the priority of the given intent filter according to policy. 10530 * <p> 10531 * <ul> 10532 * <li>The priority for non privileged applications is capped to '0'</li> 10533 * <li>The priority for protected actions on privileged applications is capped to '0'</li> 10534 * <li>The priority for unbundled updates to privileged applications is capped to the 10535 * priority defined on the system partition</li> 10536 * </ul> 10537 * <p> 10538 * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is 10539 * allowed to obtain any priority on any action. 10540 */ 10541 private void adjustPriority( 10542 List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) { 10543 // nothing to do; priority is fine as-is 10544 if (intent.getPriority() <= 0) { 10545 return; 10546 } 10547 10548 final ActivityInfo activityInfo = intent.activity.info; 10549 final ApplicationInfo applicationInfo = activityInfo.applicationInfo; 10550 10551 final boolean privilegedApp = 10552 ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0); 10553 if (!privilegedApp) { 10554 // non-privileged applications can never define a priority >0 10555 Slog.w(TAG, "Non-privileged app; cap priority to 0;" 10556 + " package: " + applicationInfo.packageName 10557 + " activity: " + intent.activity.className 10558 + " origPrio: " + intent.getPriority()); 10559 intent.setPriority(0); 10560 return; 10561 } 10562 10563 if (systemActivities == null) { 10564 // the system package is not disabled; we're parsing the system partition 10565 if (isProtectedAction(intent)) { 10566 if (mDeferProtectedFilters) { 10567 // We can't deal with these just yet. No component should ever obtain a 10568 // >0 priority for a protected actions, with ONE exception -- the setup 10569 // wizard. The setup wizard, however, cannot be known until we're able to 10570 // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do 10571 // until all intent filters have been processed. Chicken, meet egg. 10572 // Let the filter temporarily have a high priority and rectify the 10573 // priorities after all system packages have been scanned. 10574 mProtectedFilters.add(intent); 10575 if (DEBUG_FILTERS) { 10576 Slog.i(TAG, "Protected action; save for later;" 10577 + " package: " + applicationInfo.packageName 10578 + " activity: " + intent.activity.className 10579 + " origPrio: " + intent.getPriority()); 10580 } 10581 return; 10582 } else { 10583 if (DEBUG_FILTERS && mSetupWizardPackage == null) { 10584 Slog.i(TAG, "No setup wizard;" 10585 + " All protected intents capped to priority 0"); 10586 } 10587 if (intent.activity.info.packageName.equals(mSetupWizardPackage)) { 10588 if (DEBUG_FILTERS) { 10589 Slog.i(TAG, "Found setup wizard;" 10590 + " allow priority " + intent.getPriority() + ";" 10591 + " package: " + intent.activity.info.packageName 10592 + " activity: " + intent.activity.className 10593 + " priority: " + intent.getPriority()); 10594 } 10595 // setup wizard gets whatever it wants 10596 return; 10597 } 10598 Slog.w(TAG, "Protected action; cap priority to 0;" 10599 + " package: " + intent.activity.info.packageName 10600 + " activity: " + intent.activity.className 10601 + " origPrio: " + intent.getPriority()); 10602 intent.setPriority(0); 10603 return; 10604 } 10605 } 10606 // privileged apps on the system image get whatever priority they request 10607 return; 10608 } 10609 10610 // privileged app unbundled update ... try to find the same activity 10611 final PackageParser.Activity foundActivity = 10612 findMatchingActivity(systemActivities, activityInfo); 10613 if (foundActivity == null) { 10614 // this is a new activity; it cannot obtain >0 priority 10615 if (DEBUG_FILTERS) { 10616 Slog.i(TAG, "New activity; 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 // found activity, now check for filter equivalence 10626 10627 // a shallow copy is enough; we modify the list, not its contents 10628 final List<ActivityIntentInfo> intentListCopy = 10629 new ArrayList<>(foundActivity.intents); 10630 final List<ActivityIntentInfo> foundFilters = findFilters(intent); 10631 10632 // find matching action subsets 10633 final Iterator<String> actionsIterator = intent.actionsIterator(); 10634 if (actionsIterator != null) { 10635 getIntentListSubset( 10636 intentListCopy, new ActionIterGenerator(), actionsIterator); 10637 if (intentListCopy.size() == 0) { 10638 // no more intents to match; we're not equivalent 10639 if (DEBUG_FILTERS) { 10640 Slog.i(TAG, "Mismatched action; cap priority to 0;" 10641 + " package: " + applicationInfo.packageName 10642 + " activity: " + intent.activity.className 10643 + " origPrio: " + intent.getPriority()); 10644 } 10645 intent.setPriority(0); 10646 return; 10647 } 10648 } 10649 10650 // find matching category subsets 10651 final Iterator<String> categoriesIterator = intent.categoriesIterator(); 10652 if (categoriesIterator != null) { 10653 getIntentListSubset(intentListCopy, new CategoriesIterGenerator(), 10654 categoriesIterator); 10655 if (intentListCopy.size() == 0) { 10656 // no more intents to match; we're not equivalent 10657 if (DEBUG_FILTERS) { 10658 Slog.i(TAG, "Mismatched category; cap priority to 0;" 10659 + " package: " + applicationInfo.packageName 10660 + " activity: " + intent.activity.className 10661 + " origPrio: " + intent.getPriority()); 10662 } 10663 intent.setPriority(0); 10664 return; 10665 } 10666 } 10667 10668 // find matching schemes subsets 10669 final Iterator<String> schemesIterator = intent.schemesIterator(); 10670 if (schemesIterator != null) { 10671 getIntentListSubset(intentListCopy, new SchemesIterGenerator(), 10672 schemesIterator); 10673 if (intentListCopy.size() == 0) { 10674 // no more intents to match; we're not equivalent 10675 if (DEBUG_FILTERS) { 10676 Slog.i(TAG, "Mismatched scheme; cap priority to 0;" 10677 + " package: " + applicationInfo.packageName 10678 + " activity: " + intent.activity.className 10679 + " origPrio: " + intent.getPriority()); 10680 } 10681 intent.setPriority(0); 10682 return; 10683 } 10684 } 10685 10686 // find matching authorities subsets 10687 final Iterator<IntentFilter.AuthorityEntry> 10688 authoritiesIterator = intent.authoritiesIterator(); 10689 if (authoritiesIterator != null) { 10690 getIntentListSubset(intentListCopy, 10691 new AuthoritiesIterGenerator(), 10692 authoritiesIterator); 10693 if (intentListCopy.size() == 0) { 10694 // no more intents to match; we're not equivalent 10695 if (DEBUG_FILTERS) { 10696 Slog.i(TAG, "Mismatched authority; cap priority to 0;" 10697 + " package: " + applicationInfo.packageName 10698 + " activity: " + intent.activity.className 10699 + " origPrio: " + intent.getPriority()); 10700 } 10701 intent.setPriority(0); 10702 return; 10703 } 10704 } 10705 10706 // we found matching filter(s); app gets the max priority of all intents 10707 int cappedPriority = 0; 10708 for (int i = intentListCopy.size() - 1; i >= 0; --i) { 10709 cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority()); 10710 } 10711 if (intent.getPriority() > cappedPriority) { 10712 if (DEBUG_FILTERS) { 10713 Slog.i(TAG, "Found matching filter(s);" 10714 + " cap priority to " + cappedPriority + ";" 10715 + " package: " + applicationInfo.packageName 10716 + " activity: " + intent.activity.className 10717 + " origPrio: " + intent.getPriority()); 10718 } 10719 intent.setPriority(cappedPriority); 10720 return; 10721 } 10722 // all this for nothing; the requested priority was <= what was on the system 10723 } 10724 10725 public final void addActivity(PackageParser.Activity a, String type) { 10726 mActivities.put(a.getComponentName(), a); 10727 if (DEBUG_SHOW_INFO) 10728 Log.v( 10729 TAG, " " + type + " " + 10730 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":"); 10731 if (DEBUG_SHOW_INFO) 10732 Log.v(TAG, " Class=" + a.info.name); 10733 final int NI = a.intents.size(); 10734 for (int j=0; j<NI; j++) { 10735 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 10736 if ("activity".equals(type)) { 10737 final PackageSetting ps = 10738 mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName); 10739 final List<PackageParser.Activity> systemActivities = 10740 ps != null && ps.pkg != null ? ps.pkg.activities : null; 10741 adjustPriority(systemActivities, intent); 10742 } 10743 if (DEBUG_SHOW_INFO) { 10744 Log.v(TAG, " IntentFilter:"); 10745 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10746 } 10747 if (!intent.debugCheck()) { 10748 Log.w(TAG, "==> For Activity " + a.info.name); 10749 } 10750 addFilter(intent); 10751 } 10752 } 10753 10754 public final void removeActivity(PackageParser.Activity a, String type) { 10755 mActivities.remove(a.getComponentName()); 10756 if (DEBUG_SHOW_INFO) { 10757 Log.v(TAG, " " + type + " " 10758 + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel 10759 : a.info.name) + ":"); 10760 Log.v(TAG, " Class=" + a.info.name); 10761 } 10762 final int NI = a.intents.size(); 10763 for (int j=0; j<NI; j++) { 10764 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 10765 if (DEBUG_SHOW_INFO) { 10766 Log.v(TAG, " IntentFilter:"); 10767 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10768 } 10769 removeFilter(intent); 10770 } 10771 } 10772 10773 @Override 10774 protected boolean allowFilterResult( 10775 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) { 10776 ActivityInfo filterAi = filter.activity.info; 10777 for (int i=dest.size()-1; i>=0; i--) { 10778 ActivityInfo destAi = dest.get(i).activityInfo; 10779 if (destAi.name == filterAi.name 10780 && destAi.packageName == filterAi.packageName) { 10781 return false; 10782 } 10783 } 10784 return true; 10785 } 10786 10787 @Override 10788 protected ActivityIntentInfo[] newArray(int size) { 10789 return new ActivityIntentInfo[size]; 10790 } 10791 10792 @Override 10793 protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) { 10794 if (!sUserManager.exists(userId)) return true; 10795 PackageParser.Package p = filter.activity.owner; 10796 if (p != null) { 10797 PackageSetting ps = (PackageSetting)p.mExtras; 10798 if (ps != null) { 10799 // System apps are never considered stopped for purposes of 10800 // filtering, because there may be no way for the user to 10801 // actually re-launch them. 10802 return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0 10803 && ps.getStopped(userId); 10804 } 10805 } 10806 return false; 10807 } 10808 10809 @Override 10810 protected boolean isPackageForFilter(String packageName, 10811 PackageParser.ActivityIntentInfo info) { 10812 return packageName.equals(info.activity.owner.packageName); 10813 } 10814 10815 @Override 10816 protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info, 10817 int match, int userId) { 10818 if (!sUserManager.exists(userId)) return null; 10819 if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) { 10820 return null; 10821 } 10822 final PackageParser.Activity activity = info.activity; 10823 PackageSetting ps = (PackageSetting) activity.owner.mExtras; 10824 if (ps == null) { 10825 return null; 10826 } 10827 ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags, 10828 ps.readUserState(userId), userId); 10829 if (ai == null) { 10830 return null; 10831 } 10832 final ResolveInfo res = new ResolveInfo(); 10833 res.activityInfo = ai; 10834 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 10835 res.filter = info; 10836 } 10837 if (info != null) { 10838 res.handleAllWebDataURI = info.handleAllWebDataURI(); 10839 } 10840 res.priority = info.getPriority(); 10841 res.preferredOrder = activity.owner.mPreferredOrder; 10842 //System.out.println("Result: " + res.activityInfo.className + 10843 // " = " + res.priority); 10844 res.match = match; 10845 res.isDefault = info.hasDefault; 10846 res.labelRes = info.labelRes; 10847 res.nonLocalizedLabel = info.nonLocalizedLabel; 10848 if (userNeedsBadging(userId)) { 10849 res.noResourceId = true; 10850 } else { 10851 res.icon = info.icon; 10852 } 10853 res.iconResourceId = info.icon; 10854 res.system = res.activityInfo.applicationInfo.isSystemApp(); 10855 return res; 10856 } 10857 10858 @Override 10859 protected void sortResults(List<ResolveInfo> results) { 10860 Collections.sort(results, mResolvePrioritySorter); 10861 } 10862 10863 @Override 10864 protected void dumpFilter(PrintWriter out, String prefix, 10865 PackageParser.ActivityIntentInfo filter) { 10866 out.print(prefix); out.print( 10867 Integer.toHexString(System.identityHashCode(filter.activity))); 10868 out.print(' '); 10869 filter.activity.printComponentShortName(out); 10870 out.print(" filter "); 10871 out.println(Integer.toHexString(System.identityHashCode(filter))); 10872 } 10873 10874 @Override 10875 protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) { 10876 return filter.activity; 10877 } 10878 10879 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 10880 PackageParser.Activity activity = (PackageParser.Activity)label; 10881 out.print(prefix); out.print( 10882 Integer.toHexString(System.identityHashCode(activity))); 10883 out.print(' '); 10884 activity.printComponentShortName(out); 10885 if (count > 1) { 10886 out.print(" ("); out.print(count); out.print(" filters)"); 10887 } 10888 out.println(); 10889 } 10890 10891 // Keys are String (activity class name), values are Activity. 10892 private final ArrayMap<ComponentName, PackageParser.Activity> mActivities 10893 = new ArrayMap<ComponentName, PackageParser.Activity>(); 10894 private int mFlags; 10895 } 10896 10897 private final class ServiceIntentResolver 10898 extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> { 10899 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 10900 boolean defaultOnly, int userId) { 10901 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 10902 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 10903 } 10904 10905 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 10906 int userId) { 10907 if (!sUserManager.exists(userId)) return null; 10908 mFlags = flags; 10909 return super.queryIntent(intent, resolvedType, 10910 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 10911 } 10912 10913 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 10914 int flags, ArrayList<PackageParser.Service> packageServices, int userId) { 10915 if (!sUserManager.exists(userId)) return null; 10916 if (packageServices == null) { 10917 return null; 10918 } 10919 mFlags = flags; 10920 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 10921 final int N = packageServices.size(); 10922 ArrayList<PackageParser.ServiceIntentInfo[]> listCut = 10923 new ArrayList<PackageParser.ServiceIntentInfo[]>(N); 10924 10925 ArrayList<PackageParser.ServiceIntentInfo> intentFilters; 10926 for (int i = 0; i < N; ++i) { 10927 intentFilters = packageServices.get(i).intents; 10928 if (intentFilters != null && intentFilters.size() > 0) { 10929 PackageParser.ServiceIntentInfo[] array = 10930 new PackageParser.ServiceIntentInfo[intentFilters.size()]; 10931 intentFilters.toArray(array); 10932 listCut.add(array); 10933 } 10934 } 10935 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 10936 } 10937 10938 public final void addService(PackageParser.Service s) { 10939 mServices.put(s.getComponentName(), s); 10940 if (DEBUG_SHOW_INFO) { 10941 Log.v(TAG, " " 10942 + (s.info.nonLocalizedLabel != null 10943 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 10944 Log.v(TAG, " Class=" + s.info.name); 10945 } 10946 final int NI = s.intents.size(); 10947 int j; 10948 for (j=0; j<NI; j++) { 10949 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 10950 if (DEBUG_SHOW_INFO) { 10951 Log.v(TAG, " IntentFilter:"); 10952 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10953 } 10954 if (!intent.debugCheck()) { 10955 Log.w(TAG, "==> For Service " + s.info.name); 10956 } 10957 addFilter(intent); 10958 } 10959 } 10960 10961 public final void removeService(PackageParser.Service s) { 10962 mServices.remove(s.getComponentName()); 10963 if (DEBUG_SHOW_INFO) { 10964 Log.v(TAG, " " + (s.info.nonLocalizedLabel != null 10965 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 10966 Log.v(TAG, " Class=" + s.info.name); 10967 } 10968 final int NI = s.intents.size(); 10969 int j; 10970 for (j=0; j<NI; j++) { 10971 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 10972 if (DEBUG_SHOW_INFO) { 10973 Log.v(TAG, " IntentFilter:"); 10974 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10975 } 10976 removeFilter(intent); 10977 } 10978 } 10979 10980 @Override 10981 protected boolean allowFilterResult( 10982 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) { 10983 ServiceInfo filterSi = filter.service.info; 10984 for (int i=dest.size()-1; i>=0; i--) { 10985 ServiceInfo destAi = dest.get(i).serviceInfo; 10986 if (destAi.name == filterSi.name 10987 && destAi.packageName == filterSi.packageName) { 10988 return false; 10989 } 10990 } 10991 return true; 10992 } 10993 10994 @Override 10995 protected PackageParser.ServiceIntentInfo[] newArray(int size) { 10996 return new PackageParser.ServiceIntentInfo[size]; 10997 } 10998 10999 @Override 11000 protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) { 11001 if (!sUserManager.exists(userId)) return true; 11002 PackageParser.Package p = filter.service.owner; 11003 if (p != null) { 11004 PackageSetting ps = (PackageSetting)p.mExtras; 11005 if (ps != null) { 11006 // System apps are never considered stopped for purposes of 11007 // filtering, because there may be no way for the user to 11008 // actually re-launch them. 11009 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 11010 && ps.getStopped(userId); 11011 } 11012 } 11013 return false; 11014 } 11015 11016 @Override 11017 protected boolean isPackageForFilter(String packageName, 11018 PackageParser.ServiceIntentInfo info) { 11019 return packageName.equals(info.service.owner.packageName); 11020 } 11021 11022 @Override 11023 protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter, 11024 int match, int userId) { 11025 if (!sUserManager.exists(userId)) return null; 11026 final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter; 11027 if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) { 11028 return null; 11029 } 11030 final PackageParser.Service service = info.service; 11031 PackageSetting ps = (PackageSetting) service.owner.mExtras; 11032 if (ps == null) { 11033 return null; 11034 } 11035 ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags, 11036 ps.readUserState(userId), userId); 11037 if (si == null) { 11038 return null; 11039 } 11040 final ResolveInfo res = new ResolveInfo(); 11041 res.serviceInfo = si; 11042 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 11043 res.filter = filter; 11044 } 11045 res.priority = info.getPriority(); 11046 res.preferredOrder = service.owner.mPreferredOrder; 11047 res.match = match; 11048 res.isDefault = info.hasDefault; 11049 res.labelRes = info.labelRes; 11050 res.nonLocalizedLabel = info.nonLocalizedLabel; 11051 res.icon = info.icon; 11052 res.system = res.serviceInfo.applicationInfo.isSystemApp(); 11053 return res; 11054 } 11055 11056 @Override 11057 protected void sortResults(List<ResolveInfo> results) { 11058 Collections.sort(results, mResolvePrioritySorter); 11059 } 11060 11061 @Override 11062 protected void dumpFilter(PrintWriter out, String prefix, 11063 PackageParser.ServiceIntentInfo filter) { 11064 out.print(prefix); out.print( 11065 Integer.toHexString(System.identityHashCode(filter.service))); 11066 out.print(' '); 11067 filter.service.printComponentShortName(out); 11068 out.print(" filter "); 11069 out.println(Integer.toHexString(System.identityHashCode(filter))); 11070 } 11071 11072 @Override 11073 protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) { 11074 return filter.service; 11075 } 11076 11077 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 11078 PackageParser.Service service = (PackageParser.Service)label; 11079 out.print(prefix); out.print( 11080 Integer.toHexString(System.identityHashCode(service))); 11081 out.print(' '); 11082 service.printComponentShortName(out); 11083 if (count > 1) { 11084 out.print(" ("); out.print(count); out.print(" filters)"); 11085 } 11086 out.println(); 11087 } 11088 11089// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 11090// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 11091// final List<ResolveInfo> retList = Lists.newArrayList(); 11092// while (i.hasNext()) { 11093// final ResolveInfo resolveInfo = (ResolveInfo) i; 11094// if (isEnabledLP(resolveInfo.serviceInfo)) { 11095// retList.add(resolveInfo); 11096// } 11097// } 11098// return retList; 11099// } 11100 11101 // Keys are String (activity class name), values are Activity. 11102 private final ArrayMap<ComponentName, PackageParser.Service> mServices 11103 = new ArrayMap<ComponentName, PackageParser.Service>(); 11104 private int mFlags; 11105 }; 11106 11107 private final class ProviderIntentResolver 11108 extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> { 11109 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 11110 boolean defaultOnly, int userId) { 11111 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 11112 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 11113 } 11114 11115 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 11116 int userId) { 11117 if (!sUserManager.exists(userId)) 11118 return null; 11119 mFlags = flags; 11120 return super.queryIntent(intent, resolvedType, 11121 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 11122 } 11123 11124 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 11125 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) { 11126 if (!sUserManager.exists(userId)) 11127 return null; 11128 if (packageProviders == null) { 11129 return null; 11130 } 11131 mFlags = flags; 11132 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; 11133 final int N = packageProviders.size(); 11134 ArrayList<PackageParser.ProviderIntentInfo[]> listCut = 11135 new ArrayList<PackageParser.ProviderIntentInfo[]>(N); 11136 11137 ArrayList<PackageParser.ProviderIntentInfo> intentFilters; 11138 for (int i = 0; i < N; ++i) { 11139 intentFilters = packageProviders.get(i).intents; 11140 if (intentFilters != null && intentFilters.size() > 0) { 11141 PackageParser.ProviderIntentInfo[] array = 11142 new PackageParser.ProviderIntentInfo[intentFilters.size()]; 11143 intentFilters.toArray(array); 11144 listCut.add(array); 11145 } 11146 } 11147 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 11148 } 11149 11150 public final void addProvider(PackageParser.Provider p) { 11151 if (mProviders.containsKey(p.getComponentName())) { 11152 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring"); 11153 return; 11154 } 11155 11156 mProviders.put(p.getComponentName(), p); 11157 if (DEBUG_SHOW_INFO) { 11158 Log.v(TAG, " " 11159 + (p.info.nonLocalizedLabel != null 11160 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 11161 Log.v(TAG, " Class=" + p.info.name); 11162 } 11163 final int NI = p.intents.size(); 11164 int j; 11165 for (j = 0; j < NI; j++) { 11166 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 11167 if (DEBUG_SHOW_INFO) { 11168 Log.v(TAG, " IntentFilter:"); 11169 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 11170 } 11171 if (!intent.debugCheck()) { 11172 Log.w(TAG, "==> For Provider " + p.info.name); 11173 } 11174 addFilter(intent); 11175 } 11176 } 11177 11178 public final void removeProvider(PackageParser.Provider p) { 11179 mProviders.remove(p.getComponentName()); 11180 if (DEBUG_SHOW_INFO) { 11181 Log.v(TAG, " " + (p.info.nonLocalizedLabel != null 11182 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 11183 Log.v(TAG, " Class=" + p.info.name); 11184 } 11185 final int NI = p.intents.size(); 11186 int j; 11187 for (j = 0; j < NI; j++) { 11188 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 11189 if (DEBUG_SHOW_INFO) { 11190 Log.v(TAG, " IntentFilter:"); 11191 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 11192 } 11193 removeFilter(intent); 11194 } 11195 } 11196 11197 @Override 11198 protected boolean allowFilterResult( 11199 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) { 11200 ProviderInfo filterPi = filter.provider.info; 11201 for (int i = dest.size() - 1; i >= 0; i--) { 11202 ProviderInfo destPi = dest.get(i).providerInfo; 11203 if (destPi.name == filterPi.name 11204 && destPi.packageName == filterPi.packageName) { 11205 return false; 11206 } 11207 } 11208 return true; 11209 } 11210 11211 @Override 11212 protected PackageParser.ProviderIntentInfo[] newArray(int size) { 11213 return new PackageParser.ProviderIntentInfo[size]; 11214 } 11215 11216 @Override 11217 protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) { 11218 if (!sUserManager.exists(userId)) 11219 return true; 11220 PackageParser.Package p = filter.provider.owner; 11221 if (p != null) { 11222 PackageSetting ps = (PackageSetting) p.mExtras; 11223 if (ps != null) { 11224 // System apps are never considered stopped for purposes of 11225 // filtering, because there may be no way for the user to 11226 // actually re-launch them. 11227 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 11228 && ps.getStopped(userId); 11229 } 11230 } 11231 return false; 11232 } 11233 11234 @Override 11235 protected boolean isPackageForFilter(String packageName, 11236 PackageParser.ProviderIntentInfo info) { 11237 return packageName.equals(info.provider.owner.packageName); 11238 } 11239 11240 @Override 11241 protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter, 11242 int match, int userId) { 11243 if (!sUserManager.exists(userId)) 11244 return null; 11245 final PackageParser.ProviderIntentInfo info = filter; 11246 if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) { 11247 return null; 11248 } 11249 final PackageParser.Provider provider = info.provider; 11250 PackageSetting ps = (PackageSetting) provider.owner.mExtras; 11251 if (ps == null) { 11252 return null; 11253 } 11254 ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags, 11255 ps.readUserState(userId), userId); 11256 if (pi == null) { 11257 return null; 11258 } 11259 final ResolveInfo res = new ResolveInfo(); 11260 res.providerInfo = pi; 11261 if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) { 11262 res.filter = filter; 11263 } 11264 res.priority = info.getPriority(); 11265 res.preferredOrder = provider.owner.mPreferredOrder; 11266 res.match = match; 11267 res.isDefault = info.hasDefault; 11268 res.labelRes = info.labelRes; 11269 res.nonLocalizedLabel = info.nonLocalizedLabel; 11270 res.icon = info.icon; 11271 res.system = res.providerInfo.applicationInfo.isSystemApp(); 11272 return res; 11273 } 11274 11275 @Override 11276 protected void sortResults(List<ResolveInfo> results) { 11277 Collections.sort(results, mResolvePrioritySorter); 11278 } 11279 11280 @Override 11281 protected void dumpFilter(PrintWriter out, String prefix, 11282 PackageParser.ProviderIntentInfo filter) { 11283 out.print(prefix); 11284 out.print( 11285 Integer.toHexString(System.identityHashCode(filter.provider))); 11286 out.print(' '); 11287 filter.provider.printComponentShortName(out); 11288 out.print(" filter "); 11289 out.println(Integer.toHexString(System.identityHashCode(filter))); 11290 } 11291 11292 @Override 11293 protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) { 11294 return filter.provider; 11295 } 11296 11297 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 11298 PackageParser.Provider provider = (PackageParser.Provider)label; 11299 out.print(prefix); out.print( 11300 Integer.toHexString(System.identityHashCode(provider))); 11301 out.print(' '); 11302 provider.printComponentShortName(out); 11303 if (count > 1) { 11304 out.print(" ("); out.print(count); out.print(" filters)"); 11305 } 11306 out.println(); 11307 } 11308 11309 private final ArrayMap<ComponentName, PackageParser.Provider> mProviders 11310 = new ArrayMap<ComponentName, PackageParser.Provider>(); 11311 private int mFlags; 11312 } 11313 11314 private static final class EphemeralIntentResolver 11315 extends IntentResolver<EphemeralResolveIntentInfo, EphemeralResolveInfo> { 11316 /** 11317 * The result that has the highest defined order. Ordering applies on a 11318 * per-package basis. Mapping is from package name to Pair of order and 11319 * EphemeralResolveInfo. 11320 * <p> 11321 * NOTE: This is implemented as a field variable for convenience and efficiency. 11322 * By having a field variable, we're able to track filter ordering as soon as 11323 * a non-zero order is defined. Otherwise, multiple loops across the result set 11324 * would be needed to apply ordering. If the intent resolver becomes re-entrant, 11325 * this needs to be contained entirely within {@link #filterResults()}. 11326 */ 11327 final ArrayMap<String, Pair<Integer, EphemeralResolveInfo>> mOrderResult = new ArrayMap<>(); 11328 11329 @Override 11330 protected EphemeralResolveIntentInfo[] newArray(int size) { 11331 return new EphemeralResolveIntentInfo[size]; 11332 } 11333 11334 @Override 11335 protected boolean isPackageForFilter(String packageName, EphemeralResolveIntentInfo info) { 11336 return true; 11337 } 11338 11339 @Override 11340 protected EphemeralResolveInfo newResult(EphemeralResolveIntentInfo info, int match, 11341 int userId) { 11342 if (!sUserManager.exists(userId)) { 11343 return null; 11344 } 11345 final String packageName = info.getEphemeralResolveInfo().getPackageName(); 11346 final Integer order = info.getOrder(); 11347 final Pair<Integer, EphemeralResolveInfo> lastOrderResult = 11348 mOrderResult.get(packageName); 11349 // ordering is enabled and this item's order isn't high enough 11350 if (lastOrderResult != null && lastOrderResult.first >= order) { 11351 return null; 11352 } 11353 final EphemeralResolveInfo res = info.getEphemeralResolveInfo(); 11354 if (order > 0) { 11355 // non-zero order, enable ordering 11356 mOrderResult.put(packageName, new Pair<>(order, res)); 11357 } 11358 return res; 11359 } 11360 11361 @Override 11362 protected void filterResults(List<EphemeralResolveInfo> results) { 11363 // only do work if ordering is enabled [most of the time it won't be] 11364 if (mOrderResult.size() == 0) { 11365 return; 11366 } 11367 int resultSize = results.size(); 11368 for (int i = 0; i < resultSize; i++) { 11369 final EphemeralResolveInfo info = results.get(i); 11370 final String packageName = info.getPackageName(); 11371 final Pair<Integer, EphemeralResolveInfo> savedInfo = mOrderResult.get(packageName); 11372 if (savedInfo == null) { 11373 // package doesn't having ordering 11374 continue; 11375 } 11376 if (savedInfo.second == info) { 11377 // circled back to the highest ordered item; remove from order list 11378 mOrderResult.remove(savedInfo); 11379 if (mOrderResult.size() == 0) { 11380 // no more ordered items 11381 break; 11382 } 11383 continue; 11384 } 11385 // item has a worse order, remove it from the result list 11386 results.remove(i); 11387 resultSize--; 11388 i--; 11389 } 11390 } 11391 } 11392 11393 private static final Comparator<ResolveInfo> mResolvePrioritySorter = 11394 new Comparator<ResolveInfo>() { 11395 public int compare(ResolveInfo r1, ResolveInfo r2) { 11396 int v1 = r1.priority; 11397 int v2 = r2.priority; 11398 //System.out.println("Comparing: q1=" + q1 + " q2=" + q2); 11399 if (v1 != v2) { 11400 return (v1 > v2) ? -1 : 1; 11401 } 11402 v1 = r1.preferredOrder; 11403 v2 = r2.preferredOrder; 11404 if (v1 != v2) { 11405 return (v1 > v2) ? -1 : 1; 11406 } 11407 if (r1.isDefault != r2.isDefault) { 11408 return r1.isDefault ? -1 : 1; 11409 } 11410 v1 = r1.match; 11411 v2 = r2.match; 11412 //System.out.println("Comparing: m1=" + m1 + " m2=" + m2); 11413 if (v1 != v2) { 11414 return (v1 > v2) ? -1 : 1; 11415 } 11416 if (r1.system != r2.system) { 11417 return r1.system ? -1 : 1; 11418 } 11419 if (r1.activityInfo != null) { 11420 return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName); 11421 } 11422 if (r1.serviceInfo != null) { 11423 return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName); 11424 } 11425 if (r1.providerInfo != null) { 11426 return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName); 11427 } 11428 return 0; 11429 } 11430 }; 11431 11432 private static final Comparator<ProviderInfo> mProviderInitOrderSorter = 11433 new Comparator<ProviderInfo>() { 11434 public int compare(ProviderInfo p1, ProviderInfo p2) { 11435 final int v1 = p1.initOrder; 11436 final int v2 = p2.initOrder; 11437 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0); 11438 } 11439 }; 11440 11441 final void sendPackageBroadcast(final String action, final String pkg, final Bundle extras, 11442 final int flags, final String targetPkg, final IIntentReceiver finishedReceiver, 11443 final int[] userIds) { 11444 mHandler.post(new Runnable() { 11445 @Override 11446 public void run() { 11447 try { 11448 final IActivityManager am = ActivityManagerNative.getDefault(); 11449 if (am == null) return; 11450 final int[] resolvedUserIds; 11451 if (userIds == null) { 11452 resolvedUserIds = am.getRunningUserIds(); 11453 } else { 11454 resolvedUserIds = userIds; 11455 } 11456 for (int id : resolvedUserIds) { 11457 final Intent intent = new Intent(action, 11458 pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null); 11459 if (extras != null) { 11460 intent.putExtras(extras); 11461 } 11462 if (targetPkg != null) { 11463 intent.setPackage(targetPkg); 11464 } 11465 // Modify the UID when posting to other users 11466 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); 11467 if (uid > 0 && UserHandle.getUserId(uid) != id) { 11468 uid = UserHandle.getUid(id, UserHandle.getAppId(uid)); 11469 intent.putExtra(Intent.EXTRA_UID, uid); 11470 } 11471 intent.putExtra(Intent.EXTRA_USER_HANDLE, id); 11472 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags); 11473 if (DEBUG_BROADCASTS) { 11474 RuntimeException here = new RuntimeException("here"); 11475 here.fillInStackTrace(); 11476 Slog.d(TAG, "Sending to user " + id + ": " 11477 + intent.toShortString(false, true, false, false) 11478 + " " + intent.getExtras(), here); 11479 } 11480 am.broadcastIntent(null, intent, null, finishedReceiver, 11481 0, null, null, null, android.app.AppOpsManager.OP_NONE, 11482 null, finishedReceiver != null, false, id); 11483 } 11484 } catch (RemoteException ex) { 11485 } 11486 } 11487 }); 11488 } 11489 11490 /** 11491 * Check if the external storage media is available. This is true if there 11492 * is a mounted external storage medium or if the external storage is 11493 * emulated. 11494 */ 11495 private boolean isExternalMediaAvailable() { 11496 return mMediaMounted || Environment.isExternalStorageEmulated(); 11497 } 11498 11499 @Override 11500 public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) { 11501 // writer 11502 synchronized (mPackages) { 11503 if (!isExternalMediaAvailable()) { 11504 // If the external storage is no longer mounted at this point, 11505 // the caller may not have been able to delete all of this 11506 // packages files and can not delete any more. Bail. 11507 return null; 11508 } 11509 final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned; 11510 if (lastPackage != null) { 11511 pkgs.remove(lastPackage); 11512 } 11513 if (pkgs.size() > 0) { 11514 return pkgs.get(0); 11515 } 11516 } 11517 return null; 11518 } 11519 11520 void schedulePackageCleaning(String packageName, int userId, boolean andCode) { 11521 final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE, 11522 userId, andCode ? 1 : 0, packageName); 11523 if (mSystemReady) { 11524 msg.sendToTarget(); 11525 } else { 11526 if (mPostSystemReadyMessages == null) { 11527 mPostSystemReadyMessages = new ArrayList<>(); 11528 } 11529 mPostSystemReadyMessages.add(msg); 11530 } 11531 } 11532 11533 void startCleaningPackages() { 11534 // reader 11535 if (!isExternalMediaAvailable()) { 11536 return; 11537 } 11538 synchronized (mPackages) { 11539 if (mSettings.mPackagesToBeCleaned.isEmpty()) { 11540 return; 11541 } 11542 } 11543 Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE); 11544 intent.setComponent(DEFAULT_CONTAINER_COMPONENT); 11545 IActivityManager am = ActivityManagerNative.getDefault(); 11546 if (am != null) { 11547 try { 11548 am.startService(null, intent, null, mContext.getOpPackageName(), 11549 UserHandle.USER_SYSTEM); 11550 } catch (RemoteException e) { 11551 } 11552 } 11553 } 11554 11555 @Override 11556 public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer, 11557 int installFlags, String installerPackageName, int userId) { 11558 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null); 11559 11560 final int callingUid = Binder.getCallingUid(); 11561 enforceCrossUserPermission(callingUid, userId, 11562 true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser"); 11563 11564 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 11565 try { 11566 if (observer != null) { 11567 observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null); 11568 } 11569 } catch (RemoteException re) { 11570 } 11571 return; 11572 } 11573 11574 if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) { 11575 installFlags |= PackageManager.INSTALL_FROM_ADB; 11576 11577 } else { 11578 // Caller holds INSTALL_PACKAGES permission, so we're less strict 11579 // about installerPackageName. 11580 11581 installFlags &= ~PackageManager.INSTALL_FROM_ADB; 11582 installFlags &= ~PackageManager.INSTALL_ALL_USERS; 11583 } 11584 11585 UserHandle user; 11586 if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) { 11587 user = UserHandle.ALL; 11588 } else { 11589 user = new UserHandle(userId); 11590 } 11591 11592 // Only system components can circumvent runtime permissions when installing. 11593 if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0 11594 && mContext.checkCallingOrSelfPermission(Manifest.permission 11595 .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) { 11596 throw new SecurityException("You need the " 11597 + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission " 11598 + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag"); 11599 } 11600 11601 final File originFile = new File(originPath); 11602 final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile); 11603 11604 final Message msg = mHandler.obtainMessage(INIT_COPY); 11605 final VerificationInfo verificationInfo = new VerificationInfo( 11606 null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid); 11607 final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer, 11608 installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user, 11609 null /*packageAbiOverride*/, null /*grantedPermissions*/, 11610 null /*certificates*/); 11611 params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params)); 11612 msg.obj = params; 11613 11614 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser", 11615 System.identityHashCode(msg.obj)); 11616 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 11617 System.identityHashCode(msg.obj)); 11618 11619 mHandler.sendMessage(msg); 11620 } 11621 11622 void installStage(String packageName, File stagedDir, String stagedCid, 11623 IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams, 11624 String installerPackageName, int installerUid, UserHandle user, 11625 Certificate[][] certificates) { 11626 if (DEBUG_EPHEMERAL) { 11627 if ((sessionParams.installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) { 11628 Slog.d(TAG, "Ephemeral install of " + packageName); 11629 } 11630 } 11631 final VerificationInfo verificationInfo = new VerificationInfo( 11632 sessionParams.originatingUri, sessionParams.referrerUri, 11633 sessionParams.originatingUid, installerUid); 11634 11635 final OriginInfo origin; 11636 if (stagedDir != null) { 11637 origin = OriginInfo.fromStagedFile(stagedDir); 11638 } else { 11639 origin = OriginInfo.fromStagedContainer(stagedCid); 11640 } 11641 11642 final Message msg = mHandler.obtainMessage(INIT_COPY); 11643 final InstallParams params = new InstallParams(origin, null, observer, 11644 sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid, 11645 verificationInfo, user, sessionParams.abiOverride, 11646 sessionParams.grantedRuntimePermissions, certificates); 11647 params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params)); 11648 msg.obj = params; 11649 11650 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage", 11651 System.identityHashCode(msg.obj)); 11652 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 11653 System.identityHashCode(msg.obj)); 11654 11655 mHandler.sendMessage(msg); 11656 } 11657 11658 private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, 11659 int userId) { 11660 final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting); 11661 sendPackageAddedForUser(packageName, isSystem, pkgSetting.appId, userId); 11662 } 11663 11664 private void sendPackageAddedForUser(String packageName, boolean isSystem, 11665 int appId, int userId) { 11666 Bundle extras = new Bundle(1); 11667 extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, appId)); 11668 11669 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 11670 packageName, extras, 0, null, null, new int[] {userId}); 11671 try { 11672 IActivityManager am = ActivityManagerNative.getDefault(); 11673 if (isSystem && am.isUserRunning(userId, 0)) { 11674 // The just-installed/enabled app is bundled on the system, so presumed 11675 // to be able to run automatically without needing an explicit launch. 11676 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one. 11677 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED) 11678 .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES) 11679 .setPackage(packageName); 11680 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null, 11681 android.app.AppOpsManager.OP_NONE, null, false, false, userId); 11682 } 11683 } catch (RemoteException e) { 11684 // shouldn't happen 11685 Slog.w(TAG, "Unable to bootstrap installed package", e); 11686 } 11687 } 11688 11689 @Override 11690 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, 11691 int userId) { 11692 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 11693 PackageSetting pkgSetting; 11694 final int uid = Binder.getCallingUid(); 11695 enforceCrossUserPermission(uid, userId, 11696 true /* requireFullPermission */, true /* checkShell */, 11697 "setApplicationHiddenSetting for user " + userId); 11698 11699 if (hidden && isPackageDeviceAdmin(packageName, userId)) { 11700 Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin"); 11701 return false; 11702 } 11703 11704 long callingId = Binder.clearCallingIdentity(); 11705 try { 11706 boolean sendAdded = false; 11707 boolean sendRemoved = false; 11708 // writer 11709 synchronized (mPackages) { 11710 pkgSetting = mSettings.mPackages.get(packageName); 11711 if (pkgSetting == null) { 11712 return false; 11713 } 11714 // Do not allow "android" is being disabled 11715 if ("android".equals(packageName)) { 11716 Slog.w(TAG, "Cannot hide package: android"); 11717 return false; 11718 } 11719 // Only allow protected packages to hide themselves. 11720 if (hidden && !UserHandle.isSameApp(uid, pkgSetting.appId) 11721 && mProtectedPackages.isPackageStateProtected(userId, packageName)) { 11722 Slog.w(TAG, "Not hiding protected package: " + packageName); 11723 return false; 11724 } 11725 11726 if (pkgSetting.getHidden(userId) != hidden) { 11727 pkgSetting.setHidden(hidden, userId); 11728 mSettings.writePackageRestrictionsLPr(userId); 11729 if (hidden) { 11730 sendRemoved = true; 11731 } else { 11732 sendAdded = true; 11733 } 11734 } 11735 } 11736 if (sendAdded) { 11737 sendPackageAddedForUser(packageName, pkgSetting, userId); 11738 return true; 11739 } 11740 if (sendRemoved) { 11741 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId), 11742 "hiding pkg"); 11743 sendApplicationHiddenForUser(packageName, pkgSetting, userId); 11744 return true; 11745 } 11746 } finally { 11747 Binder.restoreCallingIdentity(callingId); 11748 } 11749 return false; 11750 } 11751 11752 private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting, 11753 int userId) { 11754 final PackageRemovedInfo info = new PackageRemovedInfo(); 11755 info.removedPackage = packageName; 11756 info.removedUsers = new int[] {userId}; 11757 info.uid = UserHandle.getUid(userId, pkgSetting.appId); 11758 info.sendPackageRemovedBroadcasts(true /*killApp*/); 11759 } 11760 11761 private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) { 11762 if (pkgList.length > 0) { 11763 Bundle extras = new Bundle(1); 11764 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 11765 11766 sendPackageBroadcast( 11767 suspended ? Intent.ACTION_PACKAGES_SUSPENDED 11768 : Intent.ACTION_PACKAGES_UNSUSPENDED, 11769 null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null, 11770 new int[] {userId}); 11771 } 11772 } 11773 11774 /** 11775 * Returns true if application is not found or there was an error. Otherwise it returns 11776 * the hidden state of the package for the given user. 11777 */ 11778 @Override 11779 public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) { 11780 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 11781 enforceCrossUserPermission(Binder.getCallingUid(), userId, 11782 true /* requireFullPermission */, false /* checkShell */, 11783 "getApplicationHidden for user " + userId); 11784 PackageSetting pkgSetting; 11785 long callingId = Binder.clearCallingIdentity(); 11786 try { 11787 // writer 11788 synchronized (mPackages) { 11789 pkgSetting = mSettings.mPackages.get(packageName); 11790 if (pkgSetting == null) { 11791 return true; 11792 } 11793 return pkgSetting.getHidden(userId); 11794 } 11795 } finally { 11796 Binder.restoreCallingIdentity(callingId); 11797 } 11798 } 11799 11800 /** 11801 * @hide 11802 */ 11803 @Override 11804 public int installExistingPackageAsUser(String packageName, int userId) { 11805 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, 11806 null); 11807 PackageSetting pkgSetting; 11808 final int uid = Binder.getCallingUid(); 11809 enforceCrossUserPermission(uid, userId, 11810 true /* requireFullPermission */, true /* checkShell */, 11811 "installExistingPackage for user " + userId); 11812 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 11813 return PackageManager.INSTALL_FAILED_USER_RESTRICTED; 11814 } 11815 11816 long callingId = Binder.clearCallingIdentity(); 11817 try { 11818 boolean installed = false; 11819 11820 // writer 11821 synchronized (mPackages) { 11822 pkgSetting = mSettings.mPackages.get(packageName); 11823 if (pkgSetting == null) { 11824 return PackageManager.INSTALL_FAILED_INVALID_URI; 11825 } 11826 if (!pkgSetting.getInstalled(userId)) { 11827 pkgSetting.setInstalled(true, userId); 11828 pkgSetting.setHidden(false, userId); 11829 mSettings.writePackageRestrictionsLPr(userId); 11830 installed = true; 11831 } 11832 } 11833 11834 if (installed) { 11835 if (pkgSetting.pkg != null) { 11836 synchronized (mInstallLock) { 11837 // We don't need to freeze for a brand new install 11838 prepareAppDataAfterInstallLIF(pkgSetting.pkg); 11839 } 11840 } 11841 sendPackageAddedForUser(packageName, pkgSetting, userId); 11842 } 11843 } finally { 11844 Binder.restoreCallingIdentity(callingId); 11845 } 11846 11847 return PackageManager.INSTALL_SUCCEEDED; 11848 } 11849 11850 boolean isUserRestricted(int userId, String restrictionKey) { 11851 Bundle restrictions = sUserManager.getUserRestrictions(userId); 11852 if (restrictions.getBoolean(restrictionKey, false)) { 11853 Log.w(TAG, "User is restricted: " + restrictionKey); 11854 return true; 11855 } 11856 return false; 11857 } 11858 11859 @Override 11860 public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended, 11861 int userId) { 11862 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 11863 enforceCrossUserPermission(Binder.getCallingUid(), userId, 11864 true /* requireFullPermission */, true /* checkShell */, 11865 "setPackagesSuspended for user " + userId); 11866 11867 if (ArrayUtils.isEmpty(packageNames)) { 11868 return packageNames; 11869 } 11870 11871 // List of package names for whom the suspended state has changed. 11872 List<String> changedPackages = new ArrayList<>(packageNames.length); 11873 // List of package names for whom the suspended state is not set as requested in this 11874 // method. 11875 List<String> unactionedPackages = new ArrayList<>(packageNames.length); 11876 long callingId = Binder.clearCallingIdentity(); 11877 try { 11878 for (int i = 0; i < packageNames.length; i++) { 11879 String packageName = packageNames[i]; 11880 boolean changed = false; 11881 final int appId; 11882 synchronized (mPackages) { 11883 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName); 11884 if (pkgSetting == null) { 11885 Slog.w(TAG, "Could not find package setting for package \"" + packageName 11886 + "\". Skipping suspending/un-suspending."); 11887 unactionedPackages.add(packageName); 11888 continue; 11889 } 11890 appId = pkgSetting.appId; 11891 if (pkgSetting.getSuspended(userId) != suspended) { 11892 if (!canSuspendPackageForUserLocked(packageName, userId)) { 11893 unactionedPackages.add(packageName); 11894 continue; 11895 } 11896 pkgSetting.setSuspended(suspended, userId); 11897 mSettings.writePackageRestrictionsLPr(userId); 11898 changed = true; 11899 changedPackages.add(packageName); 11900 } 11901 } 11902 11903 if (changed && suspended) { 11904 killApplication(packageName, UserHandle.getUid(userId, appId), 11905 "suspending package"); 11906 } 11907 } 11908 } finally { 11909 Binder.restoreCallingIdentity(callingId); 11910 } 11911 11912 if (!changedPackages.isEmpty()) { 11913 sendPackagesSuspendedForUser(changedPackages.toArray( 11914 new String[changedPackages.size()]), userId, suspended); 11915 } 11916 11917 return unactionedPackages.toArray(new String[unactionedPackages.size()]); 11918 } 11919 11920 @Override 11921 public boolean isPackageSuspendedForUser(String packageName, int userId) { 11922 enforceCrossUserPermission(Binder.getCallingUid(), userId, 11923 true /* requireFullPermission */, false /* checkShell */, 11924 "isPackageSuspendedForUser for user " + userId); 11925 synchronized (mPackages) { 11926 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName); 11927 if (pkgSetting == null) { 11928 throw new IllegalArgumentException("Unknown target package: " + packageName); 11929 } 11930 return pkgSetting.getSuspended(userId); 11931 } 11932 } 11933 11934 private boolean canSuspendPackageForUserLocked(String packageName, int userId) { 11935 if (isPackageDeviceAdmin(packageName, userId)) { 11936 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 11937 + "\": has an active device admin"); 11938 return false; 11939 } 11940 11941 String activeLauncherPackageName = getActiveLauncherPackageName(userId); 11942 if (packageName.equals(activeLauncherPackageName)) { 11943 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 11944 + "\": contains the active launcher"); 11945 return false; 11946 } 11947 11948 if (packageName.equals(mRequiredInstallerPackage)) { 11949 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 11950 + "\": required for package installation"); 11951 return false; 11952 } 11953 11954 if (packageName.equals(mRequiredUninstallerPackage)) { 11955 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 11956 + "\": required for package uninstallation"); 11957 return false; 11958 } 11959 11960 if (packageName.equals(mRequiredVerifierPackage)) { 11961 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 11962 + "\": required for package verification"); 11963 return false; 11964 } 11965 11966 if (packageName.equals(getDefaultDialerPackageName(userId))) { 11967 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 11968 + "\": is the default dialer"); 11969 return false; 11970 } 11971 11972 if (mProtectedPackages.isPackageStateProtected(userId, packageName)) { 11973 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 11974 + "\": protected package"); 11975 return false; 11976 } 11977 11978 return true; 11979 } 11980 11981 private String getActiveLauncherPackageName(int userId) { 11982 Intent intent = new Intent(Intent.ACTION_MAIN); 11983 intent.addCategory(Intent.CATEGORY_HOME); 11984 ResolveInfo resolveInfo = resolveIntent( 11985 intent, 11986 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 11987 PackageManager.MATCH_DEFAULT_ONLY, 11988 userId); 11989 11990 return resolveInfo == null ? null : resolveInfo.activityInfo.packageName; 11991 } 11992 11993 private String getDefaultDialerPackageName(int userId) { 11994 synchronized (mPackages) { 11995 return mSettings.getDefaultDialerPackageNameLPw(userId); 11996 } 11997 } 11998 11999 @Override 12000 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException { 12001 mContext.enforceCallingOrSelfPermission( 12002 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 12003 "Only package verification agents can verify applications"); 12004 12005 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 12006 final PackageVerificationResponse response = new PackageVerificationResponse( 12007 verificationCode, Binder.getCallingUid()); 12008 msg.arg1 = id; 12009 msg.obj = response; 12010 mHandler.sendMessage(msg); 12011 } 12012 12013 @Override 12014 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, 12015 long millisecondsToDelay) { 12016 mContext.enforceCallingOrSelfPermission( 12017 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 12018 "Only package verification agents can extend verification timeouts"); 12019 12020 final PackageVerificationState state = mPendingVerification.get(id); 12021 final PackageVerificationResponse response = new PackageVerificationResponse( 12022 verificationCodeAtTimeout, Binder.getCallingUid()); 12023 12024 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) { 12025 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT; 12026 } 12027 if (millisecondsToDelay < 0) { 12028 millisecondsToDelay = 0; 12029 } 12030 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW) 12031 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) { 12032 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT; 12033 } 12034 12035 if ((state != null) && !state.timeoutExtended()) { 12036 state.extendTimeout(); 12037 12038 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 12039 msg.arg1 = id; 12040 msg.obj = response; 12041 mHandler.sendMessageDelayed(msg, millisecondsToDelay); 12042 } 12043 } 12044 12045 private void broadcastPackageVerified(int verificationId, Uri packageUri, 12046 int verificationCode, UserHandle user) { 12047 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED); 12048 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE); 12049 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 12050 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 12051 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode); 12052 12053 mContext.sendBroadcastAsUser(intent, user, 12054 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT); 12055 } 12056 12057 private ComponentName matchComponentForVerifier(String packageName, 12058 List<ResolveInfo> receivers) { 12059 ActivityInfo targetReceiver = null; 12060 12061 final int NR = receivers.size(); 12062 for (int i = 0; i < NR; i++) { 12063 final ResolveInfo info = receivers.get(i); 12064 if (info.activityInfo == null) { 12065 continue; 12066 } 12067 12068 if (packageName.equals(info.activityInfo.packageName)) { 12069 targetReceiver = info.activityInfo; 12070 break; 12071 } 12072 } 12073 12074 if (targetReceiver == null) { 12075 return null; 12076 } 12077 12078 return new ComponentName(targetReceiver.packageName, targetReceiver.name); 12079 } 12080 12081 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo, 12082 List<ResolveInfo> receivers, final PackageVerificationState verificationState) { 12083 if (pkgInfo.verifiers.length == 0) { 12084 return null; 12085 } 12086 12087 final int N = pkgInfo.verifiers.length; 12088 final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1); 12089 for (int i = 0; i < N; i++) { 12090 final VerifierInfo verifierInfo = pkgInfo.verifiers[i]; 12091 12092 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName, 12093 receivers); 12094 if (comp == null) { 12095 continue; 12096 } 12097 12098 final int verifierUid = getUidForVerifier(verifierInfo); 12099 if (verifierUid == -1) { 12100 continue; 12101 } 12102 12103 if (DEBUG_VERIFY) { 12104 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName 12105 + " with the correct signature"); 12106 } 12107 sufficientVerifiers.add(comp); 12108 verificationState.addSufficientVerifier(verifierUid); 12109 } 12110 12111 return sufficientVerifiers; 12112 } 12113 12114 private int getUidForVerifier(VerifierInfo verifierInfo) { 12115 synchronized (mPackages) { 12116 final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName); 12117 if (pkg == null) { 12118 return -1; 12119 } else if (pkg.mSignatures.length != 1) { 12120 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 12121 + " has more than one signature; ignoring"); 12122 return -1; 12123 } 12124 12125 /* 12126 * If the public key of the package's signature does not match 12127 * our expected public key, then this is a different package and 12128 * we should skip. 12129 */ 12130 12131 final byte[] expectedPublicKey; 12132 try { 12133 final Signature verifierSig = pkg.mSignatures[0]; 12134 final PublicKey publicKey = verifierSig.getPublicKey(); 12135 expectedPublicKey = publicKey.getEncoded(); 12136 } catch (CertificateException e) { 12137 return -1; 12138 } 12139 12140 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded(); 12141 12142 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) { 12143 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 12144 + " does not have the expected public key; ignoring"); 12145 return -1; 12146 } 12147 12148 return pkg.applicationInfo.uid; 12149 } 12150 } 12151 12152 @Override 12153 public void finishPackageInstall(int token, boolean didLaunch) { 12154 enforceSystemOrRoot("Only the system is allowed to finish installs"); 12155 12156 if (DEBUG_INSTALL) { 12157 Slog.v(TAG, "BM finishing package install for " + token); 12158 } 12159 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token); 12160 12161 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0); 12162 mHandler.sendMessage(msg); 12163 } 12164 12165 /** 12166 * Get the verification agent timeout. 12167 * 12168 * @return verification timeout in milliseconds 12169 */ 12170 private long getVerificationTimeout() { 12171 return android.provider.Settings.Global.getLong(mContext.getContentResolver(), 12172 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT, 12173 DEFAULT_VERIFICATION_TIMEOUT); 12174 } 12175 12176 /** 12177 * Get the default verification agent response code. 12178 * 12179 * @return default verification response code 12180 */ 12181 private int getDefaultVerificationResponse() { 12182 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 12183 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE, 12184 DEFAULT_VERIFICATION_RESPONSE); 12185 } 12186 12187 /** 12188 * Check whether or not package verification has been enabled. 12189 * 12190 * @return true if verification should be performed 12191 */ 12192 private boolean isVerificationEnabled(int userId, int installFlags) { 12193 if (!DEFAULT_VERIFY_ENABLE) { 12194 return false; 12195 } 12196 // Ephemeral apps don't get the full verification treatment 12197 if ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) { 12198 if (DEBUG_EPHEMERAL) { 12199 Slog.d(TAG, "INSTALL_EPHEMERAL so skipping verification"); 12200 } 12201 return false; 12202 } 12203 12204 boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS); 12205 12206 // Check if installing from ADB 12207 if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) { 12208 // Do not run verification in a test harness environment 12209 if (ActivityManager.isRunningInTestHarness()) { 12210 return false; 12211 } 12212 if (ensureVerifyAppsEnabled) { 12213 return true; 12214 } 12215 // Check if the developer does not want package verification for ADB installs 12216 if (android.provider.Settings.Global.getInt(mContext.getContentResolver(), 12217 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) { 12218 return false; 12219 } 12220 } 12221 12222 if (ensureVerifyAppsEnabled) { 12223 return true; 12224 } 12225 12226 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 12227 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1; 12228 } 12229 12230 @Override 12231 public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains) 12232 throws RemoteException { 12233 mContext.enforceCallingOrSelfPermission( 12234 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 12235 "Only intentfilter verification agents can verify applications"); 12236 12237 final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED); 12238 final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse( 12239 Binder.getCallingUid(), verificationCode, failedDomains); 12240 msg.arg1 = id; 12241 msg.obj = response; 12242 mHandler.sendMessage(msg); 12243 } 12244 12245 @Override 12246 public int getIntentVerificationStatus(String packageName, int userId) { 12247 synchronized (mPackages) { 12248 return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 12249 } 12250 } 12251 12252 @Override 12253 public boolean updateIntentVerificationStatus(String packageName, int status, int userId) { 12254 mContext.enforceCallingOrSelfPermission( 12255 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 12256 12257 boolean result = false; 12258 synchronized (mPackages) { 12259 result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId); 12260 } 12261 if (result) { 12262 scheduleWritePackageRestrictionsLocked(userId); 12263 } 12264 return result; 12265 } 12266 12267 @Override 12268 public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications( 12269 String packageName) { 12270 synchronized (mPackages) { 12271 return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName)); 12272 } 12273 } 12274 12275 @Override 12276 public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) { 12277 if (TextUtils.isEmpty(packageName)) { 12278 return ParceledListSlice.emptyList(); 12279 } 12280 synchronized (mPackages) { 12281 PackageParser.Package pkg = mPackages.get(packageName); 12282 if (pkg == null || pkg.activities == null) { 12283 return ParceledListSlice.emptyList(); 12284 } 12285 final int count = pkg.activities.size(); 12286 ArrayList<IntentFilter> result = new ArrayList<>(); 12287 for (int n=0; n<count; n++) { 12288 PackageParser.Activity activity = pkg.activities.get(n); 12289 if (activity.intents != null && activity.intents.size() > 0) { 12290 result.addAll(activity.intents); 12291 } 12292 } 12293 return new ParceledListSlice<>(result); 12294 } 12295 } 12296 12297 @Override 12298 public boolean setDefaultBrowserPackageName(String packageName, int userId) { 12299 mContext.enforceCallingOrSelfPermission( 12300 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 12301 12302 synchronized (mPackages) { 12303 boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId); 12304 if (packageName != null) { 12305 result |= updateIntentVerificationStatus(packageName, 12306 PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, 12307 userId); 12308 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr( 12309 packageName, userId); 12310 } 12311 return result; 12312 } 12313 } 12314 12315 @Override 12316 public String getDefaultBrowserPackageName(int userId) { 12317 synchronized (mPackages) { 12318 return mSettings.getDefaultBrowserPackageNameLPw(userId); 12319 } 12320 } 12321 12322 /** 12323 * Get the "allow unknown sources" setting. 12324 * 12325 * @return the current "allow unknown sources" setting 12326 */ 12327 private int getUnknownSourcesSettings() { 12328 return android.provider.Settings.Secure.getInt(mContext.getContentResolver(), 12329 android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS, 12330 -1); 12331 } 12332 12333 @Override 12334 public void setInstallerPackageName(String targetPackage, String installerPackageName) { 12335 final int uid = Binder.getCallingUid(); 12336 // writer 12337 synchronized (mPackages) { 12338 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage); 12339 if (targetPackageSetting == null) { 12340 throw new IllegalArgumentException("Unknown target package: " + targetPackage); 12341 } 12342 12343 PackageSetting installerPackageSetting; 12344 if (installerPackageName != null) { 12345 installerPackageSetting = mSettings.mPackages.get(installerPackageName); 12346 if (installerPackageSetting == null) { 12347 throw new IllegalArgumentException("Unknown installer package: " 12348 + installerPackageName); 12349 } 12350 } else { 12351 installerPackageSetting = null; 12352 } 12353 12354 Signature[] callerSignature; 12355 Object obj = mSettings.getUserIdLPr(uid); 12356 if (obj != null) { 12357 if (obj instanceof SharedUserSetting) { 12358 callerSignature = ((SharedUserSetting)obj).signatures.mSignatures; 12359 } else if (obj instanceof PackageSetting) { 12360 callerSignature = ((PackageSetting)obj).signatures.mSignatures; 12361 } else { 12362 throw new SecurityException("Bad object " + obj + " for uid " + uid); 12363 } 12364 } else { 12365 throw new SecurityException("Unknown calling UID: " + uid); 12366 } 12367 12368 // Verify: can't set installerPackageName to a package that is 12369 // not signed with the same cert as the caller. 12370 if (installerPackageSetting != null) { 12371 if (compareSignatures(callerSignature, 12372 installerPackageSetting.signatures.mSignatures) 12373 != PackageManager.SIGNATURE_MATCH) { 12374 throw new SecurityException( 12375 "Caller does not have same cert as new installer package " 12376 + installerPackageName); 12377 } 12378 } 12379 12380 // Verify: if target already has an installer package, it must 12381 // be signed with the same cert as the caller. 12382 if (targetPackageSetting.installerPackageName != null) { 12383 PackageSetting setting = mSettings.mPackages.get( 12384 targetPackageSetting.installerPackageName); 12385 // If the currently set package isn't valid, then it's always 12386 // okay to change it. 12387 if (setting != null) { 12388 if (compareSignatures(callerSignature, 12389 setting.signatures.mSignatures) 12390 != PackageManager.SIGNATURE_MATCH) { 12391 throw new SecurityException( 12392 "Caller does not have same cert as old installer package " 12393 + targetPackageSetting.installerPackageName); 12394 } 12395 } 12396 } 12397 12398 // Okay! 12399 targetPackageSetting.installerPackageName = installerPackageName; 12400 if (installerPackageName != null) { 12401 mSettings.mInstallerPackages.add(installerPackageName); 12402 } 12403 scheduleWriteSettingsLocked(); 12404 } 12405 } 12406 12407 private void processPendingInstall(final InstallArgs args, final int currentStatus) { 12408 // Queue up an async operation since the package installation may take a little while. 12409 mHandler.post(new Runnable() { 12410 public void run() { 12411 mHandler.removeCallbacks(this); 12412 // Result object to be returned 12413 PackageInstalledInfo res = new PackageInstalledInfo(); 12414 res.setReturnCode(currentStatus); 12415 res.uid = -1; 12416 res.pkg = null; 12417 res.removedInfo = null; 12418 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 12419 args.doPreInstall(res.returnCode); 12420 synchronized (mInstallLock) { 12421 installPackageTracedLI(args, res); 12422 } 12423 args.doPostInstall(res.returnCode, res.uid); 12424 } 12425 12426 // A restore should be performed at this point if (a) the install 12427 // succeeded, (b) the operation is not an update, and (c) the new 12428 // package has not opted out of backup participation. 12429 final boolean update = res.removedInfo != null 12430 && res.removedInfo.removedPackage != null; 12431 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags; 12432 boolean doRestore = !update 12433 && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0); 12434 12435 // Set up the post-install work request bookkeeping. This will be used 12436 // and cleaned up by the post-install event handling regardless of whether 12437 // there's a restore pass performed. Token values are >= 1. 12438 int token; 12439 if (mNextInstallToken < 0) mNextInstallToken = 1; 12440 token = mNextInstallToken++; 12441 12442 PostInstallData data = new PostInstallData(args, res); 12443 mRunningInstalls.put(token, data); 12444 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token); 12445 12446 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) { 12447 // Pass responsibility to the Backup Manager. It will perform a 12448 // restore if appropriate, then pass responsibility back to the 12449 // Package Manager to run the post-install observer callbacks 12450 // and broadcasts. 12451 IBackupManager bm = IBackupManager.Stub.asInterface( 12452 ServiceManager.getService(Context.BACKUP_SERVICE)); 12453 if (bm != null) { 12454 if (DEBUG_INSTALL) Log.v(TAG, "token " + token 12455 + " to BM for possible restore"); 12456 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token); 12457 try { 12458 // TODO: http://b/22388012 12459 if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) { 12460 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token); 12461 } else { 12462 doRestore = false; 12463 } 12464 } catch (RemoteException e) { 12465 // can't happen; the backup manager is local 12466 } catch (Exception e) { 12467 Slog.e(TAG, "Exception trying to enqueue restore", e); 12468 doRestore = false; 12469 } 12470 } else { 12471 Slog.e(TAG, "Backup Manager not found!"); 12472 doRestore = false; 12473 } 12474 } 12475 12476 if (!doRestore) { 12477 // No restore possible, or the Backup Manager was mysteriously not 12478 // available -- just fire the post-install work request directly. 12479 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token); 12480 12481 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token); 12482 12483 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 12484 mHandler.sendMessage(msg); 12485 } 12486 } 12487 }); 12488 } 12489 12490 /** 12491 * Callback from PackageSettings whenever an app is first transitioned out of the 12492 * 'stopped' state. Normally we just issue the broadcast, but we can't do that if 12493 * the app was "launched" for a restoreAtInstall operation. Therefore we check 12494 * here whether the app is the target of an ongoing install, and only send the 12495 * broadcast immediately if it is not in that state. If it *is* undergoing a restore, 12496 * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL 12497 * handling. 12498 */ 12499 void notifyFirstLaunch(final String pkgName, final String installerPackage, final int userId) { 12500 // Serialize this with the rest of the install-process message chain. In the 12501 // restore-at-install case, this Runnable will necessarily run before the 12502 // POST_INSTALL message is processed, so the contents of mRunningInstalls 12503 // are coherent. In the non-restore case, the app has already completed install 12504 // and been launched through some other means, so it is not in a problematic 12505 // state for observers to see the FIRST_LAUNCH signal. 12506 mHandler.post(new Runnable() { 12507 @Override 12508 public void run() { 12509 for (int i = 0; i < mRunningInstalls.size(); i++) { 12510 final PostInstallData data = mRunningInstalls.valueAt(i); 12511 if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 12512 continue; 12513 } 12514 if (pkgName.equals(data.res.pkg.applicationInfo.packageName)) { 12515 // right package; but is it for the right user? 12516 for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) { 12517 if (userId == data.res.newUsers[uIndex]) { 12518 if (DEBUG_BACKUP) { 12519 Slog.i(TAG, "Package " + pkgName 12520 + " being restored so deferring FIRST_LAUNCH"); 12521 } 12522 return; 12523 } 12524 } 12525 } 12526 } 12527 // didn't find it, so not being restored 12528 if (DEBUG_BACKUP) { 12529 Slog.i(TAG, "Package " + pkgName + " sending normal FIRST_LAUNCH"); 12530 } 12531 sendFirstLaunchBroadcast(pkgName, installerPackage, new int[] {userId}); 12532 } 12533 }); 12534 } 12535 12536 private void sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds) { 12537 sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0, 12538 installerPkg, null, userIds); 12539 } 12540 12541 private abstract class HandlerParams { 12542 private static final int MAX_RETRIES = 4; 12543 12544 /** 12545 * Number of times startCopy() has been attempted and had a non-fatal 12546 * error. 12547 */ 12548 private int mRetries = 0; 12549 12550 /** User handle for the user requesting the information or installation. */ 12551 private final UserHandle mUser; 12552 String traceMethod; 12553 int traceCookie; 12554 12555 HandlerParams(UserHandle user) { 12556 mUser = user; 12557 } 12558 12559 UserHandle getUser() { 12560 return mUser; 12561 } 12562 12563 HandlerParams setTraceMethod(String traceMethod) { 12564 this.traceMethod = traceMethod; 12565 return this; 12566 } 12567 12568 HandlerParams setTraceCookie(int traceCookie) { 12569 this.traceCookie = traceCookie; 12570 return this; 12571 } 12572 12573 final boolean startCopy() { 12574 boolean res; 12575 try { 12576 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this); 12577 12578 if (++mRetries > MAX_RETRIES) { 12579 Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up"); 12580 mHandler.sendEmptyMessage(MCS_GIVE_UP); 12581 handleServiceError(); 12582 return false; 12583 } else { 12584 handleStartCopy(); 12585 res = true; 12586 } 12587 } catch (RemoteException e) { 12588 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT"); 12589 mHandler.sendEmptyMessage(MCS_RECONNECT); 12590 res = false; 12591 } 12592 handleReturnCode(); 12593 return res; 12594 } 12595 12596 final void serviceError() { 12597 if (DEBUG_INSTALL) Slog.i(TAG, "serviceError"); 12598 handleServiceError(); 12599 handleReturnCode(); 12600 } 12601 12602 abstract void handleStartCopy() throws RemoteException; 12603 abstract void handleServiceError(); 12604 abstract void handleReturnCode(); 12605 } 12606 12607 class MeasureParams extends HandlerParams { 12608 private final PackageStats mStats; 12609 private boolean mSuccess; 12610 12611 private final IPackageStatsObserver mObserver; 12612 12613 public MeasureParams(PackageStats stats, IPackageStatsObserver observer) { 12614 super(new UserHandle(stats.userHandle)); 12615 mObserver = observer; 12616 mStats = stats; 12617 } 12618 12619 @Override 12620 public String toString() { 12621 return "MeasureParams{" 12622 + Integer.toHexString(System.identityHashCode(this)) 12623 + " " + mStats.packageName + "}"; 12624 } 12625 12626 @Override 12627 void handleStartCopy() throws RemoteException { 12628 synchronized (mInstallLock) { 12629 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats); 12630 } 12631 12632 if (mSuccess) { 12633 boolean mounted = false; 12634 try { 12635 final String status = Environment.getExternalStorageState(); 12636 mounted = (Environment.MEDIA_MOUNTED.equals(status) 12637 || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status)); 12638 } catch (Exception e) { 12639 } 12640 12641 if (mounted) { 12642 final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle); 12643 12644 mStats.externalCacheSize = calculateDirectorySize(mContainerService, 12645 userEnv.buildExternalStorageAppCacheDirs(mStats.packageName)); 12646 12647 mStats.externalDataSize = calculateDirectorySize(mContainerService, 12648 userEnv.buildExternalStorageAppDataDirs(mStats.packageName)); 12649 12650 // Always subtract cache size, since it's a subdirectory 12651 mStats.externalDataSize -= mStats.externalCacheSize; 12652 12653 mStats.externalMediaSize = calculateDirectorySize(mContainerService, 12654 userEnv.buildExternalStorageAppMediaDirs(mStats.packageName)); 12655 12656 mStats.externalObbSize = calculateDirectorySize(mContainerService, 12657 userEnv.buildExternalStorageAppObbDirs(mStats.packageName)); 12658 } 12659 } 12660 } 12661 12662 @Override 12663 void handleReturnCode() { 12664 if (mObserver != null) { 12665 try { 12666 mObserver.onGetStatsCompleted(mStats, mSuccess); 12667 } catch (RemoteException e) { 12668 Slog.i(TAG, "Observer no longer exists."); 12669 } 12670 } 12671 } 12672 12673 @Override 12674 void handleServiceError() { 12675 Slog.e(TAG, "Could not measure application " + mStats.packageName 12676 + " external storage"); 12677 } 12678 } 12679 12680 private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths) 12681 throws RemoteException { 12682 long result = 0; 12683 for (File path : paths) { 12684 result += mcs.calculateDirectorySize(path.getAbsolutePath()); 12685 } 12686 return result; 12687 } 12688 12689 private static void clearDirectory(IMediaContainerService mcs, File[] paths) { 12690 for (File path : paths) { 12691 try { 12692 mcs.clearDirectory(path.getAbsolutePath()); 12693 } catch (RemoteException e) { 12694 } 12695 } 12696 } 12697 12698 static class OriginInfo { 12699 /** 12700 * Location where install is coming from, before it has been 12701 * copied/renamed into place. This could be a single monolithic APK 12702 * file, or a cluster directory. This location may be untrusted. 12703 */ 12704 final File file; 12705 final String cid; 12706 12707 /** 12708 * Flag indicating that {@link #file} or {@link #cid} has already been 12709 * staged, meaning downstream users don't need to defensively copy the 12710 * contents. 12711 */ 12712 final boolean staged; 12713 12714 /** 12715 * Flag indicating that {@link #file} or {@link #cid} is an already 12716 * installed app that is being moved. 12717 */ 12718 final boolean existing; 12719 12720 final String resolvedPath; 12721 final File resolvedFile; 12722 12723 static OriginInfo fromNothing() { 12724 return new OriginInfo(null, null, false, false); 12725 } 12726 12727 static OriginInfo fromUntrustedFile(File file) { 12728 return new OriginInfo(file, null, false, false); 12729 } 12730 12731 static OriginInfo fromExistingFile(File file) { 12732 return new OriginInfo(file, null, false, true); 12733 } 12734 12735 static OriginInfo fromStagedFile(File file) { 12736 return new OriginInfo(file, null, true, false); 12737 } 12738 12739 static OriginInfo fromStagedContainer(String cid) { 12740 return new OriginInfo(null, cid, true, false); 12741 } 12742 12743 private OriginInfo(File file, String cid, boolean staged, boolean existing) { 12744 this.file = file; 12745 this.cid = cid; 12746 this.staged = staged; 12747 this.existing = existing; 12748 12749 if (cid != null) { 12750 resolvedPath = PackageHelper.getSdDir(cid); 12751 resolvedFile = new File(resolvedPath); 12752 } else if (file != null) { 12753 resolvedPath = file.getAbsolutePath(); 12754 resolvedFile = file; 12755 } else { 12756 resolvedPath = null; 12757 resolvedFile = null; 12758 } 12759 } 12760 } 12761 12762 static class MoveInfo { 12763 final int moveId; 12764 final String fromUuid; 12765 final String toUuid; 12766 final String packageName; 12767 final String dataAppName; 12768 final int appId; 12769 final String seinfo; 12770 final int targetSdkVersion; 12771 12772 public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName, 12773 String dataAppName, int appId, String seinfo, int targetSdkVersion) { 12774 this.moveId = moveId; 12775 this.fromUuid = fromUuid; 12776 this.toUuid = toUuid; 12777 this.packageName = packageName; 12778 this.dataAppName = dataAppName; 12779 this.appId = appId; 12780 this.seinfo = seinfo; 12781 this.targetSdkVersion = targetSdkVersion; 12782 } 12783 } 12784 12785 static class VerificationInfo { 12786 /** A constant used to indicate that a uid value is not present. */ 12787 public static final int NO_UID = -1; 12788 12789 /** URI referencing where the package was downloaded from. */ 12790 final Uri originatingUri; 12791 12792 /** HTTP referrer URI associated with the originatingURI. */ 12793 final Uri referrer; 12794 12795 /** UID of the application that the install request originated from. */ 12796 final int originatingUid; 12797 12798 /** UID of application requesting the install */ 12799 final int installerUid; 12800 12801 VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) { 12802 this.originatingUri = originatingUri; 12803 this.referrer = referrer; 12804 this.originatingUid = originatingUid; 12805 this.installerUid = installerUid; 12806 } 12807 } 12808 12809 class InstallParams extends HandlerParams { 12810 final OriginInfo origin; 12811 final MoveInfo move; 12812 final IPackageInstallObserver2 observer; 12813 int installFlags; 12814 final String installerPackageName; 12815 final String volumeUuid; 12816 private InstallArgs mArgs; 12817 private int mRet; 12818 final String packageAbiOverride; 12819 final String[] grantedRuntimePermissions; 12820 final VerificationInfo verificationInfo; 12821 final Certificate[][] certificates; 12822 12823 InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 12824 int installFlags, String installerPackageName, String volumeUuid, 12825 VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride, 12826 String[] grantedPermissions, Certificate[][] certificates) { 12827 super(user); 12828 this.origin = origin; 12829 this.move = move; 12830 this.observer = observer; 12831 this.installFlags = installFlags; 12832 this.installerPackageName = installerPackageName; 12833 this.volumeUuid = volumeUuid; 12834 this.verificationInfo = verificationInfo; 12835 this.packageAbiOverride = packageAbiOverride; 12836 this.grantedRuntimePermissions = grantedPermissions; 12837 this.certificates = certificates; 12838 } 12839 12840 @Override 12841 public String toString() { 12842 return "InstallParams{" + Integer.toHexString(System.identityHashCode(this)) 12843 + " file=" + origin.file + " cid=" + origin.cid + "}"; 12844 } 12845 12846 private int installLocationPolicy(PackageInfoLite pkgLite) { 12847 String packageName = pkgLite.packageName; 12848 int installLocation = pkgLite.installLocation; 12849 boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 12850 // reader 12851 synchronized (mPackages) { 12852 // Currently installed package which the new package is attempting to replace or 12853 // null if no such package is installed. 12854 PackageParser.Package installedPkg = mPackages.get(packageName); 12855 // Package which currently owns the data which the new package will own if installed. 12856 // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg 12857 // will be null whereas dataOwnerPkg will contain information about the package 12858 // which was uninstalled while keeping its data. 12859 PackageParser.Package dataOwnerPkg = installedPkg; 12860 if (dataOwnerPkg == null) { 12861 PackageSetting ps = mSettings.mPackages.get(packageName); 12862 if (ps != null) { 12863 dataOwnerPkg = ps.pkg; 12864 } 12865 } 12866 12867 if (dataOwnerPkg != null) { 12868 // If installed, the package will get access to data left on the device by its 12869 // predecessor. As a security measure, this is permited only if this is not a 12870 // version downgrade or if the predecessor package is marked as debuggable and 12871 // a downgrade is explicitly requested. 12872 // 12873 // On debuggable platform builds, downgrades are permitted even for 12874 // non-debuggable packages to make testing easier. Debuggable platform builds do 12875 // not offer security guarantees and thus it's OK to disable some security 12876 // mechanisms to make debugging/testing easier on those builds. However, even on 12877 // debuggable builds downgrades of packages are permitted only if requested via 12878 // installFlags. This is because we aim to keep the behavior of debuggable 12879 // platform builds as close as possible to the behavior of non-debuggable 12880 // platform builds. 12881 final boolean downgradeRequested = 12882 (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0; 12883 final boolean packageDebuggable = 12884 (dataOwnerPkg.applicationInfo.flags 12885 & ApplicationInfo.FLAG_DEBUGGABLE) != 0; 12886 final boolean downgradePermitted = 12887 (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable)); 12888 if (!downgradePermitted) { 12889 try { 12890 checkDowngrade(dataOwnerPkg, pkgLite); 12891 } catch (PackageManagerException e) { 12892 Slog.w(TAG, "Downgrade detected: " + e.getMessage()); 12893 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE; 12894 } 12895 } 12896 } 12897 12898 if (installedPkg != null) { 12899 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 12900 // Check for updated system application. 12901 if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 12902 if (onSd) { 12903 Slog.w(TAG, "Cannot install update to system app on sdcard"); 12904 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION; 12905 } 12906 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 12907 } else { 12908 if (onSd) { 12909 // Install flag overrides everything. 12910 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 12911 } 12912 // If current upgrade specifies particular preference 12913 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) { 12914 // Application explicitly specified internal. 12915 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 12916 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) { 12917 // App explictly prefers external. Let policy decide 12918 } else { 12919 // Prefer previous location 12920 if (isExternal(installedPkg)) { 12921 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 12922 } 12923 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 12924 } 12925 } 12926 } else { 12927 // Invalid install. Return error code 12928 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS; 12929 } 12930 } 12931 } 12932 // All the special cases have been taken care of. 12933 // Return result based on recommended install location. 12934 if (onSd) { 12935 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 12936 } 12937 return pkgLite.recommendedInstallLocation; 12938 } 12939 12940 /* 12941 * Invoke remote method to get package information and install 12942 * location values. Override install location based on default 12943 * policy if needed and then create install arguments based 12944 * on the install location. 12945 */ 12946 public void handleStartCopy() throws RemoteException { 12947 int ret = PackageManager.INSTALL_SUCCEEDED; 12948 12949 // If we're already staged, we've firmly committed to an install location 12950 if (origin.staged) { 12951 if (origin.file != null) { 12952 installFlags |= PackageManager.INSTALL_INTERNAL; 12953 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 12954 } else if (origin.cid != null) { 12955 installFlags |= PackageManager.INSTALL_EXTERNAL; 12956 installFlags &= ~PackageManager.INSTALL_INTERNAL; 12957 } else { 12958 throw new IllegalStateException("Invalid stage location"); 12959 } 12960 } 12961 12962 final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 12963 final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0; 12964 final boolean ephemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; 12965 PackageInfoLite pkgLite = null; 12966 12967 if (onInt && onSd) { 12968 // Check if both bits are set. 12969 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external"); 12970 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 12971 } else if (onSd && ephemeral) { 12972 Slog.w(TAG, "Conflicting flags specified for installing ephemeral on external"); 12973 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 12974 } else { 12975 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags, 12976 packageAbiOverride); 12977 12978 if (DEBUG_EPHEMERAL && ephemeral) { 12979 Slog.v(TAG, "pkgLite for install: " + pkgLite); 12980 } 12981 12982 /* 12983 * If we have too little free space, try to free cache 12984 * before giving up. 12985 */ 12986 if (!origin.staged && pkgLite.recommendedInstallLocation 12987 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 12988 // TODO: focus freeing disk space on the target device 12989 final StorageManager storage = StorageManager.from(mContext); 12990 final long lowThreshold = storage.getStorageLowBytes( 12991 Environment.getDataDirectory()); 12992 12993 final long sizeBytes = mContainerService.calculateInstalledSize( 12994 origin.resolvedPath, isForwardLocked(), packageAbiOverride); 12995 12996 try { 12997 mInstaller.freeCache(null, sizeBytes + lowThreshold); 12998 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, 12999 installFlags, packageAbiOverride); 13000 } catch (InstallerException e) { 13001 Slog.w(TAG, "Failed to free cache", e); 13002 } 13003 13004 /* 13005 * The cache free must have deleted the file we 13006 * downloaded to install. 13007 * 13008 * TODO: fix the "freeCache" call to not delete 13009 * the file we care about. 13010 */ 13011 if (pkgLite.recommendedInstallLocation 13012 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 13013 pkgLite.recommendedInstallLocation 13014 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE; 13015 } 13016 } 13017 } 13018 13019 if (ret == PackageManager.INSTALL_SUCCEEDED) { 13020 int loc = pkgLite.recommendedInstallLocation; 13021 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) { 13022 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 13023 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) { 13024 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 13025 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 13026 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 13027 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) { 13028 ret = PackageManager.INSTALL_FAILED_INVALID_APK; 13029 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 13030 ret = PackageManager.INSTALL_FAILED_INVALID_URI; 13031 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) { 13032 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE; 13033 } else { 13034 // Override with defaults if needed. 13035 loc = installLocationPolicy(pkgLite); 13036 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) { 13037 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 13038 } else if (!onSd && !onInt) { 13039 // Override install location with flags 13040 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) { 13041 // Set the flag to install on external media. 13042 installFlags |= PackageManager.INSTALL_EXTERNAL; 13043 installFlags &= ~PackageManager.INSTALL_INTERNAL; 13044 } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) { 13045 if (DEBUG_EPHEMERAL) { 13046 Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag"); 13047 } 13048 installFlags |= PackageManager.INSTALL_EPHEMERAL; 13049 installFlags &= ~(PackageManager.INSTALL_EXTERNAL 13050 |PackageManager.INSTALL_INTERNAL); 13051 } else { 13052 // Make sure the flag for installing on external 13053 // media is unset 13054 installFlags |= PackageManager.INSTALL_INTERNAL; 13055 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 13056 } 13057 } 13058 } 13059 } 13060 13061 final InstallArgs args = createInstallArgs(this); 13062 mArgs = args; 13063 13064 if (ret == PackageManager.INSTALL_SUCCEEDED) { 13065 // TODO: http://b/22976637 13066 // Apps installed for "all" users use the device owner to verify the app 13067 UserHandle verifierUser = getUser(); 13068 if (verifierUser == UserHandle.ALL) { 13069 verifierUser = UserHandle.SYSTEM; 13070 } 13071 13072 /* 13073 * Determine if we have any installed package verifiers. If we 13074 * do, then we'll defer to them to verify the packages. 13075 */ 13076 final int requiredUid = mRequiredVerifierPackage == null ? -1 13077 : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 13078 verifierUser.getIdentifier()); 13079 if (!origin.existing && requiredUid != -1 13080 && isVerificationEnabled(verifierUser.getIdentifier(), installFlags)) { 13081 final Intent verification = new Intent( 13082 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 13083 verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 13084 verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)), 13085 PACKAGE_MIME_TYPE); 13086 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 13087 13088 // Query all live verifiers based on current user state 13089 final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification, 13090 PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier()); 13091 13092 if (DEBUG_VERIFY) { 13093 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent " 13094 + verification.toString() + " with " + pkgLite.verifiers.length 13095 + " optional verifiers"); 13096 } 13097 13098 final int verificationId = mPendingVerificationToken++; 13099 13100 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 13101 13102 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE, 13103 installerPackageName); 13104 13105 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, 13106 installFlags); 13107 13108 verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME, 13109 pkgLite.packageName); 13110 13111 verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE, 13112 pkgLite.versionCode); 13113 13114 if (verificationInfo != null) { 13115 if (verificationInfo.originatingUri != null) { 13116 verification.putExtra(Intent.EXTRA_ORIGINATING_URI, 13117 verificationInfo.originatingUri); 13118 } 13119 if (verificationInfo.referrer != null) { 13120 verification.putExtra(Intent.EXTRA_REFERRER, 13121 verificationInfo.referrer); 13122 } 13123 if (verificationInfo.originatingUid >= 0) { 13124 verification.putExtra(Intent.EXTRA_ORIGINATING_UID, 13125 verificationInfo.originatingUid); 13126 } 13127 if (verificationInfo.installerUid >= 0) { 13128 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID, 13129 verificationInfo.installerUid); 13130 } 13131 } 13132 13133 final PackageVerificationState verificationState = new PackageVerificationState( 13134 requiredUid, args); 13135 13136 mPendingVerification.append(verificationId, verificationState); 13137 13138 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite, 13139 receivers, verificationState); 13140 13141 /* 13142 * If any sufficient verifiers were listed in the package 13143 * manifest, attempt to ask them. 13144 */ 13145 if (sufficientVerifiers != null) { 13146 final int N = sufficientVerifiers.size(); 13147 if (N == 0) { 13148 Slog.i(TAG, "Additional verifiers required, but none installed."); 13149 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 13150 } else { 13151 for (int i = 0; i < N; i++) { 13152 final ComponentName verifierComponent = sufficientVerifiers.get(i); 13153 13154 final Intent sufficientIntent = new Intent(verification); 13155 sufficientIntent.setComponent(verifierComponent); 13156 mContext.sendBroadcastAsUser(sufficientIntent, verifierUser); 13157 } 13158 } 13159 } 13160 13161 final ComponentName requiredVerifierComponent = matchComponentForVerifier( 13162 mRequiredVerifierPackage, receivers); 13163 if (ret == PackageManager.INSTALL_SUCCEEDED 13164 && mRequiredVerifierPackage != null) { 13165 Trace.asyncTraceBegin( 13166 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 13167 /* 13168 * Send the intent to the required verification agent, 13169 * but only start the verification timeout after the 13170 * target BroadcastReceivers have run. 13171 */ 13172 verification.setComponent(requiredVerifierComponent); 13173 mContext.sendOrderedBroadcastAsUser(verification, verifierUser, 13174 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 13175 new BroadcastReceiver() { 13176 @Override 13177 public void onReceive(Context context, Intent intent) { 13178 final Message msg = mHandler 13179 .obtainMessage(CHECK_PENDING_VERIFICATION); 13180 msg.arg1 = verificationId; 13181 mHandler.sendMessageDelayed(msg, getVerificationTimeout()); 13182 } 13183 }, null, 0, null, null); 13184 13185 /* 13186 * We don't want the copy to proceed until verification 13187 * succeeds, so null out this field. 13188 */ 13189 mArgs = null; 13190 } 13191 } else { 13192 /* 13193 * No package verification is enabled, so immediately start 13194 * the remote call to initiate copy using temporary file. 13195 */ 13196 ret = args.copyApk(mContainerService, true); 13197 } 13198 } 13199 13200 mRet = ret; 13201 } 13202 13203 @Override 13204 void handleReturnCode() { 13205 // If mArgs is null, then MCS couldn't be reached. When it 13206 // reconnects, it will try again to install. At that point, this 13207 // will succeed. 13208 if (mArgs != null) { 13209 processPendingInstall(mArgs, mRet); 13210 } 13211 } 13212 13213 @Override 13214 void handleServiceError() { 13215 mArgs = createInstallArgs(this); 13216 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 13217 } 13218 13219 public boolean isForwardLocked() { 13220 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 13221 } 13222 } 13223 13224 /** 13225 * Used during creation of InstallArgs 13226 * 13227 * @param installFlags package installation flags 13228 * @return true if should be installed on external storage 13229 */ 13230 private static boolean installOnExternalAsec(int installFlags) { 13231 if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) { 13232 return false; 13233 } 13234 if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) { 13235 return true; 13236 } 13237 return false; 13238 } 13239 13240 /** 13241 * Used during creation of InstallArgs 13242 * 13243 * @param installFlags package installation flags 13244 * @return true if should be installed as forward locked 13245 */ 13246 private static boolean installForwardLocked(int installFlags) { 13247 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 13248 } 13249 13250 private InstallArgs createInstallArgs(InstallParams params) { 13251 if (params.move != null) { 13252 return new MoveInstallArgs(params); 13253 } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) { 13254 return new AsecInstallArgs(params); 13255 } else { 13256 return new FileInstallArgs(params); 13257 } 13258 } 13259 13260 /** 13261 * Create args that describe an existing installed package. Typically used 13262 * when cleaning up old installs, or used as a move source. 13263 */ 13264 private InstallArgs createInstallArgsForExisting(int installFlags, String codePath, 13265 String resourcePath, String[] instructionSets) { 13266 final boolean isInAsec; 13267 if (installOnExternalAsec(installFlags)) { 13268 /* Apps on SD card are always in ASEC containers. */ 13269 isInAsec = true; 13270 } else if (installForwardLocked(installFlags) 13271 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) { 13272 /* 13273 * Forward-locked apps are only in ASEC containers if they're the 13274 * new style 13275 */ 13276 isInAsec = true; 13277 } else { 13278 isInAsec = false; 13279 } 13280 13281 if (isInAsec) { 13282 return new AsecInstallArgs(codePath, instructionSets, 13283 installOnExternalAsec(installFlags), installForwardLocked(installFlags)); 13284 } else { 13285 return new FileInstallArgs(codePath, resourcePath, instructionSets); 13286 } 13287 } 13288 13289 static abstract class InstallArgs { 13290 /** @see InstallParams#origin */ 13291 final OriginInfo origin; 13292 /** @see InstallParams#move */ 13293 final MoveInfo move; 13294 13295 final IPackageInstallObserver2 observer; 13296 // Always refers to PackageManager flags only 13297 final int installFlags; 13298 final String installerPackageName; 13299 final String volumeUuid; 13300 final UserHandle user; 13301 final String abiOverride; 13302 final String[] installGrantPermissions; 13303 /** If non-null, drop an async trace when the install completes */ 13304 final String traceMethod; 13305 final int traceCookie; 13306 final Certificate[][] certificates; 13307 13308 // The list of instruction sets supported by this app. This is currently 13309 // only used during the rmdex() phase to clean up resources. We can get rid of this 13310 // if we move dex files under the common app path. 13311 /* nullable */ String[] instructionSets; 13312 13313 InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 13314 int installFlags, String installerPackageName, String volumeUuid, 13315 UserHandle user, String[] instructionSets, 13316 String abiOverride, String[] installGrantPermissions, 13317 String traceMethod, int traceCookie, Certificate[][] certificates) { 13318 this.origin = origin; 13319 this.move = move; 13320 this.installFlags = installFlags; 13321 this.observer = observer; 13322 this.installerPackageName = installerPackageName; 13323 this.volumeUuid = volumeUuid; 13324 this.user = user; 13325 this.instructionSets = instructionSets; 13326 this.abiOverride = abiOverride; 13327 this.installGrantPermissions = installGrantPermissions; 13328 this.traceMethod = traceMethod; 13329 this.traceCookie = traceCookie; 13330 this.certificates = certificates; 13331 } 13332 13333 abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException; 13334 abstract int doPreInstall(int status); 13335 13336 /** 13337 * Rename package into final resting place. All paths on the given 13338 * scanned package should be updated to reflect the rename. 13339 */ 13340 abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath); 13341 abstract int doPostInstall(int status, int uid); 13342 13343 /** @see PackageSettingBase#codePathString */ 13344 abstract String getCodePath(); 13345 /** @see PackageSettingBase#resourcePathString */ 13346 abstract String getResourcePath(); 13347 13348 // Need installer lock especially for dex file removal. 13349 abstract void cleanUpResourcesLI(); 13350 abstract boolean doPostDeleteLI(boolean delete); 13351 13352 /** 13353 * Called before the source arguments are copied. This is used mostly 13354 * for MoveParams when it needs to read the source file to put it in the 13355 * destination. 13356 */ 13357 int doPreCopy() { 13358 return PackageManager.INSTALL_SUCCEEDED; 13359 } 13360 13361 /** 13362 * Called after the source arguments are copied. This is used mostly for 13363 * MoveParams when it needs to read the source file to put it in the 13364 * destination. 13365 */ 13366 int doPostCopy(int uid) { 13367 return PackageManager.INSTALL_SUCCEEDED; 13368 } 13369 13370 protected boolean isFwdLocked() { 13371 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 13372 } 13373 13374 protected boolean isExternalAsec() { 13375 return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 13376 } 13377 13378 protected boolean isEphemeral() { 13379 return (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; 13380 } 13381 13382 UserHandle getUser() { 13383 return user; 13384 } 13385 } 13386 13387 private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) { 13388 if (!allCodePaths.isEmpty()) { 13389 if (instructionSets == null) { 13390 throw new IllegalStateException("instructionSet == null"); 13391 } 13392 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); 13393 for (String codePath : allCodePaths) { 13394 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 13395 try { 13396 mInstaller.rmdex(codePath, dexCodeInstructionSet); 13397 } catch (InstallerException ignored) { 13398 } 13399 } 13400 } 13401 } 13402 } 13403 13404 /** 13405 * Logic to handle installation of non-ASEC applications, including copying 13406 * and renaming logic. 13407 */ 13408 class FileInstallArgs extends InstallArgs { 13409 private File codeFile; 13410 private File resourceFile; 13411 13412 // Example topology: 13413 // /data/app/com.example/base.apk 13414 // /data/app/com.example/split_foo.apk 13415 // /data/app/com.example/lib/arm/libfoo.so 13416 // /data/app/com.example/lib/arm64/libfoo.so 13417 // /data/app/com.example/dalvik/arm/base.apk@classes.dex 13418 13419 /** New install */ 13420 FileInstallArgs(InstallParams params) { 13421 super(params.origin, params.move, params.observer, params.installFlags, 13422 params.installerPackageName, params.volumeUuid, 13423 params.getUser(), null /*instructionSets*/, params.packageAbiOverride, 13424 params.grantedRuntimePermissions, 13425 params.traceMethod, params.traceCookie, params.certificates); 13426 if (isFwdLocked()) { 13427 throw new IllegalArgumentException("Forward locking only supported in ASEC"); 13428 } 13429 } 13430 13431 /** Existing install */ 13432 FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) { 13433 super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets, 13434 null, null, null, 0, null /*certificates*/); 13435 this.codeFile = (codePath != null) ? new File(codePath) : null; 13436 this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null; 13437 } 13438 13439 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 13440 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk"); 13441 try { 13442 return doCopyApk(imcs, temp); 13443 } finally { 13444 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13445 } 13446 } 13447 13448 private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 13449 if (origin.staged) { 13450 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy"); 13451 codeFile = origin.file; 13452 resourceFile = origin.file; 13453 return PackageManager.INSTALL_SUCCEEDED; 13454 } 13455 13456 try { 13457 final boolean isEphemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; 13458 final File tempDir = 13459 mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral); 13460 codeFile = tempDir; 13461 resourceFile = tempDir; 13462 } catch (IOException e) { 13463 Slog.w(TAG, "Failed to create copy file: " + e); 13464 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 13465 } 13466 13467 final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() { 13468 @Override 13469 public ParcelFileDescriptor open(String name, int mode) throws RemoteException { 13470 if (!FileUtils.isValidExtFilename(name)) { 13471 throw new IllegalArgumentException("Invalid filename: " + name); 13472 } 13473 try { 13474 final File file = new File(codeFile, name); 13475 final FileDescriptor fd = Os.open(file.getAbsolutePath(), 13476 O_RDWR | O_CREAT, 0644); 13477 Os.chmod(file.getAbsolutePath(), 0644); 13478 return new ParcelFileDescriptor(fd); 13479 } catch (ErrnoException e) { 13480 throw new RemoteException("Failed to open: " + e.getMessage()); 13481 } 13482 } 13483 }; 13484 13485 int ret = PackageManager.INSTALL_SUCCEEDED; 13486 ret = imcs.copyPackage(origin.file.getAbsolutePath(), target); 13487 if (ret != PackageManager.INSTALL_SUCCEEDED) { 13488 Slog.e(TAG, "Failed to copy package"); 13489 return ret; 13490 } 13491 13492 final File libraryRoot = new File(codeFile, LIB_DIR_NAME); 13493 NativeLibraryHelper.Handle handle = null; 13494 try { 13495 handle = NativeLibraryHelper.Handle.create(codeFile); 13496 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot, 13497 abiOverride); 13498 } catch (IOException e) { 13499 Slog.e(TAG, "Copying native libraries failed", e); 13500 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 13501 } finally { 13502 IoUtils.closeQuietly(handle); 13503 } 13504 13505 return ret; 13506 } 13507 13508 int doPreInstall(int status) { 13509 if (status != PackageManager.INSTALL_SUCCEEDED) { 13510 cleanUp(); 13511 } 13512 return status; 13513 } 13514 13515 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 13516 if (status != PackageManager.INSTALL_SUCCEEDED) { 13517 cleanUp(); 13518 return false; 13519 } 13520 13521 final File targetDir = codeFile.getParentFile(); 13522 final File beforeCodeFile = codeFile; 13523 final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName); 13524 13525 if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile); 13526 try { 13527 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath()); 13528 } catch (ErrnoException e) { 13529 Slog.w(TAG, "Failed to rename", e); 13530 return false; 13531 } 13532 13533 if (!SELinux.restoreconRecursive(afterCodeFile)) { 13534 Slog.w(TAG, "Failed to restorecon"); 13535 return false; 13536 } 13537 13538 // Reflect the rename internally 13539 codeFile = afterCodeFile; 13540 resourceFile = afterCodeFile; 13541 13542 // Reflect the rename in scanned details 13543 pkg.setCodePath(afterCodeFile.getAbsolutePath()); 13544 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile, 13545 afterCodeFile, pkg.baseCodePath)); 13546 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile, 13547 afterCodeFile, pkg.splitCodePaths)); 13548 13549 // Reflect the rename in app info 13550 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 13551 pkg.setApplicationInfoCodePath(pkg.codePath); 13552 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 13553 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 13554 pkg.setApplicationInfoResourcePath(pkg.codePath); 13555 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 13556 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 13557 13558 return true; 13559 } 13560 13561 int doPostInstall(int status, int uid) { 13562 if (status != PackageManager.INSTALL_SUCCEEDED) { 13563 cleanUp(); 13564 } 13565 return status; 13566 } 13567 13568 @Override 13569 String getCodePath() { 13570 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 13571 } 13572 13573 @Override 13574 String getResourcePath() { 13575 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 13576 } 13577 13578 private boolean cleanUp() { 13579 if (codeFile == null || !codeFile.exists()) { 13580 return false; 13581 } 13582 13583 removeCodePathLI(codeFile); 13584 13585 if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) { 13586 resourceFile.delete(); 13587 } 13588 13589 return true; 13590 } 13591 13592 void cleanUpResourcesLI() { 13593 // Try enumerating all code paths before deleting 13594 List<String> allCodePaths = Collections.EMPTY_LIST; 13595 if (codeFile != null && codeFile.exists()) { 13596 try { 13597 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 13598 allCodePaths = pkg.getAllCodePaths(); 13599 } catch (PackageParserException e) { 13600 // Ignored; we tried our best 13601 } 13602 } 13603 13604 cleanUp(); 13605 removeDexFiles(allCodePaths, instructionSets); 13606 } 13607 13608 boolean doPostDeleteLI(boolean delete) { 13609 // XXX err, shouldn't we respect the delete flag? 13610 cleanUpResourcesLI(); 13611 return true; 13612 } 13613 } 13614 13615 private boolean isAsecExternal(String cid) { 13616 final String asecPath = PackageHelper.getSdFilesystem(cid); 13617 return !asecPath.startsWith(mAsecInternalPath); 13618 } 13619 13620 private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws 13621 PackageManagerException { 13622 if (copyRet < 0) { 13623 if (copyRet != PackageManager.NO_NATIVE_LIBRARIES && 13624 copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) { 13625 throw new PackageManagerException(copyRet, message); 13626 } 13627 } 13628 } 13629 13630 /** 13631 * Extract the MountService "container ID" from the full code path of an 13632 * .apk. 13633 */ 13634 static String cidFromCodePath(String fullCodePath) { 13635 int eidx = fullCodePath.lastIndexOf("/"); 13636 String subStr1 = fullCodePath.substring(0, eidx); 13637 int sidx = subStr1.lastIndexOf("/"); 13638 return subStr1.substring(sidx+1, eidx); 13639 } 13640 13641 /** 13642 * Logic to handle installation of ASEC applications, including copying and 13643 * renaming logic. 13644 */ 13645 class AsecInstallArgs extends InstallArgs { 13646 static final String RES_FILE_NAME = "pkg.apk"; 13647 static final String PUBLIC_RES_FILE_NAME = "res.zip"; 13648 13649 String cid; 13650 String packagePath; 13651 String resourcePath; 13652 13653 /** New install */ 13654 AsecInstallArgs(InstallParams params) { 13655 super(params.origin, params.move, params.observer, params.installFlags, 13656 params.installerPackageName, params.volumeUuid, 13657 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 13658 params.grantedRuntimePermissions, 13659 params.traceMethod, params.traceCookie, params.certificates); 13660 } 13661 13662 /** Existing install */ 13663 AsecInstallArgs(String fullCodePath, String[] instructionSets, 13664 boolean isExternal, boolean isForwardLocked) { 13665 super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0) 13666 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, 13667 instructionSets, null, null, null, 0, null /*certificates*/); 13668 // Hackily pretend we're still looking at a full code path 13669 if (!fullCodePath.endsWith(RES_FILE_NAME)) { 13670 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath(); 13671 } 13672 13673 // Extract cid from fullCodePath 13674 int eidx = fullCodePath.lastIndexOf("/"); 13675 String subStr1 = fullCodePath.substring(0, eidx); 13676 int sidx = subStr1.lastIndexOf("/"); 13677 cid = subStr1.substring(sidx+1, eidx); 13678 setMountPath(subStr1); 13679 } 13680 13681 AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) { 13682 super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0) 13683 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, 13684 instructionSets, null, null, null, 0, null /*certificates*/); 13685 this.cid = cid; 13686 setMountPath(PackageHelper.getSdDir(cid)); 13687 } 13688 13689 void createCopyFile() { 13690 cid = mInstallerService.allocateExternalStageCidLegacy(); 13691 } 13692 13693 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 13694 if (origin.staged && origin.cid != null) { 13695 if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy"); 13696 cid = origin.cid; 13697 setMountPath(PackageHelper.getSdDir(cid)); 13698 return PackageManager.INSTALL_SUCCEEDED; 13699 } 13700 13701 if (temp) { 13702 createCopyFile(); 13703 } else { 13704 /* 13705 * Pre-emptively destroy the container since it's destroyed if 13706 * copying fails due to it existing anyway. 13707 */ 13708 PackageHelper.destroySdDir(cid); 13709 } 13710 13711 final String newMountPath = imcs.copyPackageToContainer( 13712 origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(), 13713 isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */)); 13714 13715 if (newMountPath != null) { 13716 setMountPath(newMountPath); 13717 return PackageManager.INSTALL_SUCCEEDED; 13718 } else { 13719 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 13720 } 13721 } 13722 13723 @Override 13724 String getCodePath() { 13725 return packagePath; 13726 } 13727 13728 @Override 13729 String getResourcePath() { 13730 return resourcePath; 13731 } 13732 13733 int doPreInstall(int status) { 13734 if (status != PackageManager.INSTALL_SUCCEEDED) { 13735 // Destroy container 13736 PackageHelper.destroySdDir(cid); 13737 } else { 13738 boolean mounted = PackageHelper.isContainerMounted(cid); 13739 if (!mounted) { 13740 String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(), 13741 Process.SYSTEM_UID); 13742 if (newMountPath != null) { 13743 setMountPath(newMountPath); 13744 } else { 13745 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 13746 } 13747 } 13748 } 13749 return status; 13750 } 13751 13752 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 13753 String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME); 13754 String newMountPath = null; 13755 if (PackageHelper.isContainerMounted(cid)) { 13756 // Unmount the container 13757 if (!PackageHelper.unMountSdDir(cid)) { 13758 Slog.i(TAG, "Failed to unmount " + cid + " before renaming"); 13759 return false; 13760 } 13761 } 13762 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 13763 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId + 13764 " which might be stale. Will try to clean up."); 13765 // Clean up the stale container and proceed to recreate. 13766 if (!PackageHelper.destroySdDir(newCacheId)) { 13767 Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId); 13768 return false; 13769 } 13770 // Successfully cleaned up stale container. Try to rename again. 13771 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 13772 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId 13773 + " inspite of cleaning it up."); 13774 return false; 13775 } 13776 } 13777 if (!PackageHelper.isContainerMounted(newCacheId)) { 13778 Slog.w(TAG, "Mounting container " + newCacheId); 13779 newMountPath = PackageHelper.mountSdDir(newCacheId, 13780 getEncryptKey(), Process.SYSTEM_UID); 13781 } else { 13782 newMountPath = PackageHelper.getSdDir(newCacheId); 13783 } 13784 if (newMountPath == null) { 13785 Slog.w(TAG, "Failed to get cache path for " + newCacheId); 13786 return false; 13787 } 13788 Log.i(TAG, "Succesfully renamed " + cid + 13789 " to " + newCacheId + 13790 " at new path: " + newMountPath); 13791 cid = newCacheId; 13792 13793 final File beforeCodeFile = new File(packagePath); 13794 setMountPath(newMountPath); 13795 final File afterCodeFile = new File(packagePath); 13796 13797 // Reflect the rename in scanned details 13798 pkg.setCodePath(afterCodeFile.getAbsolutePath()); 13799 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile, 13800 afterCodeFile, pkg.baseCodePath)); 13801 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile, 13802 afterCodeFile, pkg.splitCodePaths)); 13803 13804 // Reflect the rename in app info 13805 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 13806 pkg.setApplicationInfoCodePath(pkg.codePath); 13807 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 13808 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 13809 pkg.setApplicationInfoResourcePath(pkg.codePath); 13810 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 13811 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 13812 13813 return true; 13814 } 13815 13816 private void setMountPath(String mountPath) { 13817 final File mountFile = new File(mountPath); 13818 13819 final File monolithicFile = new File(mountFile, RES_FILE_NAME); 13820 if (monolithicFile.exists()) { 13821 packagePath = monolithicFile.getAbsolutePath(); 13822 if (isFwdLocked()) { 13823 resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath(); 13824 } else { 13825 resourcePath = packagePath; 13826 } 13827 } else { 13828 packagePath = mountFile.getAbsolutePath(); 13829 resourcePath = packagePath; 13830 } 13831 } 13832 13833 int doPostInstall(int status, int uid) { 13834 if (status != PackageManager.INSTALL_SUCCEEDED) { 13835 cleanUp(); 13836 } else { 13837 final int groupOwner; 13838 final String protectedFile; 13839 if (isFwdLocked()) { 13840 groupOwner = UserHandle.getSharedAppGid(uid); 13841 protectedFile = RES_FILE_NAME; 13842 } else { 13843 groupOwner = -1; 13844 protectedFile = null; 13845 } 13846 13847 if (uid < Process.FIRST_APPLICATION_UID 13848 || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) { 13849 Slog.e(TAG, "Failed to finalize " + cid); 13850 PackageHelper.destroySdDir(cid); 13851 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 13852 } 13853 13854 boolean mounted = PackageHelper.isContainerMounted(cid); 13855 if (!mounted) { 13856 PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid()); 13857 } 13858 } 13859 return status; 13860 } 13861 13862 private void cleanUp() { 13863 if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp"); 13864 13865 // Destroy secure container 13866 PackageHelper.destroySdDir(cid); 13867 } 13868 13869 private List<String> getAllCodePaths() { 13870 final File codeFile = new File(getCodePath()); 13871 if (codeFile != null && codeFile.exists()) { 13872 try { 13873 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 13874 return pkg.getAllCodePaths(); 13875 } catch (PackageParserException e) { 13876 // Ignored; we tried our best 13877 } 13878 } 13879 return Collections.EMPTY_LIST; 13880 } 13881 13882 void cleanUpResourcesLI() { 13883 // Enumerate all code paths before deleting 13884 cleanUpResourcesLI(getAllCodePaths()); 13885 } 13886 13887 private void cleanUpResourcesLI(List<String> allCodePaths) { 13888 cleanUp(); 13889 removeDexFiles(allCodePaths, instructionSets); 13890 } 13891 13892 String getPackageName() { 13893 return getAsecPackageName(cid); 13894 } 13895 13896 boolean doPostDeleteLI(boolean delete) { 13897 if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete); 13898 final List<String> allCodePaths = getAllCodePaths(); 13899 boolean mounted = PackageHelper.isContainerMounted(cid); 13900 if (mounted) { 13901 // Unmount first 13902 if (PackageHelper.unMountSdDir(cid)) { 13903 mounted = false; 13904 } 13905 } 13906 if (!mounted && delete) { 13907 cleanUpResourcesLI(allCodePaths); 13908 } 13909 return !mounted; 13910 } 13911 13912 @Override 13913 int doPreCopy() { 13914 if (isFwdLocked()) { 13915 if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE, 13916 MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) { 13917 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 13918 } 13919 } 13920 13921 return PackageManager.INSTALL_SUCCEEDED; 13922 } 13923 13924 @Override 13925 int doPostCopy(int uid) { 13926 if (isFwdLocked()) { 13927 if (uid < Process.FIRST_APPLICATION_UID 13928 || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid), 13929 RES_FILE_NAME)) { 13930 Slog.e(TAG, "Failed to finalize " + cid); 13931 PackageHelper.destroySdDir(cid); 13932 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 13933 } 13934 } 13935 13936 return PackageManager.INSTALL_SUCCEEDED; 13937 } 13938 } 13939 13940 /** 13941 * Logic to handle movement of existing installed applications. 13942 */ 13943 class MoveInstallArgs extends InstallArgs { 13944 private File codeFile; 13945 private File resourceFile; 13946 13947 /** New install */ 13948 MoveInstallArgs(InstallParams params) { 13949 super(params.origin, params.move, params.observer, params.installFlags, 13950 params.installerPackageName, params.volumeUuid, 13951 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 13952 params.grantedRuntimePermissions, 13953 params.traceMethod, params.traceCookie, params.certificates); 13954 } 13955 13956 int copyApk(IMediaContainerService imcs, boolean temp) { 13957 if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from " 13958 + move.fromUuid + " to " + move.toUuid); 13959 synchronized (mInstaller) { 13960 try { 13961 mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName, 13962 move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion); 13963 } catch (InstallerException e) { 13964 Slog.w(TAG, "Failed to move app", e); 13965 return PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 13966 } 13967 } 13968 13969 codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName); 13970 resourceFile = codeFile; 13971 if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile); 13972 13973 return PackageManager.INSTALL_SUCCEEDED; 13974 } 13975 13976 int doPreInstall(int status) { 13977 if (status != PackageManager.INSTALL_SUCCEEDED) { 13978 cleanUp(move.toUuid); 13979 } 13980 return status; 13981 } 13982 13983 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 13984 if (status != PackageManager.INSTALL_SUCCEEDED) { 13985 cleanUp(move.toUuid); 13986 return false; 13987 } 13988 13989 // Reflect the move in app info 13990 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 13991 pkg.setApplicationInfoCodePath(pkg.codePath); 13992 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 13993 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 13994 pkg.setApplicationInfoResourcePath(pkg.codePath); 13995 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 13996 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 13997 13998 return true; 13999 } 14000 14001 int doPostInstall(int status, int uid) { 14002 if (status == PackageManager.INSTALL_SUCCEEDED) { 14003 cleanUp(move.fromUuid); 14004 } else { 14005 cleanUp(move.toUuid); 14006 } 14007 return status; 14008 } 14009 14010 @Override 14011 String getCodePath() { 14012 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 14013 } 14014 14015 @Override 14016 String getResourcePath() { 14017 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 14018 } 14019 14020 private boolean cleanUp(String volumeUuid) { 14021 final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid), 14022 move.dataAppName); 14023 Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid); 14024 final int[] userIds = sUserManager.getUserIds(); 14025 synchronized (mInstallLock) { 14026 // Clean up both app data and code 14027 // All package moves are frozen until finished 14028 for (int userId : userIds) { 14029 try { 14030 mInstaller.destroyAppData(volumeUuid, move.packageName, userId, 14031 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0); 14032 } catch (InstallerException e) { 14033 Slog.w(TAG, String.valueOf(e)); 14034 } 14035 } 14036 removeCodePathLI(codeFile); 14037 } 14038 return true; 14039 } 14040 14041 void cleanUpResourcesLI() { 14042 throw new UnsupportedOperationException(); 14043 } 14044 14045 boolean doPostDeleteLI(boolean delete) { 14046 throw new UnsupportedOperationException(); 14047 } 14048 } 14049 14050 static String getAsecPackageName(String packageCid) { 14051 int idx = packageCid.lastIndexOf("-"); 14052 if (idx == -1) { 14053 return packageCid; 14054 } 14055 return packageCid.substring(0, idx); 14056 } 14057 14058 // Utility method used to create code paths based on package name and available index. 14059 private static String getNextCodePath(String oldCodePath, String prefix, String suffix) { 14060 String idxStr = ""; 14061 int idx = 1; 14062 // Fall back to default value of idx=1 if prefix is not 14063 // part of oldCodePath 14064 if (oldCodePath != null) { 14065 String subStr = oldCodePath; 14066 // Drop the suffix right away 14067 if (suffix != null && subStr.endsWith(suffix)) { 14068 subStr = subStr.substring(0, subStr.length() - suffix.length()); 14069 } 14070 // If oldCodePath already contains prefix find out the 14071 // ending index to either increment or decrement. 14072 int sidx = subStr.lastIndexOf(prefix); 14073 if (sidx != -1) { 14074 subStr = subStr.substring(sidx + prefix.length()); 14075 if (subStr != null) { 14076 if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) { 14077 subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length()); 14078 } 14079 try { 14080 idx = Integer.parseInt(subStr); 14081 if (idx <= 1) { 14082 idx++; 14083 } else { 14084 idx--; 14085 } 14086 } catch(NumberFormatException e) { 14087 } 14088 } 14089 } 14090 } 14091 idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx); 14092 return prefix + idxStr; 14093 } 14094 14095 private File getNextCodePath(File targetDir, String packageName) { 14096 int suffix = 1; 14097 File result; 14098 do { 14099 result = new File(targetDir, packageName + "-" + suffix); 14100 suffix++; 14101 } while (result.exists()); 14102 return result; 14103 } 14104 14105 // Utility method that returns the relative package path with respect 14106 // to the installation directory. Like say for /data/data/com.test-1.apk 14107 // string com.test-1 is returned. 14108 static String deriveCodePathName(String codePath) { 14109 if (codePath == null) { 14110 return null; 14111 } 14112 final File codeFile = new File(codePath); 14113 final String name = codeFile.getName(); 14114 if (codeFile.isDirectory()) { 14115 return name; 14116 } else if (name.endsWith(".apk") || name.endsWith(".tmp")) { 14117 final int lastDot = name.lastIndexOf('.'); 14118 return name.substring(0, lastDot); 14119 } else { 14120 Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK"); 14121 return null; 14122 } 14123 } 14124 14125 static class PackageInstalledInfo { 14126 String name; 14127 int uid; 14128 // The set of users that originally had this package installed. 14129 int[] origUsers; 14130 // The set of users that now have this package installed. 14131 int[] newUsers; 14132 PackageParser.Package pkg; 14133 int returnCode; 14134 String returnMsg; 14135 PackageRemovedInfo removedInfo; 14136 ArrayMap<String, PackageInstalledInfo> addedChildPackages; 14137 14138 public void setError(int code, String msg) { 14139 setReturnCode(code); 14140 setReturnMessage(msg); 14141 Slog.w(TAG, msg); 14142 } 14143 14144 public void setError(String msg, PackageParserException e) { 14145 setReturnCode(e.error); 14146 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e)); 14147 Slog.w(TAG, msg, e); 14148 } 14149 14150 public void setError(String msg, PackageManagerException e) { 14151 returnCode = e.error; 14152 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e)); 14153 Slog.w(TAG, msg, e); 14154 } 14155 14156 public void setReturnCode(int returnCode) { 14157 this.returnCode = returnCode; 14158 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0; 14159 for (int i = 0; i < childCount; i++) { 14160 addedChildPackages.valueAt(i).returnCode = returnCode; 14161 } 14162 } 14163 14164 private void setReturnMessage(String returnMsg) { 14165 this.returnMsg = returnMsg; 14166 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0; 14167 for (int i = 0; i < childCount; i++) { 14168 addedChildPackages.valueAt(i).returnMsg = returnMsg; 14169 } 14170 } 14171 14172 // In some error cases we want to convey more info back to the observer 14173 String origPackage; 14174 String origPermission; 14175 } 14176 14177 /* 14178 * Install a non-existing package. 14179 */ 14180 private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags, 14181 int scanFlags, UserHandle user, String installerPackageName, String volumeUuid, 14182 PackageInstalledInfo res) { 14183 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage"); 14184 14185 // Remember this for later, in case we need to rollback this install 14186 String pkgName = pkg.packageName; 14187 14188 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg); 14189 14190 synchronized(mPackages) { 14191 if (mSettings.mRenamedPackages.containsKey(pkgName)) { 14192 // A package with the same name is already installed, though 14193 // it has been renamed to an older name. The package we 14194 // are trying to install should be installed as an update to 14195 // the existing one, but that has not been requested, so bail. 14196 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 14197 + " without first uninstalling package running as " 14198 + mSettings.mRenamedPackages.get(pkgName)); 14199 return; 14200 } 14201 if (mPackages.containsKey(pkgName)) { 14202 // Don't allow installation over an existing package with the same name. 14203 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 14204 + " without first uninstalling."); 14205 return; 14206 } 14207 } 14208 14209 try { 14210 PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 14211 System.currentTimeMillis(), user); 14212 14213 updateSettingsLI(newPackage, installerPackageName, null, res, user); 14214 14215 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 14216 prepareAppDataAfterInstallLIF(newPackage); 14217 14218 } else { 14219 // Remove package from internal structures, but keep around any 14220 // data that might have already existed 14221 deletePackageLIF(pkgName, UserHandle.ALL, false, null, 14222 PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null); 14223 } 14224 } catch (PackageManagerException e) { 14225 res.setError("Package couldn't be installed in " + pkg.codePath, e); 14226 } 14227 14228 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14229 } 14230 14231 private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) { 14232 // Can't rotate keys during boot or if sharedUser. 14233 if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null 14234 || !oldPs.keySetData.isUsingUpgradeKeySets()) { 14235 return false; 14236 } 14237 // app is using upgradeKeySets; make sure all are valid 14238 KeySetManagerService ksms = mSettings.mKeySetManagerService; 14239 long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets(); 14240 for (int i = 0; i < upgradeKeySets.length; i++) { 14241 if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) { 14242 Slog.wtf(TAG, "Package " 14243 + (oldPs.name != null ? oldPs.name : "<null>") 14244 + " contains upgrade-key-set reference to unknown key-set: " 14245 + upgradeKeySets[i] 14246 + " reverting to signatures check."); 14247 return false; 14248 } 14249 } 14250 return true; 14251 } 14252 14253 private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) { 14254 // Upgrade keysets are being used. Determine if new package has a superset of the 14255 // required keys. 14256 long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets(); 14257 KeySetManagerService ksms = mSettings.mKeySetManagerService; 14258 for (int i = 0; i < upgradeKeySets.length; i++) { 14259 Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]); 14260 if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) { 14261 return true; 14262 } 14263 } 14264 return false; 14265 } 14266 14267 private static void updateDigest(MessageDigest digest, File file) throws IOException { 14268 try (DigestInputStream digestStream = 14269 new DigestInputStream(new FileInputStream(file), digest)) { 14270 while (digestStream.read() != -1) {} // nothing to do; just plow through the file 14271 } 14272 } 14273 14274 private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags, 14275 UserHandle user, String installerPackageName, PackageInstalledInfo res) { 14276 final boolean isEphemeral = (policyFlags & PackageParser.PARSE_IS_EPHEMERAL) != 0; 14277 14278 final PackageParser.Package oldPackage; 14279 final String pkgName = pkg.packageName; 14280 final int[] allUsers; 14281 final int[] installedUsers; 14282 14283 synchronized(mPackages) { 14284 oldPackage = mPackages.get(pkgName); 14285 if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage); 14286 14287 // don't allow upgrade to target a release SDK from a pre-release SDK 14288 final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion 14289 == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT; 14290 final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion 14291 == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT; 14292 if (oldTargetsPreRelease 14293 && !newTargetsPreRelease 14294 && ((policyFlags & PackageParser.PARSE_FORCE_SDK) == 0)) { 14295 Slog.w(TAG, "Can't install package targeting released sdk"); 14296 res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE); 14297 return; 14298 } 14299 14300 // don't allow an upgrade from full to ephemeral 14301 final boolean oldIsEphemeral = oldPackage.applicationInfo.isEphemeralApp(); 14302 if (isEphemeral && !oldIsEphemeral) { 14303 // can't downgrade from full to ephemeral 14304 Slog.w(TAG, "Can't replace app with ephemeral: " + pkgName); 14305 res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID); 14306 return; 14307 } 14308 14309 // verify signatures are valid 14310 final PackageSetting ps = mSettings.mPackages.get(pkgName); 14311 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { 14312 if (!checkUpgradeKeySetLP(ps, pkg)) { 14313 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 14314 "New package not signed by keys specified by upgrade-keysets: " 14315 + pkgName); 14316 return; 14317 } 14318 } else { 14319 // default to original signature matching 14320 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures) 14321 != PackageManager.SIGNATURE_MATCH) { 14322 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 14323 "New package has a different signature: " + pkgName); 14324 return; 14325 } 14326 } 14327 14328 // don't allow a system upgrade unless the upgrade hash matches 14329 if (oldPackage.restrictUpdateHash != null && oldPackage.isSystemApp()) { 14330 byte[] digestBytes = null; 14331 try { 14332 final MessageDigest digest = MessageDigest.getInstance("SHA-512"); 14333 updateDigest(digest, new File(pkg.baseCodePath)); 14334 if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) { 14335 for (String path : pkg.splitCodePaths) { 14336 updateDigest(digest, new File(path)); 14337 } 14338 } 14339 digestBytes = digest.digest(); 14340 } catch (NoSuchAlgorithmException | IOException e) { 14341 res.setError(INSTALL_FAILED_INVALID_APK, 14342 "Could not compute hash: " + pkgName); 14343 return; 14344 } 14345 if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) { 14346 res.setError(INSTALL_FAILED_INVALID_APK, 14347 "New package fails restrict-update check: " + pkgName); 14348 return; 14349 } 14350 // retain upgrade restriction 14351 pkg.restrictUpdateHash = oldPackage.restrictUpdateHash; 14352 } 14353 14354 // Check for shared user id changes 14355 String invalidPackageName = 14356 getParentOrChildPackageChangedSharedUser(oldPackage, pkg); 14357 if (invalidPackageName != null) { 14358 res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 14359 "Package " + invalidPackageName + " tried to change user " 14360 + oldPackage.mSharedUserId); 14361 return; 14362 } 14363 14364 // In case of rollback, remember per-user/profile install state 14365 allUsers = sUserManager.getUserIds(); 14366 installedUsers = ps.queryInstalledUsers(allUsers, true); 14367 } 14368 14369 // Update what is removed 14370 res.removedInfo = new PackageRemovedInfo(); 14371 res.removedInfo.uid = oldPackage.applicationInfo.uid; 14372 res.removedInfo.removedPackage = oldPackage.packageName; 14373 res.removedInfo.isUpdate = true; 14374 res.removedInfo.origUsers = installedUsers; 14375 final int childCount = (oldPackage.childPackages != null) 14376 ? oldPackage.childPackages.size() : 0; 14377 for (int i = 0; i < childCount; i++) { 14378 boolean childPackageUpdated = false; 14379 PackageParser.Package childPkg = oldPackage.childPackages.get(i); 14380 if (res.addedChildPackages != null) { 14381 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName); 14382 if (childRes != null) { 14383 childRes.removedInfo.uid = childPkg.applicationInfo.uid; 14384 childRes.removedInfo.removedPackage = childPkg.packageName; 14385 childRes.removedInfo.isUpdate = true; 14386 childPackageUpdated = true; 14387 } 14388 } 14389 if (!childPackageUpdated) { 14390 PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(); 14391 childRemovedRes.removedPackage = childPkg.packageName; 14392 childRemovedRes.isUpdate = false; 14393 childRemovedRes.dataRemoved = true; 14394 synchronized (mPackages) { 14395 PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName); 14396 if (childPs != null) { 14397 childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true); 14398 } 14399 } 14400 if (res.removedInfo.removedChildPackages == null) { 14401 res.removedInfo.removedChildPackages = new ArrayMap<>(); 14402 } 14403 res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes); 14404 } 14405 } 14406 14407 boolean sysPkg = (isSystemApp(oldPackage)); 14408 if (sysPkg) { 14409 // Set the system/privileged flags as needed 14410 final boolean privileged = 14411 (oldPackage.applicationInfo.privateFlags 14412 & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; 14413 final int systemPolicyFlags = policyFlags 14414 | PackageParser.PARSE_IS_SYSTEM 14415 | (privileged ? PackageParser.PARSE_IS_PRIVILEGED : 0); 14416 14417 replaceSystemPackageLIF(oldPackage, pkg, systemPolicyFlags, scanFlags, 14418 user, allUsers, installerPackageName, res); 14419 } else { 14420 replaceNonSystemPackageLIF(oldPackage, pkg, policyFlags, scanFlags, 14421 user, allUsers, installerPackageName, res); 14422 } 14423 } 14424 14425 public List<String> getPreviousCodePaths(String packageName) { 14426 final PackageSetting ps = mSettings.mPackages.get(packageName); 14427 final List<String> result = new ArrayList<String>(); 14428 if (ps != null && ps.oldCodePaths != null) { 14429 result.addAll(ps.oldCodePaths); 14430 } 14431 return result; 14432 } 14433 14434 private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage, 14435 PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user, 14436 int[] allUsers, String installerPackageName, PackageInstalledInfo res) { 14437 if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old=" 14438 + deletedPackage); 14439 14440 String pkgName = deletedPackage.packageName; 14441 boolean deletedPkg = true; 14442 boolean addedPkg = false; 14443 boolean updatedSettings = false; 14444 final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0; 14445 final int deleteFlags = PackageManager.DELETE_KEEP_DATA 14446 | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP); 14447 14448 final long origUpdateTime = (pkg.mExtras != null) 14449 ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0; 14450 14451 // First delete the existing package while retaining the data directory 14452 if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags, 14453 res.removedInfo, true, pkg)) { 14454 // If the existing package wasn't successfully deleted 14455 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI"); 14456 deletedPkg = false; 14457 } else { 14458 // Successfully deleted the old package; proceed with replace. 14459 14460 // If deleted package lived in a container, give users a chance to 14461 // relinquish resources before killing. 14462 if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) { 14463 if (DEBUG_INSTALL) { 14464 Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE"); 14465 } 14466 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid }; 14467 final ArrayList<String> pkgList = new ArrayList<String>(1); 14468 pkgList.add(deletedPackage.applicationInfo.packageName); 14469 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null); 14470 } 14471 14472 clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE 14473 | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 14474 clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL); 14475 14476 try { 14477 final PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, 14478 scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user); 14479 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user); 14480 14481 // Update the in-memory copy of the previous code paths. 14482 PackageSetting ps = mSettings.mPackages.get(pkgName); 14483 if (!killApp) { 14484 if (ps.oldCodePaths == null) { 14485 ps.oldCodePaths = new ArraySet<>(); 14486 } 14487 Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath); 14488 if (deletedPackage.splitCodePaths != null) { 14489 Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths); 14490 } 14491 } else { 14492 ps.oldCodePaths = null; 14493 } 14494 if (ps.childPackageNames != null) { 14495 for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) { 14496 final String childPkgName = ps.childPackageNames.get(i); 14497 final PackageSetting childPs = mSettings.mPackages.get(childPkgName); 14498 childPs.oldCodePaths = ps.oldCodePaths; 14499 } 14500 } 14501 prepareAppDataAfterInstallLIF(newPackage); 14502 addedPkg = true; 14503 } catch (PackageManagerException e) { 14504 res.setError("Package couldn't be installed in " + pkg.codePath, e); 14505 } 14506 } 14507 14508 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 14509 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName); 14510 14511 // Revert all internal state mutations and added folders for the failed install 14512 if (addedPkg) { 14513 deletePackageLIF(pkgName, null, true, allUsers, deleteFlags, 14514 res.removedInfo, true, null); 14515 } 14516 14517 // Restore the old package 14518 if (deletedPkg) { 14519 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage); 14520 File restoreFile = new File(deletedPackage.codePath); 14521 // Parse old package 14522 boolean oldExternal = isExternal(deletedPackage); 14523 int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY | 14524 (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) | 14525 (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0); 14526 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME; 14527 try { 14528 scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, 14529 null); 14530 } catch (PackageManagerException e) { 14531 Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: " 14532 + e.getMessage()); 14533 return; 14534 } 14535 14536 synchronized (mPackages) { 14537 // Ensure the installer package name up to date 14538 setInstallerPackageNameLPw(deletedPackage, installerPackageName); 14539 14540 // Update permissions for restored package 14541 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL); 14542 14543 mSettings.writeLPr(); 14544 } 14545 14546 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade"); 14547 } 14548 } else { 14549 synchronized (mPackages) { 14550 PackageSetting ps = mSettings.peekPackageLPr(pkg.packageName); 14551 if (ps != null) { 14552 res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null; 14553 if (res.removedInfo.removedChildPackages != null) { 14554 final int childCount = res.removedInfo.removedChildPackages.size(); 14555 // Iterate in reverse as we may modify the collection 14556 for (int i = childCount - 1; i >= 0; i--) { 14557 String childPackageName = res.removedInfo.removedChildPackages.keyAt(i); 14558 if (res.addedChildPackages.containsKey(childPackageName)) { 14559 res.removedInfo.removedChildPackages.removeAt(i); 14560 } else { 14561 PackageRemovedInfo childInfo = res.removedInfo 14562 .removedChildPackages.valueAt(i); 14563 childInfo.removedForAllUsers = mPackages.get( 14564 childInfo.removedPackage) == null; 14565 } 14566 } 14567 } 14568 } 14569 } 14570 } 14571 } 14572 14573 private void replaceSystemPackageLIF(PackageParser.Package deletedPackage, 14574 PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user, 14575 int[] allUsers, String installerPackageName, PackageInstalledInfo res) { 14576 if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg 14577 + ", old=" + deletedPackage); 14578 14579 final boolean disabledSystem; 14580 14581 // Remove existing system package 14582 removePackageLI(deletedPackage, true); 14583 14584 synchronized (mPackages) { 14585 disabledSystem = disableSystemPackageLPw(deletedPackage, pkg); 14586 } 14587 if (!disabledSystem) { 14588 // We didn't need to disable the .apk as a current system package, 14589 // which means we are replacing another update that is already 14590 // installed. We need to make sure to delete the older one's .apk. 14591 res.removedInfo.args = createInstallArgsForExisting(0, 14592 deletedPackage.applicationInfo.getCodePath(), 14593 deletedPackage.applicationInfo.getResourcePath(), 14594 getAppDexInstructionSets(deletedPackage.applicationInfo)); 14595 } else { 14596 res.removedInfo.args = null; 14597 } 14598 14599 // Successfully disabled the old package. Now proceed with re-installation 14600 clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE 14601 | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 14602 clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL); 14603 14604 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 14605 pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP, 14606 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP); 14607 14608 PackageParser.Package newPackage = null; 14609 try { 14610 // Add the package to the internal data structures 14611 newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 0, user); 14612 14613 // Set the update and install times 14614 PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras; 14615 setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime, 14616 System.currentTimeMillis()); 14617 14618 // Update the package dynamic state if succeeded 14619 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 14620 // Now that the install succeeded make sure we remove data 14621 // directories for any child package the update removed. 14622 final int deletedChildCount = (deletedPackage.childPackages != null) 14623 ? deletedPackage.childPackages.size() : 0; 14624 final int newChildCount = (newPackage.childPackages != null) 14625 ? newPackage.childPackages.size() : 0; 14626 for (int i = 0; i < deletedChildCount; i++) { 14627 PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i); 14628 boolean childPackageDeleted = true; 14629 for (int j = 0; j < newChildCount; j++) { 14630 PackageParser.Package newChildPkg = newPackage.childPackages.get(j); 14631 if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) { 14632 childPackageDeleted = false; 14633 break; 14634 } 14635 } 14636 if (childPackageDeleted) { 14637 PackageSetting ps = mSettings.getDisabledSystemPkgLPr( 14638 deletedChildPkg.packageName); 14639 if (ps != null && res.removedInfo.removedChildPackages != null) { 14640 PackageRemovedInfo removedChildRes = res.removedInfo 14641 .removedChildPackages.get(deletedChildPkg.packageName); 14642 removePackageDataLIF(ps, allUsers, removedChildRes, 0, false); 14643 removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null; 14644 } 14645 } 14646 } 14647 14648 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user); 14649 prepareAppDataAfterInstallLIF(newPackage); 14650 } 14651 } catch (PackageManagerException e) { 14652 res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR); 14653 res.setError("Package couldn't be installed in " + pkg.codePath, e); 14654 } 14655 14656 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 14657 // Re installation failed. Restore old information 14658 // Remove new pkg information 14659 if (newPackage != null) { 14660 removeInstalledPackageLI(newPackage, true); 14661 } 14662 // Add back the old system package 14663 try { 14664 scanPackageTracedLI(deletedPackage, policyFlags, SCAN_UPDATE_SIGNATURE, 0, user); 14665 } catch (PackageManagerException e) { 14666 Slog.e(TAG, "Failed to restore original package: " + e.getMessage()); 14667 } 14668 14669 synchronized (mPackages) { 14670 if (disabledSystem) { 14671 enableSystemPackageLPw(deletedPackage); 14672 } 14673 14674 // Ensure the installer package name up to date 14675 setInstallerPackageNameLPw(deletedPackage, installerPackageName); 14676 14677 // Update permissions for restored package 14678 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL); 14679 14680 mSettings.writeLPr(); 14681 } 14682 14683 Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName 14684 + " after failed upgrade"); 14685 } 14686 } 14687 14688 /** 14689 * Checks whether the parent or any of the child packages have a change shared 14690 * user. For a package to be a valid update the shred users of the parent and 14691 * the children should match. We may later support changing child shared users. 14692 * @param oldPkg The updated package. 14693 * @param newPkg The update package. 14694 * @return The shared user that change between the versions. 14695 */ 14696 private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg, 14697 PackageParser.Package newPkg) { 14698 // Check parent shared user 14699 if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) { 14700 return newPkg.packageName; 14701 } 14702 // Check child shared users 14703 final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0; 14704 final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0; 14705 for (int i = 0; i < newChildCount; i++) { 14706 PackageParser.Package newChildPkg = newPkg.childPackages.get(i); 14707 // If this child was present, did it have the same shared user? 14708 for (int j = 0; j < oldChildCount; j++) { 14709 PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j); 14710 if (newChildPkg.packageName.equals(oldChildPkg.packageName) 14711 && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) { 14712 return newChildPkg.packageName; 14713 } 14714 } 14715 } 14716 return null; 14717 } 14718 14719 private void removeNativeBinariesLI(PackageSetting ps) { 14720 // Remove the lib path for the parent package 14721 if (ps != null) { 14722 NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString); 14723 // Remove the lib path for the child packages 14724 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0; 14725 for (int i = 0; i < childCount; i++) { 14726 PackageSetting childPs = null; 14727 synchronized (mPackages) { 14728 childPs = mSettings.peekPackageLPr(ps.childPackageNames.get(i)); 14729 } 14730 if (childPs != null) { 14731 NativeLibraryHelper.removeNativeBinariesLI(childPs 14732 .legacyNativeLibraryPathString); 14733 } 14734 } 14735 } 14736 } 14737 14738 private void enableSystemPackageLPw(PackageParser.Package pkg) { 14739 // Enable the parent package 14740 mSettings.enableSystemPackageLPw(pkg.packageName); 14741 // Enable the child packages 14742 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 14743 for (int i = 0; i < childCount; i++) { 14744 PackageParser.Package childPkg = pkg.childPackages.get(i); 14745 mSettings.enableSystemPackageLPw(childPkg.packageName); 14746 } 14747 } 14748 14749 private boolean disableSystemPackageLPw(PackageParser.Package oldPkg, 14750 PackageParser.Package newPkg) { 14751 // Disable the parent package (parent always replaced) 14752 boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true); 14753 // Disable the child packages 14754 final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0; 14755 for (int i = 0; i < childCount; i++) { 14756 PackageParser.Package childPkg = oldPkg.childPackages.get(i); 14757 final boolean replace = newPkg.hasChildPackage(childPkg.packageName); 14758 disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace); 14759 } 14760 return disabled; 14761 } 14762 14763 private void setInstallerPackageNameLPw(PackageParser.Package pkg, 14764 String installerPackageName) { 14765 // Enable the parent package 14766 mSettings.setInstallerPackageName(pkg.packageName, installerPackageName); 14767 // Enable the child packages 14768 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 14769 for (int i = 0; i < childCount; i++) { 14770 PackageParser.Package childPkg = pkg.childPackages.get(i); 14771 mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName); 14772 } 14773 } 14774 14775 private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) { 14776 // Collect all used permissions in the UID 14777 ArraySet<String> usedPermissions = new ArraySet<>(); 14778 final int packageCount = su.packages.size(); 14779 for (int i = 0; i < packageCount; i++) { 14780 PackageSetting ps = su.packages.valueAt(i); 14781 if (ps.pkg == null) { 14782 continue; 14783 } 14784 final int requestedPermCount = ps.pkg.requestedPermissions.size(); 14785 for (int j = 0; j < requestedPermCount; j++) { 14786 String permission = ps.pkg.requestedPermissions.get(j); 14787 BasePermission bp = mSettings.mPermissions.get(permission); 14788 if (bp != null) { 14789 usedPermissions.add(permission); 14790 } 14791 } 14792 } 14793 14794 PermissionsState permissionsState = su.getPermissionsState(); 14795 // Prune install permissions 14796 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates(); 14797 final int installPermCount = installPermStates.size(); 14798 for (int i = installPermCount - 1; i >= 0; i--) { 14799 PermissionState permissionState = installPermStates.get(i); 14800 if (!usedPermissions.contains(permissionState.getName())) { 14801 BasePermission bp = mSettings.mPermissions.get(permissionState.getName()); 14802 if (bp != null) { 14803 permissionsState.revokeInstallPermission(bp); 14804 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 14805 PackageManager.MASK_PERMISSION_FLAGS, 0); 14806 } 14807 } 14808 } 14809 14810 int[] runtimePermissionChangedUserIds = EmptyArray.INT; 14811 14812 // Prune runtime permissions 14813 for (int userId : allUserIds) { 14814 List<PermissionState> runtimePermStates = permissionsState 14815 .getRuntimePermissionStates(userId); 14816 final int runtimePermCount = runtimePermStates.size(); 14817 for (int i = runtimePermCount - 1; i >= 0; i--) { 14818 PermissionState permissionState = runtimePermStates.get(i); 14819 if (!usedPermissions.contains(permissionState.getName())) { 14820 BasePermission bp = mSettings.mPermissions.get(permissionState.getName()); 14821 if (bp != null) { 14822 permissionsState.revokeRuntimePermission(bp, userId); 14823 permissionsState.updatePermissionFlags(bp, userId, 14824 PackageManager.MASK_PERMISSION_FLAGS, 0); 14825 runtimePermissionChangedUserIds = ArrayUtils.appendInt( 14826 runtimePermissionChangedUserIds, userId); 14827 } 14828 } 14829 } 14830 } 14831 14832 return runtimePermissionChangedUserIds; 14833 } 14834 14835 private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, 14836 int[] allUsers, PackageInstalledInfo res, UserHandle user) { 14837 // Update the parent package setting 14838 updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers, 14839 res, user); 14840 // Update the child packages setting 14841 final int childCount = (newPackage.childPackages != null) 14842 ? newPackage.childPackages.size() : 0; 14843 for (int i = 0; i < childCount; i++) { 14844 PackageParser.Package childPackage = newPackage.childPackages.get(i); 14845 PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName); 14846 updateSettingsInternalLI(childPackage, installerPackageName, allUsers, 14847 childRes.origUsers, childRes, user); 14848 } 14849 } 14850 14851 private void updateSettingsInternalLI(PackageParser.Package newPackage, 14852 String installerPackageName, int[] allUsers, int[] installedForUsers, 14853 PackageInstalledInfo res, UserHandle user) { 14854 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 14855 14856 String pkgName = newPackage.packageName; 14857 synchronized (mPackages) { 14858 //write settings. the installStatus will be incomplete at this stage. 14859 //note that the new package setting would have already been 14860 //added to mPackages. It hasn't been persisted yet. 14861 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE); 14862 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings"); 14863 mSettings.writeLPr(); 14864 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14865 } 14866 14867 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath); 14868 synchronized (mPackages) { 14869 updatePermissionsLPw(newPackage.packageName, newPackage, 14870 UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0 14871 ? UPDATE_PERMISSIONS_ALL : 0)); 14872 // For system-bundled packages, we assume that installing an upgraded version 14873 // of the package implies that the user actually wants to run that new code, 14874 // so we enable the package. 14875 PackageSetting ps = mSettings.mPackages.get(pkgName); 14876 final int userId = user.getIdentifier(); 14877 if (ps != null) { 14878 if (isSystemApp(newPackage)) { 14879 if (DEBUG_INSTALL) { 14880 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName); 14881 } 14882 // Enable system package for requested users 14883 if (res.origUsers != null) { 14884 for (int origUserId : res.origUsers) { 14885 if (userId == UserHandle.USER_ALL || userId == origUserId) { 14886 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 14887 origUserId, installerPackageName); 14888 } 14889 } 14890 } 14891 // Also convey the prior install/uninstall state 14892 if (allUsers != null && installedForUsers != null) { 14893 for (int currentUserId : allUsers) { 14894 final boolean installed = ArrayUtils.contains( 14895 installedForUsers, currentUserId); 14896 if (DEBUG_INSTALL) { 14897 Slog.d(TAG, " user " + currentUserId + " => " + installed); 14898 } 14899 ps.setInstalled(installed, currentUserId); 14900 } 14901 // these install state changes will be persisted in the 14902 // upcoming call to mSettings.writeLPr(). 14903 } 14904 } 14905 // It's implied that when a user requests installation, they want the app to be 14906 // installed and enabled. 14907 if (userId != UserHandle.USER_ALL) { 14908 ps.setInstalled(true, userId); 14909 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName); 14910 } 14911 } 14912 res.name = pkgName; 14913 res.uid = newPackage.applicationInfo.uid; 14914 res.pkg = newPackage; 14915 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE); 14916 mSettings.setInstallerPackageName(pkgName, installerPackageName); 14917 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 14918 //to update install status 14919 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings"); 14920 mSettings.writeLPr(); 14921 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14922 } 14923 14924 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14925 } 14926 14927 private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) { 14928 try { 14929 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage"); 14930 installPackageLI(args, res); 14931 } finally { 14932 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14933 } 14934 } 14935 14936 private void installPackageLI(InstallArgs args, PackageInstalledInfo res) { 14937 final int installFlags = args.installFlags; 14938 final String installerPackageName = args.installerPackageName; 14939 final String volumeUuid = args.volumeUuid; 14940 final File tmpPackageFile = new File(args.getCodePath()); 14941 final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0); 14942 final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) 14943 || (args.volumeUuid != null)); 14944 final boolean ephemeral = ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0); 14945 final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0); 14946 boolean replace = false; 14947 int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE; 14948 if (args.move != null) { 14949 // moving a complete application; perform an initial scan on the new install location 14950 scanFlags |= SCAN_INITIAL; 14951 } 14952 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) { 14953 scanFlags |= SCAN_DONT_KILL_APP; 14954 } 14955 14956 // Result object to be returned 14957 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 14958 14959 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile); 14960 14961 // Sanity check 14962 if (ephemeral && (forwardLocked || onExternal)) { 14963 Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked 14964 + " external=" + onExternal); 14965 res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID); 14966 return; 14967 } 14968 14969 // Retrieve PackageSettings and parse package 14970 final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY 14971 | PackageParser.PARSE_ENFORCE_CODE 14972 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) 14973 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0) 14974 | (ephemeral ? PackageParser.PARSE_IS_EPHEMERAL : 0) 14975 | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0); 14976 PackageParser pp = new PackageParser(); 14977 pp.setSeparateProcesses(mSeparateProcesses); 14978 pp.setDisplayMetrics(mMetrics); 14979 14980 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage"); 14981 final PackageParser.Package pkg; 14982 try { 14983 pkg = pp.parsePackage(tmpPackageFile, parseFlags); 14984 } catch (PackageParserException e) { 14985 res.setError("Failed parse during installPackageLI", e); 14986 return; 14987 } finally { 14988 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14989 } 14990 14991 // If we are installing a clustered package add results for the children 14992 if (pkg.childPackages != null) { 14993 synchronized (mPackages) { 14994 final int childCount = pkg.childPackages.size(); 14995 for (int i = 0; i < childCount; i++) { 14996 PackageParser.Package childPkg = pkg.childPackages.get(i); 14997 PackageInstalledInfo childRes = new PackageInstalledInfo(); 14998 childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 14999 childRes.pkg = childPkg; 15000 childRes.name = childPkg.packageName; 15001 PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName); 15002 if (childPs != null) { 15003 childRes.origUsers = childPs.queryInstalledUsers( 15004 sUserManager.getUserIds(), true); 15005 } 15006 if ((mPackages.containsKey(childPkg.packageName))) { 15007 childRes.removedInfo = new PackageRemovedInfo(); 15008 childRes.removedInfo.removedPackage = childPkg.packageName; 15009 } 15010 if (res.addedChildPackages == null) { 15011 res.addedChildPackages = new ArrayMap<>(); 15012 } 15013 res.addedChildPackages.put(childPkg.packageName, childRes); 15014 } 15015 } 15016 } 15017 15018 // If package doesn't declare API override, mark that we have an install 15019 // time CPU ABI override. 15020 if (TextUtils.isEmpty(pkg.cpuAbiOverride)) { 15021 pkg.cpuAbiOverride = args.abiOverride; 15022 } 15023 15024 String pkgName = res.name = pkg.packageName; 15025 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) { 15026 if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) { 15027 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI"); 15028 return; 15029 } 15030 } 15031 15032 try { 15033 // either use what we've been given or parse directly from the APK 15034 if (args.certificates != null) { 15035 try { 15036 PackageParser.populateCertificates(pkg, args.certificates); 15037 } catch (PackageParserException e) { 15038 // there was something wrong with the certificates we were given; 15039 // try to pull them from the APK 15040 PackageParser.collectCertificates(pkg, parseFlags); 15041 } 15042 } else { 15043 PackageParser.collectCertificates(pkg, parseFlags); 15044 } 15045 } catch (PackageParserException e) { 15046 res.setError("Failed collect during installPackageLI", e); 15047 return; 15048 } 15049 15050 // Get rid of all references to package scan path via parser. 15051 pp = null; 15052 String oldCodePath = null; 15053 boolean systemApp = false; 15054 synchronized (mPackages) { 15055 // Check if installing already existing package 15056 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 15057 String oldName = mSettings.mRenamedPackages.get(pkgName); 15058 if (pkg.mOriginalPackages != null 15059 && pkg.mOriginalPackages.contains(oldName) 15060 && mPackages.containsKey(oldName)) { 15061 // This package is derived from an original package, 15062 // and this device has been updating from that original 15063 // name. We must continue using the original name, so 15064 // rename the new package here. 15065 pkg.setPackageName(oldName); 15066 pkgName = pkg.packageName; 15067 replace = true; 15068 if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName=" 15069 + oldName + " pkgName=" + pkgName); 15070 } else if (mPackages.containsKey(pkgName)) { 15071 // This package, under its official name, already exists 15072 // on the device; we should replace it. 15073 replace = true; 15074 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName); 15075 } 15076 15077 // Child packages are installed through the parent package 15078 if (pkg.parentPackage != null) { 15079 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME, 15080 "Package " + pkg.packageName + " is child of package " 15081 + pkg.parentPackage.parentPackage + ". Child packages " 15082 + "can be updated only through the parent package."); 15083 return; 15084 } 15085 15086 if (replace) { 15087 // Prevent apps opting out from runtime permissions 15088 PackageParser.Package oldPackage = mPackages.get(pkgName); 15089 final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion; 15090 final int newTargetSdk = pkg.applicationInfo.targetSdkVersion; 15091 if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1 15092 && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) { 15093 res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE, 15094 "Package " + pkg.packageName + " new target SDK " + newTargetSdk 15095 + " doesn't support runtime permissions but the old" 15096 + " target SDK " + oldTargetSdk + " does."); 15097 return; 15098 } 15099 15100 // Prevent installing of child packages 15101 if (oldPackage.parentPackage != null) { 15102 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME, 15103 "Package " + pkg.packageName + " is child of package " 15104 + oldPackage.parentPackage + ". Child packages " 15105 + "can be updated only through the parent package."); 15106 return; 15107 } 15108 } 15109 } 15110 15111 PackageSetting ps = mSettings.mPackages.get(pkgName); 15112 if (ps != null) { 15113 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps); 15114 15115 // Quick sanity check that we're signed correctly if updating; 15116 // we'll check this again later when scanning, but we want to 15117 // bail early here before tripping over redefined permissions. 15118 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { 15119 if (!checkUpgradeKeySetLP(ps, pkg)) { 15120 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 15121 + pkg.packageName + " upgrade keys do not match the " 15122 + "previously installed version"); 15123 return; 15124 } 15125 } else { 15126 try { 15127 verifySignaturesLP(ps, pkg); 15128 } catch (PackageManagerException e) { 15129 res.setError(e.error, e.getMessage()); 15130 return; 15131 } 15132 } 15133 15134 oldCodePath = mSettings.mPackages.get(pkgName).codePathString; 15135 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 15136 systemApp = (ps.pkg.applicationInfo.flags & 15137 ApplicationInfo.FLAG_SYSTEM) != 0; 15138 } 15139 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 15140 } 15141 15142 // Check whether the newly-scanned package wants to define an already-defined perm 15143 int N = pkg.permissions.size(); 15144 for (int i = N-1; i >= 0; i--) { 15145 PackageParser.Permission perm = pkg.permissions.get(i); 15146 BasePermission bp = mSettings.mPermissions.get(perm.info.name); 15147 if (bp != null) { 15148 // If the defining package is signed with our cert, it's okay. This 15149 // also includes the "updating the same package" case, of course. 15150 // "updating same package" could also involve key-rotation. 15151 final boolean sigsOk; 15152 if (bp.sourcePackage.equals(pkg.packageName) 15153 && (bp.packageSetting instanceof PackageSetting) 15154 && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting, 15155 scanFlags))) { 15156 sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg); 15157 } else { 15158 sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures, 15159 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 15160 } 15161 if (!sigsOk) { 15162 // If the owning package is the system itself, we log but allow 15163 // install to proceed; we fail the install on all other permission 15164 // redefinitions. 15165 if (!bp.sourcePackage.equals("android")) { 15166 res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package " 15167 + pkg.packageName + " attempting to redeclare permission " 15168 + perm.info.name + " already owned by " + bp.sourcePackage); 15169 res.origPermission = perm.info.name; 15170 res.origPackage = bp.sourcePackage; 15171 return; 15172 } else { 15173 Slog.w(TAG, "Package " + pkg.packageName 15174 + " attempting to redeclare system permission " 15175 + perm.info.name + "; ignoring new declaration"); 15176 pkg.permissions.remove(i); 15177 } 15178 } 15179 } 15180 } 15181 } 15182 15183 if (systemApp) { 15184 if (onExternal) { 15185 // Abort update; system app can't be replaced with app on sdcard 15186 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION, 15187 "Cannot install updates to system apps on sdcard"); 15188 return; 15189 } else if (ephemeral) { 15190 // Abort update; system app can't be replaced with an ephemeral app 15191 res.setError(INSTALL_FAILED_EPHEMERAL_INVALID, 15192 "Cannot update a system app with an ephemeral app"); 15193 return; 15194 } 15195 } 15196 15197 if (args.move != null) { 15198 // We did an in-place move, so dex is ready to roll 15199 scanFlags |= SCAN_NO_DEX; 15200 scanFlags |= SCAN_MOVE; 15201 15202 synchronized (mPackages) { 15203 final PackageSetting ps = mSettings.mPackages.get(pkgName); 15204 if (ps == null) { 15205 res.setError(INSTALL_FAILED_INTERNAL_ERROR, 15206 "Missing settings for moved package " + pkgName); 15207 } 15208 15209 // We moved the entire application as-is, so bring over the 15210 // previously derived ABI information. 15211 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString; 15212 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString; 15213 } 15214 15215 } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) { 15216 // Enable SCAN_NO_DEX flag to skip dexopt at a later stage 15217 scanFlags |= SCAN_NO_DEX; 15218 15219 try { 15220 String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ? 15221 args.abiOverride : pkg.cpuAbiOverride); 15222 derivePackageAbi(pkg, new File(pkg.codePath), abiOverride, 15223 true /* extract libs */); 15224 } catch (PackageManagerException pme) { 15225 Slog.e(TAG, "Error deriving application ABI", pme); 15226 res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI"); 15227 return; 15228 } 15229 15230 // Shared libraries for the package need to be updated. 15231 synchronized (mPackages) { 15232 try { 15233 updateSharedLibrariesLPw(pkg, null); 15234 } catch (PackageManagerException e) { 15235 Slog.e(TAG, "updateSharedLibrariesLPw failed: " + e.getMessage()); 15236 } 15237 } 15238 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 15239 // Do not run PackageDexOptimizer through the local performDexOpt 15240 // method because `pkg` may not be in `mPackages` yet. 15241 // 15242 // Also, don't fail application installs if the dexopt step fails. 15243 mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles, 15244 null /* instructionSets */, false /* checkProfiles */, 15245 getCompilerFilterForReason(REASON_INSTALL), 15246 getOrCreateCompilerPackageStats(pkg)); 15247 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 15248 15249 // Notify BackgroundDexOptService that the package has been changed. 15250 // If this is an update of a package which used to fail to compile, 15251 // BDOS will remove it from its blacklist. 15252 BackgroundDexOptService.notifyPackageChanged(pkg.packageName); 15253 } 15254 15255 if (!args.doRename(res.returnCode, pkg, oldCodePath)) { 15256 res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename"); 15257 return; 15258 } 15259 15260 startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg); 15261 15262 try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags, 15263 "installPackageLI")) { 15264 if (replace) { 15265 replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user, 15266 installerPackageName, res); 15267 } else { 15268 installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES, 15269 args.user, installerPackageName, volumeUuid, res); 15270 } 15271 } 15272 synchronized (mPackages) { 15273 final PackageSetting ps = mSettings.mPackages.get(pkgName); 15274 if (ps != null) { 15275 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 15276 } 15277 15278 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 15279 for (int i = 0; i < childCount; i++) { 15280 PackageParser.Package childPkg = pkg.childPackages.get(i); 15281 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName); 15282 PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName); 15283 if (childPs != null) { 15284 childRes.newUsers = childPs.queryInstalledUsers( 15285 sUserManager.getUserIds(), true); 15286 } 15287 } 15288 } 15289 } 15290 15291 private void startIntentFilterVerifications(int userId, boolean replacing, 15292 PackageParser.Package pkg) { 15293 if (mIntentFilterVerifierComponent == null) { 15294 Slog.w(TAG, "No IntentFilter verification will not be done as " 15295 + "there is no IntentFilterVerifier available!"); 15296 return; 15297 } 15298 15299 final int verifierUid = getPackageUid( 15300 mIntentFilterVerifierComponent.getPackageName(), 15301 MATCH_DEBUG_TRIAGED_MISSING, 15302 (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId); 15303 15304 Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 15305 msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid); 15306 mHandler.sendMessage(msg); 15307 15308 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 15309 for (int i = 0; i < childCount; i++) { 15310 PackageParser.Package childPkg = pkg.childPackages.get(i); 15311 msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 15312 msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid); 15313 mHandler.sendMessage(msg); 15314 } 15315 } 15316 15317 private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing, 15318 PackageParser.Package pkg) { 15319 int size = pkg.activities.size(); 15320 if (size == 0) { 15321 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 15322 "No activity, so no need to verify any IntentFilter!"); 15323 return; 15324 } 15325 15326 final boolean hasDomainURLs = hasDomainURLs(pkg); 15327 if (!hasDomainURLs) { 15328 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 15329 "No domain URLs, so no need to verify any IntentFilter!"); 15330 return; 15331 } 15332 15333 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId 15334 + " if any IntentFilter from the " + size 15335 + " Activities needs verification ..."); 15336 15337 int count = 0; 15338 final String packageName = pkg.packageName; 15339 15340 synchronized (mPackages) { 15341 // If this is a new install and we see that we've already run verification for this 15342 // package, we have nothing to do: it means the state was restored from backup. 15343 if (!replacing) { 15344 IntentFilterVerificationInfo ivi = 15345 mSettings.getIntentFilterVerificationLPr(packageName); 15346 if (ivi != null) { 15347 if (DEBUG_DOMAIN_VERIFICATION) { 15348 Slog.i(TAG, "Package " + packageName+ " already verified: status=" 15349 + ivi.getStatusString()); 15350 } 15351 return; 15352 } 15353 } 15354 15355 // If any filters need to be verified, then all need to be. 15356 boolean needToVerify = false; 15357 for (PackageParser.Activity a : pkg.activities) { 15358 for (ActivityIntentInfo filter : a.intents) { 15359 if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) { 15360 if (DEBUG_DOMAIN_VERIFICATION) { 15361 Slog.d(TAG, "Intent filter needs verification, so processing all filters"); 15362 } 15363 needToVerify = true; 15364 break; 15365 } 15366 } 15367 } 15368 15369 if (needToVerify) { 15370 final int verificationId = mIntentFilterVerificationToken++; 15371 for (PackageParser.Activity a : pkg.activities) { 15372 for (ActivityIntentInfo filter : a.intents) { 15373 if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) { 15374 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 15375 "Verification needed for IntentFilter:" + filter.toString()); 15376 mIntentFilterVerifier.addOneIntentFilterVerification( 15377 verifierUid, userId, verificationId, filter, packageName); 15378 count++; 15379 } 15380 } 15381 } 15382 } 15383 } 15384 15385 if (count > 0) { 15386 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count 15387 + " IntentFilter verification" + (count > 1 ? "s" : "") 15388 + " for userId:" + userId); 15389 mIntentFilterVerifier.startVerifications(userId); 15390 } else { 15391 if (DEBUG_DOMAIN_VERIFICATION) { 15392 Slog.d(TAG, "No filters or not all autoVerify for " + packageName); 15393 } 15394 } 15395 } 15396 15397 private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) { 15398 final ComponentName cn = filter.activity.getComponentName(); 15399 final String packageName = cn.getPackageName(); 15400 15401 IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr( 15402 packageName); 15403 if (ivi == null) { 15404 return true; 15405 } 15406 int status = ivi.getStatus(); 15407 switch (status) { 15408 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 15409 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 15410 return true; 15411 15412 default: 15413 // Nothing to do 15414 return false; 15415 } 15416 } 15417 15418 private static boolean isMultiArch(ApplicationInfo info) { 15419 return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0; 15420 } 15421 15422 private static boolean isExternal(PackageParser.Package pkg) { 15423 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 15424 } 15425 15426 private static boolean isExternal(PackageSetting ps) { 15427 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 15428 } 15429 15430 private static boolean isEphemeral(PackageParser.Package pkg) { 15431 return pkg.applicationInfo.isEphemeralApp(); 15432 } 15433 15434 private static boolean isEphemeral(PackageSetting ps) { 15435 return ps.pkg != null && isEphemeral(ps.pkg); 15436 } 15437 15438 private static boolean isSystemApp(PackageParser.Package pkg) { 15439 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 15440 } 15441 15442 private static boolean isPrivilegedApp(PackageParser.Package pkg) { 15443 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; 15444 } 15445 15446 private static boolean hasDomainURLs(PackageParser.Package pkg) { 15447 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0; 15448 } 15449 15450 private static boolean isSystemApp(PackageSetting ps) { 15451 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0; 15452 } 15453 15454 private static boolean isUpdatedSystemApp(PackageSetting ps) { 15455 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; 15456 } 15457 15458 private int packageFlagsToInstallFlags(PackageSetting ps) { 15459 int installFlags = 0; 15460 if (isEphemeral(ps)) { 15461 installFlags |= PackageManager.INSTALL_EPHEMERAL; 15462 } 15463 if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) { 15464 // This existing package was an external ASEC install when we have 15465 // the external flag without a UUID 15466 installFlags |= PackageManager.INSTALL_EXTERNAL; 15467 } 15468 if (ps.isForwardLocked()) { 15469 installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 15470 } 15471 return installFlags; 15472 } 15473 15474 private String getVolumeUuidForPackage(PackageParser.Package pkg) { 15475 if (isExternal(pkg)) { 15476 if (TextUtils.isEmpty(pkg.volumeUuid)) { 15477 return StorageManager.UUID_PRIMARY_PHYSICAL; 15478 } else { 15479 return pkg.volumeUuid; 15480 } 15481 } else { 15482 return StorageManager.UUID_PRIVATE_INTERNAL; 15483 } 15484 } 15485 15486 private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) { 15487 if (isExternal(pkg)) { 15488 if (TextUtils.isEmpty(pkg.volumeUuid)) { 15489 return mSettings.getExternalVersion(); 15490 } else { 15491 return mSettings.findOrCreateVersion(pkg.volumeUuid); 15492 } 15493 } else { 15494 return mSettings.getInternalVersion(); 15495 } 15496 } 15497 15498 private void deleteTempPackageFiles() { 15499 final FilenameFilter filter = new FilenameFilter() { 15500 public boolean accept(File dir, String name) { 15501 return name.startsWith("vmdl") && name.endsWith(".tmp"); 15502 } 15503 }; 15504 for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) { 15505 file.delete(); 15506 } 15507 } 15508 15509 @Override 15510 public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId, 15511 int flags) { 15512 deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId, 15513 flags); 15514 } 15515 15516 @Override 15517 public void deletePackage(final String packageName, 15518 final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) { 15519 mContext.enforceCallingOrSelfPermission( 15520 android.Manifest.permission.DELETE_PACKAGES, null); 15521 Preconditions.checkNotNull(packageName); 15522 Preconditions.checkNotNull(observer); 15523 final int uid = Binder.getCallingUid(); 15524 if (!isOrphaned(packageName) 15525 && !isCallerAllowedToSilentlyUninstall(uid, packageName)) { 15526 try { 15527 final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE); 15528 intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null)); 15529 intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder()); 15530 observer.onUserActionRequired(intent); 15531 } catch (RemoteException re) { 15532 } 15533 return; 15534 } 15535 final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0; 15536 final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId }; 15537 if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) { 15538 mContext.enforceCallingOrSelfPermission( 15539 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 15540 "deletePackage for user " + userId); 15541 } 15542 15543 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) { 15544 try { 15545 observer.onPackageDeleted(packageName, 15546 PackageManager.DELETE_FAILED_USER_RESTRICTED, null); 15547 } catch (RemoteException re) { 15548 } 15549 return; 15550 } 15551 15552 if (!deleteAllUsers && getBlockUninstallForUser(packageName, userId)) { 15553 try { 15554 observer.onPackageDeleted(packageName, 15555 PackageManager.DELETE_FAILED_OWNER_BLOCKED, null); 15556 } catch (RemoteException re) { 15557 } 15558 return; 15559 } 15560 15561 if (DEBUG_REMOVE) { 15562 Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId 15563 + " deleteAllUsers: " + deleteAllUsers ); 15564 } 15565 // Queue up an async operation since the package deletion may take a little while. 15566 mHandler.post(new Runnable() { 15567 public void run() { 15568 mHandler.removeCallbacks(this); 15569 int returnCode; 15570 if (!deleteAllUsers) { 15571 returnCode = deletePackageX(packageName, userId, deleteFlags); 15572 } else { 15573 int[] blockUninstallUserIds = getBlockUninstallForUsers(packageName, users); 15574 // If nobody is blocking uninstall, proceed with delete for all users 15575 if (ArrayUtils.isEmpty(blockUninstallUserIds)) { 15576 returnCode = deletePackageX(packageName, userId, deleteFlags); 15577 } else { 15578 // Otherwise uninstall individually for users with blockUninstalls=false 15579 final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS; 15580 for (int userId : users) { 15581 if (!ArrayUtils.contains(blockUninstallUserIds, userId)) { 15582 returnCode = deletePackageX(packageName, userId, userFlags); 15583 if (returnCode != PackageManager.DELETE_SUCCEEDED) { 15584 Slog.w(TAG, "Package delete failed for user " + userId 15585 + ", returnCode " + returnCode); 15586 } 15587 } 15588 } 15589 // The app has only been marked uninstalled for certain users. 15590 // We still need to report that delete was blocked 15591 returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED; 15592 } 15593 } 15594 try { 15595 observer.onPackageDeleted(packageName, returnCode, null); 15596 } catch (RemoteException e) { 15597 Log.i(TAG, "Observer no longer exists."); 15598 } //end catch 15599 } //end run 15600 }); 15601 } 15602 15603 private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) { 15604 if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID 15605 || callingUid == Process.SYSTEM_UID) { 15606 return true; 15607 } 15608 final int callingUserId = UserHandle.getUserId(callingUid); 15609 // If the caller installed the pkgName, then allow it to silently uninstall. 15610 if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) { 15611 return true; 15612 } 15613 15614 // Allow package verifier to silently uninstall. 15615 if (mRequiredVerifierPackage != null && 15616 callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) { 15617 return true; 15618 } 15619 15620 // Allow package uninstaller to silently uninstall. 15621 if (mRequiredUninstallerPackage != null && 15622 callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) { 15623 return true; 15624 } 15625 15626 // Allow storage manager to silently uninstall. 15627 if (mStorageManagerPackage != null && 15628 callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) { 15629 return true; 15630 } 15631 return false; 15632 } 15633 15634 private int[] getBlockUninstallForUsers(String packageName, int[] userIds) { 15635 int[] result = EMPTY_INT_ARRAY; 15636 for (int userId : userIds) { 15637 if (getBlockUninstallForUser(packageName, userId)) { 15638 result = ArrayUtils.appendInt(result, userId); 15639 } 15640 } 15641 return result; 15642 } 15643 15644 @Override 15645 public boolean isPackageDeviceAdminOnAnyUser(String packageName) { 15646 return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL); 15647 } 15648 15649 private boolean isPackageDeviceAdmin(String packageName, int userId) { 15650 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface( 15651 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); 15652 try { 15653 if (dpm != null) { 15654 final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent( 15655 /* callingUserOnly =*/ false); 15656 final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null 15657 : deviceOwnerComponentName.getPackageName(); 15658 // Does the package contains the device owner? 15659 // TODO Do we have to do it even if userId != UserHandle.USER_ALL? Otherwise, 15660 // this check is probably not needed, since DO should be registered as a device 15661 // admin on some user too. (Original bug for this: b/17657954) 15662 if (packageName.equals(deviceOwnerPackageName)) { 15663 return true; 15664 } 15665 // Does it contain a device admin for any user? 15666 int[] users; 15667 if (userId == UserHandle.USER_ALL) { 15668 users = sUserManager.getUserIds(); 15669 } else { 15670 users = new int[]{userId}; 15671 } 15672 for (int i = 0; i < users.length; ++i) { 15673 if (dpm.packageHasActiveAdmins(packageName, users[i])) { 15674 return true; 15675 } 15676 } 15677 } 15678 } catch (RemoteException e) { 15679 } 15680 return false; 15681 } 15682 15683 private boolean shouldKeepUninstalledPackageLPr(String packageName) { 15684 return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName); 15685 } 15686 15687 /** 15688 * This method is an internal method that could be get invoked either 15689 * to delete an installed package or to clean up a failed installation. 15690 * After deleting an installed package, a broadcast is sent to notify any 15691 * listeners that the package has been removed. For cleaning up a failed 15692 * installation, the broadcast is not necessary since the package's 15693 * installation wouldn't have sent the initial broadcast either 15694 * The key steps in deleting a package are 15695 * deleting the package information in internal structures like mPackages, 15696 * deleting the packages base directories through installd 15697 * updating mSettings to reflect current status 15698 * persisting settings for later use 15699 * sending a broadcast if necessary 15700 */ 15701 private int deletePackageX(String packageName, int userId, int deleteFlags) { 15702 final PackageRemovedInfo info = new PackageRemovedInfo(); 15703 final boolean res; 15704 15705 final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0 15706 ? UserHandle.USER_ALL : userId; 15707 15708 if (isPackageDeviceAdmin(packageName, removeUser)) { 15709 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin"); 15710 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER; 15711 } 15712 15713 PackageSetting uninstalledPs = null; 15714 15715 // for the uninstall-updates case and restricted profiles, remember the per- 15716 // user handle installed state 15717 int[] allUsers; 15718 synchronized (mPackages) { 15719 uninstalledPs = mSettings.mPackages.get(packageName); 15720 if (uninstalledPs == null) { 15721 Slog.w(TAG, "Not removing non-existent package " + packageName); 15722 return PackageManager.DELETE_FAILED_INTERNAL_ERROR; 15723 } 15724 allUsers = sUserManager.getUserIds(); 15725 info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true); 15726 } 15727 15728 final int freezeUser; 15729 if (isUpdatedSystemApp(uninstalledPs) 15730 && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) { 15731 // We're downgrading a system app, which will apply to all users, so 15732 // freeze them all during the downgrade 15733 freezeUser = UserHandle.USER_ALL; 15734 } else { 15735 freezeUser = removeUser; 15736 } 15737 15738 synchronized (mInstallLock) { 15739 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId); 15740 try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser, 15741 deleteFlags, "deletePackageX")) { 15742 res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers, 15743 deleteFlags | REMOVE_CHATTY, info, true, null); 15744 } 15745 synchronized (mPackages) { 15746 if (res) { 15747 mEphemeralApplicationRegistry.onPackageUninstalledLPw(uninstalledPs.pkg); 15748 } 15749 } 15750 } 15751 15752 if (res) { 15753 final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0; 15754 info.sendPackageRemovedBroadcasts(killApp); 15755 info.sendSystemPackageUpdatedBroadcasts(); 15756 info.sendSystemPackageAppearedBroadcasts(); 15757 } 15758 // Force a gc here. 15759 Runtime.getRuntime().gc(); 15760 // Delete the resources here after sending the broadcast to let 15761 // other processes clean up before deleting resources. 15762 if (info.args != null) { 15763 synchronized (mInstallLock) { 15764 info.args.doPostDeleteLI(true); 15765 } 15766 } 15767 15768 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR; 15769 } 15770 15771 class PackageRemovedInfo { 15772 String removedPackage; 15773 int uid = -1; 15774 int removedAppId = -1; 15775 int[] origUsers; 15776 int[] removedUsers = null; 15777 boolean isRemovedPackageSystemUpdate = false; 15778 boolean isUpdate; 15779 boolean dataRemoved; 15780 boolean removedForAllUsers; 15781 // Clean up resources deleted packages. 15782 InstallArgs args = null; 15783 ArrayMap<String, PackageRemovedInfo> removedChildPackages; 15784 ArrayMap<String, PackageInstalledInfo> appearedChildPackages; 15785 15786 void sendPackageRemovedBroadcasts(boolean killApp) { 15787 sendPackageRemovedBroadcastInternal(killApp); 15788 final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0; 15789 for (int i = 0; i < childCount; i++) { 15790 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i); 15791 childInfo.sendPackageRemovedBroadcastInternal(killApp); 15792 } 15793 } 15794 15795 void sendSystemPackageUpdatedBroadcasts() { 15796 if (isRemovedPackageSystemUpdate) { 15797 sendSystemPackageUpdatedBroadcastsInternal(); 15798 final int childCount = (removedChildPackages != null) 15799 ? removedChildPackages.size() : 0; 15800 for (int i = 0; i < childCount; i++) { 15801 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i); 15802 if (childInfo.isRemovedPackageSystemUpdate) { 15803 childInfo.sendSystemPackageUpdatedBroadcastsInternal(); 15804 } 15805 } 15806 } 15807 } 15808 15809 void sendSystemPackageAppearedBroadcasts() { 15810 final int packageCount = (appearedChildPackages != null) 15811 ? appearedChildPackages.size() : 0; 15812 for (int i = 0; i < packageCount; i++) { 15813 PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i); 15814 for (int userId : installedInfo.newUsers) { 15815 sendPackageAddedForUser(installedInfo.name, true, 15816 UserHandle.getAppId(installedInfo.uid), userId); 15817 } 15818 } 15819 } 15820 15821 private void sendSystemPackageUpdatedBroadcastsInternal() { 15822 Bundle extras = new Bundle(2); 15823 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 15824 extras.putBoolean(Intent.EXTRA_REPLACING, true); 15825 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, removedPackage, 15826 extras, 0, null, null, null); 15827 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, removedPackage, 15828 extras, 0, null, null, null); 15829 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null, 15830 null, 0, removedPackage, null, null); 15831 } 15832 15833 private void sendPackageRemovedBroadcastInternal(boolean killApp) { 15834 Bundle extras = new Bundle(2); 15835 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 15836 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved); 15837 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp); 15838 if (isUpdate || isRemovedPackageSystemUpdate) { 15839 extras.putBoolean(Intent.EXTRA_REPLACING, true); 15840 } 15841 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers); 15842 if (removedPackage != null) { 15843 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, 15844 extras, 0, null, null, removedUsers); 15845 if (dataRemoved && !isRemovedPackageSystemUpdate) { 15846 sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, 15847 removedPackage, extras, 0, null, null, removedUsers); 15848 } 15849 } 15850 if (removedAppId >= 0) { 15851 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, 0, null, null, 15852 removedUsers); 15853 } 15854 } 15855 } 15856 15857 /* 15858 * This method deletes the package from internal data structures. If the DONT_DELETE_DATA 15859 * flag is not set, the data directory is removed as well. 15860 * make sure this flag is set for partially installed apps. If not its meaningless to 15861 * delete a partially installed application. 15862 */ 15863 private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles, 15864 PackageRemovedInfo outInfo, int flags, boolean writeSettings) { 15865 String packageName = ps.name; 15866 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps); 15867 // Retrieve object to delete permissions for shared user later on 15868 final PackageParser.Package deletedPkg; 15869 final PackageSetting deletedPs; 15870 // reader 15871 synchronized (mPackages) { 15872 deletedPkg = mPackages.get(packageName); 15873 deletedPs = mSettings.mPackages.get(packageName); 15874 if (outInfo != null) { 15875 outInfo.removedPackage = packageName; 15876 outInfo.removedUsers = deletedPs != null 15877 ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true) 15878 : null; 15879 } 15880 } 15881 15882 removePackageLI(ps, (flags & REMOVE_CHATTY) != 0); 15883 15884 if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) { 15885 final PackageParser.Package resolvedPkg; 15886 if (deletedPkg != null) { 15887 resolvedPkg = deletedPkg; 15888 } else { 15889 // We don't have a parsed package when it lives on an ejected 15890 // adopted storage device, so fake something together 15891 resolvedPkg = new PackageParser.Package(ps.name); 15892 resolvedPkg.setVolumeUuid(ps.volumeUuid); 15893 } 15894 destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL, 15895 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 15896 destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL); 15897 if (outInfo != null) { 15898 outInfo.dataRemoved = true; 15899 } 15900 schedulePackageCleaning(packageName, UserHandle.USER_ALL, true); 15901 } 15902 15903 // writer 15904 synchronized (mPackages) { 15905 if (deletedPs != null) { 15906 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 15907 clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL); 15908 clearDefaultBrowserIfNeeded(packageName); 15909 if (outInfo != null) { 15910 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName); 15911 outInfo.removedAppId = mSettings.removePackageLPw(packageName); 15912 } 15913 updatePermissionsLPw(deletedPs.name, null, 0); 15914 if (deletedPs.sharedUser != null) { 15915 // Remove permissions associated with package. Since runtime 15916 // permissions are per user we have to kill the removed package 15917 // or packages running under the shared user of the removed 15918 // package if revoking the permissions requested only by the removed 15919 // package is successful and this causes a change in gids. 15920 for (int userId : UserManagerService.getInstance().getUserIds()) { 15921 final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs, 15922 userId); 15923 if (userIdToKill == UserHandle.USER_ALL 15924 || userIdToKill >= UserHandle.USER_SYSTEM) { 15925 // If gids changed for this user, kill all affected packages. 15926 mHandler.post(new Runnable() { 15927 @Override 15928 public void run() { 15929 // This has to happen with no lock held. 15930 killApplication(deletedPs.name, deletedPs.appId, 15931 KILL_APP_REASON_GIDS_CHANGED); 15932 } 15933 }); 15934 break; 15935 } 15936 } 15937 } 15938 clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL); 15939 } 15940 // make sure to preserve per-user disabled state if this removal was just 15941 // a downgrade of a system app to the factory package 15942 if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) { 15943 if (DEBUG_REMOVE) { 15944 Slog.d(TAG, "Propagating install state across downgrade"); 15945 } 15946 for (int userId : allUserHandles) { 15947 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId); 15948 if (DEBUG_REMOVE) { 15949 Slog.d(TAG, " user " + userId + " => " + installed); 15950 } 15951 ps.setInstalled(installed, userId); 15952 } 15953 } 15954 } 15955 // can downgrade to reader 15956 if (writeSettings) { 15957 // Save settings now 15958 mSettings.writeLPr(); 15959 } 15960 } 15961 if (outInfo != null) { 15962 // A user ID was deleted here. Go through all users and remove it 15963 // from KeyStore. 15964 removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId); 15965 } 15966 } 15967 15968 static boolean locationIsPrivileged(File path) { 15969 try { 15970 final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app") 15971 .getCanonicalPath(); 15972 return path.getCanonicalPath().startsWith(privilegedAppDir); 15973 } catch (IOException e) { 15974 Slog.e(TAG, "Unable to access code path " + path); 15975 } 15976 return false; 15977 } 15978 15979 /* 15980 * Tries to delete system package. 15981 */ 15982 private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg, 15983 PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo, 15984 boolean writeSettings) { 15985 if (deletedPs.parentPackageName != null) { 15986 Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName); 15987 return false; 15988 } 15989 15990 final boolean applyUserRestrictions 15991 = (allUserHandles != null) && (outInfo.origUsers != null); 15992 final PackageSetting disabledPs; 15993 // Confirm if the system package has been updated 15994 // An updated system app can be deleted. This will also have to restore 15995 // the system pkg from system partition 15996 // reader 15997 synchronized (mPackages) { 15998 disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name); 15999 } 16000 16001 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName 16002 + " disabledPs=" + disabledPs); 16003 16004 if (disabledPs == null) { 16005 Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName); 16006 return false; 16007 } else if (DEBUG_REMOVE) { 16008 Slog.d(TAG, "Deleting system pkg from data partition"); 16009 } 16010 16011 if (DEBUG_REMOVE) { 16012 if (applyUserRestrictions) { 16013 Slog.d(TAG, "Remembering install states:"); 16014 for (int userId : allUserHandles) { 16015 final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId); 16016 Slog.d(TAG, " u=" + userId + " inst=" + finstalled); 16017 } 16018 } 16019 } 16020 16021 // Delete the updated package 16022 outInfo.isRemovedPackageSystemUpdate = true; 16023 if (outInfo.removedChildPackages != null) { 16024 final int childCount = (deletedPs.childPackageNames != null) 16025 ? deletedPs.childPackageNames.size() : 0; 16026 for (int i = 0; i < childCount; i++) { 16027 String childPackageName = deletedPs.childPackageNames.get(i); 16028 if (disabledPs.childPackageNames != null && disabledPs.childPackageNames 16029 .contains(childPackageName)) { 16030 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get( 16031 childPackageName); 16032 if (childInfo != null) { 16033 childInfo.isRemovedPackageSystemUpdate = true; 16034 } 16035 } 16036 } 16037 } 16038 16039 if (disabledPs.versionCode < deletedPs.versionCode) { 16040 // Delete data for downgrades 16041 flags &= ~PackageManager.DELETE_KEEP_DATA; 16042 } else { 16043 // Preserve data by setting flag 16044 flags |= PackageManager.DELETE_KEEP_DATA; 16045 } 16046 16047 boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles, 16048 outInfo, writeSettings, disabledPs.pkg); 16049 if (!ret) { 16050 return false; 16051 } 16052 16053 // writer 16054 synchronized (mPackages) { 16055 // Reinstate the old system package 16056 enableSystemPackageLPw(disabledPs.pkg); 16057 // Remove any native libraries from the upgraded package. 16058 removeNativeBinariesLI(deletedPs); 16059 } 16060 16061 // Install the system package 16062 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs); 16063 int parseFlags = mDefParseFlags 16064 | PackageParser.PARSE_MUST_BE_APK 16065 | PackageParser.PARSE_IS_SYSTEM 16066 | PackageParser.PARSE_IS_SYSTEM_DIR; 16067 if (locationIsPrivileged(disabledPs.codePath)) { 16068 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 16069 } 16070 16071 final PackageParser.Package newPkg; 16072 try { 16073 newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null); 16074 } catch (PackageManagerException e) { 16075 Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": " 16076 + e.getMessage()); 16077 return false; 16078 } 16079 try { 16080 // update shared libraries for the newly re-installed system package 16081 updateSharedLibrariesLPw(newPkg, null); 16082 } catch (PackageManagerException e) { 16083 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 16084 } 16085 16086 prepareAppDataAfterInstallLIF(newPkg); 16087 16088 // writer 16089 synchronized (mPackages) { 16090 PackageSetting ps = mSettings.mPackages.get(newPkg.packageName); 16091 16092 // Propagate the permissions state as we do not want to drop on the floor 16093 // runtime permissions. The update permissions method below will take 16094 // care of removing obsolete permissions and grant install permissions. 16095 ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState()); 16096 updatePermissionsLPw(newPkg.packageName, newPkg, 16097 UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG); 16098 16099 if (applyUserRestrictions) { 16100 if (DEBUG_REMOVE) { 16101 Slog.d(TAG, "Propagating install state across reinstall"); 16102 } 16103 for (int userId : allUserHandles) { 16104 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId); 16105 if (DEBUG_REMOVE) { 16106 Slog.d(TAG, " user " + userId + " => " + installed); 16107 } 16108 ps.setInstalled(installed, userId); 16109 16110 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 16111 } 16112 // Regardless of writeSettings we need to ensure that this restriction 16113 // state propagation is persisted 16114 mSettings.writeAllUsersPackageRestrictionsLPr(); 16115 } 16116 // can downgrade to reader here 16117 if (writeSettings) { 16118 mSettings.writeLPr(); 16119 } 16120 } 16121 return true; 16122 } 16123 16124 private boolean deleteInstalledPackageLIF(PackageSetting ps, 16125 boolean deleteCodeAndResources, int flags, int[] allUserHandles, 16126 PackageRemovedInfo outInfo, boolean writeSettings, 16127 PackageParser.Package replacingPackage) { 16128 synchronized (mPackages) { 16129 if (outInfo != null) { 16130 outInfo.uid = ps.appId; 16131 } 16132 16133 if (outInfo != null && outInfo.removedChildPackages != null) { 16134 final int childCount = (ps.childPackageNames != null) 16135 ? ps.childPackageNames.size() : 0; 16136 for (int i = 0; i < childCount; i++) { 16137 String childPackageName = ps.childPackageNames.get(i); 16138 PackageSetting childPs = mSettings.mPackages.get(childPackageName); 16139 if (childPs == null) { 16140 return false; 16141 } 16142 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get( 16143 childPackageName); 16144 if (childInfo != null) { 16145 childInfo.uid = childPs.appId; 16146 } 16147 } 16148 } 16149 } 16150 16151 // Delete package data from internal structures and also remove data if flag is set 16152 removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings); 16153 16154 // Delete the child packages data 16155 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0; 16156 for (int i = 0; i < childCount; i++) { 16157 PackageSetting childPs; 16158 synchronized (mPackages) { 16159 childPs = mSettings.peekPackageLPr(ps.childPackageNames.get(i)); 16160 } 16161 if (childPs != null) { 16162 PackageRemovedInfo childOutInfo = (outInfo != null 16163 && outInfo.removedChildPackages != null) 16164 ? outInfo.removedChildPackages.get(childPs.name) : null; 16165 final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0 16166 && (replacingPackage != null 16167 && !replacingPackage.hasChildPackage(childPs.name)) 16168 ? flags & ~DELETE_KEEP_DATA : flags; 16169 removePackageDataLIF(childPs, allUserHandles, childOutInfo, 16170 deleteFlags, writeSettings); 16171 } 16172 } 16173 16174 // Delete application code and resources only for parent packages 16175 if (ps.parentPackageName == null) { 16176 if (deleteCodeAndResources && (outInfo != null)) { 16177 outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 16178 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 16179 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args); 16180 } 16181 } 16182 16183 return true; 16184 } 16185 16186 @Override 16187 public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall, 16188 int userId) { 16189 mContext.enforceCallingOrSelfPermission( 16190 android.Manifest.permission.DELETE_PACKAGES, null); 16191 synchronized (mPackages) { 16192 PackageSetting ps = mSettings.mPackages.get(packageName); 16193 if (ps == null) { 16194 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName); 16195 return false; 16196 } 16197 if (!ps.getInstalled(userId)) { 16198 // Can't block uninstall for an app that is not installed or enabled. 16199 Log.i(TAG, "Package not installed in set block uninstall " + packageName); 16200 return false; 16201 } 16202 ps.setBlockUninstall(blockUninstall, userId); 16203 mSettings.writePackageRestrictionsLPr(userId); 16204 } 16205 return true; 16206 } 16207 16208 @Override 16209 public boolean getBlockUninstallForUser(String packageName, int userId) { 16210 synchronized (mPackages) { 16211 PackageSetting ps = mSettings.mPackages.get(packageName); 16212 if (ps == null) { 16213 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName); 16214 return false; 16215 } 16216 return ps.getBlockUninstall(userId); 16217 } 16218 } 16219 16220 @Override 16221 public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) { 16222 int callingUid = Binder.getCallingUid(); 16223 if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) { 16224 throw new SecurityException( 16225 "setRequiredForSystemUser can only be run by the system or root"); 16226 } 16227 synchronized (mPackages) { 16228 PackageSetting ps = mSettings.mPackages.get(packageName); 16229 if (ps == null) { 16230 Log.w(TAG, "Package doesn't exist: " + packageName); 16231 return false; 16232 } 16233 if (systemUserApp) { 16234 ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER; 16235 } else { 16236 ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER; 16237 } 16238 mSettings.writeLPr(); 16239 } 16240 return true; 16241 } 16242 16243 /* 16244 * This method handles package deletion in general 16245 */ 16246 private boolean deletePackageLIF(String packageName, UserHandle user, 16247 boolean deleteCodeAndResources, int[] allUserHandles, int flags, 16248 PackageRemovedInfo outInfo, boolean writeSettings, 16249 PackageParser.Package replacingPackage) { 16250 if (packageName == null) { 16251 Slog.w(TAG, "Attempt to delete null packageName."); 16252 return false; 16253 } 16254 16255 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user); 16256 16257 PackageSetting ps; 16258 16259 synchronized (mPackages) { 16260 ps = mSettings.mPackages.get(packageName); 16261 if (ps == null) { 16262 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 16263 return false; 16264 } 16265 16266 if (ps.parentPackageName != null && (!isSystemApp(ps) 16267 || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) { 16268 if (DEBUG_REMOVE) { 16269 Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:" 16270 + ((user == null) ? UserHandle.USER_ALL : user)); 16271 } 16272 final int removedUserId = (user != null) ? user.getIdentifier() 16273 : UserHandle.USER_ALL; 16274 if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) { 16275 return false; 16276 } 16277 markPackageUninstalledForUserLPw(ps, user); 16278 scheduleWritePackageRestrictionsLocked(user); 16279 return true; 16280 } 16281 } 16282 16283 if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null 16284 && user.getIdentifier() != UserHandle.USER_ALL)) { 16285 // The caller is asking that the package only be deleted for a single 16286 // user. To do this, we just mark its uninstalled state and delete 16287 // its data. If this is a system app, we only allow this to happen if 16288 // they have set the special DELETE_SYSTEM_APP which requests different 16289 // semantics than normal for uninstalling system apps. 16290 markPackageUninstalledForUserLPw(ps, user); 16291 16292 if (!isSystemApp(ps)) { 16293 // Do not uninstall the APK if an app should be cached 16294 boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName); 16295 if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) { 16296 // Other user still have this package installed, so all 16297 // we need to do is clear this user's data and save that 16298 // it is uninstalled. 16299 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users"); 16300 if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) { 16301 return false; 16302 } 16303 scheduleWritePackageRestrictionsLocked(user); 16304 return true; 16305 } else { 16306 // We need to set it back to 'installed' so the uninstall 16307 // broadcasts will be sent correctly. 16308 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete"); 16309 ps.setInstalled(true, user.getIdentifier()); 16310 } 16311 } else { 16312 // This is a system app, so we assume that the 16313 // other users still have this package installed, so all 16314 // we need to do is clear this user's data and save that 16315 // it is uninstalled. 16316 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app"); 16317 if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) { 16318 return false; 16319 } 16320 scheduleWritePackageRestrictionsLocked(user); 16321 return true; 16322 } 16323 } 16324 16325 // If we are deleting a composite package for all users, keep track 16326 // of result for each child. 16327 if (ps.childPackageNames != null && outInfo != null) { 16328 synchronized (mPackages) { 16329 final int childCount = ps.childPackageNames.size(); 16330 outInfo.removedChildPackages = new ArrayMap<>(childCount); 16331 for (int i = 0; i < childCount; i++) { 16332 String childPackageName = ps.childPackageNames.get(i); 16333 PackageRemovedInfo childInfo = new PackageRemovedInfo(); 16334 childInfo.removedPackage = childPackageName; 16335 outInfo.removedChildPackages.put(childPackageName, childInfo); 16336 PackageSetting childPs = mSettings.peekPackageLPr(childPackageName); 16337 if (childPs != null) { 16338 childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true); 16339 } 16340 } 16341 } 16342 } 16343 16344 boolean ret = false; 16345 if (isSystemApp(ps)) { 16346 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name); 16347 // When an updated system application is deleted we delete the existing resources 16348 // as well and fall back to existing code in system partition 16349 ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings); 16350 } else { 16351 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name); 16352 ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles, 16353 outInfo, writeSettings, replacingPackage); 16354 } 16355 16356 // Take a note whether we deleted the package for all users 16357 if (outInfo != null) { 16358 outInfo.removedForAllUsers = mPackages.get(ps.name) == null; 16359 if (outInfo.removedChildPackages != null) { 16360 synchronized (mPackages) { 16361 final int childCount = outInfo.removedChildPackages.size(); 16362 for (int i = 0; i < childCount; i++) { 16363 PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i); 16364 if (childInfo != null) { 16365 childInfo.removedForAllUsers = mPackages.get( 16366 childInfo.removedPackage) == null; 16367 } 16368 } 16369 } 16370 } 16371 // If we uninstalled an update to a system app there may be some 16372 // child packages that appeared as they are declared in the system 16373 // app but were not declared in the update. 16374 if (isSystemApp(ps)) { 16375 synchronized (mPackages) { 16376 PackageSetting updatedPs = mSettings.peekPackageLPr(ps.name); 16377 final int childCount = (updatedPs.childPackageNames != null) 16378 ? updatedPs.childPackageNames.size() : 0; 16379 for (int i = 0; i < childCount; i++) { 16380 String childPackageName = updatedPs.childPackageNames.get(i); 16381 if (outInfo.removedChildPackages == null 16382 || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) { 16383 PackageSetting childPs = mSettings.peekPackageLPr(childPackageName); 16384 if (childPs == null) { 16385 continue; 16386 } 16387 PackageInstalledInfo installRes = new PackageInstalledInfo(); 16388 installRes.name = childPackageName; 16389 installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true); 16390 installRes.pkg = mPackages.get(childPackageName); 16391 installRes.uid = childPs.pkg.applicationInfo.uid; 16392 if (outInfo.appearedChildPackages == null) { 16393 outInfo.appearedChildPackages = new ArrayMap<>(); 16394 } 16395 outInfo.appearedChildPackages.put(childPackageName, installRes); 16396 } 16397 } 16398 } 16399 } 16400 } 16401 16402 return ret; 16403 } 16404 16405 private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) { 16406 final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL) 16407 ? sUserManager.getUserIds() : new int[] {user.getIdentifier()}; 16408 for (int nextUserId : userIds) { 16409 if (DEBUG_REMOVE) { 16410 Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId); 16411 } 16412 ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT, 16413 false /*installed*/, true /*stopped*/, true /*notLaunched*/, 16414 false /*hidden*/, false /*suspended*/, null, null, null, 16415 false /*blockUninstall*/, 16416 ps.readUserState(nextUserId).domainVerificationStatus, 0); 16417 } 16418 } 16419 16420 private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId, 16421 PackageRemovedInfo outInfo) { 16422 final PackageParser.Package pkg; 16423 synchronized (mPackages) { 16424 pkg = mPackages.get(ps.name); 16425 } 16426 16427 final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() 16428 : new int[] {userId}; 16429 for (int nextUserId : userIds) { 16430 if (DEBUG_REMOVE) { 16431 Slog.d(TAG, "Updating package:" + ps.name + " install state for user:" 16432 + nextUserId); 16433 } 16434 16435 destroyAppDataLIF(pkg, userId, 16436 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 16437 destroyAppProfilesLIF(pkg, userId); 16438 removeKeystoreDataIfNeeded(nextUserId, ps.appId); 16439 schedulePackageCleaning(ps.name, nextUserId, false); 16440 synchronized (mPackages) { 16441 if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) { 16442 scheduleWritePackageRestrictionsLocked(nextUserId); 16443 } 16444 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId); 16445 } 16446 } 16447 16448 if (outInfo != null) { 16449 outInfo.removedPackage = ps.name; 16450 outInfo.removedAppId = ps.appId; 16451 outInfo.removedUsers = userIds; 16452 } 16453 16454 return true; 16455 } 16456 16457 private final class ClearStorageConnection implements ServiceConnection { 16458 IMediaContainerService mContainerService; 16459 16460 @Override 16461 public void onServiceConnected(ComponentName name, IBinder service) { 16462 synchronized (this) { 16463 mContainerService = IMediaContainerService.Stub.asInterface(service); 16464 notifyAll(); 16465 } 16466 } 16467 16468 @Override 16469 public void onServiceDisconnected(ComponentName name) { 16470 } 16471 } 16472 16473 private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) { 16474 if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return; 16475 16476 final boolean mounted; 16477 if (Environment.isExternalStorageEmulated()) { 16478 mounted = true; 16479 } else { 16480 final String status = Environment.getExternalStorageState(); 16481 16482 mounted = status.equals(Environment.MEDIA_MOUNTED) 16483 || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY); 16484 } 16485 16486 if (!mounted) { 16487 return; 16488 } 16489 16490 final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 16491 int[] users; 16492 if (userId == UserHandle.USER_ALL) { 16493 users = sUserManager.getUserIds(); 16494 } else { 16495 users = new int[] { userId }; 16496 } 16497 final ClearStorageConnection conn = new ClearStorageConnection(); 16498 if (mContext.bindServiceAsUser( 16499 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) { 16500 try { 16501 for (int curUser : users) { 16502 long timeout = SystemClock.uptimeMillis() + 5000; 16503 synchronized (conn) { 16504 long now; 16505 while (conn.mContainerService == null && 16506 (now = SystemClock.uptimeMillis()) < timeout) { 16507 try { 16508 conn.wait(timeout - now); 16509 } catch (InterruptedException e) { 16510 } 16511 } 16512 } 16513 if (conn.mContainerService == null) { 16514 return; 16515 } 16516 16517 final UserEnvironment userEnv = new UserEnvironment(curUser); 16518 clearDirectory(conn.mContainerService, 16519 userEnv.buildExternalStorageAppCacheDirs(packageName)); 16520 if (allData) { 16521 clearDirectory(conn.mContainerService, 16522 userEnv.buildExternalStorageAppDataDirs(packageName)); 16523 clearDirectory(conn.mContainerService, 16524 userEnv.buildExternalStorageAppMediaDirs(packageName)); 16525 } 16526 } 16527 } finally { 16528 mContext.unbindService(conn); 16529 } 16530 } 16531 } 16532 16533 @Override 16534 public void clearApplicationProfileData(String packageName) { 16535 enforceSystemOrRoot("Only the system can clear all profile data"); 16536 16537 final PackageParser.Package pkg; 16538 synchronized (mPackages) { 16539 pkg = mPackages.get(packageName); 16540 } 16541 16542 try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) { 16543 synchronized (mInstallLock) { 16544 clearAppProfilesLIF(pkg, UserHandle.USER_ALL); 16545 destroyAppReferenceProfileLeafLIF(pkg, UserHandle.USER_ALL, 16546 true /* removeBaseMarker */); 16547 } 16548 } 16549 } 16550 16551 @Override 16552 public void clearApplicationUserData(final String packageName, 16553 final IPackageDataObserver observer, final int userId) { 16554 mContext.enforceCallingOrSelfPermission( 16555 android.Manifest.permission.CLEAR_APP_USER_DATA, null); 16556 16557 enforceCrossUserPermission(Binder.getCallingUid(), userId, 16558 true /* requireFullPermission */, false /* checkShell */, "clear application data"); 16559 16560 if (mProtectedPackages.isPackageDataProtected(userId, packageName)) { 16561 throw new SecurityException("Cannot clear data for a protected package: " 16562 + packageName); 16563 } 16564 // Queue up an async operation since the package deletion may take a little while. 16565 mHandler.post(new Runnable() { 16566 public void run() { 16567 mHandler.removeCallbacks(this); 16568 final boolean succeeded; 16569 try (PackageFreezer freezer = freezePackage(packageName, 16570 "clearApplicationUserData")) { 16571 synchronized (mInstallLock) { 16572 succeeded = clearApplicationUserDataLIF(packageName, userId); 16573 } 16574 clearExternalStorageDataSync(packageName, userId, true); 16575 } 16576 if (succeeded) { 16577 // invoke DeviceStorageMonitor's update method to clear any notifications 16578 DeviceStorageMonitorInternal dsm = LocalServices 16579 .getService(DeviceStorageMonitorInternal.class); 16580 if (dsm != null) { 16581 dsm.checkMemory(); 16582 } 16583 } 16584 if(observer != null) { 16585 try { 16586 observer.onRemoveCompleted(packageName, succeeded); 16587 } catch (RemoteException e) { 16588 Log.i(TAG, "Observer no longer exists."); 16589 } 16590 } //end if observer 16591 } //end run 16592 }); 16593 } 16594 16595 private boolean clearApplicationUserDataLIF(String packageName, int userId) { 16596 if (packageName == null) { 16597 Slog.w(TAG, "Attempt to delete null packageName."); 16598 return false; 16599 } 16600 16601 // Try finding details about the requested package 16602 PackageParser.Package pkg; 16603 synchronized (mPackages) { 16604 pkg = mPackages.get(packageName); 16605 if (pkg == null) { 16606 final PackageSetting ps = mSettings.mPackages.get(packageName); 16607 if (ps != null) { 16608 pkg = ps.pkg; 16609 } 16610 } 16611 16612 if (pkg == null) { 16613 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 16614 return false; 16615 } 16616 16617 PackageSetting ps = (PackageSetting) pkg.mExtras; 16618 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 16619 } 16620 16621 clearAppDataLIF(pkg, userId, 16622 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 16623 16624 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); 16625 removeKeystoreDataIfNeeded(userId, appId); 16626 16627 UserManagerInternal umInternal = getUserManagerInternal(); 16628 final int flags; 16629 if (umInternal.isUserUnlockingOrUnlocked(userId)) { 16630 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 16631 } else if (umInternal.isUserRunning(userId)) { 16632 flags = StorageManager.FLAG_STORAGE_DE; 16633 } else { 16634 flags = 0; 16635 } 16636 prepareAppDataContentsLIF(pkg, userId, flags); 16637 16638 return true; 16639 } 16640 16641 /** 16642 * Reverts user permission state changes (permissions and flags) in 16643 * all packages for a given user. 16644 * 16645 * @param userId The device user for which to do a reset. 16646 */ 16647 private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) { 16648 final int packageCount = mPackages.size(); 16649 for (int i = 0; i < packageCount; i++) { 16650 PackageParser.Package pkg = mPackages.valueAt(i); 16651 PackageSetting ps = (PackageSetting) pkg.mExtras; 16652 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 16653 } 16654 } 16655 16656 private void resetNetworkPolicies(int userId) { 16657 LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId); 16658 } 16659 16660 /** 16661 * Reverts user permission state changes (permissions and flags). 16662 * 16663 * @param ps The package for which to reset. 16664 * @param userId The device user for which to do a reset. 16665 */ 16666 private void resetUserChangesToRuntimePermissionsAndFlagsLPw( 16667 final PackageSetting ps, final int userId) { 16668 if (ps.pkg == null) { 16669 return; 16670 } 16671 16672 // These are flags that can change base on user actions. 16673 final int userSettableMask = FLAG_PERMISSION_USER_SET 16674 | FLAG_PERMISSION_USER_FIXED 16675 | FLAG_PERMISSION_REVOKE_ON_UPGRADE 16676 | FLAG_PERMISSION_REVIEW_REQUIRED; 16677 16678 final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED 16679 | FLAG_PERMISSION_POLICY_FIXED; 16680 16681 boolean writeInstallPermissions = false; 16682 boolean writeRuntimePermissions = false; 16683 16684 final int permissionCount = ps.pkg.requestedPermissions.size(); 16685 for (int i = 0; i < permissionCount; i++) { 16686 String permission = ps.pkg.requestedPermissions.get(i); 16687 16688 BasePermission bp = mSettings.mPermissions.get(permission); 16689 if (bp == null) { 16690 continue; 16691 } 16692 16693 // If shared user we just reset the state to which only this app contributed. 16694 if (ps.sharedUser != null) { 16695 boolean used = false; 16696 final int packageCount = ps.sharedUser.packages.size(); 16697 for (int j = 0; j < packageCount; j++) { 16698 PackageSetting pkg = ps.sharedUser.packages.valueAt(j); 16699 if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName) 16700 && pkg.pkg.requestedPermissions.contains(permission)) { 16701 used = true; 16702 break; 16703 } 16704 } 16705 if (used) { 16706 continue; 16707 } 16708 } 16709 16710 PermissionsState permissionsState = ps.getPermissionsState(); 16711 16712 final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId); 16713 16714 // Always clear the user settable flags. 16715 final boolean hasInstallState = permissionsState.getInstallPermissionState( 16716 bp.name) != null; 16717 // If permission review is enabled and this is a legacy app, mark the 16718 // permission as requiring a review as this is the initial state. 16719 int flags = 0; 16720 if ((mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED) 16721 && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 16722 flags |= FLAG_PERMISSION_REVIEW_REQUIRED; 16723 } 16724 if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) { 16725 if (hasInstallState) { 16726 writeInstallPermissions = true; 16727 } else { 16728 writeRuntimePermissions = true; 16729 } 16730 } 16731 16732 // Below is only runtime permission handling. 16733 if (!bp.isRuntime()) { 16734 continue; 16735 } 16736 16737 // Never clobber system or policy. 16738 if ((oldFlags & policyOrSystemFlags) != 0) { 16739 continue; 16740 } 16741 16742 // If this permission was granted by default, make sure it is. 16743 if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) { 16744 if (permissionsState.grantRuntimePermission(bp, userId) 16745 != PERMISSION_OPERATION_FAILURE) { 16746 writeRuntimePermissions = true; 16747 } 16748 // If permission review is enabled the permissions for a legacy apps 16749 // are represented as constantly granted runtime ones, so don't revoke. 16750 } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) { 16751 // Otherwise, reset the permission. 16752 final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId); 16753 switch (revokeResult) { 16754 case PERMISSION_OPERATION_SUCCESS: 16755 case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 16756 writeRuntimePermissions = true; 16757 final int appId = ps.appId; 16758 mHandler.post(new Runnable() { 16759 @Override 16760 public void run() { 16761 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED); 16762 } 16763 }); 16764 } break; 16765 } 16766 } 16767 } 16768 16769 // Synchronously write as we are taking permissions away. 16770 if (writeRuntimePermissions) { 16771 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 16772 } 16773 16774 // Synchronously write as we are taking permissions away. 16775 if (writeInstallPermissions) { 16776 mSettings.writeLPr(); 16777 } 16778 } 16779 16780 /** 16781 * Remove entries from the keystore daemon. Will only remove it if the 16782 * {@code appId} is valid. 16783 */ 16784 private static void removeKeystoreDataIfNeeded(int userId, int appId) { 16785 if (appId < 0) { 16786 return; 16787 } 16788 16789 final KeyStore keyStore = KeyStore.getInstance(); 16790 if (keyStore != null) { 16791 if (userId == UserHandle.USER_ALL) { 16792 for (final int individual : sUserManager.getUserIds()) { 16793 keyStore.clearUid(UserHandle.getUid(individual, appId)); 16794 } 16795 } else { 16796 keyStore.clearUid(UserHandle.getUid(userId, appId)); 16797 } 16798 } else { 16799 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId); 16800 } 16801 } 16802 16803 @Override 16804 public void deleteApplicationCacheFiles(final String packageName, 16805 final IPackageDataObserver observer) { 16806 final int userId = UserHandle.getCallingUserId(); 16807 deleteApplicationCacheFilesAsUser(packageName, userId, observer); 16808 } 16809 16810 @Override 16811 public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId, 16812 final IPackageDataObserver observer) { 16813 mContext.enforceCallingOrSelfPermission( 16814 android.Manifest.permission.DELETE_CACHE_FILES, null); 16815 enforceCrossUserPermission(Binder.getCallingUid(), userId, 16816 /* requireFullPermission= */ true, /* checkShell= */ false, 16817 "delete application cache files"); 16818 16819 final PackageParser.Package pkg; 16820 synchronized (mPackages) { 16821 pkg = mPackages.get(packageName); 16822 } 16823 16824 // Queue up an async operation since the package deletion may take a little while. 16825 mHandler.post(new Runnable() { 16826 public void run() { 16827 synchronized (mInstallLock) { 16828 final int flags = StorageManager.FLAG_STORAGE_DE 16829 | StorageManager.FLAG_STORAGE_CE; 16830 // We're only clearing cache files, so we don't care if the 16831 // app is unfrozen and still able to run 16832 clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY); 16833 clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 16834 } 16835 clearExternalStorageDataSync(packageName, userId, false); 16836 if (observer != null) { 16837 try { 16838 observer.onRemoveCompleted(packageName, true); 16839 } catch (RemoteException e) { 16840 Log.i(TAG, "Observer no longer exists."); 16841 } 16842 } 16843 } 16844 }); 16845 } 16846 16847 @Override 16848 public void getPackageSizeInfo(final String packageName, int userHandle, 16849 final IPackageStatsObserver observer) { 16850 mContext.enforceCallingOrSelfPermission( 16851 android.Manifest.permission.GET_PACKAGE_SIZE, null); 16852 if (packageName == null) { 16853 throw new IllegalArgumentException("Attempt to get size of null packageName"); 16854 } 16855 16856 PackageStats stats = new PackageStats(packageName, userHandle); 16857 16858 /* 16859 * Queue up an async operation since the package measurement may take a 16860 * little while. 16861 */ 16862 Message msg = mHandler.obtainMessage(INIT_COPY); 16863 msg.obj = new MeasureParams(stats, observer); 16864 mHandler.sendMessage(msg); 16865 } 16866 16867 private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) { 16868 final PackageSetting ps; 16869 synchronized (mPackages) { 16870 ps = mSettings.mPackages.get(packageName); 16871 if (ps == null) { 16872 Slog.w(TAG, "Failed to find settings for " + packageName); 16873 return false; 16874 } 16875 } 16876 try { 16877 mInstaller.getAppSize(ps.volumeUuid, packageName, userId, 16878 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 16879 ps.getCeDataInode(userId), ps.codePathString, stats); 16880 } catch (InstallerException e) { 16881 Slog.w(TAG, String.valueOf(e)); 16882 return false; 16883 } 16884 16885 // For now, ignore code size of packages on system partition 16886 if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) { 16887 stats.codeSize = 0; 16888 } 16889 16890 return true; 16891 } 16892 16893 private int getUidTargetSdkVersionLockedLPr(int uid) { 16894 Object obj = mSettings.getUserIdLPr(uid); 16895 if (obj instanceof SharedUserSetting) { 16896 final SharedUserSetting sus = (SharedUserSetting) obj; 16897 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT; 16898 final Iterator<PackageSetting> it = sus.packages.iterator(); 16899 while (it.hasNext()) { 16900 final PackageSetting ps = it.next(); 16901 if (ps.pkg != null) { 16902 int v = ps.pkg.applicationInfo.targetSdkVersion; 16903 if (v < vers) vers = v; 16904 } 16905 } 16906 return vers; 16907 } else if (obj instanceof PackageSetting) { 16908 final PackageSetting ps = (PackageSetting) obj; 16909 if (ps.pkg != null) { 16910 return ps.pkg.applicationInfo.targetSdkVersion; 16911 } 16912 } 16913 return Build.VERSION_CODES.CUR_DEVELOPMENT; 16914 } 16915 16916 @Override 16917 public void addPreferredActivity(IntentFilter filter, int match, 16918 ComponentName[] set, ComponentName activity, int userId) { 16919 addPreferredActivityInternal(filter, match, set, activity, true, userId, 16920 "Adding preferred"); 16921 } 16922 16923 private void addPreferredActivityInternal(IntentFilter filter, int match, 16924 ComponentName[] set, ComponentName activity, boolean always, int userId, 16925 String opname) { 16926 // writer 16927 int callingUid = Binder.getCallingUid(); 16928 enforceCrossUserPermission(callingUid, userId, 16929 true /* requireFullPermission */, false /* checkShell */, "add preferred activity"); 16930 if (filter.countActions() == 0) { 16931 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 16932 return; 16933 } 16934 synchronized (mPackages) { 16935 if (mContext.checkCallingOrSelfPermission( 16936 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 16937 != PackageManager.PERMISSION_GRANTED) { 16938 if (getUidTargetSdkVersionLockedLPr(callingUid) 16939 < Build.VERSION_CODES.FROYO) { 16940 Slog.w(TAG, "Ignoring addPreferredActivity() from uid " 16941 + callingUid); 16942 return; 16943 } 16944 mContext.enforceCallingOrSelfPermission( 16945 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 16946 } 16947 16948 PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId); 16949 Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user " 16950 + userId + ":"); 16951 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 16952 pir.addFilter(new PreferredActivity(filter, match, set, activity, always)); 16953 scheduleWritePackageRestrictionsLocked(userId); 16954 postPreferredActivityChangedBroadcast(userId); 16955 } 16956 } 16957 16958 private void postPreferredActivityChangedBroadcast(int userId) { 16959 mHandler.post(() -> { 16960 final IActivityManager am = ActivityManagerNative.getDefault(); 16961 if (am == null) { 16962 return; 16963 } 16964 16965 final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED); 16966 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16967 try { 16968 am.broadcastIntent(null, intent, null, null, 16969 0, null, null, null, android.app.AppOpsManager.OP_NONE, 16970 null, false, false, userId); 16971 } catch (RemoteException e) { 16972 } 16973 }); 16974 } 16975 16976 @Override 16977 public void replacePreferredActivity(IntentFilter filter, int match, 16978 ComponentName[] set, ComponentName activity, int userId) { 16979 if (filter.countActions() != 1) { 16980 throw new IllegalArgumentException( 16981 "replacePreferredActivity expects filter to have only 1 action."); 16982 } 16983 if (filter.countDataAuthorities() != 0 16984 || filter.countDataPaths() != 0 16985 || filter.countDataSchemes() > 1 16986 || filter.countDataTypes() != 0) { 16987 throw new IllegalArgumentException( 16988 "replacePreferredActivity expects filter to have no data authorities, " + 16989 "paths, or types; and at most one scheme."); 16990 } 16991 16992 final int callingUid = Binder.getCallingUid(); 16993 enforceCrossUserPermission(callingUid, userId, 16994 true /* requireFullPermission */, false /* checkShell */, 16995 "replace preferred activity"); 16996 synchronized (mPackages) { 16997 if (mContext.checkCallingOrSelfPermission( 16998 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 16999 != PackageManager.PERMISSION_GRANTED) { 17000 if (getUidTargetSdkVersionLockedLPr(callingUid) 17001 < Build.VERSION_CODES.FROYO) { 17002 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid " 17003 + Binder.getCallingUid()); 17004 return; 17005 } 17006 mContext.enforceCallingOrSelfPermission( 17007 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 17008 } 17009 17010 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 17011 if (pir != null) { 17012 // Get all of the existing entries that exactly match this filter. 17013 ArrayList<PreferredActivity> existing = pir.findFilters(filter); 17014 if (existing != null && existing.size() == 1) { 17015 PreferredActivity cur = existing.get(0); 17016 if (DEBUG_PREFERRED) { 17017 Slog.i(TAG, "Checking replace of preferred:"); 17018 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 17019 if (!cur.mPref.mAlways) { 17020 Slog.i(TAG, " -- CUR; not mAlways!"); 17021 } else { 17022 Slog.i(TAG, " -- CUR: mMatch=" + cur.mPref.mMatch); 17023 Slog.i(TAG, " -- CUR: mSet=" 17024 + Arrays.toString(cur.mPref.mSetComponents)); 17025 Slog.i(TAG, " -- CUR: mComponent=" + cur.mPref.mShortComponent); 17026 Slog.i(TAG, " -- NEW: mMatch=" 17027 + (match&IntentFilter.MATCH_CATEGORY_MASK)); 17028 Slog.i(TAG, " -- CUR: mSet=" + Arrays.toString(set)); 17029 Slog.i(TAG, " -- CUR: mComponent=" + activity.flattenToShortString()); 17030 } 17031 } 17032 if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity) 17033 && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK) 17034 && cur.mPref.sameSet(set)) { 17035 // Setting the preferred activity to what it happens to be already 17036 if (DEBUG_PREFERRED) { 17037 Slog.i(TAG, "Replacing with same preferred activity " 17038 + cur.mPref.mShortComponent + " for user " 17039 + userId + ":"); 17040 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 17041 } 17042 return; 17043 } 17044 } 17045 17046 if (existing != null) { 17047 if (DEBUG_PREFERRED) { 17048 Slog.i(TAG, existing.size() + " existing preferred matches for:"); 17049 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 17050 } 17051 for (int i = 0; i < existing.size(); i++) { 17052 PreferredActivity pa = existing.get(i); 17053 if (DEBUG_PREFERRED) { 17054 Slog.i(TAG, "Removing existing preferred activity " 17055 + pa.mPref.mComponent + ":"); 17056 pa.dump(new LogPrinter(Log.INFO, TAG), " "); 17057 } 17058 pir.removeFilter(pa); 17059 } 17060 } 17061 } 17062 addPreferredActivityInternal(filter, match, set, activity, true, userId, 17063 "Replacing preferred"); 17064 } 17065 } 17066 17067 @Override 17068 public void clearPackagePreferredActivities(String packageName) { 17069 final int uid = Binder.getCallingUid(); 17070 // writer 17071 synchronized (mPackages) { 17072 PackageParser.Package pkg = mPackages.get(packageName); 17073 if (pkg == null || pkg.applicationInfo.uid != uid) { 17074 if (mContext.checkCallingOrSelfPermission( 17075 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 17076 != PackageManager.PERMISSION_GRANTED) { 17077 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid()) 17078 < Build.VERSION_CODES.FROYO) { 17079 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid " 17080 + Binder.getCallingUid()); 17081 return; 17082 } 17083 mContext.enforceCallingOrSelfPermission( 17084 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 17085 } 17086 } 17087 17088 int user = UserHandle.getCallingUserId(); 17089 if (clearPackagePreferredActivitiesLPw(packageName, user)) { 17090 scheduleWritePackageRestrictionsLocked(user); 17091 } 17092 } 17093 } 17094 17095 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 17096 boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) { 17097 ArrayList<PreferredActivity> removed = null; 17098 boolean changed = false; 17099 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 17100 final int thisUserId = mSettings.mPreferredActivities.keyAt(i); 17101 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 17102 if (userId != UserHandle.USER_ALL && userId != thisUserId) { 17103 continue; 17104 } 17105 Iterator<PreferredActivity> it = pir.filterIterator(); 17106 while (it.hasNext()) { 17107 PreferredActivity pa = it.next(); 17108 // Mark entry for removal only if it matches the package name 17109 // and the entry is of type "always". 17110 if (packageName == null || 17111 (pa.mPref.mComponent.getPackageName().equals(packageName) 17112 && pa.mPref.mAlways)) { 17113 if (removed == null) { 17114 removed = new ArrayList<PreferredActivity>(); 17115 } 17116 removed.add(pa); 17117 } 17118 } 17119 if (removed != null) { 17120 for (int j=0; j<removed.size(); j++) { 17121 PreferredActivity pa = removed.get(j); 17122 pir.removeFilter(pa); 17123 } 17124 changed = true; 17125 } 17126 } 17127 if (changed) { 17128 postPreferredActivityChangedBroadcast(userId); 17129 } 17130 return changed; 17131 } 17132 17133 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 17134 private void clearIntentFilterVerificationsLPw(int userId) { 17135 final int packageCount = mPackages.size(); 17136 for (int i = 0; i < packageCount; i++) { 17137 PackageParser.Package pkg = mPackages.valueAt(i); 17138 clearIntentFilterVerificationsLPw(pkg.packageName, userId); 17139 } 17140 } 17141 17142 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 17143 void clearIntentFilterVerificationsLPw(String packageName, int userId) { 17144 if (userId == UserHandle.USER_ALL) { 17145 if (mSettings.removeIntentFilterVerificationLPw(packageName, 17146 sUserManager.getUserIds())) { 17147 for (int oneUserId : sUserManager.getUserIds()) { 17148 scheduleWritePackageRestrictionsLocked(oneUserId); 17149 } 17150 } 17151 } else { 17152 if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) { 17153 scheduleWritePackageRestrictionsLocked(userId); 17154 } 17155 } 17156 } 17157 17158 void clearDefaultBrowserIfNeeded(String packageName) { 17159 for (int oneUserId : sUserManager.getUserIds()) { 17160 String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId); 17161 if (TextUtils.isEmpty(defaultBrowserPackageName)) continue; 17162 if (packageName.equals(defaultBrowserPackageName)) { 17163 setDefaultBrowserPackageName(null, oneUserId); 17164 } 17165 } 17166 } 17167 17168 @Override 17169 public void resetApplicationPreferences(int userId) { 17170 mContext.enforceCallingOrSelfPermission( 17171 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 17172 final long identity = Binder.clearCallingIdentity(); 17173 // writer 17174 try { 17175 synchronized (mPackages) { 17176 clearPackagePreferredActivitiesLPw(null, userId); 17177 mSettings.applyDefaultPreferredAppsLPw(this, userId); 17178 // TODO: We have to reset the default SMS and Phone. This requires 17179 // significant refactoring to keep all default apps in the package 17180 // manager (cleaner but more work) or have the services provide 17181 // callbacks to the package manager to request a default app reset. 17182 applyFactoryDefaultBrowserLPw(userId); 17183 clearIntentFilterVerificationsLPw(userId); 17184 primeDomainVerificationsLPw(userId); 17185 resetUserChangesToRuntimePermissionsAndFlagsLPw(userId); 17186 scheduleWritePackageRestrictionsLocked(userId); 17187 } 17188 resetNetworkPolicies(userId); 17189 } finally { 17190 Binder.restoreCallingIdentity(identity); 17191 } 17192 } 17193 17194 @Override 17195 public int getPreferredActivities(List<IntentFilter> outFilters, 17196 List<ComponentName> outActivities, String packageName) { 17197 17198 int num = 0; 17199 final int userId = UserHandle.getCallingUserId(); 17200 // reader 17201 synchronized (mPackages) { 17202 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 17203 if (pir != null) { 17204 final Iterator<PreferredActivity> it = pir.filterIterator(); 17205 while (it.hasNext()) { 17206 final PreferredActivity pa = it.next(); 17207 if (packageName == null 17208 || (pa.mPref.mComponent.getPackageName().equals(packageName) 17209 && pa.mPref.mAlways)) { 17210 if (outFilters != null) { 17211 outFilters.add(new IntentFilter(pa)); 17212 } 17213 if (outActivities != null) { 17214 outActivities.add(pa.mPref.mComponent); 17215 } 17216 } 17217 } 17218 } 17219 } 17220 17221 return num; 17222 } 17223 17224 @Override 17225 public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity, 17226 int userId) { 17227 int callingUid = Binder.getCallingUid(); 17228 if (callingUid != Process.SYSTEM_UID) { 17229 throw new SecurityException( 17230 "addPersistentPreferredActivity can only be run by the system"); 17231 } 17232 if (filter.countActions() == 0) { 17233 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 17234 return; 17235 } 17236 synchronized (mPackages) { 17237 Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId + 17238 ":"); 17239 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 17240 mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter( 17241 new PersistentPreferredActivity(filter, activity)); 17242 scheduleWritePackageRestrictionsLocked(userId); 17243 postPreferredActivityChangedBroadcast(userId); 17244 } 17245 } 17246 17247 @Override 17248 public void clearPackagePersistentPreferredActivities(String packageName, int userId) { 17249 int callingUid = Binder.getCallingUid(); 17250 if (callingUid != Process.SYSTEM_UID) { 17251 throw new SecurityException( 17252 "clearPackagePersistentPreferredActivities can only be run by the system"); 17253 } 17254 ArrayList<PersistentPreferredActivity> removed = null; 17255 boolean changed = false; 17256 synchronized (mPackages) { 17257 for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) { 17258 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i); 17259 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 17260 .valueAt(i); 17261 if (userId != thisUserId) { 17262 continue; 17263 } 17264 Iterator<PersistentPreferredActivity> it = ppir.filterIterator(); 17265 while (it.hasNext()) { 17266 PersistentPreferredActivity ppa = it.next(); 17267 // Mark entry for removal only if it matches the package name. 17268 if (ppa.mComponent.getPackageName().equals(packageName)) { 17269 if (removed == null) { 17270 removed = new ArrayList<PersistentPreferredActivity>(); 17271 } 17272 removed.add(ppa); 17273 } 17274 } 17275 if (removed != null) { 17276 for (int j=0; j<removed.size(); j++) { 17277 PersistentPreferredActivity ppa = removed.get(j); 17278 ppir.removeFilter(ppa); 17279 } 17280 changed = true; 17281 } 17282 } 17283 17284 if (changed) { 17285 scheduleWritePackageRestrictionsLocked(userId); 17286 postPreferredActivityChangedBroadcast(userId); 17287 } 17288 } 17289 } 17290 17291 /** 17292 * Common machinery for picking apart a restored XML blob and passing 17293 * it to a caller-supplied functor to be applied to the running system. 17294 */ 17295 private void restoreFromXml(XmlPullParser parser, int userId, 17296 String expectedStartTag, BlobXmlRestorer functor) 17297 throws IOException, XmlPullParserException { 17298 int type; 17299 while ((type = parser.next()) != XmlPullParser.START_TAG 17300 && type != XmlPullParser.END_DOCUMENT) { 17301 } 17302 if (type != XmlPullParser.START_TAG) { 17303 // oops didn't find a start tag?! 17304 if (DEBUG_BACKUP) { 17305 Slog.e(TAG, "Didn't find start tag during restore"); 17306 } 17307 return; 17308 } 17309Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName()); 17310 // this is supposed to be TAG_PREFERRED_BACKUP 17311 if (!expectedStartTag.equals(parser.getName())) { 17312 if (DEBUG_BACKUP) { 17313 Slog.e(TAG, "Found unexpected tag " + parser.getName()); 17314 } 17315 return; 17316 } 17317 17318 // skip interfering stuff, then we're aligned with the backing implementation 17319 while ((type = parser.next()) == XmlPullParser.TEXT) { } 17320Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); 17321 functor.apply(parser, userId); 17322 } 17323 17324 private interface BlobXmlRestorer { 17325 public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException; 17326 } 17327 17328 /** 17329 * Non-Binder method, support for the backup/restore mechanism: write the 17330 * full set of preferred activities in its canonical XML format. Returns the 17331 * XML output as a byte array, or null if there is none. 17332 */ 17333 @Override 17334 public byte[] getPreferredActivityBackup(int userId) { 17335 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17336 throw new SecurityException("Only the system may call getPreferredActivityBackup()"); 17337 } 17338 17339 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 17340 try { 17341 final XmlSerializer serializer = new FastXmlSerializer(); 17342 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 17343 serializer.startDocument(null, true); 17344 serializer.startTag(null, TAG_PREFERRED_BACKUP); 17345 17346 synchronized (mPackages) { 17347 mSettings.writePreferredActivitiesLPr(serializer, userId, true); 17348 } 17349 17350 serializer.endTag(null, TAG_PREFERRED_BACKUP); 17351 serializer.endDocument(); 17352 serializer.flush(); 17353 } catch (Exception e) { 17354 if (DEBUG_BACKUP) { 17355 Slog.e(TAG, "Unable to write preferred activities for backup", e); 17356 } 17357 return null; 17358 } 17359 17360 return dataStream.toByteArray(); 17361 } 17362 17363 @Override 17364 public void restorePreferredActivities(byte[] backup, int userId) { 17365 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17366 throw new SecurityException("Only the system may call restorePreferredActivities()"); 17367 } 17368 17369 try { 17370 final XmlPullParser parser = Xml.newPullParser(); 17371 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 17372 restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP, 17373 new BlobXmlRestorer() { 17374 @Override 17375 public void apply(XmlPullParser parser, int userId) 17376 throws XmlPullParserException, IOException { 17377 synchronized (mPackages) { 17378 mSettings.readPreferredActivitiesLPw(parser, userId); 17379 } 17380 } 17381 } ); 17382 } catch (Exception e) { 17383 if (DEBUG_BACKUP) { 17384 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 17385 } 17386 } 17387 } 17388 17389 /** 17390 * Non-Binder method, support for the backup/restore mechanism: write the 17391 * default browser (etc) settings in its canonical XML format. Returns the default 17392 * browser XML representation as a byte array, or null if there is none. 17393 */ 17394 @Override 17395 public byte[] getDefaultAppsBackup(int userId) { 17396 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17397 throw new SecurityException("Only the system may call getDefaultAppsBackup()"); 17398 } 17399 17400 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 17401 try { 17402 final XmlSerializer serializer = new FastXmlSerializer(); 17403 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 17404 serializer.startDocument(null, true); 17405 serializer.startTag(null, TAG_DEFAULT_APPS); 17406 17407 synchronized (mPackages) { 17408 mSettings.writeDefaultAppsLPr(serializer, userId); 17409 } 17410 17411 serializer.endTag(null, TAG_DEFAULT_APPS); 17412 serializer.endDocument(); 17413 serializer.flush(); 17414 } catch (Exception e) { 17415 if (DEBUG_BACKUP) { 17416 Slog.e(TAG, "Unable to write default apps for backup", e); 17417 } 17418 return null; 17419 } 17420 17421 return dataStream.toByteArray(); 17422 } 17423 17424 @Override 17425 public void restoreDefaultApps(byte[] backup, int userId) { 17426 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17427 throw new SecurityException("Only the system may call restoreDefaultApps()"); 17428 } 17429 17430 try { 17431 final XmlPullParser parser = Xml.newPullParser(); 17432 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 17433 restoreFromXml(parser, userId, TAG_DEFAULT_APPS, 17434 new BlobXmlRestorer() { 17435 @Override 17436 public void apply(XmlPullParser parser, int userId) 17437 throws XmlPullParserException, IOException { 17438 synchronized (mPackages) { 17439 mSettings.readDefaultAppsLPw(parser, userId); 17440 } 17441 } 17442 } ); 17443 } catch (Exception e) { 17444 if (DEBUG_BACKUP) { 17445 Slog.e(TAG, "Exception restoring default apps: " + e.getMessage()); 17446 } 17447 } 17448 } 17449 17450 @Override 17451 public byte[] getIntentFilterVerificationBackup(int userId) { 17452 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17453 throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()"); 17454 } 17455 17456 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 17457 try { 17458 final XmlSerializer serializer = new FastXmlSerializer(); 17459 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 17460 serializer.startDocument(null, true); 17461 serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION); 17462 17463 synchronized (mPackages) { 17464 mSettings.writeAllDomainVerificationsLPr(serializer, userId); 17465 } 17466 17467 serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION); 17468 serializer.endDocument(); 17469 serializer.flush(); 17470 } catch (Exception e) { 17471 if (DEBUG_BACKUP) { 17472 Slog.e(TAG, "Unable to write default apps for backup", e); 17473 } 17474 return null; 17475 } 17476 17477 return dataStream.toByteArray(); 17478 } 17479 17480 @Override 17481 public void restoreIntentFilterVerification(byte[] backup, int userId) { 17482 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17483 throw new SecurityException("Only the system may call restorePreferredActivities()"); 17484 } 17485 17486 try { 17487 final XmlPullParser parser = Xml.newPullParser(); 17488 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 17489 restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION, 17490 new BlobXmlRestorer() { 17491 @Override 17492 public void apply(XmlPullParser parser, int userId) 17493 throws XmlPullParserException, IOException { 17494 synchronized (mPackages) { 17495 mSettings.readAllDomainVerificationsLPr(parser, userId); 17496 mSettings.writeLPr(); 17497 } 17498 } 17499 } ); 17500 } catch (Exception e) { 17501 if (DEBUG_BACKUP) { 17502 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 17503 } 17504 } 17505 } 17506 17507 @Override 17508 public byte[] getPermissionGrantBackup(int userId) { 17509 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17510 throw new SecurityException("Only the system may call getPermissionGrantBackup()"); 17511 } 17512 17513 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 17514 try { 17515 final XmlSerializer serializer = new FastXmlSerializer(); 17516 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 17517 serializer.startDocument(null, true); 17518 serializer.startTag(null, TAG_PERMISSION_BACKUP); 17519 17520 synchronized (mPackages) { 17521 serializeRuntimePermissionGrantsLPr(serializer, userId); 17522 } 17523 17524 serializer.endTag(null, TAG_PERMISSION_BACKUP); 17525 serializer.endDocument(); 17526 serializer.flush(); 17527 } catch (Exception e) { 17528 if (DEBUG_BACKUP) { 17529 Slog.e(TAG, "Unable to write default apps for backup", e); 17530 } 17531 return null; 17532 } 17533 17534 return dataStream.toByteArray(); 17535 } 17536 17537 @Override 17538 public void restorePermissionGrants(byte[] backup, int userId) { 17539 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17540 throw new SecurityException("Only the system may call restorePermissionGrants()"); 17541 } 17542 17543 try { 17544 final XmlPullParser parser = Xml.newPullParser(); 17545 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 17546 restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP, 17547 new BlobXmlRestorer() { 17548 @Override 17549 public void apply(XmlPullParser parser, int userId) 17550 throws XmlPullParserException, IOException { 17551 synchronized (mPackages) { 17552 processRestoredPermissionGrantsLPr(parser, userId); 17553 } 17554 } 17555 } ); 17556 } catch (Exception e) { 17557 if (DEBUG_BACKUP) { 17558 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 17559 } 17560 } 17561 } 17562 17563 private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId) 17564 throws IOException { 17565 serializer.startTag(null, TAG_ALL_GRANTS); 17566 17567 final int N = mSettings.mPackages.size(); 17568 for (int i = 0; i < N; i++) { 17569 final PackageSetting ps = mSettings.mPackages.valueAt(i); 17570 boolean pkgGrantsKnown = false; 17571 17572 PermissionsState packagePerms = ps.getPermissionsState(); 17573 17574 for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) { 17575 final int grantFlags = state.getFlags(); 17576 // only look at grants that are not system/policy fixed 17577 if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) { 17578 final boolean isGranted = state.isGranted(); 17579 // And only back up the user-twiddled state bits 17580 if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) { 17581 final String packageName = mSettings.mPackages.keyAt(i); 17582 if (!pkgGrantsKnown) { 17583 serializer.startTag(null, TAG_GRANT); 17584 serializer.attribute(null, ATTR_PACKAGE_NAME, packageName); 17585 pkgGrantsKnown = true; 17586 } 17587 17588 final boolean userSet = 17589 (grantFlags & FLAG_PERMISSION_USER_SET) != 0; 17590 final boolean userFixed = 17591 (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0; 17592 final boolean revoke = 17593 (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0; 17594 17595 serializer.startTag(null, TAG_PERMISSION); 17596 serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName()); 17597 if (isGranted) { 17598 serializer.attribute(null, ATTR_IS_GRANTED, "true"); 17599 } 17600 if (userSet) { 17601 serializer.attribute(null, ATTR_USER_SET, "true"); 17602 } 17603 if (userFixed) { 17604 serializer.attribute(null, ATTR_USER_FIXED, "true"); 17605 } 17606 if (revoke) { 17607 serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true"); 17608 } 17609 serializer.endTag(null, TAG_PERMISSION); 17610 } 17611 } 17612 } 17613 17614 if (pkgGrantsKnown) { 17615 serializer.endTag(null, TAG_GRANT); 17616 } 17617 } 17618 17619 serializer.endTag(null, TAG_ALL_GRANTS); 17620 } 17621 17622 private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId) 17623 throws XmlPullParserException, IOException { 17624 String pkgName = null; 17625 int outerDepth = parser.getDepth(); 17626 int type; 17627 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 17628 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 17629 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 17630 continue; 17631 } 17632 17633 final String tagName = parser.getName(); 17634 if (tagName.equals(TAG_GRANT)) { 17635 pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME); 17636 if (DEBUG_BACKUP) { 17637 Slog.v(TAG, "+++ Restoring grants for package " + pkgName); 17638 } 17639 } else if (tagName.equals(TAG_PERMISSION)) { 17640 17641 final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED)); 17642 final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME); 17643 17644 int newFlagSet = 0; 17645 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) { 17646 newFlagSet |= FLAG_PERMISSION_USER_SET; 17647 } 17648 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) { 17649 newFlagSet |= FLAG_PERMISSION_USER_FIXED; 17650 } 17651 if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) { 17652 newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE; 17653 } 17654 if (DEBUG_BACKUP) { 17655 Slog.v(TAG, " + Restoring grant: pkg=" + pkgName + " perm=" + permName 17656 + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet)); 17657 } 17658 final PackageSetting ps = mSettings.mPackages.get(pkgName); 17659 if (ps != null) { 17660 // Already installed so we apply the grant immediately 17661 if (DEBUG_BACKUP) { 17662 Slog.v(TAG, " + already installed; applying"); 17663 } 17664 PermissionsState perms = ps.getPermissionsState(); 17665 BasePermission bp = mSettings.mPermissions.get(permName); 17666 if (bp != null) { 17667 if (isGranted) { 17668 perms.grantRuntimePermission(bp, userId); 17669 } 17670 if (newFlagSet != 0) { 17671 perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet); 17672 } 17673 } 17674 } else { 17675 // Need to wait for post-restore install to apply the grant 17676 if (DEBUG_BACKUP) { 17677 Slog.v(TAG, " - not yet installed; saving for later"); 17678 } 17679 mSettings.processRestoredPermissionGrantLPr(pkgName, permName, 17680 isGranted, newFlagSet, userId); 17681 } 17682 } else { 17683 PackageManagerService.reportSettingsProblem(Log.WARN, 17684 "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName); 17685 XmlUtils.skipCurrentTag(parser); 17686 } 17687 } 17688 17689 scheduleWriteSettingsLocked(); 17690 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 17691 } 17692 17693 @Override 17694 public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage, 17695 int sourceUserId, int targetUserId, int flags) { 17696 mContext.enforceCallingOrSelfPermission( 17697 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 17698 int callingUid = Binder.getCallingUid(); 17699 enforceOwnerRights(ownerPackage, callingUid); 17700 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 17701 if (intentFilter.countActions() == 0) { 17702 Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions"); 17703 return; 17704 } 17705 synchronized (mPackages) { 17706 CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter, 17707 ownerPackage, targetUserId, flags); 17708 CrossProfileIntentResolver resolver = 17709 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 17710 ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter); 17711 // We have all those whose filter is equal. Now checking if the rest is equal as well. 17712 if (existing != null) { 17713 int size = existing.size(); 17714 for (int i = 0; i < size; i++) { 17715 if (newFilter.equalsIgnoreFilter(existing.get(i))) { 17716 return; 17717 } 17718 } 17719 } 17720 resolver.addFilter(newFilter); 17721 scheduleWritePackageRestrictionsLocked(sourceUserId); 17722 } 17723 } 17724 17725 @Override 17726 public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) { 17727 mContext.enforceCallingOrSelfPermission( 17728 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 17729 int callingUid = Binder.getCallingUid(); 17730 enforceOwnerRights(ownerPackage, callingUid); 17731 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 17732 synchronized (mPackages) { 17733 CrossProfileIntentResolver resolver = 17734 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 17735 ArraySet<CrossProfileIntentFilter> set = 17736 new ArraySet<CrossProfileIntentFilter>(resolver.filterSet()); 17737 for (CrossProfileIntentFilter filter : set) { 17738 if (filter.getOwnerPackage().equals(ownerPackage)) { 17739 resolver.removeFilter(filter); 17740 } 17741 } 17742 scheduleWritePackageRestrictionsLocked(sourceUserId); 17743 } 17744 } 17745 17746 // Enforcing that callingUid is owning pkg on userId 17747 private void enforceOwnerRights(String pkg, int callingUid) { 17748 // The system owns everything. 17749 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) { 17750 return; 17751 } 17752 int callingUserId = UserHandle.getUserId(callingUid); 17753 PackageInfo pi = getPackageInfo(pkg, 0, callingUserId); 17754 if (pi == null) { 17755 throw new IllegalArgumentException("Unknown package " + pkg + " on user " 17756 + callingUserId); 17757 } 17758 if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) { 17759 throw new SecurityException("Calling uid " + callingUid 17760 + " does not own package " + pkg); 17761 } 17762 } 17763 17764 @Override 17765 public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) { 17766 return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId()); 17767 } 17768 17769 private Intent getHomeIntent() { 17770 Intent intent = new Intent(Intent.ACTION_MAIN); 17771 intent.addCategory(Intent.CATEGORY_HOME); 17772 intent.addCategory(Intent.CATEGORY_DEFAULT); 17773 return intent; 17774 } 17775 17776 private IntentFilter getHomeFilter() { 17777 IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN); 17778 filter.addCategory(Intent.CATEGORY_HOME); 17779 filter.addCategory(Intent.CATEGORY_DEFAULT); 17780 return filter; 17781 } 17782 17783 ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, 17784 int userId) { 17785 Intent intent = getHomeIntent(); 17786 List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null, 17787 PackageManager.GET_META_DATA, userId); 17788 ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0, 17789 true, false, false, userId); 17790 17791 allHomeCandidates.clear(); 17792 if (list != null) { 17793 for (ResolveInfo ri : list) { 17794 allHomeCandidates.add(ri); 17795 } 17796 } 17797 return (preferred == null || preferred.activityInfo == null) 17798 ? null 17799 : new ComponentName(preferred.activityInfo.packageName, 17800 preferred.activityInfo.name); 17801 } 17802 17803 @Override 17804 public void setHomeActivity(ComponentName comp, int userId) { 17805 ArrayList<ResolveInfo> homeActivities = new ArrayList<>(); 17806 getHomeActivitiesAsUser(homeActivities, userId); 17807 17808 boolean found = false; 17809 17810 final int size = homeActivities.size(); 17811 final ComponentName[] set = new ComponentName[size]; 17812 for (int i = 0; i < size; i++) { 17813 final ResolveInfo candidate = homeActivities.get(i); 17814 final ActivityInfo info = candidate.activityInfo; 17815 final ComponentName activityName = new ComponentName(info.packageName, info.name); 17816 set[i] = activityName; 17817 if (!found && activityName.equals(comp)) { 17818 found = true; 17819 } 17820 } 17821 if (!found) { 17822 throw new IllegalArgumentException("Component " + comp + " cannot be home on user " 17823 + userId); 17824 } 17825 replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY, 17826 set, comp, userId); 17827 } 17828 17829 private @Nullable String getSetupWizardPackageName() { 17830 final Intent intent = new Intent(Intent.ACTION_MAIN); 17831 intent.addCategory(Intent.CATEGORY_SETUP_WIZARD); 17832 17833 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, 17834 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE 17835 | MATCH_DISABLED_COMPONENTS, 17836 UserHandle.myUserId()); 17837 if (matches.size() == 1) { 17838 return matches.get(0).getComponentInfo().packageName; 17839 } else { 17840 Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size() 17841 + ": matches=" + matches); 17842 return null; 17843 } 17844 } 17845 17846 private @Nullable String getStorageManagerPackageName() { 17847 final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE); 17848 17849 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, 17850 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE 17851 | MATCH_DISABLED_COMPONENTS, 17852 UserHandle.myUserId()); 17853 if (matches.size() == 1) { 17854 return matches.get(0).getComponentInfo().packageName; 17855 } else { 17856 Slog.e(TAG, "There should probably be exactly one storage manager; found " 17857 + matches.size() + ": matches=" + matches); 17858 return null; 17859 } 17860 } 17861 17862 @Override 17863 public void setApplicationEnabledSetting(String appPackageName, 17864 int newState, int flags, int userId, String callingPackage) { 17865 if (!sUserManager.exists(userId)) return; 17866 if (callingPackage == null) { 17867 callingPackage = Integer.toString(Binder.getCallingUid()); 17868 } 17869 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage); 17870 } 17871 17872 @Override 17873 public void setComponentEnabledSetting(ComponentName componentName, 17874 int newState, int flags, int userId) { 17875 if (!sUserManager.exists(userId)) return; 17876 setEnabledSetting(componentName.getPackageName(), 17877 componentName.getClassName(), newState, flags, userId, null); 17878 } 17879 17880 private void setEnabledSetting(final String packageName, String className, int newState, 17881 final int flags, int userId, String callingPackage) { 17882 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT 17883 || newState == COMPONENT_ENABLED_STATE_ENABLED 17884 || newState == COMPONENT_ENABLED_STATE_DISABLED 17885 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER 17886 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) { 17887 throw new IllegalArgumentException("Invalid new component state: " 17888 + newState); 17889 } 17890 PackageSetting pkgSetting; 17891 final int uid = Binder.getCallingUid(); 17892 final int permission; 17893 if (uid == Process.SYSTEM_UID) { 17894 permission = PackageManager.PERMISSION_GRANTED; 17895 } else { 17896 permission = mContext.checkCallingOrSelfPermission( 17897 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 17898 } 17899 enforceCrossUserPermission(uid, userId, 17900 false /* requireFullPermission */, true /* checkShell */, "set enabled"); 17901 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 17902 boolean sendNow = false; 17903 boolean isApp = (className == null); 17904 String componentName = isApp ? packageName : className; 17905 int packageUid = -1; 17906 ArrayList<String> components; 17907 17908 // writer 17909 synchronized (mPackages) { 17910 pkgSetting = mSettings.mPackages.get(packageName); 17911 if (pkgSetting == null) { 17912 if (className == null) { 17913 throw new IllegalArgumentException("Unknown package: " + packageName); 17914 } 17915 throw new IllegalArgumentException( 17916 "Unknown component: " + packageName + "/" + className); 17917 } 17918 } 17919 17920 // Limit who can change which apps 17921 if (!UserHandle.isSameApp(uid, pkgSetting.appId)) { 17922 // Don't allow apps that don't have permission to modify other apps 17923 if (!allowedByPermission) { 17924 throw new SecurityException( 17925 "Permission Denial: attempt to change component state from pid=" 17926 + Binder.getCallingPid() 17927 + ", uid=" + uid + ", package uid=" + pkgSetting.appId); 17928 } 17929 // Don't allow changing protected packages. 17930 if (mProtectedPackages.isPackageStateProtected(userId, packageName)) { 17931 throw new SecurityException("Cannot disable a protected package: " + packageName); 17932 } 17933 } 17934 17935 synchronized (mPackages) { 17936 if (uid == Process.SHELL_UID) { 17937 // Shell can only change whole packages between ENABLED and DISABLED_USER states 17938 int oldState = pkgSetting.getEnabled(userId); 17939 if (className == null 17940 && 17941 (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER 17942 || oldState == COMPONENT_ENABLED_STATE_DEFAULT 17943 || oldState == COMPONENT_ENABLED_STATE_ENABLED) 17944 && 17945 (newState == COMPONENT_ENABLED_STATE_DISABLED_USER 17946 || newState == COMPONENT_ENABLED_STATE_DEFAULT 17947 || newState == COMPONENT_ENABLED_STATE_ENABLED)) { 17948 // ok 17949 } else { 17950 throw new SecurityException( 17951 "Shell cannot change component state for " + packageName + "/" 17952 + className + " to " + newState); 17953 } 17954 } 17955 if (className == null) { 17956 // We're dealing with an application/package level state change 17957 if (pkgSetting.getEnabled(userId) == newState) { 17958 // Nothing to do 17959 return; 17960 } 17961 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT 17962 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { 17963 // Don't care about who enables an app. 17964 callingPackage = null; 17965 } 17966 pkgSetting.setEnabled(newState, userId, callingPackage); 17967 // pkgSetting.pkg.mSetEnabled = newState; 17968 } else { 17969 // We're dealing with a component level state change 17970 // First, verify that this is a valid class name. 17971 PackageParser.Package pkg = pkgSetting.pkg; 17972 if (pkg == null || !pkg.hasComponentClassName(className)) { 17973 if (pkg != null && 17974 pkg.applicationInfo.targetSdkVersion >= 17975 Build.VERSION_CODES.JELLY_BEAN) { 17976 throw new IllegalArgumentException("Component class " + className 17977 + " does not exist in " + packageName); 17978 } else { 17979 Slog.w(TAG, "Failed setComponentEnabledSetting: component class " 17980 + className + " does not exist in " + packageName); 17981 } 17982 } 17983 switch (newState) { 17984 case COMPONENT_ENABLED_STATE_ENABLED: 17985 if (!pkgSetting.enableComponentLPw(className, userId)) { 17986 return; 17987 } 17988 break; 17989 case COMPONENT_ENABLED_STATE_DISABLED: 17990 if (!pkgSetting.disableComponentLPw(className, userId)) { 17991 return; 17992 } 17993 break; 17994 case COMPONENT_ENABLED_STATE_DEFAULT: 17995 if (!pkgSetting.restoreComponentLPw(className, userId)) { 17996 return; 17997 } 17998 break; 17999 default: 18000 Slog.e(TAG, "Invalid new component state: " + newState); 18001 return; 18002 } 18003 } 18004 scheduleWritePackageRestrictionsLocked(userId); 18005 components = mPendingBroadcasts.get(userId, packageName); 18006 final boolean newPackage = components == null; 18007 if (newPackage) { 18008 components = new ArrayList<String>(); 18009 } 18010 if (!components.contains(componentName)) { 18011 components.add(componentName); 18012 } 18013 if ((flags&PackageManager.DONT_KILL_APP) == 0) { 18014 sendNow = true; 18015 // Purge entry from pending broadcast list if another one exists already 18016 // since we are sending one right away. 18017 mPendingBroadcasts.remove(userId, packageName); 18018 } else { 18019 if (newPackage) { 18020 mPendingBroadcasts.put(userId, packageName, components); 18021 } 18022 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) { 18023 // Schedule a message 18024 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY); 18025 } 18026 } 18027 } 18028 18029 long callingId = Binder.clearCallingIdentity(); 18030 try { 18031 if (sendNow) { 18032 packageUid = UserHandle.getUid(userId, pkgSetting.appId); 18033 sendPackageChangedBroadcast(packageName, 18034 (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid); 18035 } 18036 } finally { 18037 Binder.restoreCallingIdentity(callingId); 18038 } 18039 } 18040 18041 @Override 18042 public void flushPackageRestrictionsAsUser(int userId) { 18043 if (!sUserManager.exists(userId)) { 18044 return; 18045 } 18046 enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/, 18047 false /* checkShell */, "flushPackageRestrictions"); 18048 synchronized (mPackages) { 18049 mSettings.writePackageRestrictionsLPr(userId); 18050 mDirtyUsers.remove(userId); 18051 if (mDirtyUsers.isEmpty()) { 18052 mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS); 18053 } 18054 } 18055 } 18056 18057 private void sendPackageChangedBroadcast(String packageName, 18058 boolean killFlag, ArrayList<String> componentNames, int packageUid) { 18059 if (DEBUG_INSTALL) 18060 Log.v(TAG, "Sending package changed: package=" + packageName + " components=" 18061 + componentNames); 18062 Bundle extras = new Bundle(4); 18063 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0)); 18064 String nameList[] = new String[componentNames.size()]; 18065 componentNames.toArray(nameList); 18066 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList); 18067 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag); 18068 extras.putInt(Intent.EXTRA_UID, packageUid); 18069 // If this is not reporting a change of the overall package, then only send it 18070 // to registered receivers. We don't want to launch a swath of apps for every 18071 // little component state change. 18072 final int flags = !componentNames.contains(packageName) 18073 ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0; 18074 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, flags, null, null, 18075 new int[] {UserHandle.getUserId(packageUid)}); 18076 } 18077 18078 @Override 18079 public void setPackageStoppedState(String packageName, boolean stopped, int userId) { 18080 if (!sUserManager.exists(userId)) return; 18081 final int uid = Binder.getCallingUid(); 18082 final int permission = mContext.checkCallingOrSelfPermission( 18083 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 18084 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 18085 enforceCrossUserPermission(uid, userId, 18086 true /* requireFullPermission */, true /* checkShell */, "stop package"); 18087 // writer 18088 synchronized (mPackages) { 18089 if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped, 18090 allowedByPermission, uid, userId)) { 18091 scheduleWritePackageRestrictionsLocked(userId); 18092 } 18093 } 18094 } 18095 18096 @Override 18097 public String getInstallerPackageName(String packageName) { 18098 // reader 18099 synchronized (mPackages) { 18100 return mSettings.getInstallerPackageNameLPr(packageName); 18101 } 18102 } 18103 18104 public boolean isOrphaned(String packageName) { 18105 // reader 18106 synchronized (mPackages) { 18107 return mSettings.isOrphaned(packageName); 18108 } 18109 } 18110 18111 @Override 18112 public int getApplicationEnabledSetting(String packageName, int userId) { 18113 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 18114 int uid = Binder.getCallingUid(); 18115 enforceCrossUserPermission(uid, userId, 18116 false /* requireFullPermission */, false /* checkShell */, "get enabled"); 18117 // reader 18118 synchronized (mPackages) { 18119 return mSettings.getApplicationEnabledSettingLPr(packageName, userId); 18120 } 18121 } 18122 18123 @Override 18124 public int getComponentEnabledSetting(ComponentName componentName, int userId) { 18125 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 18126 int uid = Binder.getCallingUid(); 18127 enforceCrossUserPermission(uid, userId, 18128 false /* requireFullPermission */, false /* checkShell */, "get component enabled"); 18129 // reader 18130 synchronized (mPackages) { 18131 return mSettings.getComponentEnabledSettingLPr(componentName, userId); 18132 } 18133 } 18134 18135 @Override 18136 public void enterSafeMode() { 18137 enforceSystemOrRoot("Only the system can request entering safe mode"); 18138 18139 if (!mSystemReady) { 18140 mSafeMode = true; 18141 } 18142 } 18143 18144 @Override 18145 public void systemReady() { 18146 mSystemReady = true; 18147 18148 // Disable any carrier apps. We do this very early in boot to prevent the apps from being 18149 // disabled after already being started. 18150 CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this, 18151 mContext.getContentResolver(), UserHandle.USER_SYSTEM); 18152 18153 // Read the compatibilty setting when the system is ready. 18154 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt( 18155 mContext.getContentResolver(), 18156 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1; 18157 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled); 18158 if (DEBUG_SETTINGS) { 18159 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled); 18160 } 18161 18162 int[] grantPermissionsUserIds = EMPTY_INT_ARRAY; 18163 18164 synchronized (mPackages) { 18165 // Verify that all of the preferred activity components actually 18166 // exist. It is possible for applications to be updated and at 18167 // that point remove a previously declared activity component that 18168 // had been set as a preferred activity. We try to clean this up 18169 // the next time we encounter that preferred activity, but it is 18170 // possible for the user flow to never be able to return to that 18171 // situation so here we do a sanity check to make sure we haven't 18172 // left any junk around. 18173 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>(); 18174 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 18175 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 18176 removed.clear(); 18177 for (PreferredActivity pa : pir.filterSet()) { 18178 if (mActivities.mActivities.get(pa.mPref.mComponent) == null) { 18179 removed.add(pa); 18180 } 18181 } 18182 if (removed.size() > 0) { 18183 for (int r=0; r<removed.size(); r++) { 18184 PreferredActivity pa = removed.get(r); 18185 Slog.w(TAG, "Removing dangling preferred activity: " 18186 + pa.mPref.mComponent); 18187 pir.removeFilter(pa); 18188 } 18189 mSettings.writePackageRestrictionsLPr( 18190 mSettings.mPreferredActivities.keyAt(i)); 18191 } 18192 } 18193 18194 for (int userId : UserManagerService.getInstance().getUserIds()) { 18195 if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) { 18196 grantPermissionsUserIds = ArrayUtils.appendInt( 18197 grantPermissionsUserIds, userId); 18198 } 18199 } 18200 } 18201 sUserManager.systemReady(); 18202 18203 // If we upgraded grant all default permissions before kicking off. 18204 for (int userId : grantPermissionsUserIds) { 18205 mDefaultPermissionPolicy.grantDefaultPermissions(userId); 18206 } 18207 18208 // If we did not grant default permissions, we preload from this the 18209 // default permission exceptions lazily to ensure we don't hit the 18210 // disk on a new user creation. 18211 if (grantPermissionsUserIds == EMPTY_INT_ARRAY) { 18212 mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions(); 18213 } 18214 18215 // Kick off any messages waiting for system ready 18216 if (mPostSystemReadyMessages != null) { 18217 for (Message msg : mPostSystemReadyMessages) { 18218 msg.sendToTarget(); 18219 } 18220 mPostSystemReadyMessages = null; 18221 } 18222 18223 // Watch for external volumes that come and go over time 18224 final StorageManager storage = mContext.getSystemService(StorageManager.class); 18225 storage.registerListener(mStorageListener); 18226 18227 mInstallerService.systemReady(); 18228 mPackageDexOptimizer.systemReady(); 18229 18230 MountServiceInternal mountServiceInternal = LocalServices.getService( 18231 MountServiceInternal.class); 18232 mountServiceInternal.addExternalStoragePolicy( 18233 new MountServiceInternal.ExternalStorageMountPolicy() { 18234 @Override 18235 public int getMountMode(int uid, String packageName) { 18236 if (Process.isIsolated(uid)) { 18237 return Zygote.MOUNT_EXTERNAL_NONE; 18238 } 18239 if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) { 18240 return Zygote.MOUNT_EXTERNAL_DEFAULT; 18241 } 18242 if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { 18243 return Zygote.MOUNT_EXTERNAL_DEFAULT; 18244 } 18245 if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { 18246 return Zygote.MOUNT_EXTERNAL_READ; 18247 } 18248 return Zygote.MOUNT_EXTERNAL_WRITE; 18249 } 18250 18251 @Override 18252 public boolean hasExternalStorage(int uid, String packageName) { 18253 return true; 18254 } 18255 }); 18256 18257 // Now that we're mostly running, clean up stale users and apps 18258 reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL); 18259 reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL); 18260 } 18261 18262 @Override 18263 public boolean isSafeMode() { 18264 return mSafeMode; 18265 } 18266 18267 @Override 18268 public boolean hasSystemUidErrors() { 18269 return mHasSystemUidErrors; 18270 } 18271 18272 static String arrayToString(int[] array) { 18273 StringBuffer buf = new StringBuffer(128); 18274 buf.append('['); 18275 if (array != null) { 18276 for (int i=0; i<array.length; i++) { 18277 if (i > 0) buf.append(", "); 18278 buf.append(array[i]); 18279 } 18280 } 18281 buf.append(']'); 18282 return buf.toString(); 18283 } 18284 18285 static class DumpState { 18286 public static final int DUMP_LIBS = 1 << 0; 18287 public static final int DUMP_FEATURES = 1 << 1; 18288 public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2; 18289 public static final int DUMP_SERVICE_RESOLVERS = 1 << 3; 18290 public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4; 18291 public static final int DUMP_CONTENT_RESOLVERS = 1 << 5; 18292 public static final int DUMP_PERMISSIONS = 1 << 6; 18293 public static final int DUMP_PACKAGES = 1 << 7; 18294 public static final int DUMP_SHARED_USERS = 1 << 8; 18295 public static final int DUMP_MESSAGES = 1 << 9; 18296 public static final int DUMP_PROVIDERS = 1 << 10; 18297 public static final int DUMP_VERIFIERS = 1 << 11; 18298 public static final int DUMP_PREFERRED = 1 << 12; 18299 public static final int DUMP_PREFERRED_XML = 1 << 13; 18300 public static final int DUMP_KEYSETS = 1 << 14; 18301 public static final int DUMP_VERSION = 1 << 15; 18302 public static final int DUMP_INSTALLS = 1 << 16; 18303 public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17; 18304 public static final int DUMP_DOMAIN_PREFERRED = 1 << 18; 18305 public static final int DUMP_FROZEN = 1 << 19; 18306 public static final int DUMP_DEXOPT = 1 << 20; 18307 public static final int DUMP_COMPILER_STATS = 1 << 21; 18308 18309 public static final int OPTION_SHOW_FILTERS = 1 << 0; 18310 18311 private int mTypes; 18312 18313 private int mOptions; 18314 18315 private boolean mTitlePrinted; 18316 18317 private SharedUserSetting mSharedUser; 18318 18319 public boolean isDumping(int type) { 18320 if (mTypes == 0 && type != DUMP_PREFERRED_XML) { 18321 return true; 18322 } 18323 18324 return (mTypes & type) != 0; 18325 } 18326 18327 public void setDump(int type) { 18328 mTypes |= type; 18329 } 18330 18331 public boolean isOptionEnabled(int option) { 18332 return (mOptions & option) != 0; 18333 } 18334 18335 public void setOptionEnabled(int option) { 18336 mOptions |= option; 18337 } 18338 18339 public boolean onTitlePrinted() { 18340 final boolean printed = mTitlePrinted; 18341 mTitlePrinted = true; 18342 return printed; 18343 } 18344 18345 public boolean getTitlePrinted() { 18346 return mTitlePrinted; 18347 } 18348 18349 public void setTitlePrinted(boolean enabled) { 18350 mTitlePrinted = enabled; 18351 } 18352 18353 public SharedUserSetting getSharedUser() { 18354 return mSharedUser; 18355 } 18356 18357 public void setSharedUser(SharedUserSetting user) { 18358 mSharedUser = user; 18359 } 18360 } 18361 18362 @Override 18363 public void onShellCommand(FileDescriptor in, FileDescriptor out, 18364 FileDescriptor err, String[] args, ResultReceiver resultReceiver) { 18365 (new PackageManagerShellCommand(this)).exec( 18366 this, in, out, err, args, resultReceiver); 18367 } 18368 18369 @Override 18370 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 18371 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 18372 != PackageManager.PERMISSION_GRANTED) { 18373 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 18374 + Binder.getCallingPid() 18375 + ", uid=" + Binder.getCallingUid() 18376 + " without permission " 18377 + android.Manifest.permission.DUMP); 18378 return; 18379 } 18380 18381 DumpState dumpState = new DumpState(); 18382 boolean fullPreferred = false; 18383 boolean checkin = false; 18384 18385 String packageName = null; 18386 ArraySet<String> permissionNames = null; 18387 18388 int opti = 0; 18389 while (opti < args.length) { 18390 String opt = args[opti]; 18391 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 18392 break; 18393 } 18394 opti++; 18395 18396 if ("-a".equals(opt)) { 18397 // Right now we only know how to print all. 18398 } else if ("-h".equals(opt)) { 18399 pw.println("Package manager dump options:"); 18400 pw.println(" [-h] [-f] [--checkin] [cmd] ..."); 18401 pw.println(" --checkin: dump for a checkin"); 18402 pw.println(" -f: print details of intent filters"); 18403 pw.println(" -h: print this help"); 18404 pw.println(" cmd may be one of:"); 18405 pw.println(" l[ibraries]: list known shared libraries"); 18406 pw.println(" f[eatures]: list device features"); 18407 pw.println(" k[eysets]: print known keysets"); 18408 pw.println(" r[esolvers] [activity|service|receiver|content]: dump intent resolvers"); 18409 pw.println(" perm[issions]: dump permissions"); 18410 pw.println(" permission [name ...]: dump declaration and use of given permission"); 18411 pw.println(" pref[erred]: print preferred package settings"); 18412 pw.println(" preferred-xml [--full]: print preferred package settings as xml"); 18413 pw.println(" prov[iders]: dump content providers"); 18414 pw.println(" p[ackages]: dump installed packages"); 18415 pw.println(" s[hared-users]: dump shared user IDs"); 18416 pw.println(" m[essages]: print collected runtime messages"); 18417 pw.println(" v[erifiers]: print package verifier info"); 18418 pw.println(" d[omain-preferred-apps]: print domains preferred apps"); 18419 pw.println(" i[ntent-filter-verifiers]|ifv: print intent filter verifier info"); 18420 pw.println(" version: print database version info"); 18421 pw.println(" write: write current settings now"); 18422 pw.println(" installs: details about install sessions"); 18423 pw.println(" check-permission <permission> <package> [<user>]: does pkg hold perm?"); 18424 pw.println(" dexopt: dump dexopt state"); 18425 pw.println(" compiler-stats: dump compiler statistics"); 18426 pw.println(" <package.name>: info about given package"); 18427 return; 18428 } else if ("--checkin".equals(opt)) { 18429 checkin = true; 18430 } else if ("-f".equals(opt)) { 18431 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 18432 } else { 18433 pw.println("Unknown argument: " + opt + "; use -h for help"); 18434 } 18435 } 18436 18437 // Is the caller requesting to dump a particular piece of data? 18438 if (opti < args.length) { 18439 String cmd = args[opti]; 18440 opti++; 18441 // Is this a package name? 18442 if ("android".equals(cmd) || cmd.contains(".")) { 18443 packageName = cmd; 18444 // When dumping a single package, we always dump all of its 18445 // filter information since the amount of data will be reasonable. 18446 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 18447 } else if ("check-permission".equals(cmd)) { 18448 if (opti >= args.length) { 18449 pw.println("Error: check-permission missing permission argument"); 18450 return; 18451 } 18452 String perm = args[opti]; 18453 opti++; 18454 if (opti >= args.length) { 18455 pw.println("Error: check-permission missing package argument"); 18456 return; 18457 } 18458 String pkg = args[opti]; 18459 opti++; 18460 int user = UserHandle.getUserId(Binder.getCallingUid()); 18461 if (opti < args.length) { 18462 try { 18463 user = Integer.parseInt(args[opti]); 18464 } catch (NumberFormatException e) { 18465 pw.println("Error: check-permission user argument is not a number: " 18466 + args[opti]); 18467 return; 18468 } 18469 } 18470 pw.println(checkPermission(perm, pkg, user)); 18471 return; 18472 } else if ("l".equals(cmd) || "libraries".equals(cmd)) { 18473 dumpState.setDump(DumpState.DUMP_LIBS); 18474 } else if ("f".equals(cmd) || "features".equals(cmd)) { 18475 dumpState.setDump(DumpState.DUMP_FEATURES); 18476 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) { 18477 if (opti >= args.length) { 18478 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS 18479 | DumpState.DUMP_SERVICE_RESOLVERS 18480 | DumpState.DUMP_RECEIVER_RESOLVERS 18481 | DumpState.DUMP_CONTENT_RESOLVERS); 18482 } else { 18483 while (opti < args.length) { 18484 String name = args[opti]; 18485 if ("a".equals(name) || "activity".equals(name)) { 18486 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS); 18487 } else if ("s".equals(name) || "service".equals(name)) { 18488 dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS); 18489 } else if ("r".equals(name) || "receiver".equals(name)) { 18490 dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS); 18491 } else if ("c".equals(name) || "content".equals(name)) { 18492 dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS); 18493 } else { 18494 pw.println("Error: unknown resolver table type: " + name); 18495 return; 18496 } 18497 opti++; 18498 } 18499 } 18500 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) { 18501 dumpState.setDump(DumpState.DUMP_PERMISSIONS); 18502 } else if ("permission".equals(cmd)) { 18503 if (opti >= args.length) { 18504 pw.println("Error: permission requires permission name"); 18505 return; 18506 } 18507 permissionNames = new ArraySet<>(); 18508 while (opti < args.length) { 18509 permissionNames.add(args[opti]); 18510 opti++; 18511 } 18512 dumpState.setDump(DumpState.DUMP_PERMISSIONS 18513 | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS); 18514 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) { 18515 dumpState.setDump(DumpState.DUMP_PREFERRED); 18516 } else if ("preferred-xml".equals(cmd)) { 18517 dumpState.setDump(DumpState.DUMP_PREFERRED_XML); 18518 if (opti < args.length && "--full".equals(args[opti])) { 18519 fullPreferred = true; 18520 opti++; 18521 } 18522 } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) { 18523 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED); 18524 } else if ("p".equals(cmd) || "packages".equals(cmd)) { 18525 dumpState.setDump(DumpState.DUMP_PACKAGES); 18526 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) { 18527 dumpState.setDump(DumpState.DUMP_SHARED_USERS); 18528 } else if ("prov".equals(cmd) || "providers".equals(cmd)) { 18529 dumpState.setDump(DumpState.DUMP_PROVIDERS); 18530 } else if ("m".equals(cmd) || "messages".equals(cmd)) { 18531 dumpState.setDump(DumpState.DUMP_MESSAGES); 18532 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) { 18533 dumpState.setDump(DumpState.DUMP_VERIFIERS); 18534 } else if ("i".equals(cmd) || "ifv".equals(cmd) 18535 || "intent-filter-verifiers".equals(cmd)) { 18536 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS); 18537 } else if ("version".equals(cmd)) { 18538 dumpState.setDump(DumpState.DUMP_VERSION); 18539 } else if ("k".equals(cmd) || "keysets".equals(cmd)) { 18540 dumpState.setDump(DumpState.DUMP_KEYSETS); 18541 } else if ("installs".equals(cmd)) { 18542 dumpState.setDump(DumpState.DUMP_INSTALLS); 18543 } else if ("frozen".equals(cmd)) { 18544 dumpState.setDump(DumpState.DUMP_FROZEN); 18545 } else if ("dexopt".equals(cmd)) { 18546 dumpState.setDump(DumpState.DUMP_DEXOPT); 18547 } else if ("compiler-stats".equals(cmd)) { 18548 dumpState.setDump(DumpState.DUMP_COMPILER_STATS); 18549 } else if ("write".equals(cmd)) { 18550 synchronized (mPackages) { 18551 mSettings.writeLPr(); 18552 pw.println("Settings written."); 18553 return; 18554 } 18555 } 18556 } 18557 18558 if (checkin) { 18559 pw.println("vers,1"); 18560 } 18561 18562 // reader 18563 synchronized (mPackages) { 18564 if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) { 18565 if (!checkin) { 18566 if (dumpState.onTitlePrinted()) 18567 pw.println(); 18568 pw.println("Database versions:"); 18569 mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, " ")); 18570 } 18571 } 18572 18573 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) { 18574 if (!checkin) { 18575 if (dumpState.onTitlePrinted()) 18576 pw.println(); 18577 pw.println("Verifiers:"); 18578 pw.print(" Required: "); 18579 pw.print(mRequiredVerifierPackage); 18580 pw.print(" (uid="); 18581 pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 18582 UserHandle.USER_SYSTEM)); 18583 pw.println(")"); 18584 } else if (mRequiredVerifierPackage != null) { 18585 pw.print("vrfy,"); pw.print(mRequiredVerifierPackage); 18586 pw.print(","); 18587 pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 18588 UserHandle.USER_SYSTEM)); 18589 } 18590 } 18591 18592 if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) && 18593 packageName == null) { 18594 if (mIntentFilterVerifierComponent != null) { 18595 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName(); 18596 if (!checkin) { 18597 if (dumpState.onTitlePrinted()) 18598 pw.println(); 18599 pw.println("Intent Filter Verifier:"); 18600 pw.print(" Using: "); 18601 pw.print(verifierPackageName); 18602 pw.print(" (uid="); 18603 pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING, 18604 UserHandle.USER_SYSTEM)); 18605 pw.println(")"); 18606 } else if (verifierPackageName != null) { 18607 pw.print("ifv,"); pw.print(verifierPackageName); 18608 pw.print(","); 18609 pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING, 18610 UserHandle.USER_SYSTEM)); 18611 } 18612 } else { 18613 pw.println(); 18614 pw.println("No Intent Filter Verifier available!"); 18615 } 18616 } 18617 18618 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) { 18619 boolean printedHeader = false; 18620 final Iterator<String> it = mSharedLibraries.keySet().iterator(); 18621 while (it.hasNext()) { 18622 String name = it.next(); 18623 SharedLibraryEntry ent = mSharedLibraries.get(name); 18624 if (!checkin) { 18625 if (!printedHeader) { 18626 if (dumpState.onTitlePrinted()) 18627 pw.println(); 18628 pw.println("Libraries:"); 18629 printedHeader = true; 18630 } 18631 pw.print(" "); 18632 } else { 18633 pw.print("lib,"); 18634 } 18635 pw.print(name); 18636 if (!checkin) { 18637 pw.print(" -> "); 18638 } 18639 if (ent.path != null) { 18640 if (!checkin) { 18641 pw.print("(jar) "); 18642 pw.print(ent.path); 18643 } else { 18644 pw.print(",jar,"); 18645 pw.print(ent.path); 18646 } 18647 } else { 18648 if (!checkin) { 18649 pw.print("(apk) "); 18650 pw.print(ent.apk); 18651 } else { 18652 pw.print(",apk,"); 18653 pw.print(ent.apk); 18654 } 18655 } 18656 pw.println(); 18657 } 18658 } 18659 18660 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) { 18661 if (dumpState.onTitlePrinted()) 18662 pw.println(); 18663 if (!checkin) { 18664 pw.println("Features:"); 18665 } 18666 18667 for (FeatureInfo feat : mAvailableFeatures.values()) { 18668 if (checkin) { 18669 pw.print("feat,"); 18670 pw.print(feat.name); 18671 pw.print(","); 18672 pw.println(feat.version); 18673 } else { 18674 pw.print(" "); 18675 pw.print(feat.name); 18676 if (feat.version > 0) { 18677 pw.print(" version="); 18678 pw.print(feat.version); 18679 } 18680 pw.println(); 18681 } 18682 } 18683 } 18684 18685 if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) { 18686 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:" 18687 : "Activity Resolver Table:", " ", packageName, 18688 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 18689 dumpState.setTitlePrinted(true); 18690 } 18691 } 18692 if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) { 18693 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:" 18694 : "Receiver Resolver Table:", " ", packageName, 18695 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 18696 dumpState.setTitlePrinted(true); 18697 } 18698 } 18699 if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) { 18700 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:" 18701 : "Service Resolver Table:", " ", packageName, 18702 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 18703 dumpState.setTitlePrinted(true); 18704 } 18705 } 18706 if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) { 18707 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:" 18708 : "Provider Resolver Table:", " ", packageName, 18709 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 18710 dumpState.setTitlePrinted(true); 18711 } 18712 } 18713 18714 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) { 18715 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 18716 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 18717 int user = mSettings.mPreferredActivities.keyAt(i); 18718 if (pir.dump(pw, 18719 dumpState.getTitlePrinted() 18720 ? "\nPreferred Activities User " + user + ":" 18721 : "Preferred Activities User " + user + ":", " ", 18722 packageName, true, false)) { 18723 dumpState.setTitlePrinted(true); 18724 } 18725 } 18726 } 18727 18728 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) { 18729 pw.flush(); 18730 FileOutputStream fout = new FileOutputStream(fd); 18731 BufferedOutputStream str = new BufferedOutputStream(fout); 18732 XmlSerializer serializer = new FastXmlSerializer(); 18733 try { 18734 serializer.setOutput(str, StandardCharsets.UTF_8.name()); 18735 serializer.startDocument(null, true); 18736 serializer.setFeature( 18737 "http://xmlpull.org/v1/doc/features.html#indent-output", true); 18738 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred); 18739 serializer.endDocument(); 18740 serializer.flush(); 18741 } catch (IllegalArgumentException e) { 18742 pw.println("Failed writing: " + e); 18743 } catch (IllegalStateException e) { 18744 pw.println("Failed writing: " + e); 18745 } catch (IOException e) { 18746 pw.println("Failed writing: " + e); 18747 } 18748 } 18749 18750 if (!checkin 18751 && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED) 18752 && packageName == null) { 18753 pw.println(); 18754 int count = mSettings.mPackages.size(); 18755 if (count == 0) { 18756 pw.println("No applications!"); 18757 pw.println(); 18758 } else { 18759 final String prefix = " "; 18760 Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values(); 18761 if (allPackageSettings.size() == 0) { 18762 pw.println("No domain preferred apps!"); 18763 pw.println(); 18764 } else { 18765 pw.println("App verification status:"); 18766 pw.println(); 18767 count = 0; 18768 for (PackageSetting ps : allPackageSettings) { 18769 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo(); 18770 if (ivi == null || ivi.getPackageName() == null) continue; 18771 pw.println(prefix + "Package: " + ivi.getPackageName()); 18772 pw.println(prefix + "Domains: " + ivi.getDomainsString()); 18773 pw.println(prefix + "Status: " + ivi.getStatusString()); 18774 pw.println(); 18775 count++; 18776 } 18777 if (count == 0) { 18778 pw.println(prefix + "No app verification established."); 18779 pw.println(); 18780 } 18781 for (int userId : sUserManager.getUserIds()) { 18782 pw.println("App linkages for user " + userId + ":"); 18783 pw.println(); 18784 count = 0; 18785 for (PackageSetting ps : allPackageSettings) { 18786 final long status = ps.getDomainVerificationStatusForUser(userId); 18787 if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 18788 continue; 18789 } 18790 pw.println(prefix + "Package: " + ps.name); 18791 pw.println(prefix + "Domains: " + dumpDomainString(ps.name)); 18792 String statusStr = IntentFilterVerificationInfo. 18793 getStatusStringFromValue(status); 18794 pw.println(prefix + "Status: " + statusStr); 18795 pw.println(); 18796 count++; 18797 } 18798 if (count == 0) { 18799 pw.println(prefix + "No configured app linkages."); 18800 pw.println(); 18801 } 18802 } 18803 } 18804 } 18805 } 18806 18807 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) { 18808 mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState); 18809 if (packageName == null && permissionNames == null) { 18810 for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) { 18811 if (iperm == 0) { 18812 if (dumpState.onTitlePrinted()) 18813 pw.println(); 18814 pw.println("AppOp Permissions:"); 18815 } 18816 pw.print(" AppOp Permission "); 18817 pw.print(mAppOpPermissionPackages.keyAt(iperm)); 18818 pw.println(":"); 18819 ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm); 18820 for (int ipkg=0; ipkg<pkgs.size(); ipkg++) { 18821 pw.print(" "); pw.println(pkgs.valueAt(ipkg)); 18822 } 18823 } 18824 } 18825 } 18826 18827 if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) { 18828 boolean printedSomething = false; 18829 for (PackageParser.Provider p : mProviders.mProviders.values()) { 18830 if (packageName != null && !packageName.equals(p.info.packageName)) { 18831 continue; 18832 } 18833 if (!printedSomething) { 18834 if (dumpState.onTitlePrinted()) 18835 pw.println(); 18836 pw.println("Registered ContentProviders:"); 18837 printedSomething = true; 18838 } 18839 pw.print(" "); p.printComponentShortName(pw); pw.println(":"); 18840 pw.print(" "); pw.println(p.toString()); 18841 } 18842 printedSomething = false; 18843 for (Map.Entry<String, PackageParser.Provider> entry : 18844 mProvidersByAuthority.entrySet()) { 18845 PackageParser.Provider p = entry.getValue(); 18846 if (packageName != null && !packageName.equals(p.info.packageName)) { 18847 continue; 18848 } 18849 if (!printedSomething) { 18850 if (dumpState.onTitlePrinted()) 18851 pw.println(); 18852 pw.println("ContentProvider Authorities:"); 18853 printedSomething = true; 18854 } 18855 pw.print(" ["); pw.print(entry.getKey()); pw.println("]:"); 18856 pw.print(" "); pw.println(p.toString()); 18857 if (p.info != null && p.info.applicationInfo != null) { 18858 final String appInfo = p.info.applicationInfo.toString(); 18859 pw.print(" applicationInfo="); pw.println(appInfo); 18860 } 18861 } 18862 } 18863 18864 if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) { 18865 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState); 18866 } 18867 18868 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) { 18869 mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin); 18870 } 18871 18872 if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) { 18873 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin); 18874 } 18875 18876 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) { 18877 mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState); 18878 } 18879 18880 if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) { 18881 // XXX should handle packageName != null by dumping only install data that 18882 // the given package is involved with. 18883 if (dumpState.onTitlePrinted()) pw.println(); 18884 mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120)); 18885 } 18886 18887 if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) { 18888 // XXX should handle packageName != null by dumping only install data that 18889 // the given package is involved with. 18890 if (dumpState.onTitlePrinted()) pw.println(); 18891 18892 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120); 18893 ipw.println(); 18894 ipw.println("Frozen packages:"); 18895 ipw.increaseIndent(); 18896 if (mFrozenPackages.size() == 0) { 18897 ipw.println("(none)"); 18898 } else { 18899 for (int i = 0; i < mFrozenPackages.size(); i++) { 18900 ipw.println(mFrozenPackages.valueAt(i)); 18901 } 18902 } 18903 ipw.decreaseIndent(); 18904 } 18905 18906 if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) { 18907 if (dumpState.onTitlePrinted()) pw.println(); 18908 dumpDexoptStateLPr(pw, packageName); 18909 } 18910 18911 if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) { 18912 if (dumpState.onTitlePrinted()) pw.println(); 18913 dumpCompilerStatsLPr(pw, packageName); 18914 } 18915 18916 if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) { 18917 if (dumpState.onTitlePrinted()) pw.println(); 18918 mSettings.dumpReadMessagesLPr(pw, dumpState); 18919 18920 pw.println(); 18921 pw.println("Package warning messages:"); 18922 BufferedReader in = null; 18923 String line = null; 18924 try { 18925 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 18926 while ((line = in.readLine()) != null) { 18927 if (line.contains("ignored: updated version")) continue; 18928 pw.println(line); 18929 } 18930 } catch (IOException ignored) { 18931 } finally { 18932 IoUtils.closeQuietly(in); 18933 } 18934 } 18935 18936 if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) { 18937 BufferedReader in = null; 18938 String line = null; 18939 try { 18940 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 18941 while ((line = in.readLine()) != null) { 18942 if (line.contains("ignored: updated version")) continue; 18943 pw.print("msg,"); 18944 pw.println(line); 18945 } 18946 } catch (IOException ignored) { 18947 } finally { 18948 IoUtils.closeQuietly(in); 18949 } 18950 } 18951 } 18952 } 18953 18954 private void dumpDexoptStateLPr(PrintWriter pw, String packageName) { 18955 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120); 18956 ipw.println(); 18957 ipw.println("Dexopt state:"); 18958 ipw.increaseIndent(); 18959 Collection<PackageParser.Package> packages = null; 18960 if (packageName != null) { 18961 PackageParser.Package targetPackage = mPackages.get(packageName); 18962 if (targetPackage != null) { 18963 packages = Collections.singletonList(targetPackage); 18964 } else { 18965 ipw.println("Unable to find package: " + packageName); 18966 return; 18967 } 18968 } else { 18969 packages = mPackages.values(); 18970 } 18971 18972 for (PackageParser.Package pkg : packages) { 18973 ipw.println("[" + pkg.packageName + "]"); 18974 ipw.increaseIndent(); 18975 mPackageDexOptimizer.dumpDexoptState(ipw, pkg); 18976 ipw.decreaseIndent(); 18977 } 18978 } 18979 18980 private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) { 18981 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120); 18982 ipw.println(); 18983 ipw.println("Compiler stats:"); 18984 ipw.increaseIndent(); 18985 Collection<PackageParser.Package> packages = null; 18986 if (packageName != null) { 18987 PackageParser.Package targetPackage = mPackages.get(packageName); 18988 if (targetPackage != null) { 18989 packages = Collections.singletonList(targetPackage); 18990 } else { 18991 ipw.println("Unable to find package: " + packageName); 18992 return; 18993 } 18994 } else { 18995 packages = mPackages.values(); 18996 } 18997 18998 for (PackageParser.Package pkg : packages) { 18999 ipw.println("[" + pkg.packageName + "]"); 19000 ipw.increaseIndent(); 19001 19002 CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName); 19003 if (stats == null) { 19004 ipw.println("(No recorded stats)"); 19005 } else { 19006 stats.dump(ipw); 19007 } 19008 ipw.decreaseIndent(); 19009 } 19010 } 19011 19012 private String dumpDomainString(String packageName) { 19013 List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName) 19014 .getList(); 19015 List<IntentFilter> filters = getAllIntentFilters(packageName).getList(); 19016 19017 ArraySet<String> result = new ArraySet<>(); 19018 if (iviList.size() > 0) { 19019 for (IntentFilterVerificationInfo ivi : iviList) { 19020 for (String host : ivi.getDomains()) { 19021 result.add(host); 19022 } 19023 } 19024 } 19025 if (filters != null && filters.size() > 0) { 19026 for (IntentFilter filter : filters) { 19027 if (filter.hasCategory(Intent.CATEGORY_BROWSABLE) 19028 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 19029 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) { 19030 result.addAll(filter.getHostsList()); 19031 } 19032 } 19033 } 19034 19035 StringBuilder sb = new StringBuilder(result.size() * 16); 19036 for (String domain : result) { 19037 if (sb.length() > 0) sb.append(" "); 19038 sb.append(domain); 19039 } 19040 return sb.toString(); 19041 } 19042 19043 // ------- apps on sdcard specific code ------- 19044 static final boolean DEBUG_SD_INSTALL = false; 19045 19046 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD"; 19047 19048 private static final String SD_ENCRYPTION_ALGORITHM = "AES"; 19049 19050 private boolean mMediaMounted = false; 19051 19052 static String getEncryptKey() { 19053 try { 19054 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString( 19055 SD_ENCRYPTION_KEYSTORE_NAME); 19056 if (sdEncKey == null) { 19057 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128, 19058 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME); 19059 if (sdEncKey == null) { 19060 Slog.e(TAG, "Failed to create encryption keys"); 19061 return null; 19062 } 19063 } 19064 return sdEncKey; 19065 } catch (NoSuchAlgorithmException nsae) { 19066 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae); 19067 return null; 19068 } catch (IOException ioe) { 19069 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe); 19070 return null; 19071 } 19072 } 19073 19074 /* 19075 * Update media status on PackageManager. 19076 */ 19077 @Override 19078 public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) { 19079 int callingUid = Binder.getCallingUid(); 19080 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 19081 throw new SecurityException("Media status can only be updated by the system"); 19082 } 19083 // reader; this apparently protects mMediaMounted, but should probably 19084 // be a different lock in that case. 19085 synchronized (mPackages) { 19086 Log.i(TAG, "Updating external media status from " 19087 + (mMediaMounted ? "mounted" : "unmounted") + " to " 19088 + (mediaStatus ? "mounted" : "unmounted")); 19089 if (DEBUG_SD_INSTALL) 19090 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus 19091 + ", mMediaMounted=" + mMediaMounted); 19092 if (mediaStatus == mMediaMounted) { 19093 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 19094 : 0, -1); 19095 mHandler.sendMessage(msg); 19096 return; 19097 } 19098 mMediaMounted = mediaStatus; 19099 } 19100 // Queue up an async operation since the package installation may take a 19101 // little while. 19102 mHandler.post(new Runnable() { 19103 public void run() { 19104 updateExternalMediaStatusInner(mediaStatus, reportStatus, true); 19105 } 19106 }); 19107 } 19108 19109 /** 19110 * Called by MountService when the initial ASECs to scan are available. 19111 * Should block until all the ASEC containers are finished being scanned. 19112 */ 19113 public void scanAvailableAsecs() { 19114 updateExternalMediaStatusInner(true, false, false); 19115 } 19116 19117 /* 19118 * Collect information of applications on external media, map them against 19119 * existing containers and update information based on current mount status. 19120 * Please note that we always have to report status if reportStatus has been 19121 * set to true especially when unloading packages. 19122 */ 19123 private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus, 19124 boolean externalStorage) { 19125 ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>(); 19126 int[] uidArr = EmptyArray.INT; 19127 19128 final String[] list = PackageHelper.getSecureContainerList(); 19129 if (ArrayUtils.isEmpty(list)) { 19130 Log.i(TAG, "No secure containers found"); 19131 } else { 19132 // Process list of secure containers and categorize them 19133 // as active or stale based on their package internal state. 19134 19135 // reader 19136 synchronized (mPackages) { 19137 for (String cid : list) { 19138 // Leave stages untouched for now; installer service owns them 19139 if (PackageInstallerService.isStageName(cid)) continue; 19140 19141 if (DEBUG_SD_INSTALL) 19142 Log.i(TAG, "Processing container " + cid); 19143 String pkgName = getAsecPackageName(cid); 19144 if (pkgName == null) { 19145 Slog.i(TAG, "Found stale container " + cid + " with no package name"); 19146 continue; 19147 } 19148 if (DEBUG_SD_INSTALL) 19149 Log.i(TAG, "Looking for pkg : " + pkgName); 19150 19151 final PackageSetting ps = mSettings.mPackages.get(pkgName); 19152 if (ps == null) { 19153 Slog.i(TAG, "Found stale container " + cid + " with no matching settings"); 19154 continue; 19155 } 19156 19157 /* 19158 * Skip packages that are not external if we're unmounting 19159 * external storage. 19160 */ 19161 if (externalStorage && !isMounted && !isExternal(ps)) { 19162 continue; 19163 } 19164 19165 final AsecInstallArgs args = new AsecInstallArgs(cid, 19166 getAppDexInstructionSets(ps), ps.isForwardLocked()); 19167 // The package status is changed only if the code path 19168 // matches between settings and the container id. 19169 if (ps.codePathString != null 19170 && ps.codePathString.startsWith(args.getCodePath())) { 19171 if (DEBUG_SD_INSTALL) { 19172 Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName 19173 + " at code path: " + ps.codePathString); 19174 } 19175 19176 // We do have a valid package installed on sdcard 19177 processCids.put(args, ps.codePathString); 19178 final int uid = ps.appId; 19179 if (uid != -1) { 19180 uidArr = ArrayUtils.appendInt(uidArr, uid); 19181 } 19182 } else { 19183 Slog.i(TAG, "Found stale container " + cid + ": expected codePath=" 19184 + ps.codePathString); 19185 } 19186 } 19187 } 19188 19189 Arrays.sort(uidArr); 19190 } 19191 19192 // Process packages with valid entries. 19193 if (isMounted) { 19194 if (DEBUG_SD_INSTALL) 19195 Log.i(TAG, "Loading packages"); 19196 loadMediaPackages(processCids, uidArr, externalStorage); 19197 startCleaningPackages(); 19198 mInstallerService.onSecureContainersAvailable(); 19199 } else { 19200 if (DEBUG_SD_INSTALL) 19201 Log.i(TAG, "Unloading packages"); 19202 unloadMediaPackages(processCids, uidArr, reportStatus); 19203 } 19204 } 19205 19206 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 19207 ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) { 19208 final int size = infos.size(); 19209 final String[] packageNames = new String[size]; 19210 final int[] packageUids = new int[size]; 19211 for (int i = 0; i < size; i++) { 19212 final ApplicationInfo info = infos.get(i); 19213 packageNames[i] = info.packageName; 19214 packageUids[i] = info.uid; 19215 } 19216 sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids, 19217 finishedReceiver); 19218 } 19219 19220 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 19221 ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 19222 sendResourcesChangedBroadcast(mediaStatus, replacing, 19223 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver); 19224 } 19225 19226 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 19227 String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 19228 int size = pkgList.length; 19229 if (size > 0) { 19230 // Send broadcasts here 19231 Bundle extras = new Bundle(); 19232 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 19233 if (uidArr != null) { 19234 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr); 19235 } 19236 if (replacing) { 19237 extras.putBoolean(Intent.EXTRA_REPLACING, replacing); 19238 } 19239 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE 19240 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE; 19241 sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null); 19242 } 19243 } 19244 19245 /* 19246 * Look at potentially valid container ids from processCids If package 19247 * information doesn't match the one on record or package scanning fails, 19248 * the cid is added to list of removeCids. We currently don't delete stale 19249 * containers. 19250 */ 19251 private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr, 19252 boolean externalStorage) { 19253 ArrayList<String> pkgList = new ArrayList<String>(); 19254 Set<AsecInstallArgs> keys = processCids.keySet(); 19255 19256 for (AsecInstallArgs args : keys) { 19257 String codePath = processCids.get(args); 19258 if (DEBUG_SD_INSTALL) 19259 Log.i(TAG, "Loading container : " + args.cid); 19260 int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 19261 try { 19262 // Make sure there are no container errors first. 19263 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) { 19264 Slog.e(TAG, "Failed to mount cid : " + args.cid 19265 + " when installing from sdcard"); 19266 continue; 19267 } 19268 // Check code path here. 19269 if (codePath == null || !codePath.startsWith(args.getCodePath())) { 19270 Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath() 19271 + " does not match one in settings " + codePath); 19272 continue; 19273 } 19274 // Parse package 19275 int parseFlags = mDefParseFlags; 19276 if (args.isExternalAsec()) { 19277 parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE; 19278 } 19279 if (args.isFwdLocked()) { 19280 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 19281 } 19282 19283 synchronized (mInstallLock) { 19284 PackageParser.Package pkg = null; 19285 try { 19286 // Sadly we don't know the package name yet to freeze it 19287 pkg = scanPackageTracedLI(new File(codePath), parseFlags, 19288 SCAN_IGNORE_FROZEN, 0, null); 19289 } catch (PackageManagerException e) { 19290 Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage()); 19291 } 19292 // Scan the package 19293 if (pkg != null) { 19294 /* 19295 * TODO why is the lock being held? doPostInstall is 19296 * called in other places without the lock. This needs 19297 * to be straightened out. 19298 */ 19299 // writer 19300 synchronized (mPackages) { 19301 retCode = PackageManager.INSTALL_SUCCEEDED; 19302 pkgList.add(pkg.packageName); 19303 // Post process args 19304 args.doPostInstall(PackageManager.INSTALL_SUCCEEDED, 19305 pkg.applicationInfo.uid); 19306 } 19307 } else { 19308 Slog.i(TAG, "Failed to install pkg from " + codePath + " from sdcard"); 19309 } 19310 } 19311 19312 } finally { 19313 if (retCode != PackageManager.INSTALL_SUCCEEDED) { 19314 Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode); 19315 } 19316 } 19317 } 19318 // writer 19319 synchronized (mPackages) { 19320 // If the platform SDK has changed since the last time we booted, 19321 // we need to re-grant app permission to catch any new ones that 19322 // appear. This is really a hack, and means that apps can in some 19323 // cases get permissions that the user didn't initially explicitly 19324 // allow... it would be nice to have some better way to handle 19325 // this situation. 19326 final VersionInfo ver = externalStorage ? mSettings.getExternalVersion() 19327 : mSettings.getInternalVersion(); 19328 final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL 19329 : StorageManager.UUID_PRIVATE_INTERNAL; 19330 19331 int updateFlags = UPDATE_PERMISSIONS_ALL; 19332 if (ver.sdkVersion != mSdkVersion) { 19333 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " 19334 + mSdkVersion + "; regranting permissions for external"); 19335 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 19336 } 19337 updatePermissionsLPw(null, null, volumeUuid, updateFlags); 19338 19339 // Yay, everything is now upgraded 19340 ver.forceCurrent(); 19341 19342 // can downgrade to reader 19343 // Persist settings 19344 mSettings.writeLPr(); 19345 } 19346 // Send a broadcast to let everyone know we are done processing 19347 if (pkgList.size() > 0) { 19348 sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null); 19349 } 19350 } 19351 19352 /* 19353 * Utility method to unload a list of specified containers 19354 */ 19355 private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) { 19356 // Just unmount all valid containers. 19357 for (AsecInstallArgs arg : cidArgs) { 19358 synchronized (mInstallLock) { 19359 arg.doPostDeleteLI(false); 19360 } 19361 } 19362 } 19363 19364 /* 19365 * Unload packages mounted on external media. This involves deleting package 19366 * data from internal structures, sending broadcasts about disabled packages, 19367 * gc'ing to free up references, unmounting all secure containers 19368 * corresponding to packages on external media, and posting a 19369 * UPDATED_MEDIA_STATUS message if status has been requested. Please note 19370 * that we always have to post this message if status has been requested no 19371 * matter what. 19372 */ 19373 private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[], 19374 final boolean reportStatus) { 19375 if (DEBUG_SD_INSTALL) 19376 Log.i(TAG, "unloading media packages"); 19377 ArrayList<String> pkgList = new ArrayList<String>(); 19378 ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>(); 19379 final Set<AsecInstallArgs> keys = processCids.keySet(); 19380 for (AsecInstallArgs args : keys) { 19381 String pkgName = args.getPackageName(); 19382 if (DEBUG_SD_INSTALL) 19383 Log.i(TAG, "Trying to unload pkg : " + pkgName); 19384 // Delete package internally 19385 PackageRemovedInfo outInfo = new PackageRemovedInfo(); 19386 synchronized (mInstallLock) { 19387 final int deleteFlags = PackageManager.DELETE_KEEP_DATA; 19388 final boolean res; 19389 try (PackageFreezer freezer = freezePackageForDelete(pkgName, deleteFlags, 19390 "unloadMediaPackages")) { 19391 res = deletePackageLIF(pkgName, null, false, null, deleteFlags, outInfo, false, 19392 null); 19393 } 19394 if (res) { 19395 pkgList.add(pkgName); 19396 } else { 19397 Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName); 19398 failedList.add(args); 19399 } 19400 } 19401 } 19402 19403 // reader 19404 synchronized (mPackages) { 19405 // We didn't update the settings after removing each package; 19406 // write them now for all packages. 19407 mSettings.writeLPr(); 19408 } 19409 19410 // We have to absolutely send UPDATED_MEDIA_STATUS only 19411 // after confirming that all the receivers processed the ordered 19412 // broadcast when packages get disabled, force a gc to clean things up. 19413 // and unload all the containers. 19414 if (pkgList.size() > 0) { 19415 sendResourcesChangedBroadcast(false, false, pkgList, uidArr, 19416 new IIntentReceiver.Stub() { 19417 public void performReceive(Intent intent, int resultCode, String data, 19418 Bundle extras, boolean ordered, boolean sticky, 19419 int sendingUser) throws RemoteException { 19420 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, 19421 reportStatus ? 1 : 0, 1, keys); 19422 mHandler.sendMessage(msg); 19423 } 19424 }); 19425 } else { 19426 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1, 19427 keys); 19428 mHandler.sendMessage(msg); 19429 } 19430 } 19431 19432 private void loadPrivatePackages(final VolumeInfo vol) { 19433 mHandler.post(new Runnable() { 19434 @Override 19435 public void run() { 19436 loadPrivatePackagesInner(vol); 19437 } 19438 }); 19439 } 19440 19441 private void loadPrivatePackagesInner(VolumeInfo vol) { 19442 final String volumeUuid = vol.fsUuid; 19443 if (TextUtils.isEmpty(volumeUuid)) { 19444 Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring"); 19445 return; 19446 } 19447 19448 final ArrayList<PackageFreezer> freezers = new ArrayList<>(); 19449 final ArrayList<ApplicationInfo> loaded = new ArrayList<>(); 19450 final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE; 19451 19452 final VersionInfo ver; 19453 final List<PackageSetting> packages; 19454 synchronized (mPackages) { 19455 ver = mSettings.findOrCreateVersion(volumeUuid); 19456 packages = mSettings.getVolumePackagesLPr(volumeUuid); 19457 } 19458 19459 for (PackageSetting ps : packages) { 19460 freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner")); 19461 synchronized (mInstallLock) { 19462 final PackageParser.Package pkg; 19463 try { 19464 pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null); 19465 loaded.add(pkg.applicationInfo); 19466 19467 } catch (PackageManagerException e) { 19468 Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage()); 19469 } 19470 19471 if (!Build.FINGERPRINT.equals(ver.fingerprint)) { 19472 clearAppDataLIF(ps.pkg, UserHandle.USER_ALL, 19473 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE 19474 | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 19475 } 19476 } 19477 } 19478 19479 // Reconcile app data for all started/unlocked users 19480 final StorageManager sm = mContext.getSystemService(StorageManager.class); 19481 final UserManager um = mContext.getSystemService(UserManager.class); 19482 UserManagerInternal umInternal = getUserManagerInternal(); 19483 for (UserInfo user : um.getUsers()) { 19484 final int flags; 19485 if (umInternal.isUserUnlockingOrUnlocked(user.id)) { 19486 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 19487 } else if (umInternal.isUserRunning(user.id)) { 19488 flags = StorageManager.FLAG_STORAGE_DE; 19489 } else { 19490 continue; 19491 } 19492 19493 try { 19494 sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags); 19495 synchronized (mInstallLock) { 19496 reconcileAppsDataLI(volumeUuid, user.id, flags); 19497 } 19498 } catch (IllegalStateException e) { 19499 // Device was probably ejected, and we'll process that event momentarily 19500 Slog.w(TAG, "Failed to prepare storage: " + e); 19501 } 19502 } 19503 19504 synchronized (mPackages) { 19505 int updateFlags = UPDATE_PERMISSIONS_ALL; 19506 if (ver.sdkVersion != mSdkVersion) { 19507 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " 19508 + mSdkVersion + "; regranting permissions for " + volumeUuid); 19509 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 19510 } 19511 updatePermissionsLPw(null, null, volumeUuid, updateFlags); 19512 19513 // Yay, everything is now upgraded 19514 ver.forceCurrent(); 19515 19516 mSettings.writeLPr(); 19517 } 19518 19519 for (PackageFreezer freezer : freezers) { 19520 freezer.close(); 19521 } 19522 19523 if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded); 19524 sendResourcesChangedBroadcast(true, false, loaded, null); 19525 } 19526 19527 private void unloadPrivatePackages(final VolumeInfo vol) { 19528 mHandler.post(new Runnable() { 19529 @Override 19530 public void run() { 19531 unloadPrivatePackagesInner(vol); 19532 } 19533 }); 19534 } 19535 19536 private void unloadPrivatePackagesInner(VolumeInfo vol) { 19537 final String volumeUuid = vol.fsUuid; 19538 if (TextUtils.isEmpty(volumeUuid)) { 19539 Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring"); 19540 return; 19541 } 19542 19543 final ArrayList<ApplicationInfo> unloaded = new ArrayList<>(); 19544 synchronized (mInstallLock) { 19545 synchronized (mPackages) { 19546 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid); 19547 for (PackageSetting ps : packages) { 19548 if (ps.pkg == null) continue; 19549 19550 final ApplicationInfo info = ps.pkg.applicationInfo; 19551 final int deleteFlags = PackageManager.DELETE_KEEP_DATA; 19552 final PackageRemovedInfo outInfo = new PackageRemovedInfo(); 19553 19554 try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags, 19555 "unloadPrivatePackagesInner")) { 19556 if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo, 19557 false, null)) { 19558 unloaded.add(info); 19559 } else { 19560 Slog.w(TAG, "Failed to unload " + ps.codePath); 19561 } 19562 } 19563 19564 // Try very hard to release any references to this package 19565 // so we don't risk the system server being killed due to 19566 // open FDs 19567 AttributeCache.instance().removePackage(ps.name); 19568 } 19569 19570 mSettings.writeLPr(); 19571 } 19572 } 19573 19574 if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded); 19575 sendResourcesChangedBroadcast(false, false, unloaded, null); 19576 19577 // Try very hard to release any references to this path so we don't risk 19578 // the system server being killed due to open FDs 19579 ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath()); 19580 19581 for (int i = 0; i < 3; i++) { 19582 System.gc(); 19583 System.runFinalization(); 19584 } 19585 } 19586 19587 /** 19588 * Prepare storage areas for given user on all mounted devices. 19589 */ 19590 void prepareUserData(int userId, int userSerial, int flags) { 19591 synchronized (mInstallLock) { 19592 final StorageManager storage = mContext.getSystemService(StorageManager.class); 19593 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 19594 final String volumeUuid = vol.getFsUuid(); 19595 prepareUserDataLI(volumeUuid, userId, userSerial, flags, true); 19596 } 19597 } 19598 } 19599 19600 private void prepareUserDataLI(String volumeUuid, int userId, int userSerial, int flags, 19601 boolean allowRecover) { 19602 // Prepare storage and verify that serial numbers are consistent; if 19603 // there's a mismatch we need to destroy to avoid leaking data 19604 final StorageManager storage = mContext.getSystemService(StorageManager.class); 19605 try { 19606 storage.prepareUserStorage(volumeUuid, userId, userSerial, flags); 19607 19608 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0 && !mOnlyCore) { 19609 UserManagerService.enforceSerialNumber( 19610 Environment.getDataUserDeDirectory(volumeUuid, userId), userSerial); 19611 if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) { 19612 UserManagerService.enforceSerialNumber( 19613 Environment.getDataSystemDeDirectory(userId), userSerial); 19614 } 19615 } 19616 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && !mOnlyCore) { 19617 UserManagerService.enforceSerialNumber( 19618 Environment.getDataUserCeDirectory(volumeUuid, userId), userSerial); 19619 if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) { 19620 UserManagerService.enforceSerialNumber( 19621 Environment.getDataSystemCeDirectory(userId), userSerial); 19622 } 19623 } 19624 19625 synchronized (mInstallLock) { 19626 mInstaller.createUserData(volumeUuid, userId, userSerial, flags); 19627 } 19628 } catch (Exception e) { 19629 logCriticalInfo(Log.WARN, "Destroying user " + userId + " on volume " + volumeUuid 19630 + " because we failed to prepare: " + e); 19631 destroyUserDataLI(volumeUuid, userId, 19632 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 19633 19634 if (allowRecover) { 19635 // Try one last time; if we fail again we're really in trouble 19636 prepareUserDataLI(volumeUuid, userId, userSerial, flags, false); 19637 } 19638 } 19639 } 19640 19641 /** 19642 * Destroy storage areas for given user on all mounted devices. 19643 */ 19644 void destroyUserData(int userId, int flags) { 19645 synchronized (mInstallLock) { 19646 final StorageManager storage = mContext.getSystemService(StorageManager.class); 19647 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 19648 final String volumeUuid = vol.getFsUuid(); 19649 destroyUserDataLI(volumeUuid, userId, flags); 19650 } 19651 } 19652 } 19653 19654 private void destroyUserDataLI(String volumeUuid, int userId, int flags) { 19655 final StorageManager storage = mContext.getSystemService(StorageManager.class); 19656 try { 19657 // Clean up app data, profile data, and media data 19658 mInstaller.destroyUserData(volumeUuid, userId, flags); 19659 19660 // Clean up system data 19661 if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) { 19662 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) { 19663 FileUtils.deleteContentsAndDir(Environment.getUserSystemDirectory(userId)); 19664 FileUtils.deleteContentsAndDir(Environment.getDataSystemDeDirectory(userId)); 19665 } 19666 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 19667 FileUtils.deleteContentsAndDir(Environment.getDataSystemCeDirectory(userId)); 19668 } 19669 } 19670 19671 // Data with special labels is now gone, so finish the job 19672 storage.destroyUserStorage(volumeUuid, userId, flags); 19673 19674 } catch (Exception e) { 19675 logCriticalInfo(Log.WARN, 19676 "Failed to destroy user " + userId + " on volume " + volumeUuid + ": " + e); 19677 } 19678 } 19679 19680 /** 19681 * Examine all users present on given mounted volume, and destroy data 19682 * belonging to users that are no longer valid, or whose user ID has been 19683 * recycled. 19684 */ 19685 private void reconcileUsers(String volumeUuid) { 19686 final List<File> files = new ArrayList<>(); 19687 Collections.addAll(files, FileUtils 19688 .listFilesOrEmpty(Environment.getDataUserDeDirectory(volumeUuid))); 19689 Collections.addAll(files, FileUtils 19690 .listFilesOrEmpty(Environment.getDataUserCeDirectory(volumeUuid))); 19691 Collections.addAll(files, FileUtils 19692 .listFilesOrEmpty(Environment.getDataSystemDeDirectory())); 19693 Collections.addAll(files, FileUtils 19694 .listFilesOrEmpty(Environment.getDataSystemCeDirectory())); 19695 for (File file : files) { 19696 if (!file.isDirectory()) continue; 19697 19698 final int userId; 19699 final UserInfo info; 19700 try { 19701 userId = Integer.parseInt(file.getName()); 19702 info = sUserManager.getUserInfo(userId); 19703 } catch (NumberFormatException e) { 19704 Slog.w(TAG, "Invalid user directory " + file); 19705 continue; 19706 } 19707 19708 boolean destroyUser = false; 19709 if (info == null) { 19710 logCriticalInfo(Log.WARN, "Destroying user directory " + file 19711 + " because no matching user was found"); 19712 destroyUser = true; 19713 } else if (!mOnlyCore) { 19714 try { 19715 UserManagerService.enforceSerialNumber(file, info.serialNumber); 19716 } catch (IOException e) { 19717 logCriticalInfo(Log.WARN, "Destroying user directory " + file 19718 + " because we failed to enforce serial number: " + e); 19719 destroyUser = true; 19720 } 19721 } 19722 19723 if (destroyUser) { 19724 synchronized (mInstallLock) { 19725 destroyUserDataLI(volumeUuid, userId, 19726 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 19727 } 19728 } 19729 } 19730 } 19731 19732 private void assertPackageKnown(String volumeUuid, String packageName) 19733 throws PackageManagerException { 19734 synchronized (mPackages) { 19735 final PackageSetting ps = mSettings.mPackages.get(packageName); 19736 if (ps == null) { 19737 throw new PackageManagerException("Package " + packageName + " is unknown"); 19738 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) { 19739 throw new PackageManagerException( 19740 "Package " + packageName + " found on unknown volume " + volumeUuid 19741 + "; expected volume " + ps.volumeUuid); 19742 } 19743 } 19744 } 19745 19746 private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId) 19747 throws PackageManagerException { 19748 synchronized (mPackages) { 19749 final PackageSetting ps = mSettings.mPackages.get(packageName); 19750 if (ps == null) { 19751 throw new PackageManagerException("Package " + packageName + " is unknown"); 19752 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) { 19753 throw new PackageManagerException( 19754 "Package " + packageName + " found on unknown volume " + volumeUuid 19755 + "; expected volume " + ps.volumeUuid); 19756 } else if (!ps.getInstalled(userId)) { 19757 throw new PackageManagerException( 19758 "Package " + packageName + " not installed for user " + userId); 19759 } 19760 } 19761 } 19762 19763 /** 19764 * Examine all apps present on given mounted volume, and destroy apps that 19765 * aren't expected, either due to uninstallation or reinstallation on 19766 * another volume. 19767 */ 19768 private void reconcileApps(String volumeUuid) { 19769 final File[] files = FileUtils 19770 .listFilesOrEmpty(Environment.getDataAppDirectory(volumeUuid)); 19771 for (File file : files) { 19772 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 19773 && !PackageInstallerService.isStageName(file.getName()); 19774 if (!isPackage) { 19775 // Ignore entries which are not packages 19776 continue; 19777 } 19778 19779 try { 19780 final PackageLite pkg = PackageParser.parsePackageLite(file, 19781 PackageParser.PARSE_MUST_BE_APK); 19782 assertPackageKnown(volumeUuid, pkg.packageName); 19783 19784 } catch (PackageParserException | PackageManagerException e) { 19785 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 19786 synchronized (mInstallLock) { 19787 removeCodePathLI(file); 19788 } 19789 } 19790 } 19791 } 19792 19793 /** 19794 * Reconcile all app data for the given user. 19795 * <p> 19796 * Verifies that directories exist and that ownership and labeling is 19797 * correct for all installed apps on all mounted volumes. 19798 */ 19799 void reconcileAppsData(int userId, int flags) { 19800 final StorageManager storage = mContext.getSystemService(StorageManager.class); 19801 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 19802 final String volumeUuid = vol.getFsUuid(); 19803 synchronized (mInstallLock) { 19804 reconcileAppsDataLI(volumeUuid, userId, flags); 19805 } 19806 } 19807 } 19808 19809 /** 19810 * Reconcile all app data on given mounted volume. 19811 * <p> 19812 * Destroys app data that isn't expected, either due to uninstallation or 19813 * reinstallation on another volume. 19814 * <p> 19815 * Verifies that directories exist and that ownership and labeling is 19816 * correct for all installed apps. 19817 */ 19818 private void reconcileAppsDataLI(String volumeUuid, int userId, int flags) { 19819 Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x" 19820 + Integer.toHexString(flags)); 19821 19822 final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId); 19823 final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId); 19824 19825 // First look for stale data that doesn't belong, and check if things 19826 // have changed since we did our last restorecon 19827 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 19828 if (StorageManager.isFileEncryptedNativeOrEmulated() 19829 && !StorageManager.isUserKeyUnlocked(userId)) { 19830 throw new RuntimeException( 19831 "Yikes, someone asked us to reconcile CE storage while " + userId 19832 + " was still locked; this would have caused massive data loss!"); 19833 } 19834 19835 final File[] files = FileUtils.listFilesOrEmpty(ceDir); 19836 for (File file : files) { 19837 final String packageName = file.getName(); 19838 try { 19839 assertPackageKnownAndInstalled(volumeUuid, packageName, userId); 19840 } catch (PackageManagerException e) { 19841 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 19842 try { 19843 mInstaller.destroyAppData(volumeUuid, packageName, userId, 19844 StorageManager.FLAG_STORAGE_CE, 0); 19845 } catch (InstallerException e2) { 19846 logCriticalInfo(Log.WARN, "Failed to destroy: " + e2); 19847 } 19848 } 19849 } 19850 } 19851 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) { 19852 final File[] files = FileUtils.listFilesOrEmpty(deDir); 19853 for (File file : files) { 19854 final String packageName = file.getName(); 19855 try { 19856 assertPackageKnownAndInstalled(volumeUuid, packageName, userId); 19857 } catch (PackageManagerException e) { 19858 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 19859 try { 19860 mInstaller.destroyAppData(volumeUuid, packageName, userId, 19861 StorageManager.FLAG_STORAGE_DE, 0); 19862 } catch (InstallerException e2) { 19863 logCriticalInfo(Log.WARN, "Failed to destroy: " + e2); 19864 } 19865 } 19866 } 19867 } 19868 19869 // Ensure that data directories are ready to roll for all packages 19870 // installed for this volume and user 19871 final List<PackageSetting> packages; 19872 synchronized (mPackages) { 19873 packages = mSettings.getVolumePackagesLPr(volumeUuid); 19874 } 19875 int preparedCount = 0; 19876 for (PackageSetting ps : packages) { 19877 final String packageName = ps.name; 19878 if (ps.pkg == null) { 19879 Slog.w(TAG, "Odd, missing scanned package " + packageName); 19880 // TODO: might be due to legacy ASEC apps; we should circle back 19881 // and reconcile again once they're scanned 19882 continue; 19883 } 19884 19885 if (ps.getInstalled(userId)) { 19886 prepareAppDataLIF(ps.pkg, userId, flags); 19887 19888 if (maybeMigrateAppDataLIF(ps.pkg, userId)) { 19889 // We may have just shuffled around app data directories, so 19890 // prepare them one more time 19891 prepareAppDataLIF(ps.pkg, userId, flags); 19892 } 19893 19894 preparedCount++; 19895 } 19896 } 19897 19898 Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages"); 19899 } 19900 19901 /** 19902 * Prepare app data for the given app just after it was installed or 19903 * upgraded. This method carefully only touches users that it's installed 19904 * for, and it forces a restorecon to handle any seinfo changes. 19905 * <p> 19906 * Verifies that directories exist and that ownership and labeling is 19907 * correct for all installed apps. If there is an ownership mismatch, it 19908 * will try recovering system apps by wiping data; third-party app data is 19909 * left intact. 19910 * <p> 19911 * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em> 19912 */ 19913 private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) { 19914 final PackageSetting ps; 19915 synchronized (mPackages) { 19916 ps = mSettings.mPackages.get(pkg.packageName); 19917 mSettings.writeKernelMappingLPr(ps); 19918 } 19919 19920 final UserManager um = mContext.getSystemService(UserManager.class); 19921 UserManagerInternal umInternal = getUserManagerInternal(); 19922 for (UserInfo user : um.getUsers()) { 19923 final int flags; 19924 if (umInternal.isUserUnlockingOrUnlocked(user.id)) { 19925 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 19926 } else if (umInternal.isUserRunning(user.id)) { 19927 flags = StorageManager.FLAG_STORAGE_DE; 19928 } else { 19929 continue; 19930 } 19931 19932 if (ps.getInstalled(user.id)) { 19933 // TODO: when user data is locked, mark that we're still dirty 19934 prepareAppDataLIF(pkg, user.id, flags); 19935 } 19936 } 19937 } 19938 19939 /** 19940 * Prepare app data for the given app. 19941 * <p> 19942 * Verifies that directories exist and that ownership and labeling is 19943 * correct for all installed apps. If there is an ownership mismatch, this 19944 * will try recovering system apps by wiping data; third-party app data is 19945 * left intact. 19946 */ 19947 private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) { 19948 if (pkg == null) { 19949 Slog.wtf(TAG, "Package was null!", new Throwable()); 19950 return; 19951 } 19952 prepareAppDataLeafLIF(pkg, userId, flags); 19953 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 19954 for (int i = 0; i < childCount; i++) { 19955 prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags); 19956 } 19957 } 19958 19959 private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) { 19960 if (DEBUG_APP_DATA) { 19961 Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x" 19962 + Integer.toHexString(flags)); 19963 } 19964 19965 final String volumeUuid = pkg.volumeUuid; 19966 final String packageName = pkg.packageName; 19967 final ApplicationInfo app = pkg.applicationInfo; 19968 final int appId = UserHandle.getAppId(app.uid); 19969 19970 Preconditions.checkNotNull(app.seinfo); 19971 19972 long ceDataInode = -1; 19973 try { 19974 ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags, 19975 appId, app.seinfo, app.targetSdkVersion); 19976 } catch (InstallerException e) { 19977 if (app.isSystemApp()) { 19978 logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName 19979 + ", but trying to recover: " + e); 19980 destroyAppDataLeafLIF(pkg, userId, flags); 19981 try { 19982 ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags, 19983 appId, app.seinfo, app.targetSdkVersion); 19984 logCriticalInfo(Log.DEBUG, "Recovery succeeded!"); 19985 } catch (InstallerException e2) { 19986 logCriticalInfo(Log.DEBUG, "Recovery failed!"); 19987 } 19988 } else { 19989 Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e); 19990 } 19991 } 19992 19993 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) { 19994 // TODO: mark this structure as dirty so we persist it! 19995 synchronized (mPackages) { 19996 final PackageSetting ps = mSettings.mPackages.get(packageName); 19997 if (ps != null) { 19998 ps.setCeDataInode(ceDataInode, userId); 19999 } 20000 } 20001 } 20002 20003 prepareAppDataContentsLeafLIF(pkg, userId, flags); 20004 } 20005 20006 private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) { 20007 if (pkg == null) { 20008 Slog.wtf(TAG, "Package was null!", new Throwable()); 20009 return; 20010 } 20011 prepareAppDataContentsLeafLIF(pkg, userId, flags); 20012 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 20013 for (int i = 0; i < childCount; i++) { 20014 prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags); 20015 } 20016 } 20017 20018 private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) { 20019 final String volumeUuid = pkg.volumeUuid; 20020 final String packageName = pkg.packageName; 20021 final ApplicationInfo app = pkg.applicationInfo; 20022 20023 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 20024 // Create a native library symlink only if we have native libraries 20025 // and if the native libraries are 32 bit libraries. We do not provide 20026 // this symlink for 64 bit libraries. 20027 if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) { 20028 final String nativeLibPath = app.nativeLibraryDir; 20029 try { 20030 mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName, 20031 nativeLibPath, userId); 20032 } catch (InstallerException e) { 20033 Slog.e(TAG, "Failed to link native for " + packageName + ": " + e); 20034 } 20035 } 20036 } 20037 } 20038 20039 /** 20040 * For system apps on non-FBE devices, this method migrates any existing 20041 * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag 20042 * requested by the app. 20043 */ 20044 private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) { 20045 if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated() 20046 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) { 20047 final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage() 20048 ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE; 20049 try { 20050 mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId, 20051 storageTarget); 20052 } catch (InstallerException e) { 20053 logCriticalInfo(Log.WARN, 20054 "Failed to migrate " + pkg.packageName + ": " + e.getMessage()); 20055 } 20056 return true; 20057 } else { 20058 return false; 20059 } 20060 } 20061 20062 public PackageFreezer freezePackage(String packageName, String killReason) { 20063 return freezePackage(packageName, UserHandle.USER_ALL, killReason); 20064 } 20065 20066 public PackageFreezer freezePackage(String packageName, int userId, String killReason) { 20067 return new PackageFreezer(packageName, userId, killReason); 20068 } 20069 20070 public PackageFreezer freezePackageForInstall(String packageName, int installFlags, 20071 String killReason) { 20072 return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason); 20073 } 20074 20075 public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags, 20076 String killReason) { 20077 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) { 20078 return new PackageFreezer(); 20079 } else { 20080 return freezePackage(packageName, userId, killReason); 20081 } 20082 } 20083 20084 public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags, 20085 String killReason) { 20086 return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason); 20087 } 20088 20089 public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags, 20090 String killReason) { 20091 if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) { 20092 return new PackageFreezer(); 20093 } else { 20094 return freezePackage(packageName, userId, killReason); 20095 } 20096 } 20097 20098 /** 20099 * Class that freezes and kills the given package upon creation, and 20100 * unfreezes it upon closing. This is typically used when doing surgery on 20101 * app code/data to prevent the app from running while you're working. 20102 */ 20103 private class PackageFreezer implements AutoCloseable { 20104 private final String mPackageName; 20105 private final PackageFreezer[] mChildren; 20106 20107 private final boolean mWeFroze; 20108 20109 private final AtomicBoolean mClosed = new AtomicBoolean(); 20110 private final CloseGuard mCloseGuard = CloseGuard.get(); 20111 20112 /** 20113 * Create and return a stub freezer that doesn't actually do anything, 20114 * typically used when someone requested 20115 * {@link PackageManager#INSTALL_DONT_KILL_APP} or 20116 * {@link PackageManager#DELETE_DONT_KILL_APP}. 20117 */ 20118 public PackageFreezer() { 20119 mPackageName = null; 20120 mChildren = null; 20121 mWeFroze = false; 20122 mCloseGuard.open("close"); 20123 } 20124 20125 public PackageFreezer(String packageName, int userId, String killReason) { 20126 synchronized (mPackages) { 20127 mPackageName = packageName; 20128 mWeFroze = mFrozenPackages.add(mPackageName); 20129 20130 final PackageSetting ps = mSettings.mPackages.get(mPackageName); 20131 if (ps != null) { 20132 killApplication(ps.name, ps.appId, userId, killReason); 20133 } 20134 20135 final PackageParser.Package p = mPackages.get(packageName); 20136 if (p != null && p.childPackages != null) { 20137 final int N = p.childPackages.size(); 20138 mChildren = new PackageFreezer[N]; 20139 for (int i = 0; i < N; i++) { 20140 mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName, 20141 userId, killReason); 20142 } 20143 } else { 20144 mChildren = null; 20145 } 20146 } 20147 mCloseGuard.open("close"); 20148 } 20149 20150 @Override 20151 protected void finalize() throws Throwable { 20152 try { 20153 mCloseGuard.warnIfOpen(); 20154 close(); 20155 } finally { 20156 super.finalize(); 20157 } 20158 } 20159 20160 @Override 20161 public void close() { 20162 mCloseGuard.close(); 20163 if (mClosed.compareAndSet(false, true)) { 20164 synchronized (mPackages) { 20165 if (mWeFroze) { 20166 mFrozenPackages.remove(mPackageName); 20167 } 20168 20169 if (mChildren != null) { 20170 for (PackageFreezer freezer : mChildren) { 20171 freezer.close(); 20172 } 20173 } 20174 } 20175 } 20176 } 20177 } 20178 20179 /** 20180 * Verify that given package is currently frozen. 20181 */ 20182 private void checkPackageFrozen(String packageName) { 20183 synchronized (mPackages) { 20184 if (!mFrozenPackages.contains(packageName)) { 20185 Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable()); 20186 } 20187 } 20188 } 20189 20190 @Override 20191 public int movePackage(final String packageName, final String volumeUuid) { 20192 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 20193 20194 final UserHandle user = new UserHandle(UserHandle.getCallingUserId()); 20195 final int moveId = mNextMoveId.getAndIncrement(); 20196 mHandler.post(new Runnable() { 20197 @Override 20198 public void run() { 20199 try { 20200 movePackageInternal(packageName, volumeUuid, moveId, user); 20201 } catch (PackageManagerException e) { 20202 Slog.w(TAG, "Failed to move " + packageName, e); 20203 mMoveCallbacks.notifyStatusChanged(moveId, 20204 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 20205 } 20206 } 20207 }); 20208 return moveId; 20209 } 20210 20211 private void movePackageInternal(final String packageName, final String volumeUuid, 20212 final int moveId, UserHandle user) throws PackageManagerException { 20213 final StorageManager storage = mContext.getSystemService(StorageManager.class); 20214 final PackageManager pm = mContext.getPackageManager(); 20215 20216 final boolean currentAsec; 20217 final String currentVolumeUuid; 20218 final File codeFile; 20219 final String installerPackageName; 20220 final String packageAbiOverride; 20221 final int appId; 20222 final String seinfo; 20223 final String label; 20224 final int targetSdkVersion; 20225 final PackageFreezer freezer; 20226 final int[] installedUserIds; 20227 20228 // reader 20229 synchronized (mPackages) { 20230 final PackageParser.Package pkg = mPackages.get(packageName); 20231 final PackageSetting ps = mSettings.mPackages.get(packageName); 20232 if (pkg == null || ps == null) { 20233 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package"); 20234 } 20235 20236 if (pkg.applicationInfo.isSystemApp()) { 20237 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE, 20238 "Cannot move system application"); 20239 } 20240 20241 if (pkg.applicationInfo.isExternalAsec()) { 20242 currentAsec = true; 20243 currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL; 20244 } else if (pkg.applicationInfo.isForwardLocked()) { 20245 currentAsec = true; 20246 currentVolumeUuid = "forward_locked"; 20247 } else { 20248 currentAsec = false; 20249 currentVolumeUuid = ps.volumeUuid; 20250 20251 final File probe = new File(pkg.codePath); 20252 final File probeOat = new File(probe, "oat"); 20253 if (!probe.isDirectory() || !probeOat.isDirectory()) { 20254 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 20255 "Move only supported for modern cluster style installs"); 20256 } 20257 } 20258 20259 if (Objects.equals(currentVolumeUuid, volumeUuid)) { 20260 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 20261 "Package already moved to " + volumeUuid); 20262 } 20263 if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) { 20264 throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN, 20265 "Device admin cannot be moved"); 20266 } 20267 20268 if (mFrozenPackages.contains(packageName)) { 20269 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING, 20270 "Failed to move already frozen package"); 20271 } 20272 20273 codeFile = new File(pkg.codePath); 20274 installerPackageName = ps.installerPackageName; 20275 packageAbiOverride = ps.cpuAbiOverrideString; 20276 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 20277 seinfo = pkg.applicationInfo.seinfo; 20278 label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo)); 20279 targetSdkVersion = pkg.applicationInfo.targetSdkVersion; 20280 freezer = freezePackage(packageName, "movePackageInternal"); 20281 installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 20282 } 20283 20284 final Bundle extras = new Bundle(); 20285 extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName); 20286 extras.putString(Intent.EXTRA_TITLE, label); 20287 mMoveCallbacks.notifyCreated(moveId, extras); 20288 20289 int installFlags; 20290 final boolean moveCompleteApp; 20291 final File measurePath; 20292 20293 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) { 20294 installFlags = INSTALL_INTERNAL; 20295 moveCompleteApp = !currentAsec; 20296 measurePath = Environment.getDataAppDirectory(volumeUuid); 20297 } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) { 20298 installFlags = INSTALL_EXTERNAL; 20299 moveCompleteApp = false; 20300 measurePath = storage.getPrimaryPhysicalVolume().getPath(); 20301 } else { 20302 final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid); 20303 if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE 20304 || !volume.isMountedWritable()) { 20305 freezer.close(); 20306 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 20307 "Move location not mounted private volume"); 20308 } 20309 20310 Preconditions.checkState(!currentAsec); 20311 20312 installFlags = INSTALL_INTERNAL; 20313 moveCompleteApp = true; 20314 measurePath = Environment.getDataAppDirectory(volumeUuid); 20315 } 20316 20317 final PackageStats stats = new PackageStats(null, -1); 20318 synchronized (mInstaller) { 20319 for (int userId : installedUserIds) { 20320 if (!getPackageSizeInfoLI(packageName, userId, stats)) { 20321 freezer.close(); 20322 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 20323 "Failed to measure package size"); 20324 } 20325 } 20326 } 20327 20328 if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size " 20329 + stats.dataSize); 20330 20331 final long startFreeBytes = measurePath.getFreeSpace(); 20332 final long sizeBytes; 20333 if (moveCompleteApp) { 20334 sizeBytes = stats.codeSize + stats.dataSize; 20335 } else { 20336 sizeBytes = stats.codeSize; 20337 } 20338 20339 if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) { 20340 freezer.close(); 20341 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 20342 "Not enough free space to move"); 20343 } 20344 20345 mMoveCallbacks.notifyStatusChanged(moveId, 10); 20346 20347 final CountDownLatch installedLatch = new CountDownLatch(1); 20348 final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() { 20349 @Override 20350 public void onUserActionRequired(Intent intent) throws RemoteException { 20351 throw new IllegalStateException(); 20352 } 20353 20354 @Override 20355 public void onPackageInstalled(String basePackageName, int returnCode, String msg, 20356 Bundle extras) throws RemoteException { 20357 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: " 20358 + PackageManager.installStatusToString(returnCode, msg)); 20359 20360 installedLatch.countDown(); 20361 freezer.close(); 20362 20363 final int status = PackageManager.installStatusToPublicStatus(returnCode); 20364 switch (status) { 20365 case PackageInstaller.STATUS_SUCCESS: 20366 mMoveCallbacks.notifyStatusChanged(moveId, 20367 PackageManager.MOVE_SUCCEEDED); 20368 break; 20369 case PackageInstaller.STATUS_FAILURE_STORAGE: 20370 mMoveCallbacks.notifyStatusChanged(moveId, 20371 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE); 20372 break; 20373 default: 20374 mMoveCallbacks.notifyStatusChanged(moveId, 20375 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 20376 break; 20377 } 20378 } 20379 }; 20380 20381 final MoveInfo move; 20382 if (moveCompleteApp) { 20383 // Kick off a thread to report progress estimates 20384 new Thread() { 20385 @Override 20386 public void run() { 20387 while (true) { 20388 try { 20389 if (installedLatch.await(1, TimeUnit.SECONDS)) { 20390 break; 20391 } 20392 } catch (InterruptedException ignored) { 20393 } 20394 20395 final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace(); 20396 final int progress = 10 + (int) MathUtils.constrain( 20397 ((deltaFreeBytes * 80) / sizeBytes), 0, 80); 20398 mMoveCallbacks.notifyStatusChanged(moveId, progress); 20399 } 20400 } 20401 }.start(); 20402 20403 final String dataAppName = codeFile.getName(); 20404 move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName, 20405 dataAppName, appId, seinfo, targetSdkVersion); 20406 } else { 20407 move = null; 20408 } 20409 20410 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 20411 20412 final Message msg = mHandler.obtainMessage(INIT_COPY); 20413 final OriginInfo origin = OriginInfo.fromExistingFile(codeFile); 20414 final InstallParams params = new InstallParams(origin, move, installObserver, installFlags, 20415 installerPackageName, volumeUuid, null /*verificationInfo*/, user, 20416 packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/); 20417 params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params)); 20418 msg.obj = params; 20419 20420 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage", 20421 System.identityHashCode(msg.obj)); 20422 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 20423 System.identityHashCode(msg.obj)); 20424 20425 mHandler.sendMessage(msg); 20426 } 20427 20428 @Override 20429 public int movePrimaryStorage(String volumeUuid) throws RemoteException { 20430 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 20431 20432 final int realMoveId = mNextMoveId.getAndIncrement(); 20433 final Bundle extras = new Bundle(); 20434 extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid); 20435 mMoveCallbacks.notifyCreated(realMoveId, extras); 20436 20437 final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() { 20438 @Override 20439 public void onCreated(int moveId, Bundle extras) { 20440 // Ignored 20441 } 20442 20443 @Override 20444 public void onStatusChanged(int moveId, int status, long estMillis) { 20445 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis); 20446 } 20447 }; 20448 20449 final StorageManager storage = mContext.getSystemService(StorageManager.class); 20450 storage.setPrimaryStorageUuid(volumeUuid, callback); 20451 return realMoveId; 20452 } 20453 20454 @Override 20455 public int getMoveStatus(int moveId) { 20456 mContext.enforceCallingOrSelfPermission( 20457 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 20458 return mMoveCallbacks.mLastStatus.get(moveId); 20459 } 20460 20461 @Override 20462 public void registerMoveCallback(IPackageMoveObserver callback) { 20463 mContext.enforceCallingOrSelfPermission( 20464 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 20465 mMoveCallbacks.register(callback); 20466 } 20467 20468 @Override 20469 public void unregisterMoveCallback(IPackageMoveObserver callback) { 20470 mContext.enforceCallingOrSelfPermission( 20471 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 20472 mMoveCallbacks.unregister(callback); 20473 } 20474 20475 @Override 20476 public boolean setInstallLocation(int loc) { 20477 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, 20478 null); 20479 if (getInstallLocation() == loc) { 20480 return true; 20481 } 20482 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL 20483 || loc == PackageHelper.APP_INSTALL_EXTERNAL) { 20484 android.provider.Settings.Global.putInt(mContext.getContentResolver(), 20485 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc); 20486 return true; 20487 } 20488 return false; 20489 } 20490 20491 @Override 20492 public int getInstallLocation() { 20493 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 20494 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, 20495 PackageHelper.APP_INSTALL_AUTO); 20496 } 20497 20498 /** Called by UserManagerService */ 20499 void cleanUpUser(UserManagerService userManager, int userHandle) { 20500 synchronized (mPackages) { 20501 mDirtyUsers.remove(userHandle); 20502 mUserNeedsBadging.delete(userHandle); 20503 mSettings.removeUserLPw(userHandle); 20504 mPendingBroadcasts.remove(userHandle); 20505 mEphemeralApplicationRegistry.onUserRemovedLPw(userHandle); 20506 removeUnusedPackagesLPw(userManager, userHandle); 20507 } 20508 } 20509 20510 /** 20511 * We're removing userHandle and would like to remove any downloaded packages 20512 * that are no longer in use by any other user. 20513 * @param userHandle the user being removed 20514 */ 20515 private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) { 20516 final boolean DEBUG_CLEAN_APKS = false; 20517 int [] users = userManager.getUserIds(); 20518 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 20519 while (psit.hasNext()) { 20520 PackageSetting ps = psit.next(); 20521 if (ps.pkg == null) { 20522 continue; 20523 } 20524 final String packageName = ps.pkg.packageName; 20525 // Skip over if system app 20526 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) { 20527 continue; 20528 } 20529 if (DEBUG_CLEAN_APKS) { 20530 Slog.i(TAG, "Checking package " + packageName); 20531 } 20532 boolean keep = shouldKeepUninstalledPackageLPr(packageName); 20533 if (keep) { 20534 if (DEBUG_CLEAN_APKS) { 20535 Slog.i(TAG, " Keeping package " + packageName + " - requested by DO"); 20536 } 20537 } else { 20538 for (int i = 0; i < users.length; i++) { 20539 if (users[i] != userHandle && ps.getInstalled(users[i])) { 20540 keep = true; 20541 if (DEBUG_CLEAN_APKS) { 20542 Slog.i(TAG, " Keeping package " + packageName + " for user " 20543 + users[i]); 20544 } 20545 break; 20546 } 20547 } 20548 } 20549 if (!keep) { 20550 if (DEBUG_CLEAN_APKS) { 20551 Slog.i(TAG, " Removing package " + packageName); 20552 } 20553 mHandler.post(new Runnable() { 20554 public void run() { 20555 deletePackageX(packageName, userHandle, 0); 20556 } //end run 20557 }); 20558 } 20559 } 20560 } 20561 20562 /** Called by UserManagerService */ 20563 void createNewUser(int userId) { 20564 synchronized (mInstallLock) { 20565 mSettings.createNewUserLI(this, mInstaller, userId); 20566 } 20567 synchronized (mPackages) { 20568 scheduleWritePackageRestrictionsLocked(userId); 20569 scheduleWritePackageListLocked(userId); 20570 applyFactoryDefaultBrowserLPw(userId); 20571 primeDomainVerificationsLPw(userId); 20572 } 20573 } 20574 20575 void onNewUserCreated(final int userId) { 20576 mDefaultPermissionPolicy.grantDefaultPermissions(userId); 20577 // If permission review for legacy apps is required, we represent 20578 // dagerous permissions for such apps as always granted runtime 20579 // permissions to keep per user flag state whether review is needed. 20580 // Hence, if a new user is added we have to propagate dangerous 20581 // permission grants for these legacy apps. 20582 if (mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED) { 20583 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL 20584 | UPDATE_PERMISSIONS_REPLACE_ALL); 20585 } 20586 } 20587 20588 @Override 20589 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException { 20590 mContext.enforceCallingOrSelfPermission( 20591 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 20592 "Only package verification agents can read the verifier device identity"); 20593 20594 synchronized (mPackages) { 20595 return mSettings.getVerifierDeviceIdentityLPw(); 20596 } 20597 } 20598 20599 @Override 20600 public void setPermissionEnforced(String permission, boolean enforced) { 20601 // TODO: Now that we no longer change GID for storage, this should to away. 20602 mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 20603 "setPermissionEnforced"); 20604 if (READ_EXTERNAL_STORAGE.equals(permission)) { 20605 synchronized (mPackages) { 20606 if (mSettings.mReadExternalStorageEnforced == null 20607 || mSettings.mReadExternalStorageEnforced != enforced) { 20608 mSettings.mReadExternalStorageEnforced = enforced; 20609 mSettings.writeLPr(); 20610 } 20611 } 20612 // kill any non-foreground processes so we restart them and 20613 // grant/revoke the GID. 20614 final IActivityManager am = ActivityManagerNative.getDefault(); 20615 if (am != null) { 20616 final long token = Binder.clearCallingIdentity(); 20617 try { 20618 am.killProcessesBelowForeground("setPermissionEnforcement"); 20619 } catch (RemoteException e) { 20620 } finally { 20621 Binder.restoreCallingIdentity(token); 20622 } 20623 } 20624 } else { 20625 throw new IllegalArgumentException("No selective enforcement for " + permission); 20626 } 20627 } 20628 20629 @Override 20630 @Deprecated 20631 public boolean isPermissionEnforced(String permission) { 20632 return true; 20633 } 20634 20635 @Override 20636 public boolean isStorageLow() { 20637 final long token = Binder.clearCallingIdentity(); 20638 try { 20639 final DeviceStorageMonitorInternal 20640 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 20641 if (dsm != null) { 20642 return dsm.isMemoryLow(); 20643 } else { 20644 return false; 20645 } 20646 } finally { 20647 Binder.restoreCallingIdentity(token); 20648 } 20649 } 20650 20651 @Override 20652 public IPackageInstaller getPackageInstaller() { 20653 return mInstallerService; 20654 } 20655 20656 private boolean userNeedsBadging(int userId) { 20657 int index = mUserNeedsBadging.indexOfKey(userId); 20658 if (index < 0) { 20659 final UserInfo userInfo; 20660 final long token = Binder.clearCallingIdentity(); 20661 try { 20662 userInfo = sUserManager.getUserInfo(userId); 20663 } finally { 20664 Binder.restoreCallingIdentity(token); 20665 } 20666 final boolean b; 20667 if (userInfo != null && userInfo.isManagedProfile()) { 20668 b = true; 20669 } else { 20670 b = false; 20671 } 20672 mUserNeedsBadging.put(userId, b); 20673 return b; 20674 } 20675 return mUserNeedsBadging.valueAt(index); 20676 } 20677 20678 @Override 20679 public KeySet getKeySetByAlias(String packageName, String alias) { 20680 if (packageName == null || alias == null) { 20681 return null; 20682 } 20683 synchronized(mPackages) { 20684 final PackageParser.Package pkg = mPackages.get(packageName); 20685 if (pkg == null) { 20686 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 20687 throw new IllegalArgumentException("Unknown package: " + packageName); 20688 } 20689 KeySetManagerService ksms = mSettings.mKeySetManagerService; 20690 return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias)); 20691 } 20692 } 20693 20694 @Override 20695 public KeySet getSigningKeySet(String packageName) { 20696 if (packageName == null) { 20697 return null; 20698 } 20699 synchronized(mPackages) { 20700 final PackageParser.Package pkg = mPackages.get(packageName); 20701 if (pkg == null) { 20702 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 20703 throw new IllegalArgumentException("Unknown package: " + packageName); 20704 } 20705 if (pkg.applicationInfo.uid != Binder.getCallingUid() 20706 && Process.SYSTEM_UID != Binder.getCallingUid()) { 20707 throw new SecurityException("May not access signing KeySet of other apps."); 20708 } 20709 KeySetManagerService ksms = mSettings.mKeySetManagerService; 20710 return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName)); 20711 } 20712 } 20713 20714 @Override 20715 public boolean isPackageSignedByKeySet(String packageName, KeySet ks) { 20716 if (packageName == null || ks == null) { 20717 return false; 20718 } 20719 synchronized(mPackages) { 20720 final PackageParser.Package pkg = mPackages.get(packageName); 20721 if (pkg == null) { 20722 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 20723 throw new IllegalArgumentException("Unknown package: " + packageName); 20724 } 20725 IBinder ksh = ks.getToken(); 20726 if (ksh instanceof KeySetHandle) { 20727 KeySetManagerService ksms = mSettings.mKeySetManagerService; 20728 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh); 20729 } 20730 return false; 20731 } 20732 } 20733 20734 @Override 20735 public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) { 20736 if (packageName == null || ks == null) { 20737 return false; 20738 } 20739 synchronized(mPackages) { 20740 final PackageParser.Package pkg = mPackages.get(packageName); 20741 if (pkg == null) { 20742 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 20743 throw new IllegalArgumentException("Unknown package: " + packageName); 20744 } 20745 IBinder ksh = ks.getToken(); 20746 if (ksh instanceof KeySetHandle) { 20747 KeySetManagerService ksms = mSettings.mKeySetManagerService; 20748 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh); 20749 } 20750 return false; 20751 } 20752 } 20753 20754 private void deletePackageIfUnusedLPr(final String packageName) { 20755 PackageSetting ps = mSettings.mPackages.get(packageName); 20756 if (ps == null) { 20757 return; 20758 } 20759 if (!ps.isAnyInstalled(sUserManager.getUserIds())) { 20760 // TODO Implement atomic delete if package is unused 20761 // It is currently possible that the package will be deleted even if it is installed 20762 // after this method returns. 20763 mHandler.post(new Runnable() { 20764 public void run() { 20765 deletePackageX(packageName, 0, PackageManager.DELETE_ALL_USERS); 20766 } 20767 }); 20768 } 20769 } 20770 20771 /** 20772 * Check and throw if the given before/after packages would be considered a 20773 * downgrade. 20774 */ 20775 private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after) 20776 throws PackageManagerException { 20777 if (after.versionCode < before.mVersionCode) { 20778 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 20779 "Update version code " + after.versionCode + " is older than current " 20780 + before.mVersionCode); 20781 } else if (after.versionCode == before.mVersionCode) { 20782 if (after.baseRevisionCode < before.baseRevisionCode) { 20783 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 20784 "Update base revision code " + after.baseRevisionCode 20785 + " is older than current " + before.baseRevisionCode); 20786 } 20787 20788 if (!ArrayUtils.isEmpty(after.splitNames)) { 20789 for (int i = 0; i < after.splitNames.length; i++) { 20790 final String splitName = after.splitNames[i]; 20791 final int j = ArrayUtils.indexOf(before.splitNames, splitName); 20792 if (j != -1) { 20793 if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) { 20794 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 20795 "Update split " + splitName + " revision code " 20796 + after.splitRevisionCodes[i] + " is older than current " 20797 + before.splitRevisionCodes[j]); 20798 } 20799 } 20800 } 20801 } 20802 } 20803 } 20804 20805 private static class MoveCallbacks extends Handler { 20806 private static final int MSG_CREATED = 1; 20807 private static final int MSG_STATUS_CHANGED = 2; 20808 20809 private final RemoteCallbackList<IPackageMoveObserver> 20810 mCallbacks = new RemoteCallbackList<>(); 20811 20812 private final SparseIntArray mLastStatus = new SparseIntArray(); 20813 20814 public MoveCallbacks(Looper looper) { 20815 super(looper); 20816 } 20817 20818 public void register(IPackageMoveObserver callback) { 20819 mCallbacks.register(callback); 20820 } 20821 20822 public void unregister(IPackageMoveObserver callback) { 20823 mCallbacks.unregister(callback); 20824 } 20825 20826 @Override 20827 public void handleMessage(Message msg) { 20828 final SomeArgs args = (SomeArgs) msg.obj; 20829 final int n = mCallbacks.beginBroadcast(); 20830 for (int i = 0; i < n; i++) { 20831 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i); 20832 try { 20833 invokeCallback(callback, msg.what, args); 20834 } catch (RemoteException ignored) { 20835 } 20836 } 20837 mCallbacks.finishBroadcast(); 20838 args.recycle(); 20839 } 20840 20841 private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args) 20842 throws RemoteException { 20843 switch (what) { 20844 case MSG_CREATED: { 20845 callback.onCreated(args.argi1, (Bundle) args.arg2); 20846 break; 20847 } 20848 case MSG_STATUS_CHANGED: { 20849 callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3); 20850 break; 20851 } 20852 } 20853 } 20854 20855 private void notifyCreated(int moveId, Bundle extras) { 20856 Slog.v(TAG, "Move " + moveId + " created " + extras.toString()); 20857 20858 final SomeArgs args = SomeArgs.obtain(); 20859 args.argi1 = moveId; 20860 args.arg2 = extras; 20861 obtainMessage(MSG_CREATED, args).sendToTarget(); 20862 } 20863 20864 private void notifyStatusChanged(int moveId, int status) { 20865 notifyStatusChanged(moveId, status, -1); 20866 } 20867 20868 private void notifyStatusChanged(int moveId, int status, long estMillis) { 20869 Slog.v(TAG, "Move " + moveId + " status " + status); 20870 20871 final SomeArgs args = SomeArgs.obtain(); 20872 args.argi1 = moveId; 20873 args.argi2 = status; 20874 args.arg3 = estMillis; 20875 obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget(); 20876 20877 synchronized (mLastStatus) { 20878 mLastStatus.put(moveId, status); 20879 } 20880 } 20881 } 20882 20883 private final static class OnPermissionChangeListeners extends Handler { 20884 private static final int MSG_ON_PERMISSIONS_CHANGED = 1; 20885 20886 private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners = 20887 new RemoteCallbackList<>(); 20888 20889 public OnPermissionChangeListeners(Looper looper) { 20890 super(looper); 20891 } 20892 20893 @Override 20894 public void handleMessage(Message msg) { 20895 switch (msg.what) { 20896 case MSG_ON_PERMISSIONS_CHANGED: { 20897 final int uid = msg.arg1; 20898 handleOnPermissionsChanged(uid); 20899 } break; 20900 } 20901 } 20902 20903 public void addListenerLocked(IOnPermissionsChangeListener listener) { 20904 mPermissionListeners.register(listener); 20905 20906 } 20907 20908 public void removeListenerLocked(IOnPermissionsChangeListener listener) { 20909 mPermissionListeners.unregister(listener); 20910 } 20911 20912 public void onPermissionsChanged(int uid) { 20913 if (mPermissionListeners.getRegisteredCallbackCount() > 0) { 20914 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget(); 20915 } 20916 } 20917 20918 private void handleOnPermissionsChanged(int uid) { 20919 final int count = mPermissionListeners.beginBroadcast(); 20920 try { 20921 for (int i = 0; i < count; i++) { 20922 IOnPermissionsChangeListener callback = mPermissionListeners 20923 .getBroadcastItem(i); 20924 try { 20925 callback.onPermissionsChanged(uid); 20926 } catch (RemoteException e) { 20927 Log.e(TAG, "Permission listener is dead", e); 20928 } 20929 } 20930 } finally { 20931 mPermissionListeners.finishBroadcast(); 20932 } 20933 } 20934 } 20935 20936 private class PackageManagerInternalImpl extends PackageManagerInternal { 20937 @Override 20938 public void setLocationPackagesProvider(PackagesProvider provider) { 20939 synchronized (mPackages) { 20940 mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider); 20941 } 20942 } 20943 20944 @Override 20945 public void setVoiceInteractionPackagesProvider(PackagesProvider provider) { 20946 synchronized (mPackages) { 20947 mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider); 20948 } 20949 } 20950 20951 @Override 20952 public void setSmsAppPackagesProvider(PackagesProvider provider) { 20953 synchronized (mPackages) { 20954 mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider); 20955 } 20956 } 20957 20958 @Override 20959 public void setDialerAppPackagesProvider(PackagesProvider provider) { 20960 synchronized (mPackages) { 20961 mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider); 20962 } 20963 } 20964 20965 @Override 20966 public void setSimCallManagerPackagesProvider(PackagesProvider provider) { 20967 synchronized (mPackages) { 20968 mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider); 20969 } 20970 } 20971 20972 @Override 20973 public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) { 20974 synchronized (mPackages) { 20975 mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider); 20976 } 20977 } 20978 20979 @Override 20980 public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) { 20981 synchronized (mPackages) { 20982 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr( 20983 packageName, userId); 20984 } 20985 } 20986 20987 @Override 20988 public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) { 20989 synchronized (mPackages) { 20990 mSettings.setDefaultDialerPackageNameLPw(packageName, userId); 20991 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr( 20992 packageName, userId); 20993 } 20994 } 20995 20996 @Override 20997 public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) { 20998 synchronized (mPackages) { 20999 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr( 21000 packageName, userId); 21001 } 21002 } 21003 21004 @Override 21005 public void setKeepUninstalledPackages(final List<String> packageList) { 21006 Preconditions.checkNotNull(packageList); 21007 List<String> removedFromList = null; 21008 synchronized (mPackages) { 21009 if (mKeepUninstalledPackages != null) { 21010 final int packagesCount = mKeepUninstalledPackages.size(); 21011 for (int i = 0; i < packagesCount; i++) { 21012 String oldPackage = mKeepUninstalledPackages.get(i); 21013 if (packageList != null && packageList.contains(oldPackage)) { 21014 continue; 21015 } 21016 if (removedFromList == null) { 21017 removedFromList = new ArrayList<>(); 21018 } 21019 removedFromList.add(oldPackage); 21020 } 21021 } 21022 mKeepUninstalledPackages = new ArrayList<>(packageList); 21023 if (removedFromList != null) { 21024 final int removedCount = removedFromList.size(); 21025 for (int i = 0; i < removedCount; i++) { 21026 deletePackageIfUnusedLPr(removedFromList.get(i)); 21027 } 21028 } 21029 } 21030 } 21031 21032 @Override 21033 public boolean isPermissionsReviewRequired(String packageName, int userId) { 21034 synchronized (mPackages) { 21035 // If we do not support permission review, done. 21036 if (!mPermissionReviewRequired && !Build.PERMISSIONS_REVIEW_REQUIRED) { 21037 return false; 21038 } 21039 21040 PackageSetting packageSetting = mSettings.mPackages.get(packageName); 21041 if (packageSetting == null) { 21042 return false; 21043 } 21044 21045 // Permission review applies only to apps not supporting the new permission model. 21046 if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) { 21047 return false; 21048 } 21049 21050 // Legacy apps have the permission and get user consent on launch. 21051 PermissionsState permissionsState = packageSetting.getPermissionsState(); 21052 return permissionsState.isPermissionReviewRequired(userId); 21053 } 21054 } 21055 21056 @Override 21057 public ApplicationInfo getApplicationInfo(String packageName, int userId) { 21058 return PackageManagerService.this.getApplicationInfo(packageName, 0 /*flags*/, userId); 21059 } 21060 21061 @Override 21062 public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, 21063 int userId) { 21064 return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId); 21065 } 21066 21067 @Override 21068 public void setDeviceAndProfileOwnerPackages( 21069 int deviceOwnerUserId, String deviceOwnerPackage, 21070 SparseArray<String> profileOwnerPackages) { 21071 mProtectedPackages.setDeviceAndProfileOwnerPackages( 21072 deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages); 21073 } 21074 21075 @Override 21076 public boolean isPackageDataProtected(int userId, String packageName) { 21077 return mProtectedPackages.isPackageDataProtected(userId, packageName); 21078 } 21079 21080 @Override 21081 public boolean wasPackageEverLaunched(String packageName, int userId) { 21082 synchronized (mPackages) { 21083 return mSettings.wasPackageEverLaunchedLPr(packageName, userId); 21084 } 21085 } 21086 } 21087 21088 @Override 21089 public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) { 21090 enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps"); 21091 synchronized (mPackages) { 21092 final long identity = Binder.clearCallingIdentity(); 21093 try { 21094 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr( 21095 packageNames, userId); 21096 } finally { 21097 Binder.restoreCallingIdentity(identity); 21098 } 21099 } 21100 } 21101 21102 private static void enforceSystemOrPhoneCaller(String tag) { 21103 int callingUid = Binder.getCallingUid(); 21104 if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) { 21105 throw new SecurityException( 21106 "Cannot call " + tag + " from UID " + callingUid); 21107 } 21108 } 21109 21110 boolean isHistoricalPackageUsageAvailable() { 21111 return mPackageUsage.isHistoricalPackageUsageAvailable(); 21112 } 21113 21114 /** 21115 * Return a <b>copy</b> of the collection of packages known to the package manager. 21116 * @return A copy of the values of mPackages. 21117 */ 21118 Collection<PackageParser.Package> getPackages() { 21119 synchronized (mPackages) { 21120 return new ArrayList<>(mPackages.values()); 21121 } 21122 } 21123 21124 /** 21125 * Logs process start information (including base APK hash) to the security log. 21126 * @hide 21127 */ 21128 public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo, 21129 String apkFile, int pid) { 21130 if (!SecurityLog.isLoggingEnabled()) { 21131 return; 21132 } 21133 Bundle data = new Bundle(); 21134 data.putLong("startTimestamp", System.currentTimeMillis()); 21135 data.putString("processName", processName); 21136 data.putInt("uid", uid); 21137 data.putString("seinfo", seinfo); 21138 data.putString("apkFile", apkFile); 21139 data.putInt("pid", pid); 21140 Message msg = mProcessLoggingHandler.obtainMessage( 21141 ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG); 21142 msg.setData(data); 21143 mProcessLoggingHandler.sendMessage(msg); 21144 } 21145 21146 public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) { 21147 return mCompilerStats.getPackageStats(pkgName); 21148 } 21149 21150 public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) { 21151 return getOrCreateCompilerPackageStats(pkg.packageName); 21152 } 21153 21154 public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) { 21155 return mCompilerStats.getOrCreatePackageStats(pkgName); 21156 } 21157 21158 public void deleteCompilerPackageStats(String pkgName) { 21159 mCompilerStats.deletePackageStats(pkgName); 21160 } 21161} 21162