PackageManagerService.java revision 9abb501075b1309ff6d238e42fc8cc87ce5c3bdf
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 @Override 7364 public void notifyDexLoad(String loadingPackageName, List<String> dexPaths, String loaderIsa) { 7365 // TODO(calin): b/32871170 7366 } 7367 7368 // TODO: this is not used nor needed. Delete it. 7369 @Override 7370 public boolean performDexOptIfNeeded(String packageName) { 7371 int dexOptStatus = performDexOptTraced(packageName, 7372 false /* checkProfiles */, getFullCompilerFilter(), false /* force */); 7373 return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED; 7374 } 7375 7376 @Override 7377 public boolean performDexOpt(String packageName, 7378 boolean checkProfiles, int compileReason, boolean force) { 7379 int dexOptStatus = performDexOptTraced(packageName, checkProfiles, 7380 getCompilerFilterForReason(compileReason), force); 7381 return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED; 7382 } 7383 7384 @Override 7385 public boolean performDexOptMode(String packageName, 7386 boolean checkProfiles, String targetCompilerFilter, boolean force) { 7387 int dexOptStatus = performDexOptTraced(packageName, checkProfiles, 7388 targetCompilerFilter, force); 7389 return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED; 7390 } 7391 7392 private int performDexOptTraced(String packageName, 7393 boolean checkProfiles, String targetCompilerFilter, boolean force) { 7394 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 7395 try { 7396 return performDexOptInternal(packageName, checkProfiles, 7397 targetCompilerFilter, force); 7398 } finally { 7399 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7400 } 7401 } 7402 7403 // Run dexopt on a given package. Returns true if dexopt did not fail, i.e. 7404 // if the package can now be considered up to date for the given filter. 7405 private int performDexOptInternal(String packageName, 7406 boolean checkProfiles, String targetCompilerFilter, boolean force) { 7407 PackageParser.Package p; 7408 synchronized (mPackages) { 7409 p = mPackages.get(packageName); 7410 if (p == null) { 7411 // Package could not be found. Report failure. 7412 return PackageDexOptimizer.DEX_OPT_FAILED; 7413 } 7414 mPackageUsage.maybeWriteAsync(mPackages); 7415 mCompilerStats.maybeWriteAsync(); 7416 } 7417 long callingId = Binder.clearCallingIdentity(); 7418 try { 7419 synchronized (mInstallLock) { 7420 return performDexOptInternalWithDependenciesLI(p, checkProfiles, 7421 targetCompilerFilter, force); 7422 } 7423 } finally { 7424 Binder.restoreCallingIdentity(callingId); 7425 } 7426 } 7427 7428 public ArraySet<String> getOptimizablePackages() { 7429 ArraySet<String> pkgs = new ArraySet<String>(); 7430 synchronized (mPackages) { 7431 for (PackageParser.Package p : mPackages.values()) { 7432 if (PackageDexOptimizer.canOptimizePackage(p)) { 7433 pkgs.add(p.packageName); 7434 } 7435 } 7436 } 7437 return pkgs; 7438 } 7439 7440 private int performDexOptInternalWithDependenciesLI(PackageParser.Package p, 7441 boolean checkProfiles, String targetCompilerFilter, 7442 boolean force) { 7443 // Select the dex optimizer based on the force parameter. 7444 // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to 7445 // allocate an object here. 7446 PackageDexOptimizer pdo = force 7447 ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer) 7448 : mPackageDexOptimizer; 7449 7450 // Optimize all dependencies first. Note: we ignore the return value and march on 7451 // on errors. 7452 Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p); 7453 final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo); 7454 if (!deps.isEmpty()) { 7455 for (PackageParser.Package depPackage : deps) { 7456 // TODO: Analyze and investigate if we (should) profile libraries. 7457 // Currently this will do a full compilation of the library by default. 7458 pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets, 7459 false /* checkProfiles */, 7460 getCompilerFilterForReason(REASON_NON_SYSTEM_LIBRARY), 7461 getOrCreateCompilerPackageStats(depPackage)); 7462 } 7463 } 7464 return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles, 7465 targetCompilerFilter, getOrCreateCompilerPackageStats(p)); 7466 } 7467 7468 Collection<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) { 7469 if (p.usesLibraries != null || p.usesOptionalLibraries != null) { 7470 ArrayList<PackageParser.Package> retValue = new ArrayList<>(); 7471 Set<String> collectedNames = new HashSet<>(); 7472 findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames); 7473 7474 retValue.remove(p); 7475 7476 return retValue; 7477 } else { 7478 return Collections.emptyList(); 7479 } 7480 } 7481 7482 private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p, 7483 Collection<PackageParser.Package> collected, Set<String> collectedNames) { 7484 if (!collectedNames.contains(p.packageName)) { 7485 collectedNames.add(p.packageName); 7486 collected.add(p); 7487 7488 if (p.usesLibraries != null) { 7489 findSharedNonSystemLibrariesRecursive(p.usesLibraries, collected, collectedNames); 7490 } 7491 if (p.usesOptionalLibraries != null) { 7492 findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries, collected, 7493 collectedNames); 7494 } 7495 } 7496 } 7497 7498 private void findSharedNonSystemLibrariesRecursive(Collection<String> libs, 7499 Collection<PackageParser.Package> collected, Set<String> collectedNames) { 7500 for (String libName : libs) { 7501 PackageParser.Package libPkg = findSharedNonSystemLibrary(libName); 7502 if (libPkg != null) { 7503 findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames); 7504 } 7505 } 7506 } 7507 7508 private PackageParser.Package findSharedNonSystemLibrary(String libName) { 7509 synchronized (mPackages) { 7510 PackageManagerService.SharedLibraryEntry lib = mSharedLibraries.get(libName); 7511 if (lib != null && lib.apk != null) { 7512 return mPackages.get(lib.apk); 7513 } 7514 } 7515 return null; 7516 } 7517 7518 public void shutdown() { 7519 mPackageUsage.writeNow(mPackages); 7520 mCompilerStats.writeNow(); 7521 } 7522 7523 @Override 7524 public void dumpProfiles(String packageName) { 7525 PackageParser.Package pkg; 7526 synchronized (mPackages) { 7527 pkg = mPackages.get(packageName); 7528 if (pkg == null) { 7529 throw new IllegalArgumentException("Unknown package: " + packageName); 7530 } 7531 } 7532 /* Only the shell, root, or the app user should be able to dump profiles. */ 7533 int callingUid = Binder.getCallingUid(); 7534 if (callingUid != Process.SHELL_UID && 7535 callingUid != Process.ROOT_UID && 7536 callingUid != pkg.applicationInfo.uid) { 7537 throw new SecurityException("dumpProfiles"); 7538 } 7539 7540 synchronized (mInstallLock) { 7541 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles"); 7542 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 7543 try { 7544 List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly(); 7545 String codePaths = TextUtils.join(";", allCodePaths); 7546 mInstaller.dumpProfiles(sharedGid, packageName, codePaths); 7547 } catch (InstallerException e) { 7548 Slog.w(TAG, "Failed to dump profiles", e); 7549 } 7550 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7551 } 7552 } 7553 7554 @Override 7555 public void forceDexOpt(String packageName) { 7556 enforceSystemOrRoot("forceDexOpt"); 7557 7558 PackageParser.Package pkg; 7559 synchronized (mPackages) { 7560 pkg = mPackages.get(packageName); 7561 if (pkg == null) { 7562 throw new IllegalArgumentException("Unknown package: " + packageName); 7563 } 7564 } 7565 7566 synchronized (mInstallLock) { 7567 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 7568 7569 // Whoever is calling forceDexOpt wants a fully compiled package. 7570 // Don't use profiles since that may cause compilation to be skipped. 7571 final int res = performDexOptInternalWithDependenciesLI(pkg, 7572 false /* checkProfiles */, getCompilerFilterForReason(REASON_FORCED_DEXOPT), 7573 true /* force */); 7574 7575 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7576 if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) { 7577 throw new IllegalStateException("Failed to dexopt: " + res); 7578 } 7579 } 7580 } 7581 7582 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) { 7583 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) { 7584 Slog.w(TAG, "Unable to update from " + oldPkg.name 7585 + " to " + newPkg.packageName 7586 + ": old package not in system partition"); 7587 return false; 7588 } else if (mPackages.get(oldPkg.name) != null) { 7589 Slog.w(TAG, "Unable to update from " + oldPkg.name 7590 + " to " + newPkg.packageName 7591 + ": old package still exists"); 7592 return false; 7593 } 7594 return true; 7595 } 7596 7597 void removeCodePathLI(File codePath) { 7598 if (codePath.isDirectory()) { 7599 try { 7600 mInstaller.rmPackageDir(codePath.getAbsolutePath()); 7601 } catch (InstallerException e) { 7602 Slog.w(TAG, "Failed to remove code path", e); 7603 } 7604 } else { 7605 codePath.delete(); 7606 } 7607 } 7608 7609 private int[] resolveUserIds(int userId) { 7610 return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId }; 7611 } 7612 7613 private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) { 7614 if (pkg == null) { 7615 Slog.wtf(TAG, "Package was null!", new Throwable()); 7616 return; 7617 } 7618 clearAppDataLeafLIF(pkg, userId, flags); 7619 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7620 for (int i = 0; i < childCount; i++) { 7621 clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags); 7622 } 7623 } 7624 7625 private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) { 7626 final PackageSetting ps; 7627 synchronized (mPackages) { 7628 ps = mSettings.mPackages.get(pkg.packageName); 7629 } 7630 for (int realUserId : resolveUserIds(userId)) { 7631 final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0; 7632 try { 7633 mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags, 7634 ceDataInode); 7635 } catch (InstallerException e) { 7636 Slog.w(TAG, String.valueOf(e)); 7637 } 7638 } 7639 } 7640 7641 private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) { 7642 if (pkg == null) { 7643 Slog.wtf(TAG, "Package was null!", new Throwable()); 7644 return; 7645 } 7646 destroyAppDataLeafLIF(pkg, userId, flags); 7647 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7648 for (int i = 0; i < childCount; i++) { 7649 destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags); 7650 } 7651 } 7652 7653 private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) { 7654 final PackageSetting ps; 7655 synchronized (mPackages) { 7656 ps = mSettings.mPackages.get(pkg.packageName); 7657 } 7658 for (int realUserId : resolveUserIds(userId)) { 7659 final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0; 7660 try { 7661 mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags, 7662 ceDataInode); 7663 } catch (InstallerException e) { 7664 Slog.w(TAG, String.valueOf(e)); 7665 } 7666 } 7667 } 7668 7669 private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) { 7670 if (pkg == null) { 7671 Slog.wtf(TAG, "Package was null!", new Throwable()); 7672 return; 7673 } 7674 destroyAppProfilesLeafLIF(pkg); 7675 destroyAppReferenceProfileLeafLIF(pkg, userId, true /* removeBaseMarker */); 7676 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7677 for (int i = 0; i < childCount; i++) { 7678 destroyAppProfilesLeafLIF(pkg.childPackages.get(i)); 7679 destroyAppReferenceProfileLeafLIF(pkg.childPackages.get(i), userId, 7680 true /* removeBaseMarker */); 7681 } 7682 } 7683 7684 private void destroyAppReferenceProfileLeafLIF(PackageParser.Package pkg, int userId, 7685 boolean removeBaseMarker) { 7686 if (pkg.isForwardLocked()) { 7687 return; 7688 } 7689 7690 for (String path : pkg.getAllCodePathsExcludingResourceOnly()) { 7691 try { 7692 path = PackageManagerServiceUtils.realpath(new File(path)); 7693 } catch (IOException e) { 7694 // TODO: Should we return early here ? 7695 Slog.w(TAG, "Failed to get canonical path", e); 7696 continue; 7697 } 7698 7699 final String useMarker = path.replace('/', '@'); 7700 for (int realUserId : resolveUserIds(userId)) { 7701 File profileDir = Environment.getDataProfilesDeForeignDexDirectory(realUserId); 7702 if (removeBaseMarker) { 7703 File foreignUseMark = new File(profileDir, useMarker); 7704 if (foreignUseMark.exists()) { 7705 if (!foreignUseMark.delete()) { 7706 Slog.w(TAG, "Unable to delete foreign user mark for package: " 7707 + pkg.packageName); 7708 } 7709 } 7710 } 7711 7712 File[] markers = profileDir.listFiles(); 7713 if (markers != null) { 7714 final String searchString = "@" + pkg.packageName + "@"; 7715 // We also delete all markers that contain the package name we're 7716 // uninstalling. These are associated with secondary dex-files belonging 7717 // to the package. Reconstructing the path of these dex files is messy 7718 // in general. 7719 for (File marker : markers) { 7720 if (marker.getName().indexOf(searchString) > 0) { 7721 if (!marker.delete()) { 7722 Slog.w(TAG, "Unable to delete foreign user mark for package: " 7723 + pkg.packageName); 7724 } 7725 } 7726 } 7727 } 7728 } 7729 } 7730 } 7731 7732 private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) { 7733 try { 7734 mInstaller.destroyAppProfiles(pkg.packageName); 7735 } catch (InstallerException e) { 7736 Slog.w(TAG, String.valueOf(e)); 7737 } 7738 } 7739 7740 private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) { 7741 if (pkg == null) { 7742 Slog.wtf(TAG, "Package was null!", new Throwable()); 7743 return; 7744 } 7745 clearAppProfilesLeafLIF(pkg); 7746 // We don't remove the base foreign use marker when clearing profiles because 7747 // we will rename it when the app is updated. Unlike the actual profile contents, 7748 // the foreign use marker is good across installs. 7749 destroyAppReferenceProfileLeafLIF(pkg, userId, false /* removeBaseMarker */); 7750 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7751 for (int i = 0; i < childCount; i++) { 7752 clearAppProfilesLeafLIF(pkg.childPackages.get(i)); 7753 } 7754 } 7755 7756 private void clearAppProfilesLeafLIF(PackageParser.Package pkg) { 7757 try { 7758 mInstaller.clearAppProfiles(pkg.packageName); 7759 } catch (InstallerException e) { 7760 Slog.w(TAG, String.valueOf(e)); 7761 } 7762 } 7763 7764 private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime, 7765 long lastUpdateTime) { 7766 // Set parent install/update time 7767 PackageSetting ps = (PackageSetting) pkg.mExtras; 7768 if (ps != null) { 7769 ps.firstInstallTime = firstInstallTime; 7770 ps.lastUpdateTime = lastUpdateTime; 7771 } 7772 // Set children install/update time 7773 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7774 for (int i = 0; i < childCount; i++) { 7775 PackageParser.Package childPkg = pkg.childPackages.get(i); 7776 ps = (PackageSetting) childPkg.mExtras; 7777 if (ps != null) { 7778 ps.firstInstallTime = firstInstallTime; 7779 ps.lastUpdateTime = lastUpdateTime; 7780 } 7781 } 7782 } 7783 7784 private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file, 7785 PackageParser.Package changingLib) { 7786 if (file.path != null) { 7787 usesLibraryFiles.add(file.path); 7788 return; 7789 } 7790 PackageParser.Package p = mPackages.get(file.apk); 7791 if (changingLib != null && changingLib.packageName.equals(file.apk)) { 7792 // If we are doing this while in the middle of updating a library apk, 7793 // then we need to make sure to use that new apk for determining the 7794 // dependencies here. (We haven't yet finished committing the new apk 7795 // to the package manager state.) 7796 if (p == null || p.packageName.equals(changingLib.packageName)) { 7797 p = changingLib; 7798 } 7799 } 7800 if (p != null) { 7801 usesLibraryFiles.addAll(p.getAllCodePaths()); 7802 } 7803 } 7804 7805 private void updateSharedLibrariesLPw(PackageParser.Package pkg, 7806 PackageParser.Package changingLib) throws PackageManagerException { 7807 if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) { 7808 final ArraySet<String> usesLibraryFiles = new ArraySet<>(); 7809 int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0; 7810 for (int i=0; i<N; i++) { 7811 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i)); 7812 if (file == null) { 7813 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, 7814 "Package " + pkg.packageName + " requires unavailable shared library " 7815 + pkg.usesLibraries.get(i) + "; failing!"); 7816 } 7817 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 7818 } 7819 N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0; 7820 for (int i=0; i<N; i++) { 7821 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i)); 7822 if (file == null) { 7823 Slog.w(TAG, "Package " + pkg.packageName 7824 + " desires unavailable shared library " 7825 + pkg.usesOptionalLibraries.get(i) + "; ignoring!"); 7826 } else { 7827 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 7828 } 7829 } 7830 N = usesLibraryFiles.size(); 7831 if (N > 0) { 7832 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]); 7833 } else { 7834 pkg.usesLibraryFiles = null; 7835 } 7836 } 7837 } 7838 7839 private static boolean hasString(List<String> list, List<String> which) { 7840 if (list == null) { 7841 return false; 7842 } 7843 for (int i=list.size()-1; i>=0; i--) { 7844 for (int j=which.size()-1; j>=0; j--) { 7845 if (which.get(j).equals(list.get(i))) { 7846 return true; 7847 } 7848 } 7849 } 7850 return false; 7851 } 7852 7853 private void updateAllSharedLibrariesLPw() { 7854 for (PackageParser.Package pkg : mPackages.values()) { 7855 try { 7856 updateSharedLibrariesLPw(pkg, null); 7857 } catch (PackageManagerException e) { 7858 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 7859 } 7860 } 7861 } 7862 7863 private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw( 7864 PackageParser.Package changingPkg) { 7865 ArrayList<PackageParser.Package> res = null; 7866 for (PackageParser.Package pkg : mPackages.values()) { 7867 if (hasString(pkg.usesLibraries, changingPkg.libraryNames) 7868 || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) { 7869 if (res == null) { 7870 res = new ArrayList<PackageParser.Package>(); 7871 } 7872 res.add(pkg); 7873 try { 7874 updateSharedLibrariesLPw(pkg, changingPkg); 7875 } catch (PackageManagerException e) { 7876 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 7877 } 7878 } 7879 } 7880 return res; 7881 } 7882 7883 /** 7884 * Derive the value of the {@code cpuAbiOverride} based on the provided 7885 * value and an optional stored value from the package settings. 7886 */ 7887 private static String deriveAbiOverride(String abiOverride, PackageSetting settings) { 7888 String cpuAbiOverride = null; 7889 7890 if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) { 7891 cpuAbiOverride = null; 7892 } else if (abiOverride != null) { 7893 cpuAbiOverride = abiOverride; 7894 } else if (settings != null) { 7895 cpuAbiOverride = settings.cpuAbiOverrideString; 7896 } 7897 7898 return cpuAbiOverride; 7899 } 7900 7901 private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg, 7902 final int policyFlags, int scanFlags, long currentTime, UserHandle user) 7903 throws PackageManagerException { 7904 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage"); 7905 // If the package has children and this is the first dive in the function 7906 // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see 7907 // whether all packages (parent and children) would be successfully scanned 7908 // before the actual scan since scanning mutates internal state and we want 7909 // to atomically install the package and its children. 7910 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 7911 if (pkg.childPackages != null && pkg.childPackages.size() > 0) { 7912 scanFlags |= SCAN_CHECK_ONLY; 7913 } 7914 } else { 7915 scanFlags &= ~SCAN_CHECK_ONLY; 7916 } 7917 7918 final PackageParser.Package scannedPkg; 7919 try { 7920 // Scan the parent 7921 scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags, currentTime, user); 7922 // Scan the children 7923 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7924 for (int i = 0; i < childCount; i++) { 7925 PackageParser.Package childPkg = pkg.childPackages.get(i); 7926 scanPackageLI(childPkg, policyFlags, 7927 scanFlags, currentTime, user); 7928 } 7929 } finally { 7930 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7931 } 7932 7933 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 7934 return scanPackageTracedLI(pkg, policyFlags, scanFlags, currentTime, user); 7935 } 7936 7937 return scannedPkg; 7938 } 7939 7940 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags, 7941 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 7942 boolean success = false; 7943 try { 7944 final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags, 7945 currentTime, user); 7946 success = true; 7947 return res; 7948 } finally { 7949 if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) { 7950 // DELETE_DATA_ON_FAILURES is only used by frozen paths 7951 destroyAppDataLIF(pkg, UserHandle.USER_ALL, 7952 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 7953 destroyAppProfilesLIF(pkg, UserHandle.USER_ALL); 7954 } 7955 } 7956 } 7957 7958 /** 7959 * Returns {@code true} if the given file contains code. Otherwise {@code false}. 7960 */ 7961 private static boolean apkHasCode(String fileName) { 7962 StrictJarFile jarFile = null; 7963 try { 7964 jarFile = new StrictJarFile(fileName, 7965 false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/); 7966 return jarFile.findEntry("classes.dex") != null; 7967 } catch (IOException ignore) { 7968 } finally { 7969 try { 7970 if (jarFile != null) { 7971 jarFile.close(); 7972 } 7973 } catch (IOException ignore) {} 7974 } 7975 return false; 7976 } 7977 7978 /** 7979 * Enforces code policy for the package. This ensures that if an APK has 7980 * declared hasCode="true" in its manifest that the APK actually contains 7981 * code. 7982 * 7983 * @throws PackageManagerException If bytecode could not be found when it should exist 7984 */ 7985 private static void enforceCodePolicy(PackageParser.Package pkg) 7986 throws PackageManagerException { 7987 final boolean shouldHaveCode = 7988 (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0; 7989 if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) { 7990 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 7991 "Package " + pkg.baseCodePath + " code is missing"); 7992 } 7993 7994 if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) { 7995 for (int i = 0; i < pkg.splitCodePaths.length; i++) { 7996 final boolean splitShouldHaveCode = 7997 (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0; 7998 if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) { 7999 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 8000 "Package " + pkg.splitCodePaths[i] + " code is missing"); 8001 } 8002 } 8003 } 8004 } 8005 8006 private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, 8007 final int policyFlags, final int scanFlags, long currentTime, UserHandle user) 8008 throws PackageManagerException { 8009 final File scanFile = new File(pkg.codePath); 8010 if (pkg.applicationInfo.getCodePath() == null || 8011 pkg.applicationInfo.getResourcePath() == null) { 8012 // Bail out. The resource and code paths haven't been set. 8013 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 8014 "Code and resource paths haven't been set correctly"); 8015 } 8016 8017 // Apply policy 8018 if ((policyFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 8019 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; 8020 if (pkg.applicationInfo.isDirectBootAware()) { 8021 // we're direct boot aware; set for all components 8022 for (PackageParser.Service s : pkg.services) { 8023 s.info.encryptionAware = s.info.directBootAware = true; 8024 } 8025 for (PackageParser.Provider p : pkg.providers) { 8026 p.info.encryptionAware = p.info.directBootAware = true; 8027 } 8028 for (PackageParser.Activity a : pkg.activities) { 8029 a.info.encryptionAware = a.info.directBootAware = true; 8030 } 8031 for (PackageParser.Activity r : pkg.receivers) { 8032 r.info.encryptionAware = r.info.directBootAware = true; 8033 } 8034 } 8035 } else { 8036 // Only allow system apps to be flagged as core apps. 8037 pkg.coreApp = false; 8038 // clear flags not applicable to regular apps 8039 pkg.applicationInfo.privateFlags &= 8040 ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE; 8041 pkg.applicationInfo.privateFlags &= 8042 ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE; 8043 } 8044 pkg.mTrustedOverlay = (policyFlags&PackageParser.PARSE_TRUSTED_OVERLAY) != 0; 8045 8046 if ((policyFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) { 8047 pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 8048 } 8049 8050 if ((policyFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) { 8051 enforceCodePolicy(pkg); 8052 } 8053 8054 if (mCustomResolverComponentName != null && 8055 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) { 8056 setUpCustomResolverActivity(pkg); 8057 } 8058 8059 if (pkg.packageName.equals("android")) { 8060 synchronized (mPackages) { 8061 if (mAndroidApplication != null) { 8062 Slog.w(TAG, "*************************************************"); 8063 Slog.w(TAG, "Core android package being redefined. Skipping."); 8064 Slog.w(TAG, " file=" + scanFile); 8065 Slog.w(TAG, "*************************************************"); 8066 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 8067 "Core android package being redefined. Skipping."); 8068 } 8069 8070 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 8071 // Set up information for our fall-back user intent resolution activity. 8072 mPlatformPackage = pkg; 8073 pkg.mVersionCode = mSdkVersion; 8074 mAndroidApplication = pkg.applicationInfo; 8075 8076 if (!mResolverReplaced) { 8077 mResolveActivity.applicationInfo = mAndroidApplication; 8078 mResolveActivity.name = ResolverActivity.class.getName(); 8079 mResolveActivity.packageName = mAndroidApplication.packageName; 8080 mResolveActivity.processName = "system:ui"; 8081 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 8082 mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER; 8083 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS; 8084 mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert; 8085 mResolveActivity.exported = true; 8086 mResolveActivity.enabled = true; 8087 mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE; 8088 mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE 8089 | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE 8090 | ActivityInfo.CONFIG_SCREEN_LAYOUT 8091 | ActivityInfo.CONFIG_ORIENTATION 8092 | ActivityInfo.CONFIG_KEYBOARD 8093 | ActivityInfo.CONFIG_KEYBOARD_HIDDEN; 8094 mResolveInfo.activityInfo = mResolveActivity; 8095 mResolveInfo.priority = 0; 8096 mResolveInfo.preferredOrder = 0; 8097 mResolveInfo.match = 0; 8098 mResolveComponentName = new ComponentName( 8099 mAndroidApplication.packageName, mResolveActivity.name); 8100 } 8101 } 8102 } 8103 } 8104 8105 if (DEBUG_PACKAGE_SCANNING) { 8106 if ((policyFlags & PackageParser.PARSE_CHATTY) != 0) 8107 Log.d(TAG, "Scanning package " + pkg.packageName); 8108 } 8109 8110 synchronized (mPackages) { 8111 if (mPackages.containsKey(pkg.packageName) 8112 || mSharedLibraries.containsKey(pkg.packageName)) { 8113 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 8114 "Application package " + pkg.packageName 8115 + " already installed. Skipping duplicate."); 8116 } 8117 8118 // If we're only installing presumed-existing packages, require that the 8119 // scanned APK is both already known and at the path previously established 8120 // for it. Previously unknown packages we pick up normally, but if we have an 8121 // a priori expectation about this package's install presence, enforce it. 8122 // With a singular exception for new system packages. When an OTA contains 8123 // a new system package, we allow the codepath to change from a system location 8124 // to the user-installed location. If we don't allow this change, any newer, 8125 // user-installed version of the application will be ignored. 8126 if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) { 8127 if (mExpectingBetter.containsKey(pkg.packageName)) { 8128 logCriticalInfo(Log.WARN, 8129 "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName); 8130 } else { 8131 PackageSetting known = mSettings.peekPackageLPr(pkg.packageName); 8132 if (known != null) { 8133 if (DEBUG_PACKAGE_SCANNING) { 8134 Log.d(TAG, "Examining " + pkg.codePath 8135 + " and requiring known paths " + known.codePathString 8136 + " & " + known.resourcePathString); 8137 } 8138 if (!pkg.applicationInfo.getCodePath().equals(known.codePathString) 8139 || !pkg.applicationInfo.getResourcePath().equals( 8140 known.resourcePathString)) { 8141 throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED, 8142 "Application package " + pkg.packageName 8143 + " found at " + pkg.applicationInfo.getCodePath() 8144 + " but expected at " + known.codePathString 8145 + "; ignoring."); 8146 } 8147 } 8148 } 8149 } 8150 } 8151 8152 // Initialize package source and resource directories 8153 File destCodeFile = new File(pkg.applicationInfo.getCodePath()); 8154 File destResourceFile = new File(pkg.applicationInfo.getResourcePath()); 8155 8156 SharedUserSetting suid = null; 8157 PackageSetting pkgSetting = null; 8158 8159 if (!isSystemApp(pkg)) { 8160 // Only system apps can use these features. 8161 pkg.mOriginalPackages = null; 8162 pkg.mRealPackage = null; 8163 pkg.mAdoptPermissions = null; 8164 } 8165 8166 // Getting the package setting may have a side-effect, so if we 8167 // are only checking if scan would succeed, stash a copy of the 8168 // old setting to restore at the end. 8169 PackageSetting nonMutatedPs = null; 8170 8171 // writer 8172 synchronized (mPackages) { 8173 if (pkg.mSharedUserId != null) { 8174 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, true); 8175 if (suid == null) { 8176 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 8177 "Creating application package " + pkg.packageName 8178 + " for shared user failed"); 8179 } 8180 if (DEBUG_PACKAGE_SCANNING) { 8181 if ((policyFlags & PackageParser.PARSE_CHATTY) != 0) 8182 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId 8183 + "): packages=" + suid.packages); 8184 } 8185 } 8186 8187 // Check if we are renaming from an original package name. 8188 PackageSetting origPackage = null; 8189 String realName = null; 8190 if (pkg.mOriginalPackages != null) { 8191 // This package may need to be renamed to a previously 8192 // installed name. Let's check on that... 8193 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage); 8194 if (pkg.mOriginalPackages.contains(renamed)) { 8195 // This package had originally been installed as the 8196 // original name, and we have already taken care of 8197 // transitioning to the new one. Just update the new 8198 // one to continue using the old name. 8199 realName = pkg.mRealPackage; 8200 if (!pkg.packageName.equals(renamed)) { 8201 // Callers into this function may have already taken 8202 // care of renaming the package; only do it here if 8203 // it is not already done. 8204 pkg.setPackageName(renamed); 8205 } 8206 8207 } else { 8208 for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) { 8209 if ((origPackage = mSettings.peekPackageLPr( 8210 pkg.mOriginalPackages.get(i))) != null) { 8211 // We do have the package already installed under its 8212 // original name... should we use it? 8213 if (!verifyPackageUpdateLPr(origPackage, pkg)) { 8214 // New package is not compatible with original. 8215 origPackage = null; 8216 continue; 8217 } else if (origPackage.sharedUser != null) { 8218 // Make sure uid is compatible between packages. 8219 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) { 8220 Slog.w(TAG, "Unable to migrate data from " + origPackage.name 8221 + " to " + pkg.packageName + ": old uid " 8222 + origPackage.sharedUser.name 8223 + " differs from " + pkg.mSharedUserId); 8224 origPackage = null; 8225 continue; 8226 } 8227 // TODO: Add case when shared user id is added [b/28144775] 8228 } else { 8229 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package " 8230 + pkg.packageName + " to old name " + origPackage.name); 8231 } 8232 break; 8233 } 8234 } 8235 } 8236 } 8237 8238 if (mTransferedPackages.contains(pkg.packageName)) { 8239 Slog.w(TAG, "Package " + pkg.packageName 8240 + " was transferred to another, but its .apk remains"); 8241 } 8242 8243 // See comments in nonMutatedPs declaration 8244 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 8245 PackageSetting foundPs = mSettings.peekPackageLPr(pkg.packageName); 8246 if (foundPs != null) { 8247 nonMutatedPs = new PackageSetting(foundPs); 8248 } 8249 } 8250 8251 // Just create the setting, don't add it yet. For already existing packages 8252 // the PkgSetting exists already and doesn't have to be created. 8253 pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile, 8254 destResourceFile, pkg.applicationInfo.nativeLibraryRootDir, 8255 pkg.applicationInfo.primaryCpuAbi, 8256 pkg.applicationInfo.secondaryCpuAbi, 8257 pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, 8258 user, false); 8259 if (pkgSetting == null) { 8260 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 8261 "Creating application package " + pkg.packageName + " failed"); 8262 } 8263 8264 if (pkgSetting.origPackage != null) { 8265 // If we are first transitioning from an original package, 8266 // fix up the new package's name now. We need to do this after 8267 // looking up the package under its new name, so getPackageLP 8268 // can take care of fiddling things correctly. 8269 pkg.setPackageName(origPackage.name); 8270 8271 // File a report about this. 8272 String msg = "New package " + pkgSetting.realName 8273 + " renamed to replace old package " + pkgSetting.name; 8274 reportSettingsProblem(Log.WARN, msg); 8275 8276 // Make a note of it. 8277 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 8278 mTransferedPackages.add(origPackage.name); 8279 } 8280 8281 // No longer need to retain this. 8282 pkgSetting.origPackage = null; 8283 } 8284 8285 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) { 8286 // Make a note of it. 8287 mTransferedPackages.add(pkg.packageName); 8288 } 8289 8290 if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) { 8291 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 8292 } 8293 8294 if ((policyFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 8295 // Check all shared libraries and map to their actual file path. 8296 // We only do this here for apps not on a system dir, because those 8297 // are the only ones that can fail an install due to this. We 8298 // will take care of the system apps by updating all of their 8299 // library paths after the scan is done. 8300 updateSharedLibrariesLPw(pkg, null); 8301 } 8302 8303 if (mFoundPolicyFile) { 8304 SELinuxMMAC.assignSeinfoValue(pkg); 8305 } 8306 8307 pkg.applicationInfo.uid = pkgSetting.appId; 8308 pkg.mExtras = pkgSetting; 8309 if (shouldCheckUpgradeKeySetLP(pkgSetting, scanFlags)) { 8310 if (checkUpgradeKeySetLP(pkgSetting, pkg)) { 8311 // We just determined the app is signed correctly, so bring 8312 // over the latest parsed certs. 8313 pkgSetting.signatures.mSignatures = pkg.mSignatures; 8314 } else { 8315 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 8316 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 8317 "Package " + pkg.packageName + " upgrade keys do not match the " 8318 + "previously installed version"); 8319 } else { 8320 pkgSetting.signatures.mSignatures = pkg.mSignatures; 8321 String msg = "System package " + pkg.packageName 8322 + " signature changed; retaining data."; 8323 reportSettingsProblem(Log.WARN, msg); 8324 } 8325 } 8326 } else { 8327 try { 8328 verifySignaturesLP(pkgSetting, pkg); 8329 // We just determined the app is signed correctly, so bring 8330 // over the latest parsed certs. 8331 pkgSetting.signatures.mSignatures = pkg.mSignatures; 8332 } catch (PackageManagerException e) { 8333 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 8334 throw e; 8335 } 8336 // The signature has changed, but this package is in the system 8337 // image... let's recover! 8338 pkgSetting.signatures.mSignatures = pkg.mSignatures; 8339 // However... if this package is part of a shared user, but it 8340 // doesn't match the signature of the shared user, let's fail. 8341 // What this means is that you can't change the signatures 8342 // associated with an overall shared user, which doesn't seem all 8343 // that unreasonable. 8344 if (pkgSetting.sharedUser != null) { 8345 if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 8346 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { 8347 throw new PackageManagerException( 8348 INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES, 8349 "Signature mismatch for shared user: " 8350 + pkgSetting.sharedUser); 8351 } 8352 } 8353 // File a report about this. 8354 String msg = "System package " + pkg.packageName 8355 + " signature changed; retaining data."; 8356 reportSettingsProblem(Log.WARN, msg); 8357 } 8358 } 8359 // Verify that this new package doesn't have any content providers 8360 // that conflict with existing packages. Only do this if the 8361 // package isn't already installed, since we don't want to break 8362 // things that are installed. 8363 if ((scanFlags & SCAN_NEW_INSTALL) != 0) { 8364 final int N = pkg.providers.size(); 8365 int i; 8366 for (i=0; i<N; i++) { 8367 PackageParser.Provider p = pkg.providers.get(i); 8368 if (p.info.authority != null) { 8369 String names[] = p.info.authority.split(";"); 8370 for (int j = 0; j < names.length; j++) { 8371 if (mProvidersByAuthority.containsKey(names[j])) { 8372 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 8373 final String otherPackageName = 8374 ((other != null && other.getComponentName() != null) ? 8375 other.getComponentName().getPackageName() : "?"); 8376 throw new PackageManagerException( 8377 INSTALL_FAILED_CONFLICTING_PROVIDER, 8378 "Can't install because provider name " + names[j] 8379 + " (in package " + pkg.applicationInfo.packageName 8380 + ") is already used by " + otherPackageName); 8381 } 8382 } 8383 } 8384 } 8385 } 8386 8387 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) { 8388 // This package wants to adopt ownership of permissions from 8389 // another package. 8390 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) { 8391 final String origName = pkg.mAdoptPermissions.get(i); 8392 final PackageSetting orig = mSettings.peekPackageLPr(origName); 8393 if (orig != null) { 8394 if (verifyPackageUpdateLPr(orig, pkg)) { 8395 Slog.i(TAG, "Adopting permissions from " + origName + " to " 8396 + pkg.packageName); 8397 mSettings.transferPermissionsLPw(origName, pkg.packageName); 8398 } 8399 } 8400 } 8401 } 8402 } 8403 8404 final String pkgName = pkg.packageName; 8405 8406 final long scanFileTime = getLastModifiedTime(pkg, scanFile); 8407 final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0; 8408 pkg.applicationInfo.processName = fixProcessName( 8409 pkg.applicationInfo.packageName, 8410 pkg.applicationInfo.processName, 8411 pkg.applicationInfo.uid); 8412 8413 if (pkg != mPlatformPackage) { 8414 // Get all of our default paths setup 8415 pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM); 8416 } 8417 8418 final String path = scanFile.getPath(); 8419 final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting); 8420 8421 if ((scanFlags & SCAN_NEW_INSTALL) == 0) { 8422 derivePackageAbi(pkg, scanFile, cpuAbiOverride, true /* extract libs */); 8423 8424 // Some system apps still use directory structure for native libraries 8425 // in which case we might end up not detecting abi solely based on apk 8426 // structure. Try to detect abi based on directory structure. 8427 if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() && 8428 pkg.applicationInfo.primaryCpuAbi == null) { 8429 setBundledAppAbisAndRoots(pkg, pkgSetting); 8430 setNativeLibraryPaths(pkg); 8431 } 8432 8433 } else { 8434 if ((scanFlags & SCAN_MOVE) != 0) { 8435 // We haven't run dex-opt for this move (since we've moved the compiled output too) 8436 // but we already have this packages package info in the PackageSetting. We just 8437 // use that and derive the native library path based on the new codepath. 8438 pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString; 8439 pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString; 8440 } 8441 8442 // Set native library paths again. For moves, the path will be updated based on the 8443 // ABIs we've determined above. For non-moves, the path will be updated based on the 8444 // ABIs we determined during compilation, but the path will depend on the final 8445 // package path (after the rename away from the stage path). 8446 setNativeLibraryPaths(pkg); 8447 } 8448 8449 // This is a special case for the "system" package, where the ABI is 8450 // dictated by the zygote configuration (and init.rc). We should keep track 8451 // of this ABI so that we can deal with "normal" applications that run under 8452 // the same UID correctly. 8453 if (mPlatformPackage == pkg) { 8454 pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ? 8455 Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]; 8456 } 8457 8458 // If there's a mismatch between the abi-override in the package setting 8459 // and the abiOverride specified for the install. Warn about this because we 8460 // would've already compiled the app without taking the package setting into 8461 // account. 8462 if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) { 8463 if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) { 8464 Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride + 8465 " for package " + pkg.packageName); 8466 } 8467 } 8468 8469 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 8470 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 8471 pkgSetting.cpuAbiOverrideString = cpuAbiOverride; 8472 8473 // Copy the derived override back to the parsed package, so that we can 8474 // update the package settings accordingly. 8475 pkg.cpuAbiOverride = cpuAbiOverride; 8476 8477 if (DEBUG_ABI_SELECTION) { 8478 Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName 8479 + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa=" 8480 + pkg.applicationInfo.nativeLibraryRootRequiresIsa); 8481 } 8482 8483 // Push the derived path down into PackageSettings so we know what to 8484 // clean up at uninstall time. 8485 pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir; 8486 8487 if (DEBUG_ABI_SELECTION) { 8488 Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" + 8489 " primary=" + pkg.applicationInfo.primaryCpuAbi + 8490 " secondary=" + pkg.applicationInfo.secondaryCpuAbi); 8491 } 8492 8493 if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) { 8494 // We don't do this here during boot because we can do it all 8495 // at once after scanning all existing packages. 8496 // 8497 // We also do this *before* we perform dexopt on this package, so that 8498 // we can avoid redundant dexopts, and also to make sure we've got the 8499 // code and package path correct. 8500 adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, 8501 pkg, true /* boot complete */); 8502 } 8503 8504 if (mFactoryTest && pkg.requestedPermissions.contains( 8505 android.Manifest.permission.FACTORY_TEST)) { 8506 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST; 8507 } 8508 8509 if (isSystemApp(pkg)) { 8510 pkgSetting.isOrphaned = true; 8511 } 8512 8513 ArrayList<PackageParser.Package> clientLibPkgs = null; 8514 8515 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 8516 if (nonMutatedPs != null) { 8517 synchronized (mPackages) { 8518 mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs); 8519 } 8520 } 8521 return pkg; 8522 } 8523 8524 // Only privileged apps and updated privileged apps can add child packages. 8525 if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) { 8526 if ((policyFlags & PARSE_IS_PRIVILEGED) == 0) { 8527 throw new PackageManagerException("Only privileged apps and updated " 8528 + "privileged apps can add child packages. Ignoring package " 8529 + pkg.packageName); 8530 } 8531 final int childCount = pkg.childPackages.size(); 8532 for (int i = 0; i < childCount; i++) { 8533 PackageParser.Package childPkg = pkg.childPackages.get(i); 8534 if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName, 8535 childPkg.packageName)) { 8536 throw new PackageManagerException("Cannot override a child package of " 8537 + "another disabled system app. Ignoring package " + pkg.packageName); 8538 } 8539 } 8540 } 8541 8542 // writer 8543 synchronized (mPackages) { 8544 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 8545 // Only system apps can add new shared libraries. 8546 if (pkg.libraryNames != null) { 8547 for (int i=0; i<pkg.libraryNames.size(); i++) { 8548 String name = pkg.libraryNames.get(i); 8549 boolean allowed = false; 8550 if (pkg.isUpdatedSystemApp()) { 8551 // New library entries can only be added through the 8552 // system image. This is important to get rid of a lot 8553 // of nasty edge cases: for example if we allowed a non- 8554 // system update of the app to add a library, then uninstalling 8555 // the update would make the library go away, and assumptions 8556 // we made such as through app install filtering would now 8557 // have allowed apps on the device which aren't compatible 8558 // with it. Better to just have the restriction here, be 8559 // conservative, and create many fewer cases that can negatively 8560 // impact the user experience. 8561 final PackageSetting sysPs = mSettings 8562 .getDisabledSystemPkgLPr(pkg.packageName); 8563 if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) { 8564 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) { 8565 if (name.equals(sysPs.pkg.libraryNames.get(j))) { 8566 allowed = true; 8567 break; 8568 } 8569 } 8570 } 8571 } else { 8572 allowed = true; 8573 } 8574 if (allowed) { 8575 if (!mSharedLibraries.containsKey(name)) { 8576 mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName)); 8577 } else if (!name.equals(pkg.packageName)) { 8578 Slog.w(TAG, "Package " + pkg.packageName + " library " 8579 + name + " already exists; skipping"); 8580 } 8581 } else { 8582 Slog.w(TAG, "Package " + pkg.packageName + " declares lib " 8583 + name + " that is not declared on system image; skipping"); 8584 } 8585 } 8586 if ((scanFlags & SCAN_BOOTING) == 0) { 8587 // If we are not booting, we need to update any applications 8588 // that are clients of our shared library. If we are booting, 8589 // this will all be done once the scan is complete. 8590 clientLibPkgs = updateAllSharedLibrariesLPw(pkg); 8591 } 8592 } 8593 } 8594 } 8595 8596 if ((scanFlags & SCAN_BOOTING) != 0) { 8597 // No apps can run during boot scan, so they don't need to be frozen 8598 } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) { 8599 // Caller asked to not kill app, so it's probably not frozen 8600 } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) { 8601 // Caller asked us to ignore frozen check for some reason; they 8602 // probably didn't know the package name 8603 } else { 8604 // We're doing major surgery on this package, so it better be frozen 8605 // right now to keep it from launching 8606 checkPackageFrozen(pkgName); 8607 } 8608 8609 // Also need to kill any apps that are dependent on the library. 8610 if (clientLibPkgs != null) { 8611 for (int i=0; i<clientLibPkgs.size(); i++) { 8612 PackageParser.Package clientPkg = clientLibPkgs.get(i); 8613 killApplication(clientPkg.applicationInfo.packageName, 8614 clientPkg.applicationInfo.uid, "update lib"); 8615 } 8616 } 8617 8618 // Make sure we're not adding any bogus keyset info 8619 KeySetManagerService ksms = mSettings.mKeySetManagerService; 8620 ksms.assertScannedPackageValid(pkg); 8621 8622 // writer 8623 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 8624 8625 boolean createIdmapFailed = false; 8626 synchronized (mPackages) { 8627 // We don't expect installation to fail beyond this point 8628 8629 if (pkgSetting.pkg != null) { 8630 // Note that |user| might be null during the initial boot scan. If a codePath 8631 // for an app has changed during a boot scan, it's due to an app update that's 8632 // part of the system partition and marker changes must be applied to all users. 8633 maybeRenameForeignDexMarkers(pkgSetting.pkg, pkg, 8634 (user != null) ? user : UserHandle.ALL); 8635 } 8636 8637 // Add the new setting to mSettings 8638 mSettings.insertPackageSettingLPw(pkgSetting, pkg); 8639 // Add the new setting to mPackages 8640 mPackages.put(pkg.applicationInfo.packageName, pkg); 8641 // Make sure we don't accidentally delete its data. 8642 final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator(); 8643 while (iter.hasNext()) { 8644 PackageCleanItem item = iter.next(); 8645 if (pkgName.equals(item.packageName)) { 8646 iter.remove(); 8647 } 8648 } 8649 8650 // Take care of first install / last update times. 8651 if (currentTime != 0) { 8652 if (pkgSetting.firstInstallTime == 0) { 8653 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime; 8654 } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) { 8655 pkgSetting.lastUpdateTime = currentTime; 8656 } 8657 } else if (pkgSetting.firstInstallTime == 0) { 8658 // We need *something*. Take time time stamp of the file. 8659 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime; 8660 } else if ((policyFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) { 8661 if (scanFileTime != pkgSetting.timeStamp) { 8662 // A package on the system image has changed; consider this 8663 // to be an update. 8664 pkgSetting.lastUpdateTime = scanFileTime; 8665 } 8666 } 8667 8668 // Add the package's KeySets to the global KeySetManagerService 8669 ksms.addScannedPackageLPw(pkg); 8670 8671 int N = pkg.providers.size(); 8672 StringBuilder r = null; 8673 int i; 8674 for (i=0; i<N; i++) { 8675 PackageParser.Provider p = pkg.providers.get(i); 8676 p.info.processName = fixProcessName(pkg.applicationInfo.processName, 8677 p.info.processName, pkg.applicationInfo.uid); 8678 mProviders.addProvider(p); 8679 p.syncable = p.info.isSyncable; 8680 if (p.info.authority != null) { 8681 String names[] = p.info.authority.split(";"); 8682 p.info.authority = null; 8683 for (int j = 0; j < names.length; j++) { 8684 if (j == 1 && p.syncable) { 8685 // We only want the first authority for a provider to possibly be 8686 // syncable, so if we already added this provider using a different 8687 // authority clear the syncable flag. We copy the provider before 8688 // changing it because the mProviders object contains a reference 8689 // to a provider that we don't want to change. 8690 // Only do this for the second authority since the resulting provider 8691 // object can be the same for all future authorities for this provider. 8692 p = new PackageParser.Provider(p); 8693 p.syncable = false; 8694 } 8695 if (!mProvidersByAuthority.containsKey(names[j])) { 8696 mProvidersByAuthority.put(names[j], p); 8697 if (p.info.authority == null) { 8698 p.info.authority = names[j]; 8699 } else { 8700 p.info.authority = p.info.authority + ";" + names[j]; 8701 } 8702 if (DEBUG_PACKAGE_SCANNING) { 8703 if ((policyFlags & PackageParser.PARSE_CHATTY) != 0) 8704 Log.d(TAG, "Registered content provider: " + names[j] 8705 + ", className = " + p.info.name + ", isSyncable = " 8706 + p.info.isSyncable); 8707 } 8708 } else { 8709 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 8710 Slog.w(TAG, "Skipping provider name " + names[j] + 8711 " (in package " + pkg.applicationInfo.packageName + 8712 "): name already used by " 8713 + ((other != null && other.getComponentName() != null) 8714 ? other.getComponentName().getPackageName() : "?")); 8715 } 8716 } 8717 } 8718 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) { 8719 if (r == null) { 8720 r = new StringBuilder(256); 8721 } else { 8722 r.append(' '); 8723 } 8724 r.append(p.info.name); 8725 } 8726 } 8727 if (r != null) { 8728 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r); 8729 } 8730 8731 N = pkg.services.size(); 8732 r = null; 8733 for (i=0; i<N; i++) { 8734 PackageParser.Service s = pkg.services.get(i); 8735 s.info.processName = fixProcessName(pkg.applicationInfo.processName, 8736 s.info.processName, pkg.applicationInfo.uid); 8737 mServices.addService(s); 8738 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) { 8739 if (r == null) { 8740 r = new StringBuilder(256); 8741 } else { 8742 r.append(' '); 8743 } 8744 r.append(s.info.name); 8745 } 8746 } 8747 if (r != null) { 8748 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r); 8749 } 8750 8751 N = pkg.receivers.size(); 8752 r = null; 8753 for (i=0; i<N; i++) { 8754 PackageParser.Activity a = pkg.receivers.get(i); 8755 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 8756 a.info.processName, pkg.applicationInfo.uid); 8757 mReceivers.addActivity(a, "receiver"); 8758 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) { 8759 if (r == null) { 8760 r = new StringBuilder(256); 8761 } else { 8762 r.append(' '); 8763 } 8764 r.append(a.info.name); 8765 } 8766 } 8767 if (r != null) { 8768 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r); 8769 } 8770 8771 N = pkg.activities.size(); 8772 r = null; 8773 for (i=0; i<N; i++) { 8774 PackageParser.Activity a = pkg.activities.get(i); 8775 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 8776 a.info.processName, pkg.applicationInfo.uid); 8777 mActivities.addActivity(a, "activity"); 8778 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) { 8779 if (r == null) { 8780 r = new StringBuilder(256); 8781 } else { 8782 r.append(' '); 8783 } 8784 r.append(a.info.name); 8785 } 8786 } 8787 if (r != null) { 8788 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r); 8789 } 8790 8791 N = pkg.permissionGroups.size(); 8792 r = null; 8793 for (i=0; i<N; i++) { 8794 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i); 8795 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name); 8796 final String curPackageName = cur == null ? null : cur.info.packageName; 8797 final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName); 8798 if (cur == null || isPackageUpdate) { 8799 mPermissionGroups.put(pg.info.name, pg); 8800 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) { 8801 if (r == null) { 8802 r = new StringBuilder(256); 8803 } else { 8804 r.append(' '); 8805 } 8806 if (isPackageUpdate) { 8807 r.append("UPD:"); 8808 } 8809 r.append(pg.info.name); 8810 } 8811 } else { 8812 Slog.w(TAG, "Permission group " + pg.info.name + " from package " 8813 + pg.info.packageName + " ignored: original from " 8814 + cur.info.packageName); 8815 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) { 8816 if (r == null) { 8817 r = new StringBuilder(256); 8818 } else { 8819 r.append(' '); 8820 } 8821 r.append("DUP:"); 8822 r.append(pg.info.name); 8823 } 8824 } 8825 } 8826 if (r != null) { 8827 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permission Groups: " + r); 8828 } 8829 8830 N = pkg.permissions.size(); 8831 r = null; 8832 for (i=0; i<N; i++) { 8833 PackageParser.Permission p = pkg.permissions.get(i); 8834 8835 // Assume by default that we did not install this permission into the system. 8836 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED; 8837 8838 // Now that permission groups have a special meaning, we ignore permission 8839 // groups for legacy apps to prevent unexpected behavior. In particular, 8840 // permissions for one app being granted to someone just becase they happen 8841 // to be in a group defined by another app (before this had no implications). 8842 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) { 8843 p.group = mPermissionGroups.get(p.info.group); 8844 // Warn for a permission in an unknown group. 8845 if (p.info.group != null && p.group == null) { 8846 Slog.w(TAG, "Permission " + p.info.name + " from package " 8847 + p.info.packageName + " in an unknown group " + p.info.group); 8848 } 8849 } 8850 8851 ArrayMap<String, BasePermission> permissionMap = 8852 p.tree ? mSettings.mPermissionTrees 8853 : mSettings.mPermissions; 8854 BasePermission bp = permissionMap.get(p.info.name); 8855 8856 // Allow system apps to redefine non-system permissions 8857 if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) { 8858 final boolean currentOwnerIsSystem = (bp.perm != null 8859 && isSystemApp(bp.perm.owner)); 8860 if (isSystemApp(p.owner)) { 8861 if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) { 8862 // It's a built-in permission and no owner, take ownership now 8863 bp.packageSetting = pkgSetting; 8864 bp.perm = p; 8865 bp.uid = pkg.applicationInfo.uid; 8866 bp.sourcePackage = p.info.packageName; 8867 p.info.flags |= PermissionInfo.FLAG_INSTALLED; 8868 } else if (!currentOwnerIsSystem) { 8869 String msg = "New decl " + p.owner + " of permission " 8870 + p.info.name + " is system; overriding " + bp.sourcePackage; 8871 reportSettingsProblem(Log.WARN, msg); 8872 bp = null; 8873 } 8874 } 8875 } 8876 8877 if (bp == null) { 8878 bp = new BasePermission(p.info.name, p.info.packageName, 8879 BasePermission.TYPE_NORMAL); 8880 permissionMap.put(p.info.name, bp); 8881 } 8882 8883 if (bp.perm == null) { 8884 if (bp.sourcePackage == null 8885 || bp.sourcePackage.equals(p.info.packageName)) { 8886 BasePermission tree = findPermissionTreeLP(p.info.name); 8887 if (tree == null 8888 || tree.sourcePackage.equals(p.info.packageName)) { 8889 bp.packageSetting = pkgSetting; 8890 bp.perm = p; 8891 bp.uid = pkg.applicationInfo.uid; 8892 bp.sourcePackage = p.info.packageName; 8893 p.info.flags |= PermissionInfo.FLAG_INSTALLED; 8894 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) { 8895 if (r == null) { 8896 r = new StringBuilder(256); 8897 } else { 8898 r.append(' '); 8899 } 8900 r.append(p.info.name); 8901 } 8902 } else { 8903 Slog.w(TAG, "Permission " + p.info.name + " from package " 8904 + p.info.packageName + " ignored: base tree " 8905 + tree.name + " is from package " 8906 + tree.sourcePackage); 8907 } 8908 } else { 8909 Slog.w(TAG, "Permission " + p.info.name + " from package " 8910 + p.info.packageName + " ignored: original from " 8911 + bp.sourcePackage); 8912 } 8913 } else if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) { 8914 if (r == null) { 8915 r = new StringBuilder(256); 8916 } else { 8917 r.append(' '); 8918 } 8919 r.append("DUP:"); 8920 r.append(p.info.name); 8921 } 8922 if (bp.perm == p) { 8923 bp.protectionLevel = p.info.protectionLevel; 8924 } 8925 } 8926 8927 if (r != null) { 8928 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permissions: " + r); 8929 } 8930 8931 N = pkg.instrumentation.size(); 8932 r = null; 8933 for (i=0; i<N; i++) { 8934 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 8935 a.info.packageName = pkg.applicationInfo.packageName; 8936 a.info.sourceDir = pkg.applicationInfo.sourceDir; 8937 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir; 8938 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs; 8939 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs; 8940 a.info.dataDir = pkg.applicationInfo.dataDir; 8941 a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir; 8942 a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir; 8943 8944 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir; 8945 a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir; 8946 mInstrumentation.put(a.getComponentName(), a); 8947 if ((policyFlags&PackageParser.PARSE_CHATTY) != 0) { 8948 if (r == null) { 8949 r = new StringBuilder(256); 8950 } else { 8951 r.append(' '); 8952 } 8953 r.append(a.info.name); 8954 } 8955 } 8956 if (r != null) { 8957 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r); 8958 } 8959 8960 if (pkg.protectedBroadcasts != null) { 8961 N = pkg.protectedBroadcasts.size(); 8962 for (i=0; i<N; i++) { 8963 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i)); 8964 } 8965 } 8966 8967 pkgSetting.setTimeStamp(scanFileTime); 8968 8969 // Create idmap files for pairs of (packages, overlay packages). 8970 // Note: "android", ie framework-res.apk, is handled by native layers. 8971 if (pkg.mOverlayTarget != null) { 8972 // This is an overlay package. 8973 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) { 8974 if (!mOverlays.containsKey(pkg.mOverlayTarget)) { 8975 mOverlays.put(pkg.mOverlayTarget, 8976 new ArrayMap<String, PackageParser.Package>()); 8977 } 8978 ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget); 8979 map.put(pkg.packageName, pkg); 8980 PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget); 8981 if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) { 8982 createIdmapFailed = true; 8983 } 8984 } 8985 } else if (mOverlays.containsKey(pkg.packageName) && 8986 !pkg.packageName.equals("android")) { 8987 // This is a regular package, with one or more known overlay packages. 8988 createIdmapsForPackageLI(pkg); 8989 } 8990 } 8991 8992 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 8993 8994 if (createIdmapFailed) { 8995 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 8996 "scanPackageLI failed to createIdmap"); 8997 } 8998 return pkg; 8999 } 9000 9001 private void maybeRenameForeignDexMarkers(PackageParser.Package existing, 9002 PackageParser.Package update, UserHandle user) { 9003 if (existing.applicationInfo == null || update.applicationInfo == null) { 9004 // This isn't due to an app installation. 9005 return; 9006 } 9007 9008 final File oldCodePath = new File(existing.applicationInfo.getCodePath()); 9009 final File newCodePath = new File(update.applicationInfo.getCodePath()); 9010 9011 // The codePath hasn't changed, so there's nothing for us to do. 9012 if (Objects.equals(oldCodePath, newCodePath)) { 9013 return; 9014 } 9015 9016 File canonicalNewCodePath; 9017 try { 9018 canonicalNewCodePath = new File(PackageManagerServiceUtils.realpath(newCodePath)); 9019 } catch (IOException e) { 9020 Slog.w(TAG, "Failed to get canonical path.", e); 9021 return; 9022 } 9023 9024 // This is a bit of a hack. The oldCodePath doesn't exist at this point (because 9025 // we've already renamed / deleted it) so we cannot call realpath on it. Here we assume 9026 // that the last component of the path (i.e, the name) doesn't need canonicalization 9027 // (i.e, that it isn't ".", ".." or a symbolic link). This is a valid assumption for now 9028 // but may change in the future. Hopefully this function won't exist at that point. 9029 final File canonicalOldCodePath = new File(canonicalNewCodePath.getParentFile(), 9030 oldCodePath.getName()); 9031 9032 // Calculate the prefixes of the markers. These are just the paths with "/" replaced 9033 // with "@". 9034 String oldMarkerPrefix = canonicalOldCodePath.getAbsolutePath().replace('/', '@'); 9035 if (!oldMarkerPrefix.endsWith("@")) { 9036 oldMarkerPrefix += "@"; 9037 } 9038 String newMarkerPrefix = canonicalNewCodePath.getAbsolutePath().replace('/', '@'); 9039 if (!newMarkerPrefix.endsWith("@")) { 9040 newMarkerPrefix += "@"; 9041 } 9042 9043 List<String> updatedPaths = update.getAllCodePathsExcludingResourceOnly(); 9044 List<String> markerSuffixes = new ArrayList<String>(updatedPaths.size()); 9045 for (String updatedPath : updatedPaths) { 9046 String updatedPathName = new File(updatedPath).getName(); 9047 markerSuffixes.add(updatedPathName.replace('/', '@')); 9048 } 9049 9050 for (int userId : resolveUserIds(user.getIdentifier())) { 9051 File profileDir = Environment.getDataProfilesDeForeignDexDirectory(userId); 9052 9053 for (String markerSuffix : markerSuffixes) { 9054 File oldForeignUseMark = new File(profileDir, oldMarkerPrefix + markerSuffix); 9055 File newForeignUseMark = new File(profileDir, newMarkerPrefix + markerSuffix); 9056 if (oldForeignUseMark.exists()) { 9057 try { 9058 Os.rename(oldForeignUseMark.getAbsolutePath(), 9059 newForeignUseMark.getAbsolutePath()); 9060 } catch (ErrnoException e) { 9061 Slog.w(TAG, "Failed to rename foreign use marker", e); 9062 oldForeignUseMark.delete(); 9063 } 9064 } 9065 } 9066 } 9067 } 9068 9069 /** 9070 * Derive the ABI of a non-system package located at {@code scanFile}. This information 9071 * is derived purely on the basis of the contents of {@code scanFile} and 9072 * {@code cpuAbiOverride}. 9073 * 9074 * If {@code extractLibs} is true, native libraries are extracted from the app if required. 9075 */ 9076 private void derivePackageAbi(PackageParser.Package pkg, File scanFile, 9077 String cpuAbiOverride, boolean extractLibs) 9078 throws PackageManagerException { 9079 // TODO: We can probably be smarter about this stuff. For installed apps, 9080 // we can calculate this information at install time once and for all. For 9081 // system apps, we can probably assume that this information doesn't change 9082 // after the first boot scan. As things stand, we do lots of unnecessary work. 9083 9084 // Give ourselves some initial paths; we'll come back for another 9085 // pass once we've determined ABI below. 9086 setNativeLibraryPaths(pkg); 9087 9088 // We would never need to extract libs for forward-locked and external packages, 9089 // since the container service will do it for us. We shouldn't attempt to 9090 // extract libs from system app when it was not updated. 9091 if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() || 9092 (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) { 9093 extractLibs = false; 9094 } 9095 9096 final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir; 9097 final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa; 9098 9099 NativeLibraryHelper.Handle handle = null; 9100 try { 9101 handle = NativeLibraryHelper.Handle.create(pkg); 9102 // TODO(multiArch): This can be null for apps that didn't go through the 9103 // usual installation process. We can calculate it again, like we 9104 // do during install time. 9105 // 9106 // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally 9107 // unnecessary. 9108 final File nativeLibraryRoot = new File(nativeLibraryRootStr); 9109 9110 // Null out the abis so that they can be recalculated. 9111 pkg.applicationInfo.primaryCpuAbi = null; 9112 pkg.applicationInfo.secondaryCpuAbi = null; 9113 if (isMultiArch(pkg.applicationInfo)) { 9114 // Warn if we've set an abiOverride for multi-lib packages.. 9115 // By definition, we need to copy both 32 and 64 bit libraries for 9116 // such packages. 9117 if (pkg.cpuAbiOverride != null 9118 && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) { 9119 Slog.w(TAG, "Ignoring abiOverride for multi arch application."); 9120 } 9121 9122 int abi32 = PackageManager.NO_NATIVE_LIBRARIES; 9123 int abi64 = PackageManager.NO_NATIVE_LIBRARIES; 9124 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) { 9125 if (extractLibs) { 9126 abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 9127 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS, 9128 useIsaSpecificSubdirs); 9129 } else { 9130 abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS); 9131 } 9132 } 9133 9134 maybeThrowExceptionForMultiArchCopy( 9135 "Error unpackaging 32 bit native libs for multiarch app.", abi32); 9136 9137 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) { 9138 if (extractLibs) { 9139 abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 9140 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS, 9141 useIsaSpecificSubdirs); 9142 } else { 9143 abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS); 9144 } 9145 } 9146 9147 maybeThrowExceptionForMultiArchCopy( 9148 "Error unpackaging 64 bit native libs for multiarch app.", abi64); 9149 9150 if (abi64 >= 0) { 9151 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64]; 9152 } 9153 9154 if (abi32 >= 0) { 9155 final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32]; 9156 if (abi64 >= 0) { 9157 if (pkg.use32bitAbi) { 9158 pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi; 9159 pkg.applicationInfo.primaryCpuAbi = abi; 9160 } else { 9161 pkg.applicationInfo.secondaryCpuAbi = abi; 9162 } 9163 } else { 9164 pkg.applicationInfo.primaryCpuAbi = abi; 9165 } 9166 } 9167 9168 } else { 9169 String[] abiList = (cpuAbiOverride != null) ? 9170 new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS; 9171 9172 // Enable gross and lame hacks for apps that are built with old 9173 // SDK tools. We must scan their APKs for renderscript bitcode and 9174 // not launch them if it's present. Don't bother checking on devices 9175 // that don't have 64 bit support. 9176 boolean needsRenderScriptOverride = false; 9177 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null && 9178 NativeLibraryHelper.hasRenderscriptBitcode(handle)) { 9179 abiList = Build.SUPPORTED_32_BIT_ABIS; 9180 needsRenderScriptOverride = true; 9181 } 9182 9183 final int copyRet; 9184 if (extractLibs) { 9185 copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 9186 nativeLibraryRoot, abiList, useIsaSpecificSubdirs); 9187 } else { 9188 copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList); 9189 } 9190 9191 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { 9192 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, 9193 "Error unpackaging native libs for app, errorCode=" + copyRet); 9194 } 9195 9196 if (copyRet >= 0) { 9197 pkg.applicationInfo.primaryCpuAbi = abiList[copyRet]; 9198 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) { 9199 pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride; 9200 } else if (needsRenderScriptOverride) { 9201 pkg.applicationInfo.primaryCpuAbi = abiList[0]; 9202 } 9203 } 9204 } catch (IOException ioe) { 9205 Slog.e(TAG, "Unable to get canonical file " + ioe.toString()); 9206 } finally { 9207 IoUtils.closeQuietly(handle); 9208 } 9209 9210 // Now that we've calculated the ABIs and determined if it's an internal app, 9211 // we will go ahead and populate the nativeLibraryPath. 9212 setNativeLibraryPaths(pkg); 9213 } 9214 9215 /** 9216 * Adjusts ABIs for a set of packages belonging to a shared user so that they all match. 9217 * i.e, so that all packages can be run inside a single process if required. 9218 * 9219 * Optionally, callers can pass in a parsed package via {@code newPackage} in which case 9220 * this function will either try and make the ABI for all packages in {@code packagesForUser} 9221 * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match 9222 * the ABI selected for {@code packagesForUser}. This variant is used when installing or 9223 * updating a package that belongs to a shared user. 9224 * 9225 * NOTE: We currently only match for the primary CPU abi string. Matching the secondary 9226 * adds unnecessary complexity. 9227 */ 9228 private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser, 9229 PackageParser.Package scannedPackage, boolean bootComplete) { 9230 String requiredInstructionSet = null; 9231 if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) { 9232 requiredInstructionSet = VMRuntime.getInstructionSet( 9233 scannedPackage.applicationInfo.primaryCpuAbi); 9234 } 9235 9236 PackageSetting requirer = null; 9237 for (PackageSetting ps : packagesForUser) { 9238 // If packagesForUser contains scannedPackage, we skip it. This will happen 9239 // when scannedPackage is an update of an existing package. Without this check, 9240 // we will never be able to change the ABI of any package belonging to a shared 9241 // user, even if it's compatible with other packages. 9242 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 9243 if (ps.primaryCpuAbiString == null) { 9244 continue; 9245 } 9246 9247 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString); 9248 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) { 9249 // We have a mismatch between instruction sets (say arm vs arm64) warn about 9250 // this but there's not much we can do. 9251 String errorMessage = "Instruction set mismatch, " 9252 + ((requirer == null) ? "[caller]" : requirer) 9253 + " requires " + requiredInstructionSet + " whereas " + ps 9254 + " requires " + instructionSet; 9255 Slog.w(TAG, errorMessage); 9256 } 9257 9258 if (requiredInstructionSet == null) { 9259 requiredInstructionSet = instructionSet; 9260 requirer = ps; 9261 } 9262 } 9263 } 9264 9265 if (requiredInstructionSet != null) { 9266 String adjustedAbi; 9267 if (requirer != null) { 9268 // requirer != null implies that either scannedPackage was null or that scannedPackage 9269 // did not require an ABI, in which case we have to adjust scannedPackage to match 9270 // the ABI of the set (which is the same as requirer's ABI) 9271 adjustedAbi = requirer.primaryCpuAbiString; 9272 if (scannedPackage != null) { 9273 scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi; 9274 } 9275 } else { 9276 // requirer == null implies that we're updating all ABIs in the set to 9277 // match scannedPackage. 9278 adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi; 9279 } 9280 9281 for (PackageSetting ps : packagesForUser) { 9282 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 9283 if (ps.primaryCpuAbiString != null) { 9284 continue; 9285 } 9286 9287 ps.primaryCpuAbiString = adjustedAbi; 9288 if (ps.pkg != null && ps.pkg.applicationInfo != null && 9289 !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) { 9290 ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi; 9291 Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi 9292 + " (requirer=" 9293 + (requirer == null ? "null" : requirer.pkg.packageName) 9294 + ", scannedPackage=" 9295 + (scannedPackage != null ? scannedPackage.packageName : "null") 9296 + ")"); 9297 try { 9298 mInstaller.rmdex(ps.codePathString, 9299 getDexCodeInstructionSet(getPreferredInstructionSet())); 9300 } catch (InstallerException ignored) { 9301 } 9302 } 9303 } 9304 } 9305 } 9306 } 9307 9308 private void setUpCustomResolverActivity(PackageParser.Package pkg) { 9309 synchronized (mPackages) { 9310 mResolverReplaced = true; 9311 // Set up information for custom user intent resolution activity. 9312 mResolveActivity.applicationInfo = pkg.applicationInfo; 9313 mResolveActivity.name = mCustomResolverComponentName.getClassName(); 9314 mResolveActivity.packageName = pkg.applicationInfo.packageName; 9315 mResolveActivity.processName = pkg.applicationInfo.packageName; 9316 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 9317 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS | 9318 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 9319 mResolveActivity.theme = 0; 9320 mResolveActivity.exported = true; 9321 mResolveActivity.enabled = true; 9322 mResolveInfo.activityInfo = mResolveActivity; 9323 mResolveInfo.priority = 0; 9324 mResolveInfo.preferredOrder = 0; 9325 mResolveInfo.match = 0; 9326 mResolveComponentName = mCustomResolverComponentName; 9327 Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " + 9328 mResolveComponentName); 9329 } 9330 } 9331 9332 private void setUpEphemeralInstallerActivityLP(ComponentName installerComponent) { 9333 final PackageParser.Package pkg = mPackages.get(installerComponent.getPackageName()); 9334 9335 // Set up information for ephemeral installer activity 9336 mEphemeralInstallerActivity.applicationInfo = pkg.applicationInfo; 9337 mEphemeralInstallerActivity.name = mEphemeralInstallerComponent.getClassName(); 9338 mEphemeralInstallerActivity.packageName = pkg.applicationInfo.packageName; 9339 mEphemeralInstallerActivity.processName = pkg.applicationInfo.packageName; 9340 mEphemeralInstallerActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 9341 mEphemeralInstallerActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS 9342 | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 9343 mEphemeralInstallerActivity.theme = 0; 9344 mEphemeralInstallerActivity.exported = true; 9345 mEphemeralInstallerActivity.enabled = true; 9346 mEphemeralInstallerInfo.activityInfo = mEphemeralInstallerActivity; 9347 mEphemeralInstallerInfo.priority = 0; 9348 mEphemeralInstallerInfo.preferredOrder = 1; 9349 mEphemeralInstallerInfo.isDefault = true; 9350 mEphemeralInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART 9351 | IntentFilter.MATCH_ADJUSTMENT_NORMAL; 9352 9353 if (DEBUG_EPHEMERAL) { 9354 Slog.d(TAG, "Set ephemeral installer activity: " + mEphemeralInstallerComponent); 9355 } 9356 } 9357 9358 private static String calculateBundledApkRoot(final String codePathString) { 9359 final File codePath = new File(codePathString); 9360 final File codeRoot; 9361 if (FileUtils.contains(Environment.getRootDirectory(), codePath)) { 9362 codeRoot = Environment.getRootDirectory(); 9363 } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) { 9364 codeRoot = Environment.getOemDirectory(); 9365 } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) { 9366 codeRoot = Environment.getVendorDirectory(); 9367 } else { 9368 // Unrecognized code path; take its top real segment as the apk root: 9369 // e.g. /something/app/blah.apk => /something 9370 try { 9371 File f = codePath.getCanonicalFile(); 9372 File parent = f.getParentFile(); // non-null because codePath is a file 9373 File tmp; 9374 while ((tmp = parent.getParentFile()) != null) { 9375 f = parent; 9376 parent = tmp; 9377 } 9378 codeRoot = f; 9379 Slog.w(TAG, "Unrecognized code path " 9380 + codePath + " - using " + codeRoot); 9381 } catch (IOException e) { 9382 // Can't canonicalize the code path -- shenanigans? 9383 Slog.w(TAG, "Can't canonicalize code path " + codePath); 9384 return Environment.getRootDirectory().getPath(); 9385 } 9386 } 9387 return codeRoot.getPath(); 9388 } 9389 9390 /** 9391 * Derive and set the location of native libraries for the given package, 9392 * which varies depending on where and how the package was installed. 9393 */ 9394 private void setNativeLibraryPaths(PackageParser.Package pkg) { 9395 final ApplicationInfo info = pkg.applicationInfo; 9396 final String codePath = pkg.codePath; 9397 final File codeFile = new File(codePath); 9398 final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp(); 9399 final boolean asecApp = info.isForwardLocked() || info.isExternalAsec(); 9400 9401 info.nativeLibraryRootDir = null; 9402 info.nativeLibraryRootRequiresIsa = false; 9403 info.nativeLibraryDir = null; 9404 info.secondaryNativeLibraryDir = null; 9405 9406 if (isApkFile(codeFile)) { 9407 // Monolithic install 9408 if (bundledApp) { 9409 // If "/system/lib64/apkname" exists, assume that is the per-package 9410 // native library directory to use; otherwise use "/system/lib/apkname". 9411 final String apkRoot = calculateBundledApkRoot(info.sourceDir); 9412 final boolean is64Bit = VMRuntime.is64BitInstructionSet( 9413 getPrimaryInstructionSet(info)); 9414 9415 // This is a bundled system app so choose the path based on the ABI. 9416 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this 9417 // is just the default path. 9418 final String apkName = deriveCodePathName(codePath); 9419 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME; 9420 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir, 9421 apkName).getAbsolutePath(); 9422 9423 if (info.secondaryCpuAbi != null) { 9424 final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME; 9425 info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot), 9426 secondaryLibDir, apkName).getAbsolutePath(); 9427 } 9428 } else if (asecApp) { 9429 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME) 9430 .getAbsolutePath(); 9431 } else { 9432 final String apkName = deriveCodePathName(codePath); 9433 info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName) 9434 .getAbsolutePath(); 9435 } 9436 9437 info.nativeLibraryRootRequiresIsa = false; 9438 info.nativeLibraryDir = info.nativeLibraryRootDir; 9439 } else { 9440 // Cluster install 9441 info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath(); 9442 info.nativeLibraryRootRequiresIsa = true; 9443 9444 info.nativeLibraryDir = new File(info.nativeLibraryRootDir, 9445 getPrimaryInstructionSet(info)).getAbsolutePath(); 9446 9447 if (info.secondaryCpuAbi != null) { 9448 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir, 9449 VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath(); 9450 } 9451 } 9452 } 9453 9454 /** 9455 * Calculate the abis and roots for a bundled app. These can uniquely 9456 * be determined from the contents of the system partition, i.e whether 9457 * it contains 64 or 32 bit shared libraries etc. We do not validate any 9458 * of this information, and instead assume that the system was built 9459 * sensibly. 9460 */ 9461 private void setBundledAppAbisAndRoots(PackageParser.Package pkg, 9462 PackageSetting pkgSetting) { 9463 final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath()); 9464 9465 // If "/system/lib64/apkname" exists, assume that is the per-package 9466 // native library directory to use; otherwise use "/system/lib/apkname". 9467 final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir); 9468 setBundledAppAbi(pkg, apkRoot, apkName); 9469 // pkgSetting might be null during rescan following uninstall of updates 9470 // to a bundled app, so accommodate that possibility. The settings in 9471 // that case will be established later from the parsed package. 9472 // 9473 // If the settings aren't null, sync them up with what we've just derived. 9474 // note that apkRoot isn't stored in the package settings. 9475 if (pkgSetting != null) { 9476 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 9477 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 9478 } 9479 } 9480 9481 /** 9482 * Deduces the ABI of a bundled app and sets the relevant fields on the 9483 * parsed pkg object. 9484 * 9485 * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem} 9486 * under which system libraries are installed. 9487 * @param apkName the name of the installed package. 9488 */ 9489 private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) { 9490 final File codeFile = new File(pkg.codePath); 9491 9492 final boolean has64BitLibs; 9493 final boolean has32BitLibs; 9494 if (isApkFile(codeFile)) { 9495 // Monolithic install 9496 has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists(); 9497 has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists(); 9498 } else { 9499 // Cluster install 9500 final File rootDir = new File(codeFile, LIB_DIR_NAME); 9501 if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS) 9502 && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) { 9503 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]); 9504 has64BitLibs = (new File(rootDir, isa)).exists(); 9505 } else { 9506 has64BitLibs = false; 9507 } 9508 if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS) 9509 && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) { 9510 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]); 9511 has32BitLibs = (new File(rootDir, isa)).exists(); 9512 } else { 9513 has32BitLibs = false; 9514 } 9515 } 9516 9517 if (has64BitLibs && !has32BitLibs) { 9518 // The package has 64 bit libs, but not 32 bit libs. Its primary 9519 // ABI should be 64 bit. We can safely assume here that the bundled 9520 // native libraries correspond to the most preferred ABI in the list. 9521 9522 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 9523 pkg.applicationInfo.secondaryCpuAbi = null; 9524 } else if (has32BitLibs && !has64BitLibs) { 9525 // The package has 32 bit libs but not 64 bit libs. Its primary 9526 // ABI should be 32 bit. 9527 9528 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 9529 pkg.applicationInfo.secondaryCpuAbi = null; 9530 } else if (has32BitLibs && has64BitLibs) { 9531 // The application has both 64 and 32 bit bundled libraries. We check 9532 // here that the app declares multiArch support, and warn if it doesn't. 9533 // 9534 // We will be lenient here and record both ABIs. The primary will be the 9535 // ABI that's higher on the list, i.e, a device that's configured to prefer 9536 // 64 bit apps will see a 64 bit primary ABI, 9537 9538 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) { 9539 Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch."); 9540 } 9541 9542 if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) { 9543 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 9544 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 9545 } else { 9546 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 9547 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 9548 } 9549 } else { 9550 pkg.applicationInfo.primaryCpuAbi = null; 9551 pkg.applicationInfo.secondaryCpuAbi = null; 9552 } 9553 } 9554 9555 private void killApplication(String pkgName, int appId, String reason) { 9556 killApplication(pkgName, appId, UserHandle.USER_ALL, reason); 9557 } 9558 9559 private void killApplication(String pkgName, int appId, int userId, String reason) { 9560 // Request the ActivityManager to kill the process(only for existing packages) 9561 // so that we do not end up in a confused state while the user is still using the older 9562 // version of the application while the new one gets installed. 9563 final long token = Binder.clearCallingIdentity(); 9564 try { 9565 IActivityManager am = ActivityManagerNative.getDefault(); 9566 if (am != null) { 9567 try { 9568 am.killApplication(pkgName, appId, userId, reason); 9569 } catch (RemoteException e) { 9570 } 9571 } 9572 } finally { 9573 Binder.restoreCallingIdentity(token); 9574 } 9575 } 9576 9577 private void removePackageLI(PackageParser.Package pkg, boolean chatty) { 9578 // Remove the parent package setting 9579 PackageSetting ps = (PackageSetting) pkg.mExtras; 9580 if (ps != null) { 9581 removePackageLI(ps, chatty); 9582 } 9583 // Remove the child package setting 9584 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 9585 for (int i = 0; i < childCount; i++) { 9586 PackageParser.Package childPkg = pkg.childPackages.get(i); 9587 ps = (PackageSetting) childPkg.mExtras; 9588 if (ps != null) { 9589 removePackageLI(ps, chatty); 9590 } 9591 } 9592 } 9593 9594 void removePackageLI(PackageSetting ps, boolean chatty) { 9595 if (DEBUG_INSTALL) { 9596 if (chatty) 9597 Log.d(TAG, "Removing package " + ps.name); 9598 } 9599 9600 // writer 9601 synchronized (mPackages) { 9602 mPackages.remove(ps.name); 9603 final PackageParser.Package pkg = ps.pkg; 9604 if (pkg != null) { 9605 cleanPackageDataStructuresLILPw(pkg, chatty); 9606 } 9607 } 9608 } 9609 9610 void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) { 9611 if (DEBUG_INSTALL) { 9612 if (chatty) 9613 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName); 9614 } 9615 9616 // writer 9617 synchronized (mPackages) { 9618 // Remove the parent package 9619 mPackages.remove(pkg.applicationInfo.packageName); 9620 cleanPackageDataStructuresLILPw(pkg, chatty); 9621 9622 // Remove the child packages 9623 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 9624 for (int i = 0; i < childCount; i++) { 9625 PackageParser.Package childPkg = pkg.childPackages.get(i); 9626 mPackages.remove(childPkg.applicationInfo.packageName); 9627 cleanPackageDataStructuresLILPw(childPkg, chatty); 9628 } 9629 } 9630 } 9631 9632 void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) { 9633 int N = pkg.providers.size(); 9634 StringBuilder r = null; 9635 int i; 9636 for (i=0; i<N; i++) { 9637 PackageParser.Provider p = pkg.providers.get(i); 9638 mProviders.removeProvider(p); 9639 if (p.info.authority == null) { 9640 9641 /* There was another ContentProvider with this authority when 9642 * this app was installed so this authority is null, 9643 * Ignore it as we don't have to unregister the provider. 9644 */ 9645 continue; 9646 } 9647 String names[] = p.info.authority.split(";"); 9648 for (int j = 0; j < names.length; j++) { 9649 if (mProvidersByAuthority.get(names[j]) == p) { 9650 mProvidersByAuthority.remove(names[j]); 9651 if (DEBUG_REMOVE) { 9652 if (chatty) 9653 Log.d(TAG, "Unregistered content provider: " + names[j] 9654 + ", className = " + p.info.name + ", isSyncable = " 9655 + p.info.isSyncable); 9656 } 9657 } 9658 } 9659 if (DEBUG_REMOVE && chatty) { 9660 if (r == null) { 9661 r = new StringBuilder(256); 9662 } else { 9663 r.append(' '); 9664 } 9665 r.append(p.info.name); 9666 } 9667 } 9668 if (r != null) { 9669 if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r); 9670 } 9671 9672 N = pkg.services.size(); 9673 r = null; 9674 for (i=0; i<N; i++) { 9675 PackageParser.Service s = pkg.services.get(i); 9676 mServices.removeService(s); 9677 if (chatty) { 9678 if (r == null) { 9679 r = new StringBuilder(256); 9680 } else { 9681 r.append(' '); 9682 } 9683 r.append(s.info.name); 9684 } 9685 } 9686 if (r != null) { 9687 if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r); 9688 } 9689 9690 N = pkg.receivers.size(); 9691 r = null; 9692 for (i=0; i<N; i++) { 9693 PackageParser.Activity a = pkg.receivers.get(i); 9694 mReceivers.removeActivity(a, "receiver"); 9695 if (DEBUG_REMOVE && chatty) { 9696 if (r == null) { 9697 r = new StringBuilder(256); 9698 } else { 9699 r.append(' '); 9700 } 9701 r.append(a.info.name); 9702 } 9703 } 9704 if (r != null) { 9705 if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r); 9706 } 9707 9708 N = pkg.activities.size(); 9709 r = null; 9710 for (i=0; i<N; i++) { 9711 PackageParser.Activity a = pkg.activities.get(i); 9712 mActivities.removeActivity(a, "activity"); 9713 if (DEBUG_REMOVE && chatty) { 9714 if (r == null) { 9715 r = new StringBuilder(256); 9716 } else { 9717 r.append(' '); 9718 } 9719 r.append(a.info.name); 9720 } 9721 } 9722 if (r != null) { 9723 if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r); 9724 } 9725 9726 N = pkg.permissions.size(); 9727 r = null; 9728 for (i=0; i<N; i++) { 9729 PackageParser.Permission p = pkg.permissions.get(i); 9730 BasePermission bp = mSettings.mPermissions.get(p.info.name); 9731 if (bp == null) { 9732 bp = mSettings.mPermissionTrees.get(p.info.name); 9733 } 9734 if (bp != null && bp.perm == p) { 9735 bp.perm = null; 9736 if (DEBUG_REMOVE && chatty) { 9737 if (r == null) { 9738 r = new StringBuilder(256); 9739 } else { 9740 r.append(' '); 9741 } 9742 r.append(p.info.name); 9743 } 9744 } 9745 if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 9746 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name); 9747 if (appOpPkgs != null) { 9748 appOpPkgs.remove(pkg.packageName); 9749 } 9750 } 9751 } 9752 if (r != null) { 9753 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 9754 } 9755 9756 N = pkg.requestedPermissions.size(); 9757 r = null; 9758 for (i=0; i<N; i++) { 9759 String perm = pkg.requestedPermissions.get(i); 9760 BasePermission bp = mSettings.mPermissions.get(perm); 9761 if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 9762 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm); 9763 if (appOpPkgs != null) { 9764 appOpPkgs.remove(pkg.packageName); 9765 if (appOpPkgs.isEmpty()) { 9766 mAppOpPermissionPackages.remove(perm); 9767 } 9768 } 9769 } 9770 } 9771 if (r != null) { 9772 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 9773 } 9774 9775 N = pkg.instrumentation.size(); 9776 r = null; 9777 for (i=0; i<N; i++) { 9778 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 9779 mInstrumentation.remove(a.getComponentName()); 9780 if (DEBUG_REMOVE && chatty) { 9781 if (r == null) { 9782 r = new StringBuilder(256); 9783 } else { 9784 r.append(' '); 9785 } 9786 r.append(a.info.name); 9787 } 9788 } 9789 if (r != null) { 9790 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r); 9791 } 9792 9793 r = null; 9794 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9795 // Only system apps can hold shared libraries. 9796 if (pkg.libraryNames != null) { 9797 for (i=0; i<pkg.libraryNames.size(); i++) { 9798 String name = pkg.libraryNames.get(i); 9799 SharedLibraryEntry cur = mSharedLibraries.get(name); 9800 if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) { 9801 mSharedLibraries.remove(name); 9802 if (DEBUG_REMOVE && chatty) { 9803 if (r == null) { 9804 r = new StringBuilder(256); 9805 } else { 9806 r.append(' '); 9807 } 9808 r.append(name); 9809 } 9810 } 9811 } 9812 } 9813 } 9814 if (r != null) { 9815 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r); 9816 } 9817 } 9818 9819 private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) { 9820 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) { 9821 if (pkgInfo.permissions.get(i).info.name.equals(perm)) { 9822 return true; 9823 } 9824 } 9825 return false; 9826 } 9827 9828 static final int UPDATE_PERMISSIONS_ALL = 1<<0; 9829 static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1; 9830 static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2; 9831 9832 private void updatePermissionsLPw(PackageParser.Package pkg, int flags) { 9833 // Update the parent permissions 9834 updatePermissionsLPw(pkg.packageName, pkg, flags); 9835 // Update the child permissions 9836 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 9837 for (int i = 0; i < childCount; i++) { 9838 PackageParser.Package childPkg = pkg.childPackages.get(i); 9839 updatePermissionsLPw(childPkg.packageName, childPkg, flags); 9840 } 9841 } 9842 9843 private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo, 9844 int flags) { 9845 final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null; 9846 updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags); 9847 } 9848 9849 private void updatePermissionsLPw(String changingPkg, 9850 PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) { 9851 // Make sure there are no dangling permission trees. 9852 Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator(); 9853 while (it.hasNext()) { 9854 final BasePermission bp = it.next(); 9855 if (bp.packageSetting == null) { 9856 // We may not yet have parsed the package, so just see if 9857 // we still know about its settings. 9858 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 9859 } 9860 if (bp.packageSetting == null) { 9861 Slog.w(TAG, "Removing dangling permission tree: " + bp.name 9862 + " from package " + bp.sourcePackage); 9863 it.remove(); 9864 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 9865 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 9866 Slog.i(TAG, "Removing old permission tree: " + bp.name 9867 + " from package " + bp.sourcePackage); 9868 flags |= UPDATE_PERMISSIONS_ALL; 9869 it.remove(); 9870 } 9871 } 9872 } 9873 9874 // Make sure all dynamic permissions have been assigned to a package, 9875 // and make sure there are no dangling permissions. 9876 it = mSettings.mPermissions.values().iterator(); 9877 while (it.hasNext()) { 9878 final BasePermission bp = it.next(); 9879 if (bp.type == BasePermission.TYPE_DYNAMIC) { 9880 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name=" 9881 + bp.name + " pkg=" + bp.sourcePackage 9882 + " info=" + bp.pendingInfo); 9883 if (bp.packageSetting == null && bp.pendingInfo != null) { 9884 final BasePermission tree = findPermissionTreeLP(bp.name); 9885 if (tree != null && tree.perm != null) { 9886 bp.packageSetting = tree.packageSetting; 9887 bp.perm = new PackageParser.Permission(tree.perm.owner, 9888 new PermissionInfo(bp.pendingInfo)); 9889 bp.perm.info.packageName = tree.perm.info.packageName; 9890 bp.perm.info.name = bp.name; 9891 bp.uid = tree.uid; 9892 } 9893 } 9894 } 9895 if (bp.packageSetting == null) { 9896 // We may not yet have parsed the package, so just see if 9897 // we still know about its settings. 9898 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 9899 } 9900 if (bp.packageSetting == null) { 9901 Slog.w(TAG, "Removing dangling permission: " + bp.name 9902 + " from package " + bp.sourcePackage); 9903 it.remove(); 9904 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 9905 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 9906 Slog.i(TAG, "Removing old permission: " + bp.name 9907 + " from package " + bp.sourcePackage); 9908 flags |= UPDATE_PERMISSIONS_ALL; 9909 it.remove(); 9910 } 9911 } 9912 } 9913 9914 // Now update the permissions for all packages, in particular 9915 // replace the granted permissions of the system packages. 9916 if ((flags&UPDATE_PERMISSIONS_ALL) != 0) { 9917 for (PackageParser.Package pkg : mPackages.values()) { 9918 if (pkg != pkgInfo) { 9919 // Only replace for packages on requested volume 9920 final String volumeUuid = getVolumeUuidForPackage(pkg); 9921 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0) 9922 && Objects.equals(replaceVolumeUuid, volumeUuid); 9923 grantPermissionsLPw(pkg, replace, changingPkg); 9924 } 9925 } 9926 } 9927 9928 if (pkgInfo != null) { 9929 // Only replace for packages on requested volume 9930 final String volumeUuid = getVolumeUuidForPackage(pkgInfo); 9931 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0) 9932 && Objects.equals(replaceVolumeUuid, volumeUuid); 9933 grantPermissionsLPw(pkgInfo, replace, changingPkg); 9934 } 9935 } 9936 9937 private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace, 9938 String packageOfInterest) { 9939 // IMPORTANT: There are two types of permissions: install and runtime. 9940 // Install time permissions are granted when the app is installed to 9941 // all device users and users added in the future. Runtime permissions 9942 // are granted at runtime explicitly to specific users. Normal and signature 9943 // protected permissions are install time permissions. Dangerous permissions 9944 // are install permissions if the app's target SDK is Lollipop MR1 or older, 9945 // otherwise they are runtime permissions. This function does not manage 9946 // runtime permissions except for the case an app targeting Lollipop MR1 9947 // being upgraded to target a newer SDK, in which case dangerous permissions 9948 // are transformed from install time to runtime ones. 9949 9950 final PackageSetting ps = (PackageSetting) pkg.mExtras; 9951 if (ps == null) { 9952 return; 9953 } 9954 9955 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions"); 9956 9957 PermissionsState permissionsState = ps.getPermissionsState(); 9958 PermissionsState origPermissions = permissionsState; 9959 9960 final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); 9961 9962 boolean runtimePermissionsRevoked = false; 9963 int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY; 9964 9965 boolean changedInstallPermission = false; 9966 9967 if (replace) { 9968 ps.installPermissionsFixed = false; 9969 if (!ps.isSharedUser()) { 9970 origPermissions = new PermissionsState(permissionsState); 9971 permissionsState.reset(); 9972 } else { 9973 // We need to know only about runtime permission changes since the 9974 // calling code always writes the install permissions state but 9975 // the runtime ones are written only if changed. The only cases of 9976 // changed runtime permissions here are promotion of an install to 9977 // runtime and revocation of a runtime from a shared user. 9978 changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw( 9979 ps.sharedUser, UserManagerService.getInstance().getUserIds()); 9980 if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) { 9981 runtimePermissionsRevoked = true; 9982 } 9983 } 9984 } 9985 9986 permissionsState.setGlobalGids(mGlobalGids); 9987 9988 final int N = pkg.requestedPermissions.size(); 9989 for (int i=0; i<N; i++) { 9990 final String name = pkg.requestedPermissions.get(i); 9991 final BasePermission bp = mSettings.mPermissions.get(name); 9992 9993 if (DEBUG_INSTALL) { 9994 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp); 9995 } 9996 9997 if (bp == null || bp.packageSetting == null) { 9998 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 9999 Slog.w(TAG, "Unknown permission " + name 10000 + " in package " + pkg.packageName); 10001 } 10002 continue; 10003 } 10004 10005 final String perm = bp.name; 10006 boolean allowedSig = false; 10007 int grant = GRANT_DENIED; 10008 10009 // Keep track of app op permissions. 10010 if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 10011 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name); 10012 if (pkgs == null) { 10013 pkgs = new ArraySet<>(); 10014 mAppOpPermissionPackages.put(bp.name, pkgs); 10015 } 10016 pkgs.add(pkg.packageName); 10017 } 10018 10019 final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; 10020 final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion 10021 >= Build.VERSION_CODES.M; 10022 switch (level) { 10023 case PermissionInfo.PROTECTION_NORMAL: { 10024 // For all apps normal permissions are install time ones. 10025 grant = GRANT_INSTALL; 10026 } break; 10027 10028 case PermissionInfo.PROTECTION_DANGEROUS: { 10029 // If a permission review is required for legacy apps we represent 10030 // their permissions as always granted runtime ones since we need 10031 // to keep the review required permission flag per user while an 10032 // install permission's state is shared across all users. 10033 if (!appSupportsRuntimePermissions && !mPermissionReviewRequired 10034 && !Build.PERMISSIONS_REVIEW_REQUIRED) { 10035 // For legacy apps dangerous permissions are install time ones. 10036 grant = GRANT_INSTALL; 10037 } else if (origPermissions.hasInstallPermission(bp.name)) { 10038 // For legacy apps that became modern, install becomes runtime. 10039 grant = GRANT_UPGRADE; 10040 } else if (mPromoteSystemApps 10041 && isSystemApp(ps) 10042 && mExistingSystemPackages.contains(ps.name)) { 10043 // For legacy system apps, install becomes runtime. 10044 // We cannot check hasInstallPermission() for system apps since those 10045 // permissions were granted implicitly and not persisted pre-M. 10046 grant = GRANT_UPGRADE; 10047 } else { 10048 // For modern apps keep runtime permissions unchanged. 10049 grant = GRANT_RUNTIME; 10050 } 10051 } break; 10052 10053 case PermissionInfo.PROTECTION_SIGNATURE: { 10054 // For all apps signature permissions are install time ones. 10055 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions); 10056 if (allowedSig) { 10057 grant = GRANT_INSTALL; 10058 } 10059 } break; 10060 } 10061 10062 if (DEBUG_INSTALL) { 10063 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm); 10064 } 10065 10066 if (grant != GRANT_DENIED) { 10067 if (!isSystemApp(ps) && ps.installPermissionsFixed) { 10068 // If this is an existing, non-system package, then 10069 // we can't add any new permissions to it. 10070 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) { 10071 // Except... if this is a permission that was added 10072 // to the platform (note: need to only do this when 10073 // updating the platform). 10074 if (!isNewPlatformPermissionForPackage(perm, pkg)) { 10075 grant = GRANT_DENIED; 10076 } 10077 } 10078 } 10079 10080 switch (grant) { 10081 case GRANT_INSTALL: { 10082 // Revoke this as runtime permission to handle the case of 10083 // a runtime permission being downgraded to an install one. 10084 // Also in permission review mode we keep dangerous permissions 10085 // for legacy apps 10086 for (int userId : UserManagerService.getInstance().getUserIds()) { 10087 if (origPermissions.getRuntimePermissionState( 10088 bp.name, userId) != null) { 10089 // Revoke the runtime permission and clear the flags. 10090 origPermissions.revokeRuntimePermission(bp, userId); 10091 origPermissions.updatePermissionFlags(bp, userId, 10092 PackageManager.MASK_PERMISSION_FLAGS, 0); 10093 // If we revoked a permission permission, we have to write. 10094 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 10095 changedRuntimePermissionUserIds, userId); 10096 } 10097 } 10098 // Grant an install permission. 10099 if (permissionsState.grantInstallPermission(bp) != 10100 PermissionsState.PERMISSION_OPERATION_FAILURE) { 10101 changedInstallPermission = true; 10102 } 10103 } break; 10104 10105 case GRANT_RUNTIME: { 10106 // Grant previously granted runtime permissions. 10107 for (int userId : UserManagerService.getInstance().getUserIds()) { 10108 PermissionState permissionState = origPermissions 10109 .getRuntimePermissionState(bp.name, userId); 10110 int flags = permissionState != null 10111 ? permissionState.getFlags() : 0; 10112 if (origPermissions.hasRuntimePermission(bp.name, userId)) { 10113 if (permissionsState.grantRuntimePermission(bp, userId) == 10114 PermissionsState.PERMISSION_OPERATION_FAILURE) { 10115 // If we cannot put the permission as it was, we have to write. 10116 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 10117 changedRuntimePermissionUserIds, userId); 10118 } 10119 // If the app supports runtime permissions no need for a review. 10120 if ((mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED) 10121 && appSupportsRuntimePermissions 10122 && (flags & PackageManager 10123 .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) { 10124 flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 10125 // Since we changed the flags, we have to write. 10126 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 10127 changedRuntimePermissionUserIds, userId); 10128 } 10129 } else if ((mPermissionReviewRequired 10130 || Build.PERMISSIONS_REVIEW_REQUIRED) 10131 && !appSupportsRuntimePermissions) { 10132 // For legacy apps that need a permission review, every new 10133 // runtime permission is granted but it is pending a review. 10134 // We also need to review only platform defined runtime 10135 // permissions as these are the only ones the platform knows 10136 // how to disable the API to simulate revocation as legacy 10137 // apps don't expect to run with revoked permissions. 10138 if (PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage)) { 10139 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) { 10140 flags |= FLAG_PERMISSION_REVIEW_REQUIRED; 10141 // We changed the flags, hence have to write. 10142 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 10143 changedRuntimePermissionUserIds, userId); 10144 } 10145 } 10146 if (permissionsState.grantRuntimePermission(bp, userId) 10147 != PermissionsState.PERMISSION_OPERATION_FAILURE) { 10148 // We changed the permission, hence have to write. 10149 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 10150 changedRuntimePermissionUserIds, userId); 10151 } 10152 } 10153 // Propagate the permission flags. 10154 permissionsState.updatePermissionFlags(bp, userId, flags, flags); 10155 } 10156 } break; 10157 10158 case GRANT_UPGRADE: { 10159 // Grant runtime permissions for a previously held install permission. 10160 PermissionState permissionState = origPermissions 10161 .getInstallPermissionState(bp.name); 10162 final int flags = permissionState != null ? permissionState.getFlags() : 0; 10163 10164 if (origPermissions.revokeInstallPermission(bp) 10165 != PermissionsState.PERMISSION_OPERATION_FAILURE) { 10166 // We will be transferring the permission flags, so clear them. 10167 origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL, 10168 PackageManager.MASK_PERMISSION_FLAGS, 0); 10169 changedInstallPermission = true; 10170 } 10171 10172 // If the permission is not to be promoted to runtime we ignore it and 10173 // also its other flags as they are not applicable to install permissions. 10174 if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) { 10175 for (int userId : currentUserIds) { 10176 if (permissionsState.grantRuntimePermission(bp, userId) != 10177 PermissionsState.PERMISSION_OPERATION_FAILURE) { 10178 // Transfer the permission flags. 10179 permissionsState.updatePermissionFlags(bp, userId, 10180 flags, flags); 10181 // If we granted the permission, we have to write. 10182 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 10183 changedRuntimePermissionUserIds, userId); 10184 } 10185 } 10186 } 10187 } break; 10188 10189 default: { 10190 if (packageOfInterest == null 10191 || packageOfInterest.equals(pkg.packageName)) { 10192 Slog.w(TAG, "Not granting permission " + perm 10193 + " to package " + pkg.packageName 10194 + " because it was previously installed without"); 10195 } 10196 } break; 10197 } 10198 } else { 10199 if (permissionsState.revokeInstallPermission(bp) != 10200 PermissionsState.PERMISSION_OPERATION_FAILURE) { 10201 // Also drop the permission flags. 10202 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 10203 PackageManager.MASK_PERMISSION_FLAGS, 0); 10204 changedInstallPermission = true; 10205 Slog.i(TAG, "Un-granting permission " + perm 10206 + " from package " + pkg.packageName 10207 + " (protectionLevel=" + bp.protectionLevel 10208 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 10209 + ")"); 10210 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) { 10211 // Don't print warning for app op permissions, since it is fine for them 10212 // not to be granted, there is a UI for the user to decide. 10213 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 10214 Slog.w(TAG, "Not granting permission " + perm 10215 + " to package " + pkg.packageName 10216 + " (protectionLevel=" + bp.protectionLevel 10217 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 10218 + ")"); 10219 } 10220 } 10221 } 10222 } 10223 10224 if ((changedInstallPermission || replace) && !ps.installPermissionsFixed && 10225 !isSystemApp(ps) || isUpdatedSystemApp(ps)){ 10226 // This is the first that we have heard about this package, so the 10227 // permissions we have now selected are fixed until explicitly 10228 // changed. 10229 ps.installPermissionsFixed = true; 10230 } 10231 10232 // Persist the runtime permissions state for users with changes. If permissions 10233 // were revoked because no app in the shared user declares them we have to 10234 // write synchronously to avoid losing runtime permissions state. 10235 for (int userId : changedRuntimePermissionUserIds) { 10236 mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked); 10237 } 10238 10239 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 10240 } 10241 10242 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) { 10243 boolean allowed = false; 10244 final int NP = PackageParser.NEW_PERMISSIONS.length; 10245 for (int ip=0; ip<NP; ip++) { 10246 final PackageParser.NewPermissionInfo npi 10247 = PackageParser.NEW_PERMISSIONS[ip]; 10248 if (npi.name.equals(perm) 10249 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) { 10250 allowed = true; 10251 Log.i(TAG, "Auto-granting " + perm + " to old pkg " 10252 + pkg.packageName); 10253 break; 10254 } 10255 } 10256 return allowed; 10257 } 10258 10259 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg, 10260 BasePermission bp, PermissionsState origPermissions) { 10261 boolean allowed; 10262 allowed = (compareSignatures( 10263 bp.packageSetting.signatures.mSignatures, pkg.mSignatures) 10264 == PackageManager.SIGNATURE_MATCH) 10265 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures) 10266 == PackageManager.SIGNATURE_MATCH); 10267 if (!allowed && (bp.protectionLevel 10268 & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) { 10269 if (isSystemApp(pkg)) { 10270 // For updated system applications, a system permission 10271 // is granted only if it had been defined by the original application. 10272 if (pkg.isUpdatedSystemApp()) { 10273 final PackageSetting sysPs = mSettings 10274 .getDisabledSystemPkgLPr(pkg.packageName); 10275 if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) { 10276 // If the original was granted this permission, we take 10277 // that grant decision as read and propagate it to the 10278 // update. 10279 if (sysPs.isPrivileged()) { 10280 allowed = true; 10281 } 10282 } else { 10283 // The system apk may have been updated with an older 10284 // version of the one on the data partition, but which 10285 // granted a new system permission that it didn't have 10286 // before. In this case we do want to allow the app to 10287 // now get the new permission if the ancestral apk is 10288 // privileged to get it. 10289 if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) { 10290 for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) { 10291 if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) { 10292 allowed = true; 10293 break; 10294 } 10295 } 10296 } 10297 // Also if a privileged parent package on the system image or any of 10298 // its children requested a privileged permission, the updated child 10299 // packages can also get the permission. 10300 if (pkg.parentPackage != null) { 10301 final PackageSetting disabledSysParentPs = mSettings 10302 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName); 10303 if (disabledSysParentPs != null && disabledSysParentPs.pkg != null 10304 && disabledSysParentPs.isPrivileged()) { 10305 if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) { 10306 allowed = true; 10307 } else if (disabledSysParentPs.pkg.childPackages != null) { 10308 final int count = disabledSysParentPs.pkg.childPackages.size(); 10309 for (int i = 0; i < count; i++) { 10310 PackageParser.Package disabledSysChildPkg = 10311 disabledSysParentPs.pkg.childPackages.get(i); 10312 if (isPackageRequestingPermission(disabledSysChildPkg, 10313 perm)) { 10314 allowed = true; 10315 break; 10316 } 10317 } 10318 } 10319 } 10320 } 10321 } 10322 } else { 10323 allowed = isPrivilegedApp(pkg); 10324 } 10325 } 10326 } 10327 if (!allowed) { 10328 if (!allowed && (bp.protectionLevel 10329 & PermissionInfo.PROTECTION_FLAG_PRE23) != 0 10330 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 10331 // If this was a previously normal/dangerous permission that got moved 10332 // to a system permission as part of the runtime permission redesign, then 10333 // we still want to blindly grant it to old apps. 10334 allowed = true; 10335 } 10336 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0 10337 && pkg.packageName.equals(mRequiredInstallerPackage)) { 10338 // If this permission is to be granted to the system installer and 10339 // this app is an installer, then it gets the permission. 10340 allowed = true; 10341 } 10342 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0 10343 && pkg.packageName.equals(mRequiredVerifierPackage)) { 10344 // If this permission is to be granted to the system verifier and 10345 // this app is a verifier, then it gets the permission. 10346 allowed = true; 10347 } 10348 if (!allowed && (bp.protectionLevel 10349 & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0 10350 && isSystemApp(pkg)) { 10351 // Any pre-installed system app is allowed to get this permission. 10352 allowed = true; 10353 } 10354 if (!allowed && (bp.protectionLevel 10355 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) { 10356 // For development permissions, a development permission 10357 // is granted only if it was already granted. 10358 allowed = origPermissions.hasInstallPermission(perm); 10359 } 10360 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0 10361 && pkg.packageName.equals(mSetupWizardPackage)) { 10362 // If this permission is to be granted to the system setup wizard and 10363 // this app is a setup wizard, then it gets the permission. 10364 allowed = true; 10365 } 10366 } 10367 return allowed; 10368 } 10369 10370 private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) { 10371 final int permCount = pkg.requestedPermissions.size(); 10372 for (int j = 0; j < permCount; j++) { 10373 String requestedPermission = pkg.requestedPermissions.get(j); 10374 if (permission.equals(requestedPermission)) { 10375 return true; 10376 } 10377 } 10378 return false; 10379 } 10380 10381 final class ActivityIntentResolver 10382 extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> { 10383 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 10384 boolean defaultOnly, int userId) { 10385 if (!sUserManager.exists(userId)) return null; 10386 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 10387 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 10388 } 10389 10390 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 10391 int userId) { 10392 if (!sUserManager.exists(userId)) return null; 10393 mFlags = flags; 10394 return super.queryIntent(intent, resolvedType, 10395 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 10396 } 10397 10398 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 10399 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) { 10400 if (!sUserManager.exists(userId)) return null; 10401 if (packageActivities == null) { 10402 return null; 10403 } 10404 mFlags = flags; 10405 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 10406 final int N = packageActivities.size(); 10407 ArrayList<PackageParser.ActivityIntentInfo[]> listCut = 10408 new ArrayList<PackageParser.ActivityIntentInfo[]>(N); 10409 10410 ArrayList<PackageParser.ActivityIntentInfo> intentFilters; 10411 for (int i = 0; i < N; ++i) { 10412 intentFilters = packageActivities.get(i).intents; 10413 if (intentFilters != null && intentFilters.size() > 0) { 10414 PackageParser.ActivityIntentInfo[] array = 10415 new PackageParser.ActivityIntentInfo[intentFilters.size()]; 10416 intentFilters.toArray(array); 10417 listCut.add(array); 10418 } 10419 } 10420 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 10421 } 10422 10423 /** 10424 * Finds a privileged activity that matches the specified activity names. 10425 */ 10426 private PackageParser.Activity findMatchingActivity( 10427 List<PackageParser.Activity> activityList, ActivityInfo activityInfo) { 10428 for (PackageParser.Activity sysActivity : activityList) { 10429 if (sysActivity.info.name.equals(activityInfo.name)) { 10430 return sysActivity; 10431 } 10432 if (sysActivity.info.name.equals(activityInfo.targetActivity)) { 10433 return sysActivity; 10434 } 10435 if (sysActivity.info.targetActivity != null) { 10436 if (sysActivity.info.targetActivity.equals(activityInfo.name)) { 10437 return sysActivity; 10438 } 10439 if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) { 10440 return sysActivity; 10441 } 10442 } 10443 } 10444 return null; 10445 } 10446 10447 public class IterGenerator<E> { 10448 public Iterator<E> generate(ActivityIntentInfo info) { 10449 return null; 10450 } 10451 } 10452 10453 public class ActionIterGenerator extends IterGenerator<String> { 10454 @Override 10455 public Iterator<String> generate(ActivityIntentInfo info) { 10456 return info.actionsIterator(); 10457 } 10458 } 10459 10460 public class CategoriesIterGenerator extends IterGenerator<String> { 10461 @Override 10462 public Iterator<String> generate(ActivityIntentInfo info) { 10463 return info.categoriesIterator(); 10464 } 10465 } 10466 10467 public class SchemesIterGenerator extends IterGenerator<String> { 10468 @Override 10469 public Iterator<String> generate(ActivityIntentInfo info) { 10470 return info.schemesIterator(); 10471 } 10472 } 10473 10474 public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> { 10475 @Override 10476 public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) { 10477 return info.authoritiesIterator(); 10478 } 10479 } 10480 10481 /** 10482 * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE 10483 * MODIFIED. Do not pass in a list that should not be changed. 10484 */ 10485 private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList, 10486 IterGenerator<T> generator, Iterator<T> searchIterator) { 10487 // loop through the set of actions; every one must be found in the intent filter 10488 while (searchIterator.hasNext()) { 10489 // we must have at least one filter in the list to consider a match 10490 if (intentList.size() == 0) { 10491 break; 10492 } 10493 10494 final T searchAction = searchIterator.next(); 10495 10496 // loop through the set of intent filters 10497 final Iterator<ActivityIntentInfo> intentIter = intentList.iterator(); 10498 while (intentIter.hasNext()) { 10499 final ActivityIntentInfo intentInfo = intentIter.next(); 10500 boolean selectionFound = false; 10501 10502 // loop through the intent filter's selection criteria; at least one 10503 // of them must match the searched criteria 10504 final Iterator<T> intentSelectionIter = generator.generate(intentInfo); 10505 while (intentSelectionIter != null && intentSelectionIter.hasNext()) { 10506 final T intentSelection = intentSelectionIter.next(); 10507 if (intentSelection != null && intentSelection.equals(searchAction)) { 10508 selectionFound = true; 10509 break; 10510 } 10511 } 10512 10513 // the selection criteria wasn't found in this filter's set; this filter 10514 // is not a potential match 10515 if (!selectionFound) { 10516 intentIter.remove(); 10517 } 10518 } 10519 } 10520 } 10521 10522 private boolean isProtectedAction(ActivityIntentInfo filter) { 10523 final Iterator<String> actionsIter = filter.actionsIterator(); 10524 while (actionsIter != null && actionsIter.hasNext()) { 10525 final String filterAction = actionsIter.next(); 10526 if (PROTECTED_ACTIONS.contains(filterAction)) { 10527 return true; 10528 } 10529 } 10530 return false; 10531 } 10532 10533 /** 10534 * Adjusts the priority of the given intent filter according to policy. 10535 * <p> 10536 * <ul> 10537 * <li>The priority for non privileged applications is capped to '0'</li> 10538 * <li>The priority for protected actions on privileged applications is capped to '0'</li> 10539 * <li>The priority for unbundled updates to privileged applications is capped to the 10540 * priority defined on the system partition</li> 10541 * </ul> 10542 * <p> 10543 * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is 10544 * allowed to obtain any priority on any action. 10545 */ 10546 private void adjustPriority( 10547 List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) { 10548 // nothing to do; priority is fine as-is 10549 if (intent.getPriority() <= 0) { 10550 return; 10551 } 10552 10553 final ActivityInfo activityInfo = intent.activity.info; 10554 final ApplicationInfo applicationInfo = activityInfo.applicationInfo; 10555 10556 final boolean privilegedApp = 10557 ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0); 10558 if (!privilegedApp) { 10559 // non-privileged applications can never define a priority >0 10560 Slog.w(TAG, "Non-privileged app; cap priority to 0;" 10561 + " package: " + applicationInfo.packageName 10562 + " activity: " + intent.activity.className 10563 + " origPrio: " + intent.getPriority()); 10564 intent.setPriority(0); 10565 return; 10566 } 10567 10568 if (systemActivities == null) { 10569 // the system package is not disabled; we're parsing the system partition 10570 if (isProtectedAction(intent)) { 10571 if (mDeferProtectedFilters) { 10572 // We can't deal with these just yet. No component should ever obtain a 10573 // >0 priority for a protected actions, with ONE exception -- the setup 10574 // wizard. The setup wizard, however, cannot be known until we're able to 10575 // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do 10576 // until all intent filters have been processed. Chicken, meet egg. 10577 // Let the filter temporarily have a high priority and rectify the 10578 // priorities after all system packages have been scanned. 10579 mProtectedFilters.add(intent); 10580 if (DEBUG_FILTERS) { 10581 Slog.i(TAG, "Protected action; save for later;" 10582 + " package: " + applicationInfo.packageName 10583 + " activity: " + intent.activity.className 10584 + " origPrio: " + intent.getPriority()); 10585 } 10586 return; 10587 } else { 10588 if (DEBUG_FILTERS && mSetupWizardPackage == null) { 10589 Slog.i(TAG, "No setup wizard;" 10590 + " All protected intents capped to priority 0"); 10591 } 10592 if (intent.activity.info.packageName.equals(mSetupWizardPackage)) { 10593 if (DEBUG_FILTERS) { 10594 Slog.i(TAG, "Found setup wizard;" 10595 + " allow priority " + intent.getPriority() + ";" 10596 + " package: " + intent.activity.info.packageName 10597 + " activity: " + intent.activity.className 10598 + " priority: " + intent.getPriority()); 10599 } 10600 // setup wizard gets whatever it wants 10601 return; 10602 } 10603 Slog.w(TAG, "Protected action; cap priority to 0;" 10604 + " package: " + intent.activity.info.packageName 10605 + " activity: " + intent.activity.className 10606 + " origPrio: " + intent.getPriority()); 10607 intent.setPriority(0); 10608 return; 10609 } 10610 } 10611 // privileged apps on the system image get whatever priority they request 10612 return; 10613 } 10614 10615 // privileged app unbundled update ... try to find the same activity 10616 final PackageParser.Activity foundActivity = 10617 findMatchingActivity(systemActivities, activityInfo); 10618 if (foundActivity == null) { 10619 // this is a new activity; it cannot obtain >0 priority 10620 if (DEBUG_FILTERS) { 10621 Slog.i(TAG, "New activity; cap priority to 0;" 10622 + " package: " + applicationInfo.packageName 10623 + " activity: " + intent.activity.className 10624 + " origPrio: " + intent.getPriority()); 10625 } 10626 intent.setPriority(0); 10627 return; 10628 } 10629 10630 // found activity, now check for filter equivalence 10631 10632 // a shallow copy is enough; we modify the list, not its contents 10633 final List<ActivityIntentInfo> intentListCopy = 10634 new ArrayList<>(foundActivity.intents); 10635 final List<ActivityIntentInfo> foundFilters = findFilters(intent); 10636 10637 // find matching action subsets 10638 final Iterator<String> actionsIterator = intent.actionsIterator(); 10639 if (actionsIterator != null) { 10640 getIntentListSubset( 10641 intentListCopy, new ActionIterGenerator(), actionsIterator); 10642 if (intentListCopy.size() == 0) { 10643 // no more intents to match; we're not equivalent 10644 if (DEBUG_FILTERS) { 10645 Slog.i(TAG, "Mismatched action; cap priority to 0;" 10646 + " package: " + applicationInfo.packageName 10647 + " activity: " + intent.activity.className 10648 + " origPrio: " + intent.getPriority()); 10649 } 10650 intent.setPriority(0); 10651 return; 10652 } 10653 } 10654 10655 // find matching category subsets 10656 final Iterator<String> categoriesIterator = intent.categoriesIterator(); 10657 if (categoriesIterator != null) { 10658 getIntentListSubset(intentListCopy, new CategoriesIterGenerator(), 10659 categoriesIterator); 10660 if (intentListCopy.size() == 0) { 10661 // no more intents to match; we're not equivalent 10662 if (DEBUG_FILTERS) { 10663 Slog.i(TAG, "Mismatched category; cap priority to 0;" 10664 + " package: " + applicationInfo.packageName 10665 + " activity: " + intent.activity.className 10666 + " origPrio: " + intent.getPriority()); 10667 } 10668 intent.setPriority(0); 10669 return; 10670 } 10671 } 10672 10673 // find matching schemes subsets 10674 final Iterator<String> schemesIterator = intent.schemesIterator(); 10675 if (schemesIterator != null) { 10676 getIntentListSubset(intentListCopy, new SchemesIterGenerator(), 10677 schemesIterator); 10678 if (intentListCopy.size() == 0) { 10679 // no more intents to match; we're not equivalent 10680 if (DEBUG_FILTERS) { 10681 Slog.i(TAG, "Mismatched scheme; cap priority to 0;" 10682 + " package: " + applicationInfo.packageName 10683 + " activity: " + intent.activity.className 10684 + " origPrio: " + intent.getPriority()); 10685 } 10686 intent.setPriority(0); 10687 return; 10688 } 10689 } 10690 10691 // find matching authorities subsets 10692 final Iterator<IntentFilter.AuthorityEntry> 10693 authoritiesIterator = intent.authoritiesIterator(); 10694 if (authoritiesIterator != null) { 10695 getIntentListSubset(intentListCopy, 10696 new AuthoritiesIterGenerator(), 10697 authoritiesIterator); 10698 if (intentListCopy.size() == 0) { 10699 // no more intents to match; we're not equivalent 10700 if (DEBUG_FILTERS) { 10701 Slog.i(TAG, "Mismatched authority; cap priority to 0;" 10702 + " package: " + applicationInfo.packageName 10703 + " activity: " + intent.activity.className 10704 + " origPrio: " + intent.getPriority()); 10705 } 10706 intent.setPriority(0); 10707 return; 10708 } 10709 } 10710 10711 // we found matching filter(s); app gets the max priority of all intents 10712 int cappedPriority = 0; 10713 for (int i = intentListCopy.size() - 1; i >= 0; --i) { 10714 cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority()); 10715 } 10716 if (intent.getPriority() > cappedPriority) { 10717 if (DEBUG_FILTERS) { 10718 Slog.i(TAG, "Found matching filter(s);" 10719 + " cap priority to " + cappedPriority + ";" 10720 + " package: " + applicationInfo.packageName 10721 + " activity: " + intent.activity.className 10722 + " origPrio: " + intent.getPriority()); 10723 } 10724 intent.setPriority(cappedPriority); 10725 return; 10726 } 10727 // all this for nothing; the requested priority was <= what was on the system 10728 } 10729 10730 public final void addActivity(PackageParser.Activity a, String type) { 10731 mActivities.put(a.getComponentName(), a); 10732 if (DEBUG_SHOW_INFO) 10733 Log.v( 10734 TAG, " " + type + " " + 10735 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":"); 10736 if (DEBUG_SHOW_INFO) 10737 Log.v(TAG, " Class=" + a.info.name); 10738 final int NI = a.intents.size(); 10739 for (int j=0; j<NI; j++) { 10740 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 10741 if ("activity".equals(type)) { 10742 final PackageSetting ps = 10743 mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName); 10744 final List<PackageParser.Activity> systemActivities = 10745 ps != null && ps.pkg != null ? ps.pkg.activities : null; 10746 adjustPriority(systemActivities, intent); 10747 } 10748 if (DEBUG_SHOW_INFO) { 10749 Log.v(TAG, " IntentFilter:"); 10750 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10751 } 10752 if (!intent.debugCheck()) { 10753 Log.w(TAG, "==> For Activity " + a.info.name); 10754 } 10755 addFilter(intent); 10756 } 10757 } 10758 10759 public final void removeActivity(PackageParser.Activity a, String type) { 10760 mActivities.remove(a.getComponentName()); 10761 if (DEBUG_SHOW_INFO) { 10762 Log.v(TAG, " " + type + " " 10763 + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel 10764 : a.info.name) + ":"); 10765 Log.v(TAG, " Class=" + a.info.name); 10766 } 10767 final int NI = a.intents.size(); 10768 for (int j=0; j<NI; j++) { 10769 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 10770 if (DEBUG_SHOW_INFO) { 10771 Log.v(TAG, " IntentFilter:"); 10772 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10773 } 10774 removeFilter(intent); 10775 } 10776 } 10777 10778 @Override 10779 protected boolean allowFilterResult( 10780 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) { 10781 ActivityInfo filterAi = filter.activity.info; 10782 for (int i=dest.size()-1; i>=0; i--) { 10783 ActivityInfo destAi = dest.get(i).activityInfo; 10784 if (destAi.name == filterAi.name 10785 && destAi.packageName == filterAi.packageName) { 10786 return false; 10787 } 10788 } 10789 return true; 10790 } 10791 10792 @Override 10793 protected ActivityIntentInfo[] newArray(int size) { 10794 return new ActivityIntentInfo[size]; 10795 } 10796 10797 @Override 10798 protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) { 10799 if (!sUserManager.exists(userId)) return true; 10800 PackageParser.Package p = filter.activity.owner; 10801 if (p != null) { 10802 PackageSetting ps = (PackageSetting)p.mExtras; 10803 if (ps != null) { 10804 // System apps are never considered stopped for purposes of 10805 // filtering, because there may be no way for the user to 10806 // actually re-launch them. 10807 return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0 10808 && ps.getStopped(userId); 10809 } 10810 } 10811 return false; 10812 } 10813 10814 @Override 10815 protected boolean isPackageForFilter(String packageName, 10816 PackageParser.ActivityIntentInfo info) { 10817 return packageName.equals(info.activity.owner.packageName); 10818 } 10819 10820 @Override 10821 protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info, 10822 int match, int userId) { 10823 if (!sUserManager.exists(userId)) return null; 10824 if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) { 10825 return null; 10826 } 10827 final PackageParser.Activity activity = info.activity; 10828 PackageSetting ps = (PackageSetting) activity.owner.mExtras; 10829 if (ps == null) { 10830 return null; 10831 } 10832 ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags, 10833 ps.readUserState(userId), userId); 10834 if (ai == null) { 10835 return null; 10836 } 10837 final ResolveInfo res = new ResolveInfo(); 10838 res.activityInfo = ai; 10839 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 10840 res.filter = info; 10841 } 10842 if (info != null) { 10843 res.handleAllWebDataURI = info.handleAllWebDataURI(); 10844 } 10845 res.priority = info.getPriority(); 10846 res.preferredOrder = activity.owner.mPreferredOrder; 10847 //System.out.println("Result: " + res.activityInfo.className + 10848 // " = " + res.priority); 10849 res.match = match; 10850 res.isDefault = info.hasDefault; 10851 res.labelRes = info.labelRes; 10852 res.nonLocalizedLabel = info.nonLocalizedLabel; 10853 if (userNeedsBadging(userId)) { 10854 res.noResourceId = true; 10855 } else { 10856 res.icon = info.icon; 10857 } 10858 res.iconResourceId = info.icon; 10859 res.system = res.activityInfo.applicationInfo.isSystemApp(); 10860 return res; 10861 } 10862 10863 @Override 10864 protected void sortResults(List<ResolveInfo> results) { 10865 Collections.sort(results, mResolvePrioritySorter); 10866 } 10867 10868 @Override 10869 protected void dumpFilter(PrintWriter out, String prefix, 10870 PackageParser.ActivityIntentInfo filter) { 10871 out.print(prefix); out.print( 10872 Integer.toHexString(System.identityHashCode(filter.activity))); 10873 out.print(' '); 10874 filter.activity.printComponentShortName(out); 10875 out.print(" filter "); 10876 out.println(Integer.toHexString(System.identityHashCode(filter))); 10877 } 10878 10879 @Override 10880 protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) { 10881 return filter.activity; 10882 } 10883 10884 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 10885 PackageParser.Activity activity = (PackageParser.Activity)label; 10886 out.print(prefix); out.print( 10887 Integer.toHexString(System.identityHashCode(activity))); 10888 out.print(' '); 10889 activity.printComponentShortName(out); 10890 if (count > 1) { 10891 out.print(" ("); out.print(count); out.print(" filters)"); 10892 } 10893 out.println(); 10894 } 10895 10896 // Keys are String (activity class name), values are Activity. 10897 private final ArrayMap<ComponentName, PackageParser.Activity> mActivities 10898 = new ArrayMap<ComponentName, PackageParser.Activity>(); 10899 private int mFlags; 10900 } 10901 10902 private final class ServiceIntentResolver 10903 extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> { 10904 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 10905 boolean defaultOnly, int userId) { 10906 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 10907 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 10908 } 10909 10910 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 10911 int userId) { 10912 if (!sUserManager.exists(userId)) return null; 10913 mFlags = flags; 10914 return super.queryIntent(intent, resolvedType, 10915 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 10916 } 10917 10918 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 10919 int flags, ArrayList<PackageParser.Service> packageServices, int userId) { 10920 if (!sUserManager.exists(userId)) return null; 10921 if (packageServices == null) { 10922 return null; 10923 } 10924 mFlags = flags; 10925 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 10926 final int N = packageServices.size(); 10927 ArrayList<PackageParser.ServiceIntentInfo[]> listCut = 10928 new ArrayList<PackageParser.ServiceIntentInfo[]>(N); 10929 10930 ArrayList<PackageParser.ServiceIntentInfo> intentFilters; 10931 for (int i = 0; i < N; ++i) { 10932 intentFilters = packageServices.get(i).intents; 10933 if (intentFilters != null && intentFilters.size() > 0) { 10934 PackageParser.ServiceIntentInfo[] array = 10935 new PackageParser.ServiceIntentInfo[intentFilters.size()]; 10936 intentFilters.toArray(array); 10937 listCut.add(array); 10938 } 10939 } 10940 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 10941 } 10942 10943 public final void addService(PackageParser.Service s) { 10944 mServices.put(s.getComponentName(), s); 10945 if (DEBUG_SHOW_INFO) { 10946 Log.v(TAG, " " 10947 + (s.info.nonLocalizedLabel != null 10948 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 10949 Log.v(TAG, " Class=" + s.info.name); 10950 } 10951 final int NI = s.intents.size(); 10952 int j; 10953 for (j=0; j<NI; j++) { 10954 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 10955 if (DEBUG_SHOW_INFO) { 10956 Log.v(TAG, " IntentFilter:"); 10957 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10958 } 10959 if (!intent.debugCheck()) { 10960 Log.w(TAG, "==> For Service " + s.info.name); 10961 } 10962 addFilter(intent); 10963 } 10964 } 10965 10966 public final void removeService(PackageParser.Service s) { 10967 mServices.remove(s.getComponentName()); 10968 if (DEBUG_SHOW_INFO) { 10969 Log.v(TAG, " " + (s.info.nonLocalizedLabel != null 10970 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 10971 Log.v(TAG, " Class=" + s.info.name); 10972 } 10973 final int NI = s.intents.size(); 10974 int j; 10975 for (j=0; j<NI; j++) { 10976 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 10977 if (DEBUG_SHOW_INFO) { 10978 Log.v(TAG, " IntentFilter:"); 10979 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10980 } 10981 removeFilter(intent); 10982 } 10983 } 10984 10985 @Override 10986 protected boolean allowFilterResult( 10987 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) { 10988 ServiceInfo filterSi = filter.service.info; 10989 for (int i=dest.size()-1; i>=0; i--) { 10990 ServiceInfo destAi = dest.get(i).serviceInfo; 10991 if (destAi.name == filterSi.name 10992 && destAi.packageName == filterSi.packageName) { 10993 return false; 10994 } 10995 } 10996 return true; 10997 } 10998 10999 @Override 11000 protected PackageParser.ServiceIntentInfo[] newArray(int size) { 11001 return new PackageParser.ServiceIntentInfo[size]; 11002 } 11003 11004 @Override 11005 protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) { 11006 if (!sUserManager.exists(userId)) return true; 11007 PackageParser.Package p = filter.service.owner; 11008 if (p != null) { 11009 PackageSetting ps = (PackageSetting)p.mExtras; 11010 if (ps != null) { 11011 // System apps are never considered stopped for purposes of 11012 // filtering, because there may be no way for the user to 11013 // actually re-launch them. 11014 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 11015 && ps.getStopped(userId); 11016 } 11017 } 11018 return false; 11019 } 11020 11021 @Override 11022 protected boolean isPackageForFilter(String packageName, 11023 PackageParser.ServiceIntentInfo info) { 11024 return packageName.equals(info.service.owner.packageName); 11025 } 11026 11027 @Override 11028 protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter, 11029 int match, int userId) { 11030 if (!sUserManager.exists(userId)) return null; 11031 final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter; 11032 if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) { 11033 return null; 11034 } 11035 final PackageParser.Service service = info.service; 11036 PackageSetting ps = (PackageSetting) service.owner.mExtras; 11037 if (ps == null) { 11038 return null; 11039 } 11040 ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags, 11041 ps.readUserState(userId), userId); 11042 if (si == null) { 11043 return null; 11044 } 11045 final ResolveInfo res = new ResolveInfo(); 11046 res.serviceInfo = si; 11047 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 11048 res.filter = filter; 11049 } 11050 res.priority = info.getPriority(); 11051 res.preferredOrder = service.owner.mPreferredOrder; 11052 res.match = match; 11053 res.isDefault = info.hasDefault; 11054 res.labelRes = info.labelRes; 11055 res.nonLocalizedLabel = info.nonLocalizedLabel; 11056 res.icon = info.icon; 11057 res.system = res.serviceInfo.applicationInfo.isSystemApp(); 11058 return res; 11059 } 11060 11061 @Override 11062 protected void sortResults(List<ResolveInfo> results) { 11063 Collections.sort(results, mResolvePrioritySorter); 11064 } 11065 11066 @Override 11067 protected void dumpFilter(PrintWriter out, String prefix, 11068 PackageParser.ServiceIntentInfo filter) { 11069 out.print(prefix); out.print( 11070 Integer.toHexString(System.identityHashCode(filter.service))); 11071 out.print(' '); 11072 filter.service.printComponentShortName(out); 11073 out.print(" filter "); 11074 out.println(Integer.toHexString(System.identityHashCode(filter))); 11075 } 11076 11077 @Override 11078 protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) { 11079 return filter.service; 11080 } 11081 11082 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 11083 PackageParser.Service service = (PackageParser.Service)label; 11084 out.print(prefix); out.print( 11085 Integer.toHexString(System.identityHashCode(service))); 11086 out.print(' '); 11087 service.printComponentShortName(out); 11088 if (count > 1) { 11089 out.print(" ("); out.print(count); out.print(" filters)"); 11090 } 11091 out.println(); 11092 } 11093 11094// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 11095// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 11096// final List<ResolveInfo> retList = Lists.newArrayList(); 11097// while (i.hasNext()) { 11098// final ResolveInfo resolveInfo = (ResolveInfo) i; 11099// if (isEnabledLP(resolveInfo.serviceInfo)) { 11100// retList.add(resolveInfo); 11101// } 11102// } 11103// return retList; 11104// } 11105 11106 // Keys are String (activity class name), values are Activity. 11107 private final ArrayMap<ComponentName, PackageParser.Service> mServices 11108 = new ArrayMap<ComponentName, PackageParser.Service>(); 11109 private int mFlags; 11110 }; 11111 11112 private final class ProviderIntentResolver 11113 extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> { 11114 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 11115 boolean defaultOnly, int userId) { 11116 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 11117 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 11118 } 11119 11120 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 11121 int userId) { 11122 if (!sUserManager.exists(userId)) 11123 return null; 11124 mFlags = flags; 11125 return super.queryIntent(intent, resolvedType, 11126 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 11127 } 11128 11129 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 11130 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) { 11131 if (!sUserManager.exists(userId)) 11132 return null; 11133 if (packageProviders == null) { 11134 return null; 11135 } 11136 mFlags = flags; 11137 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; 11138 final int N = packageProviders.size(); 11139 ArrayList<PackageParser.ProviderIntentInfo[]> listCut = 11140 new ArrayList<PackageParser.ProviderIntentInfo[]>(N); 11141 11142 ArrayList<PackageParser.ProviderIntentInfo> intentFilters; 11143 for (int i = 0; i < N; ++i) { 11144 intentFilters = packageProviders.get(i).intents; 11145 if (intentFilters != null && intentFilters.size() > 0) { 11146 PackageParser.ProviderIntentInfo[] array = 11147 new PackageParser.ProviderIntentInfo[intentFilters.size()]; 11148 intentFilters.toArray(array); 11149 listCut.add(array); 11150 } 11151 } 11152 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 11153 } 11154 11155 public final void addProvider(PackageParser.Provider p) { 11156 if (mProviders.containsKey(p.getComponentName())) { 11157 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring"); 11158 return; 11159 } 11160 11161 mProviders.put(p.getComponentName(), p); 11162 if (DEBUG_SHOW_INFO) { 11163 Log.v(TAG, " " 11164 + (p.info.nonLocalizedLabel != null 11165 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 11166 Log.v(TAG, " Class=" + p.info.name); 11167 } 11168 final int NI = p.intents.size(); 11169 int j; 11170 for (j = 0; j < NI; j++) { 11171 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 11172 if (DEBUG_SHOW_INFO) { 11173 Log.v(TAG, " IntentFilter:"); 11174 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 11175 } 11176 if (!intent.debugCheck()) { 11177 Log.w(TAG, "==> For Provider " + p.info.name); 11178 } 11179 addFilter(intent); 11180 } 11181 } 11182 11183 public final void removeProvider(PackageParser.Provider p) { 11184 mProviders.remove(p.getComponentName()); 11185 if (DEBUG_SHOW_INFO) { 11186 Log.v(TAG, " " + (p.info.nonLocalizedLabel != null 11187 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 11188 Log.v(TAG, " Class=" + p.info.name); 11189 } 11190 final int NI = p.intents.size(); 11191 int j; 11192 for (j = 0; j < NI; j++) { 11193 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 11194 if (DEBUG_SHOW_INFO) { 11195 Log.v(TAG, " IntentFilter:"); 11196 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 11197 } 11198 removeFilter(intent); 11199 } 11200 } 11201 11202 @Override 11203 protected boolean allowFilterResult( 11204 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) { 11205 ProviderInfo filterPi = filter.provider.info; 11206 for (int i = dest.size() - 1; i >= 0; i--) { 11207 ProviderInfo destPi = dest.get(i).providerInfo; 11208 if (destPi.name == filterPi.name 11209 && destPi.packageName == filterPi.packageName) { 11210 return false; 11211 } 11212 } 11213 return true; 11214 } 11215 11216 @Override 11217 protected PackageParser.ProviderIntentInfo[] newArray(int size) { 11218 return new PackageParser.ProviderIntentInfo[size]; 11219 } 11220 11221 @Override 11222 protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) { 11223 if (!sUserManager.exists(userId)) 11224 return true; 11225 PackageParser.Package p = filter.provider.owner; 11226 if (p != null) { 11227 PackageSetting ps = (PackageSetting) p.mExtras; 11228 if (ps != null) { 11229 // System apps are never considered stopped for purposes of 11230 // filtering, because there may be no way for the user to 11231 // actually re-launch them. 11232 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 11233 && ps.getStopped(userId); 11234 } 11235 } 11236 return false; 11237 } 11238 11239 @Override 11240 protected boolean isPackageForFilter(String packageName, 11241 PackageParser.ProviderIntentInfo info) { 11242 return packageName.equals(info.provider.owner.packageName); 11243 } 11244 11245 @Override 11246 protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter, 11247 int match, int userId) { 11248 if (!sUserManager.exists(userId)) 11249 return null; 11250 final PackageParser.ProviderIntentInfo info = filter; 11251 if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) { 11252 return null; 11253 } 11254 final PackageParser.Provider provider = info.provider; 11255 PackageSetting ps = (PackageSetting) provider.owner.mExtras; 11256 if (ps == null) { 11257 return null; 11258 } 11259 ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags, 11260 ps.readUserState(userId), userId); 11261 if (pi == null) { 11262 return null; 11263 } 11264 final ResolveInfo res = new ResolveInfo(); 11265 res.providerInfo = pi; 11266 if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) { 11267 res.filter = filter; 11268 } 11269 res.priority = info.getPriority(); 11270 res.preferredOrder = provider.owner.mPreferredOrder; 11271 res.match = match; 11272 res.isDefault = info.hasDefault; 11273 res.labelRes = info.labelRes; 11274 res.nonLocalizedLabel = info.nonLocalizedLabel; 11275 res.icon = info.icon; 11276 res.system = res.providerInfo.applicationInfo.isSystemApp(); 11277 return res; 11278 } 11279 11280 @Override 11281 protected void sortResults(List<ResolveInfo> results) { 11282 Collections.sort(results, mResolvePrioritySorter); 11283 } 11284 11285 @Override 11286 protected void dumpFilter(PrintWriter out, String prefix, 11287 PackageParser.ProviderIntentInfo filter) { 11288 out.print(prefix); 11289 out.print( 11290 Integer.toHexString(System.identityHashCode(filter.provider))); 11291 out.print(' '); 11292 filter.provider.printComponentShortName(out); 11293 out.print(" filter "); 11294 out.println(Integer.toHexString(System.identityHashCode(filter))); 11295 } 11296 11297 @Override 11298 protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) { 11299 return filter.provider; 11300 } 11301 11302 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 11303 PackageParser.Provider provider = (PackageParser.Provider)label; 11304 out.print(prefix); out.print( 11305 Integer.toHexString(System.identityHashCode(provider))); 11306 out.print(' '); 11307 provider.printComponentShortName(out); 11308 if (count > 1) { 11309 out.print(" ("); out.print(count); out.print(" filters)"); 11310 } 11311 out.println(); 11312 } 11313 11314 private final ArrayMap<ComponentName, PackageParser.Provider> mProviders 11315 = new ArrayMap<ComponentName, PackageParser.Provider>(); 11316 private int mFlags; 11317 } 11318 11319 private static final class EphemeralIntentResolver 11320 extends IntentResolver<EphemeralResolveIntentInfo, EphemeralResolveInfo> { 11321 /** 11322 * The result that has the highest defined order. Ordering applies on a 11323 * per-package basis. Mapping is from package name to Pair of order and 11324 * EphemeralResolveInfo. 11325 * <p> 11326 * NOTE: This is implemented as a field variable for convenience and efficiency. 11327 * By having a field variable, we're able to track filter ordering as soon as 11328 * a non-zero order is defined. Otherwise, multiple loops across the result set 11329 * would be needed to apply ordering. If the intent resolver becomes re-entrant, 11330 * this needs to be contained entirely within {@link #filterResults()}. 11331 */ 11332 final ArrayMap<String, Pair<Integer, EphemeralResolveInfo>> mOrderResult = new ArrayMap<>(); 11333 11334 @Override 11335 protected EphemeralResolveIntentInfo[] newArray(int size) { 11336 return new EphemeralResolveIntentInfo[size]; 11337 } 11338 11339 @Override 11340 protected boolean isPackageForFilter(String packageName, EphemeralResolveIntentInfo info) { 11341 return true; 11342 } 11343 11344 @Override 11345 protected EphemeralResolveInfo newResult(EphemeralResolveIntentInfo info, int match, 11346 int userId) { 11347 if (!sUserManager.exists(userId)) { 11348 return null; 11349 } 11350 final String packageName = info.getEphemeralResolveInfo().getPackageName(); 11351 final Integer order = info.getOrder(); 11352 final Pair<Integer, EphemeralResolveInfo> lastOrderResult = 11353 mOrderResult.get(packageName); 11354 // ordering is enabled and this item's order isn't high enough 11355 if (lastOrderResult != null && lastOrderResult.first >= order) { 11356 return null; 11357 } 11358 final EphemeralResolveInfo res = info.getEphemeralResolveInfo(); 11359 if (order > 0) { 11360 // non-zero order, enable ordering 11361 mOrderResult.put(packageName, new Pair<>(order, res)); 11362 } 11363 return res; 11364 } 11365 11366 @Override 11367 protected void filterResults(List<EphemeralResolveInfo> results) { 11368 // only do work if ordering is enabled [most of the time it won't be] 11369 if (mOrderResult.size() == 0) { 11370 return; 11371 } 11372 int resultSize = results.size(); 11373 for (int i = 0; i < resultSize; i++) { 11374 final EphemeralResolveInfo info = results.get(i); 11375 final String packageName = info.getPackageName(); 11376 final Pair<Integer, EphemeralResolveInfo> savedInfo = mOrderResult.get(packageName); 11377 if (savedInfo == null) { 11378 // package doesn't having ordering 11379 continue; 11380 } 11381 if (savedInfo.second == info) { 11382 // circled back to the highest ordered item; remove from order list 11383 mOrderResult.remove(savedInfo); 11384 if (mOrderResult.size() == 0) { 11385 // no more ordered items 11386 break; 11387 } 11388 continue; 11389 } 11390 // item has a worse order, remove it from the result list 11391 results.remove(i); 11392 resultSize--; 11393 i--; 11394 } 11395 } 11396 } 11397 11398 private static final Comparator<ResolveInfo> mResolvePrioritySorter = 11399 new Comparator<ResolveInfo>() { 11400 public int compare(ResolveInfo r1, ResolveInfo r2) { 11401 int v1 = r1.priority; 11402 int v2 = r2.priority; 11403 //System.out.println("Comparing: q1=" + q1 + " q2=" + q2); 11404 if (v1 != v2) { 11405 return (v1 > v2) ? -1 : 1; 11406 } 11407 v1 = r1.preferredOrder; 11408 v2 = r2.preferredOrder; 11409 if (v1 != v2) { 11410 return (v1 > v2) ? -1 : 1; 11411 } 11412 if (r1.isDefault != r2.isDefault) { 11413 return r1.isDefault ? -1 : 1; 11414 } 11415 v1 = r1.match; 11416 v2 = r2.match; 11417 //System.out.println("Comparing: m1=" + m1 + " m2=" + m2); 11418 if (v1 != v2) { 11419 return (v1 > v2) ? -1 : 1; 11420 } 11421 if (r1.system != r2.system) { 11422 return r1.system ? -1 : 1; 11423 } 11424 if (r1.activityInfo != null) { 11425 return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName); 11426 } 11427 if (r1.serviceInfo != null) { 11428 return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName); 11429 } 11430 if (r1.providerInfo != null) { 11431 return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName); 11432 } 11433 return 0; 11434 } 11435 }; 11436 11437 private static final Comparator<ProviderInfo> mProviderInitOrderSorter = 11438 new Comparator<ProviderInfo>() { 11439 public int compare(ProviderInfo p1, ProviderInfo p2) { 11440 final int v1 = p1.initOrder; 11441 final int v2 = p2.initOrder; 11442 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0); 11443 } 11444 }; 11445 11446 final void sendPackageBroadcast(final String action, final String pkg, final Bundle extras, 11447 final int flags, final String targetPkg, final IIntentReceiver finishedReceiver, 11448 final int[] userIds) { 11449 mHandler.post(new Runnable() { 11450 @Override 11451 public void run() { 11452 try { 11453 final IActivityManager am = ActivityManagerNative.getDefault(); 11454 if (am == null) return; 11455 final int[] resolvedUserIds; 11456 if (userIds == null) { 11457 resolvedUserIds = am.getRunningUserIds(); 11458 } else { 11459 resolvedUserIds = userIds; 11460 } 11461 for (int id : resolvedUserIds) { 11462 final Intent intent = new Intent(action, 11463 pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null); 11464 if (extras != null) { 11465 intent.putExtras(extras); 11466 } 11467 if (targetPkg != null) { 11468 intent.setPackage(targetPkg); 11469 } 11470 // Modify the UID when posting to other users 11471 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); 11472 if (uid > 0 && UserHandle.getUserId(uid) != id) { 11473 uid = UserHandle.getUid(id, UserHandle.getAppId(uid)); 11474 intent.putExtra(Intent.EXTRA_UID, uid); 11475 } 11476 intent.putExtra(Intent.EXTRA_USER_HANDLE, id); 11477 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags); 11478 if (DEBUG_BROADCASTS) { 11479 RuntimeException here = new RuntimeException("here"); 11480 here.fillInStackTrace(); 11481 Slog.d(TAG, "Sending to user " + id + ": " 11482 + intent.toShortString(false, true, false, false) 11483 + " " + intent.getExtras(), here); 11484 } 11485 am.broadcastIntent(null, intent, null, finishedReceiver, 11486 0, null, null, null, android.app.AppOpsManager.OP_NONE, 11487 null, finishedReceiver != null, false, id); 11488 } 11489 } catch (RemoteException ex) { 11490 } 11491 } 11492 }); 11493 } 11494 11495 /** 11496 * Check if the external storage media is available. This is true if there 11497 * is a mounted external storage medium or if the external storage is 11498 * emulated. 11499 */ 11500 private boolean isExternalMediaAvailable() { 11501 return mMediaMounted || Environment.isExternalStorageEmulated(); 11502 } 11503 11504 @Override 11505 public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) { 11506 // writer 11507 synchronized (mPackages) { 11508 if (!isExternalMediaAvailable()) { 11509 // If the external storage is no longer mounted at this point, 11510 // the caller may not have been able to delete all of this 11511 // packages files and can not delete any more. Bail. 11512 return null; 11513 } 11514 final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned; 11515 if (lastPackage != null) { 11516 pkgs.remove(lastPackage); 11517 } 11518 if (pkgs.size() > 0) { 11519 return pkgs.get(0); 11520 } 11521 } 11522 return null; 11523 } 11524 11525 void schedulePackageCleaning(String packageName, int userId, boolean andCode) { 11526 final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE, 11527 userId, andCode ? 1 : 0, packageName); 11528 if (mSystemReady) { 11529 msg.sendToTarget(); 11530 } else { 11531 if (mPostSystemReadyMessages == null) { 11532 mPostSystemReadyMessages = new ArrayList<>(); 11533 } 11534 mPostSystemReadyMessages.add(msg); 11535 } 11536 } 11537 11538 void startCleaningPackages() { 11539 // reader 11540 if (!isExternalMediaAvailable()) { 11541 return; 11542 } 11543 synchronized (mPackages) { 11544 if (mSettings.mPackagesToBeCleaned.isEmpty()) { 11545 return; 11546 } 11547 } 11548 Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE); 11549 intent.setComponent(DEFAULT_CONTAINER_COMPONENT); 11550 IActivityManager am = ActivityManagerNative.getDefault(); 11551 if (am != null) { 11552 try { 11553 am.startService(null, intent, null, mContext.getOpPackageName(), 11554 UserHandle.USER_SYSTEM); 11555 } catch (RemoteException e) { 11556 } 11557 } 11558 } 11559 11560 @Override 11561 public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer, 11562 int installFlags, String installerPackageName, int userId) { 11563 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null); 11564 11565 final int callingUid = Binder.getCallingUid(); 11566 enforceCrossUserPermission(callingUid, userId, 11567 true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser"); 11568 11569 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 11570 try { 11571 if (observer != null) { 11572 observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null); 11573 } 11574 } catch (RemoteException re) { 11575 } 11576 return; 11577 } 11578 11579 if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) { 11580 installFlags |= PackageManager.INSTALL_FROM_ADB; 11581 11582 } else { 11583 // Caller holds INSTALL_PACKAGES permission, so we're less strict 11584 // about installerPackageName. 11585 11586 installFlags &= ~PackageManager.INSTALL_FROM_ADB; 11587 installFlags &= ~PackageManager.INSTALL_ALL_USERS; 11588 } 11589 11590 UserHandle user; 11591 if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) { 11592 user = UserHandle.ALL; 11593 } else { 11594 user = new UserHandle(userId); 11595 } 11596 11597 // Only system components can circumvent runtime permissions when installing. 11598 if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0 11599 && mContext.checkCallingOrSelfPermission(Manifest.permission 11600 .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) { 11601 throw new SecurityException("You need the " 11602 + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission " 11603 + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag"); 11604 } 11605 11606 final File originFile = new File(originPath); 11607 final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile); 11608 11609 final Message msg = mHandler.obtainMessage(INIT_COPY); 11610 final VerificationInfo verificationInfo = new VerificationInfo( 11611 null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid); 11612 final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer, 11613 installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user, 11614 null /*packageAbiOverride*/, null /*grantedPermissions*/, 11615 null /*certificates*/); 11616 params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params)); 11617 msg.obj = params; 11618 11619 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser", 11620 System.identityHashCode(msg.obj)); 11621 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 11622 System.identityHashCode(msg.obj)); 11623 11624 mHandler.sendMessage(msg); 11625 } 11626 11627 void installStage(String packageName, File stagedDir, String stagedCid, 11628 IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams, 11629 String installerPackageName, int installerUid, UserHandle user, 11630 Certificate[][] certificates) { 11631 if (DEBUG_EPHEMERAL) { 11632 if ((sessionParams.installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) { 11633 Slog.d(TAG, "Ephemeral install of " + packageName); 11634 } 11635 } 11636 final VerificationInfo verificationInfo = new VerificationInfo( 11637 sessionParams.originatingUri, sessionParams.referrerUri, 11638 sessionParams.originatingUid, installerUid); 11639 11640 final OriginInfo origin; 11641 if (stagedDir != null) { 11642 origin = OriginInfo.fromStagedFile(stagedDir); 11643 } else { 11644 origin = OriginInfo.fromStagedContainer(stagedCid); 11645 } 11646 11647 final Message msg = mHandler.obtainMessage(INIT_COPY); 11648 final InstallParams params = new InstallParams(origin, null, observer, 11649 sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid, 11650 verificationInfo, user, sessionParams.abiOverride, 11651 sessionParams.grantedRuntimePermissions, certificates); 11652 params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params)); 11653 msg.obj = params; 11654 11655 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage", 11656 System.identityHashCode(msg.obj)); 11657 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 11658 System.identityHashCode(msg.obj)); 11659 11660 mHandler.sendMessage(msg); 11661 } 11662 11663 private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, 11664 int userId) { 11665 final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting); 11666 sendPackageAddedForUser(packageName, isSystem, pkgSetting.appId, userId); 11667 } 11668 11669 private void sendPackageAddedForUser(String packageName, boolean isSystem, 11670 int appId, int userId) { 11671 Bundle extras = new Bundle(1); 11672 extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, appId)); 11673 11674 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 11675 packageName, extras, 0, null, null, new int[] {userId}); 11676 try { 11677 IActivityManager am = ActivityManagerNative.getDefault(); 11678 if (isSystem && am.isUserRunning(userId, 0)) { 11679 // The just-installed/enabled app is bundled on the system, so presumed 11680 // to be able to run automatically without needing an explicit launch. 11681 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one. 11682 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED) 11683 .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES) 11684 .setPackage(packageName); 11685 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null, 11686 android.app.AppOpsManager.OP_NONE, null, false, false, userId); 11687 } 11688 } catch (RemoteException e) { 11689 // shouldn't happen 11690 Slog.w(TAG, "Unable to bootstrap installed package", e); 11691 } 11692 } 11693 11694 @Override 11695 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, 11696 int userId) { 11697 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 11698 PackageSetting pkgSetting; 11699 final int uid = Binder.getCallingUid(); 11700 enforceCrossUserPermission(uid, userId, 11701 true /* requireFullPermission */, true /* checkShell */, 11702 "setApplicationHiddenSetting for user " + userId); 11703 11704 if (hidden && isPackageDeviceAdmin(packageName, userId)) { 11705 Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin"); 11706 return false; 11707 } 11708 11709 long callingId = Binder.clearCallingIdentity(); 11710 try { 11711 boolean sendAdded = false; 11712 boolean sendRemoved = false; 11713 // writer 11714 synchronized (mPackages) { 11715 pkgSetting = mSettings.mPackages.get(packageName); 11716 if (pkgSetting == null) { 11717 return false; 11718 } 11719 // Do not allow "android" is being disabled 11720 if ("android".equals(packageName)) { 11721 Slog.w(TAG, "Cannot hide package: android"); 11722 return false; 11723 } 11724 // Only allow protected packages to hide themselves. 11725 if (hidden && !UserHandle.isSameApp(uid, pkgSetting.appId) 11726 && mProtectedPackages.isPackageStateProtected(userId, packageName)) { 11727 Slog.w(TAG, "Not hiding protected package: " + packageName); 11728 return false; 11729 } 11730 11731 if (pkgSetting.getHidden(userId) != hidden) { 11732 pkgSetting.setHidden(hidden, userId); 11733 mSettings.writePackageRestrictionsLPr(userId); 11734 if (hidden) { 11735 sendRemoved = true; 11736 } else { 11737 sendAdded = true; 11738 } 11739 } 11740 } 11741 if (sendAdded) { 11742 sendPackageAddedForUser(packageName, pkgSetting, userId); 11743 return true; 11744 } 11745 if (sendRemoved) { 11746 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId), 11747 "hiding pkg"); 11748 sendApplicationHiddenForUser(packageName, pkgSetting, userId); 11749 return true; 11750 } 11751 } finally { 11752 Binder.restoreCallingIdentity(callingId); 11753 } 11754 return false; 11755 } 11756 11757 private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting, 11758 int userId) { 11759 final PackageRemovedInfo info = new PackageRemovedInfo(); 11760 info.removedPackage = packageName; 11761 info.removedUsers = new int[] {userId}; 11762 info.uid = UserHandle.getUid(userId, pkgSetting.appId); 11763 info.sendPackageRemovedBroadcasts(true /*killApp*/); 11764 } 11765 11766 private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) { 11767 if (pkgList.length > 0) { 11768 Bundle extras = new Bundle(1); 11769 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 11770 11771 sendPackageBroadcast( 11772 suspended ? Intent.ACTION_PACKAGES_SUSPENDED 11773 : Intent.ACTION_PACKAGES_UNSUSPENDED, 11774 null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null, 11775 new int[] {userId}); 11776 } 11777 } 11778 11779 /** 11780 * Returns true if application is not found or there was an error. Otherwise it returns 11781 * the hidden state of the package for the given user. 11782 */ 11783 @Override 11784 public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) { 11785 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 11786 enforceCrossUserPermission(Binder.getCallingUid(), userId, 11787 true /* requireFullPermission */, false /* checkShell */, 11788 "getApplicationHidden for user " + userId); 11789 PackageSetting pkgSetting; 11790 long callingId = Binder.clearCallingIdentity(); 11791 try { 11792 // writer 11793 synchronized (mPackages) { 11794 pkgSetting = mSettings.mPackages.get(packageName); 11795 if (pkgSetting == null) { 11796 return true; 11797 } 11798 return pkgSetting.getHidden(userId); 11799 } 11800 } finally { 11801 Binder.restoreCallingIdentity(callingId); 11802 } 11803 } 11804 11805 /** 11806 * @hide 11807 */ 11808 @Override 11809 public int installExistingPackageAsUser(String packageName, int userId) { 11810 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, 11811 null); 11812 PackageSetting pkgSetting; 11813 final int uid = Binder.getCallingUid(); 11814 enforceCrossUserPermission(uid, userId, 11815 true /* requireFullPermission */, true /* checkShell */, 11816 "installExistingPackage for user " + userId); 11817 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 11818 return PackageManager.INSTALL_FAILED_USER_RESTRICTED; 11819 } 11820 11821 long callingId = Binder.clearCallingIdentity(); 11822 try { 11823 boolean installed = false; 11824 11825 // writer 11826 synchronized (mPackages) { 11827 pkgSetting = mSettings.mPackages.get(packageName); 11828 if (pkgSetting == null) { 11829 return PackageManager.INSTALL_FAILED_INVALID_URI; 11830 } 11831 if (!pkgSetting.getInstalled(userId)) { 11832 pkgSetting.setInstalled(true, userId); 11833 pkgSetting.setHidden(false, userId); 11834 mSettings.writePackageRestrictionsLPr(userId); 11835 installed = true; 11836 } 11837 } 11838 11839 if (installed) { 11840 if (pkgSetting.pkg != null) { 11841 synchronized (mInstallLock) { 11842 // We don't need to freeze for a brand new install 11843 prepareAppDataAfterInstallLIF(pkgSetting.pkg); 11844 } 11845 } 11846 sendPackageAddedForUser(packageName, pkgSetting, userId); 11847 } 11848 } finally { 11849 Binder.restoreCallingIdentity(callingId); 11850 } 11851 11852 return PackageManager.INSTALL_SUCCEEDED; 11853 } 11854 11855 boolean isUserRestricted(int userId, String restrictionKey) { 11856 Bundle restrictions = sUserManager.getUserRestrictions(userId); 11857 if (restrictions.getBoolean(restrictionKey, false)) { 11858 Log.w(TAG, "User is restricted: " + restrictionKey); 11859 return true; 11860 } 11861 return false; 11862 } 11863 11864 @Override 11865 public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended, 11866 int userId) { 11867 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 11868 enforceCrossUserPermission(Binder.getCallingUid(), userId, 11869 true /* requireFullPermission */, true /* checkShell */, 11870 "setPackagesSuspended for user " + userId); 11871 11872 if (ArrayUtils.isEmpty(packageNames)) { 11873 return packageNames; 11874 } 11875 11876 // List of package names for whom the suspended state has changed. 11877 List<String> changedPackages = new ArrayList<>(packageNames.length); 11878 // List of package names for whom the suspended state is not set as requested in this 11879 // method. 11880 List<String> unactionedPackages = new ArrayList<>(packageNames.length); 11881 long callingId = Binder.clearCallingIdentity(); 11882 try { 11883 for (int i = 0; i < packageNames.length; i++) { 11884 String packageName = packageNames[i]; 11885 boolean changed = false; 11886 final int appId; 11887 synchronized (mPackages) { 11888 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName); 11889 if (pkgSetting == null) { 11890 Slog.w(TAG, "Could not find package setting for package \"" + packageName 11891 + "\". Skipping suspending/un-suspending."); 11892 unactionedPackages.add(packageName); 11893 continue; 11894 } 11895 appId = pkgSetting.appId; 11896 if (pkgSetting.getSuspended(userId) != suspended) { 11897 if (!canSuspendPackageForUserLocked(packageName, userId)) { 11898 unactionedPackages.add(packageName); 11899 continue; 11900 } 11901 pkgSetting.setSuspended(suspended, userId); 11902 mSettings.writePackageRestrictionsLPr(userId); 11903 changed = true; 11904 changedPackages.add(packageName); 11905 } 11906 } 11907 11908 if (changed && suspended) { 11909 killApplication(packageName, UserHandle.getUid(userId, appId), 11910 "suspending package"); 11911 } 11912 } 11913 } finally { 11914 Binder.restoreCallingIdentity(callingId); 11915 } 11916 11917 if (!changedPackages.isEmpty()) { 11918 sendPackagesSuspendedForUser(changedPackages.toArray( 11919 new String[changedPackages.size()]), userId, suspended); 11920 } 11921 11922 return unactionedPackages.toArray(new String[unactionedPackages.size()]); 11923 } 11924 11925 @Override 11926 public boolean isPackageSuspendedForUser(String packageName, int userId) { 11927 enforceCrossUserPermission(Binder.getCallingUid(), userId, 11928 true /* requireFullPermission */, false /* checkShell */, 11929 "isPackageSuspendedForUser for user " + userId); 11930 synchronized (mPackages) { 11931 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName); 11932 if (pkgSetting == null) { 11933 throw new IllegalArgumentException("Unknown target package: " + packageName); 11934 } 11935 return pkgSetting.getSuspended(userId); 11936 } 11937 } 11938 11939 private boolean canSuspendPackageForUserLocked(String packageName, int userId) { 11940 if (isPackageDeviceAdmin(packageName, userId)) { 11941 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 11942 + "\": has an active device admin"); 11943 return false; 11944 } 11945 11946 String activeLauncherPackageName = getActiveLauncherPackageName(userId); 11947 if (packageName.equals(activeLauncherPackageName)) { 11948 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 11949 + "\": contains the active launcher"); 11950 return false; 11951 } 11952 11953 if (packageName.equals(mRequiredInstallerPackage)) { 11954 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 11955 + "\": required for package installation"); 11956 return false; 11957 } 11958 11959 if (packageName.equals(mRequiredUninstallerPackage)) { 11960 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 11961 + "\": required for package uninstallation"); 11962 return false; 11963 } 11964 11965 if (packageName.equals(mRequiredVerifierPackage)) { 11966 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 11967 + "\": required for package verification"); 11968 return false; 11969 } 11970 11971 if (packageName.equals(getDefaultDialerPackageName(userId))) { 11972 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 11973 + "\": is the default dialer"); 11974 return false; 11975 } 11976 11977 if (mProtectedPackages.isPackageStateProtected(userId, packageName)) { 11978 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 11979 + "\": protected package"); 11980 return false; 11981 } 11982 11983 return true; 11984 } 11985 11986 private String getActiveLauncherPackageName(int userId) { 11987 Intent intent = new Intent(Intent.ACTION_MAIN); 11988 intent.addCategory(Intent.CATEGORY_HOME); 11989 ResolveInfo resolveInfo = resolveIntent( 11990 intent, 11991 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 11992 PackageManager.MATCH_DEFAULT_ONLY, 11993 userId); 11994 11995 return resolveInfo == null ? null : resolveInfo.activityInfo.packageName; 11996 } 11997 11998 private String getDefaultDialerPackageName(int userId) { 11999 synchronized (mPackages) { 12000 return mSettings.getDefaultDialerPackageNameLPw(userId); 12001 } 12002 } 12003 12004 @Override 12005 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException { 12006 mContext.enforceCallingOrSelfPermission( 12007 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 12008 "Only package verification agents can verify applications"); 12009 12010 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 12011 final PackageVerificationResponse response = new PackageVerificationResponse( 12012 verificationCode, Binder.getCallingUid()); 12013 msg.arg1 = id; 12014 msg.obj = response; 12015 mHandler.sendMessage(msg); 12016 } 12017 12018 @Override 12019 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, 12020 long millisecondsToDelay) { 12021 mContext.enforceCallingOrSelfPermission( 12022 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 12023 "Only package verification agents can extend verification timeouts"); 12024 12025 final PackageVerificationState state = mPendingVerification.get(id); 12026 final PackageVerificationResponse response = new PackageVerificationResponse( 12027 verificationCodeAtTimeout, Binder.getCallingUid()); 12028 12029 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) { 12030 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT; 12031 } 12032 if (millisecondsToDelay < 0) { 12033 millisecondsToDelay = 0; 12034 } 12035 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW) 12036 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) { 12037 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT; 12038 } 12039 12040 if ((state != null) && !state.timeoutExtended()) { 12041 state.extendTimeout(); 12042 12043 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 12044 msg.arg1 = id; 12045 msg.obj = response; 12046 mHandler.sendMessageDelayed(msg, millisecondsToDelay); 12047 } 12048 } 12049 12050 private void broadcastPackageVerified(int verificationId, Uri packageUri, 12051 int verificationCode, UserHandle user) { 12052 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED); 12053 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE); 12054 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 12055 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 12056 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode); 12057 12058 mContext.sendBroadcastAsUser(intent, user, 12059 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT); 12060 } 12061 12062 private ComponentName matchComponentForVerifier(String packageName, 12063 List<ResolveInfo> receivers) { 12064 ActivityInfo targetReceiver = null; 12065 12066 final int NR = receivers.size(); 12067 for (int i = 0; i < NR; i++) { 12068 final ResolveInfo info = receivers.get(i); 12069 if (info.activityInfo == null) { 12070 continue; 12071 } 12072 12073 if (packageName.equals(info.activityInfo.packageName)) { 12074 targetReceiver = info.activityInfo; 12075 break; 12076 } 12077 } 12078 12079 if (targetReceiver == null) { 12080 return null; 12081 } 12082 12083 return new ComponentName(targetReceiver.packageName, targetReceiver.name); 12084 } 12085 12086 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo, 12087 List<ResolveInfo> receivers, final PackageVerificationState verificationState) { 12088 if (pkgInfo.verifiers.length == 0) { 12089 return null; 12090 } 12091 12092 final int N = pkgInfo.verifiers.length; 12093 final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1); 12094 for (int i = 0; i < N; i++) { 12095 final VerifierInfo verifierInfo = pkgInfo.verifiers[i]; 12096 12097 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName, 12098 receivers); 12099 if (comp == null) { 12100 continue; 12101 } 12102 12103 final int verifierUid = getUidForVerifier(verifierInfo); 12104 if (verifierUid == -1) { 12105 continue; 12106 } 12107 12108 if (DEBUG_VERIFY) { 12109 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName 12110 + " with the correct signature"); 12111 } 12112 sufficientVerifiers.add(comp); 12113 verificationState.addSufficientVerifier(verifierUid); 12114 } 12115 12116 return sufficientVerifiers; 12117 } 12118 12119 private int getUidForVerifier(VerifierInfo verifierInfo) { 12120 synchronized (mPackages) { 12121 final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName); 12122 if (pkg == null) { 12123 return -1; 12124 } else if (pkg.mSignatures.length != 1) { 12125 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 12126 + " has more than one signature; ignoring"); 12127 return -1; 12128 } 12129 12130 /* 12131 * If the public key of the package's signature does not match 12132 * our expected public key, then this is a different package and 12133 * we should skip. 12134 */ 12135 12136 final byte[] expectedPublicKey; 12137 try { 12138 final Signature verifierSig = pkg.mSignatures[0]; 12139 final PublicKey publicKey = verifierSig.getPublicKey(); 12140 expectedPublicKey = publicKey.getEncoded(); 12141 } catch (CertificateException e) { 12142 return -1; 12143 } 12144 12145 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded(); 12146 12147 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) { 12148 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 12149 + " does not have the expected public key; ignoring"); 12150 return -1; 12151 } 12152 12153 return pkg.applicationInfo.uid; 12154 } 12155 } 12156 12157 @Override 12158 public void finishPackageInstall(int token, boolean didLaunch) { 12159 enforceSystemOrRoot("Only the system is allowed to finish installs"); 12160 12161 if (DEBUG_INSTALL) { 12162 Slog.v(TAG, "BM finishing package install for " + token); 12163 } 12164 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token); 12165 12166 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0); 12167 mHandler.sendMessage(msg); 12168 } 12169 12170 /** 12171 * Get the verification agent timeout. 12172 * 12173 * @return verification timeout in milliseconds 12174 */ 12175 private long getVerificationTimeout() { 12176 return android.provider.Settings.Global.getLong(mContext.getContentResolver(), 12177 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT, 12178 DEFAULT_VERIFICATION_TIMEOUT); 12179 } 12180 12181 /** 12182 * Get the default verification agent response code. 12183 * 12184 * @return default verification response code 12185 */ 12186 private int getDefaultVerificationResponse() { 12187 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 12188 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE, 12189 DEFAULT_VERIFICATION_RESPONSE); 12190 } 12191 12192 /** 12193 * Check whether or not package verification has been enabled. 12194 * 12195 * @return true if verification should be performed 12196 */ 12197 private boolean isVerificationEnabled(int userId, int installFlags) { 12198 if (!DEFAULT_VERIFY_ENABLE) { 12199 return false; 12200 } 12201 // Ephemeral apps don't get the full verification treatment 12202 if ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) { 12203 if (DEBUG_EPHEMERAL) { 12204 Slog.d(TAG, "INSTALL_EPHEMERAL so skipping verification"); 12205 } 12206 return false; 12207 } 12208 12209 boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS); 12210 12211 // Check if installing from ADB 12212 if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) { 12213 // Do not run verification in a test harness environment 12214 if (ActivityManager.isRunningInTestHarness()) { 12215 return false; 12216 } 12217 if (ensureVerifyAppsEnabled) { 12218 return true; 12219 } 12220 // Check if the developer does not want package verification for ADB installs 12221 if (android.provider.Settings.Global.getInt(mContext.getContentResolver(), 12222 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) { 12223 return false; 12224 } 12225 } 12226 12227 if (ensureVerifyAppsEnabled) { 12228 return true; 12229 } 12230 12231 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 12232 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1; 12233 } 12234 12235 @Override 12236 public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains) 12237 throws RemoteException { 12238 mContext.enforceCallingOrSelfPermission( 12239 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 12240 "Only intentfilter verification agents can verify applications"); 12241 12242 final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED); 12243 final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse( 12244 Binder.getCallingUid(), verificationCode, failedDomains); 12245 msg.arg1 = id; 12246 msg.obj = response; 12247 mHandler.sendMessage(msg); 12248 } 12249 12250 @Override 12251 public int getIntentVerificationStatus(String packageName, int userId) { 12252 synchronized (mPackages) { 12253 return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 12254 } 12255 } 12256 12257 @Override 12258 public boolean updateIntentVerificationStatus(String packageName, int status, int userId) { 12259 mContext.enforceCallingOrSelfPermission( 12260 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 12261 12262 boolean result = false; 12263 synchronized (mPackages) { 12264 result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId); 12265 } 12266 if (result) { 12267 scheduleWritePackageRestrictionsLocked(userId); 12268 } 12269 return result; 12270 } 12271 12272 @Override 12273 public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications( 12274 String packageName) { 12275 synchronized (mPackages) { 12276 return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName)); 12277 } 12278 } 12279 12280 @Override 12281 public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) { 12282 if (TextUtils.isEmpty(packageName)) { 12283 return ParceledListSlice.emptyList(); 12284 } 12285 synchronized (mPackages) { 12286 PackageParser.Package pkg = mPackages.get(packageName); 12287 if (pkg == null || pkg.activities == null) { 12288 return ParceledListSlice.emptyList(); 12289 } 12290 final int count = pkg.activities.size(); 12291 ArrayList<IntentFilter> result = new ArrayList<>(); 12292 for (int n=0; n<count; n++) { 12293 PackageParser.Activity activity = pkg.activities.get(n); 12294 if (activity.intents != null && activity.intents.size() > 0) { 12295 result.addAll(activity.intents); 12296 } 12297 } 12298 return new ParceledListSlice<>(result); 12299 } 12300 } 12301 12302 @Override 12303 public boolean setDefaultBrowserPackageName(String packageName, int userId) { 12304 mContext.enforceCallingOrSelfPermission( 12305 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 12306 12307 synchronized (mPackages) { 12308 boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId); 12309 if (packageName != null) { 12310 result |= updateIntentVerificationStatus(packageName, 12311 PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, 12312 userId); 12313 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr( 12314 packageName, userId); 12315 } 12316 return result; 12317 } 12318 } 12319 12320 @Override 12321 public String getDefaultBrowserPackageName(int userId) { 12322 synchronized (mPackages) { 12323 return mSettings.getDefaultBrowserPackageNameLPw(userId); 12324 } 12325 } 12326 12327 /** 12328 * Get the "allow unknown sources" setting. 12329 * 12330 * @return the current "allow unknown sources" setting 12331 */ 12332 private int getUnknownSourcesSettings() { 12333 return android.provider.Settings.Secure.getInt(mContext.getContentResolver(), 12334 android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS, 12335 -1); 12336 } 12337 12338 @Override 12339 public void setInstallerPackageName(String targetPackage, String installerPackageName) { 12340 final int uid = Binder.getCallingUid(); 12341 // writer 12342 synchronized (mPackages) { 12343 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage); 12344 if (targetPackageSetting == null) { 12345 throw new IllegalArgumentException("Unknown target package: " + targetPackage); 12346 } 12347 12348 PackageSetting installerPackageSetting; 12349 if (installerPackageName != null) { 12350 installerPackageSetting = mSettings.mPackages.get(installerPackageName); 12351 if (installerPackageSetting == null) { 12352 throw new IllegalArgumentException("Unknown installer package: " 12353 + installerPackageName); 12354 } 12355 } else { 12356 installerPackageSetting = null; 12357 } 12358 12359 Signature[] callerSignature; 12360 Object obj = mSettings.getUserIdLPr(uid); 12361 if (obj != null) { 12362 if (obj instanceof SharedUserSetting) { 12363 callerSignature = ((SharedUserSetting)obj).signatures.mSignatures; 12364 } else if (obj instanceof PackageSetting) { 12365 callerSignature = ((PackageSetting)obj).signatures.mSignatures; 12366 } else { 12367 throw new SecurityException("Bad object " + obj + " for uid " + uid); 12368 } 12369 } else { 12370 throw new SecurityException("Unknown calling UID: " + uid); 12371 } 12372 12373 // Verify: can't set installerPackageName to a package that is 12374 // not signed with the same cert as the caller. 12375 if (installerPackageSetting != null) { 12376 if (compareSignatures(callerSignature, 12377 installerPackageSetting.signatures.mSignatures) 12378 != PackageManager.SIGNATURE_MATCH) { 12379 throw new SecurityException( 12380 "Caller does not have same cert as new installer package " 12381 + installerPackageName); 12382 } 12383 } 12384 12385 // Verify: if target already has an installer package, it must 12386 // be signed with the same cert as the caller. 12387 if (targetPackageSetting.installerPackageName != null) { 12388 PackageSetting setting = mSettings.mPackages.get( 12389 targetPackageSetting.installerPackageName); 12390 // If the currently set package isn't valid, then it's always 12391 // okay to change it. 12392 if (setting != null) { 12393 if (compareSignatures(callerSignature, 12394 setting.signatures.mSignatures) 12395 != PackageManager.SIGNATURE_MATCH) { 12396 throw new SecurityException( 12397 "Caller does not have same cert as old installer package " 12398 + targetPackageSetting.installerPackageName); 12399 } 12400 } 12401 } 12402 12403 // Okay! 12404 targetPackageSetting.installerPackageName = installerPackageName; 12405 if (installerPackageName != null) { 12406 mSettings.mInstallerPackages.add(installerPackageName); 12407 } 12408 scheduleWriteSettingsLocked(); 12409 } 12410 } 12411 12412 private void processPendingInstall(final InstallArgs args, final int currentStatus) { 12413 // Queue up an async operation since the package installation may take a little while. 12414 mHandler.post(new Runnable() { 12415 public void run() { 12416 mHandler.removeCallbacks(this); 12417 // Result object to be returned 12418 PackageInstalledInfo res = new PackageInstalledInfo(); 12419 res.setReturnCode(currentStatus); 12420 res.uid = -1; 12421 res.pkg = null; 12422 res.removedInfo = null; 12423 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 12424 args.doPreInstall(res.returnCode); 12425 synchronized (mInstallLock) { 12426 installPackageTracedLI(args, res); 12427 } 12428 args.doPostInstall(res.returnCode, res.uid); 12429 } 12430 12431 // A restore should be performed at this point if (a) the install 12432 // succeeded, (b) the operation is not an update, and (c) the new 12433 // package has not opted out of backup participation. 12434 final boolean update = res.removedInfo != null 12435 && res.removedInfo.removedPackage != null; 12436 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags; 12437 boolean doRestore = !update 12438 && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0); 12439 12440 // Set up the post-install work request bookkeeping. This will be used 12441 // and cleaned up by the post-install event handling regardless of whether 12442 // there's a restore pass performed. Token values are >= 1. 12443 int token; 12444 if (mNextInstallToken < 0) mNextInstallToken = 1; 12445 token = mNextInstallToken++; 12446 12447 PostInstallData data = new PostInstallData(args, res); 12448 mRunningInstalls.put(token, data); 12449 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token); 12450 12451 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) { 12452 // Pass responsibility to the Backup Manager. It will perform a 12453 // restore if appropriate, then pass responsibility back to the 12454 // Package Manager to run the post-install observer callbacks 12455 // and broadcasts. 12456 IBackupManager bm = IBackupManager.Stub.asInterface( 12457 ServiceManager.getService(Context.BACKUP_SERVICE)); 12458 if (bm != null) { 12459 if (DEBUG_INSTALL) Log.v(TAG, "token " + token 12460 + " to BM for possible restore"); 12461 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token); 12462 try { 12463 // TODO: http://b/22388012 12464 if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) { 12465 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token); 12466 } else { 12467 doRestore = false; 12468 } 12469 } catch (RemoteException e) { 12470 // can't happen; the backup manager is local 12471 } catch (Exception e) { 12472 Slog.e(TAG, "Exception trying to enqueue restore", e); 12473 doRestore = false; 12474 } 12475 } else { 12476 Slog.e(TAG, "Backup Manager not found!"); 12477 doRestore = false; 12478 } 12479 } 12480 12481 if (!doRestore) { 12482 // No restore possible, or the Backup Manager was mysteriously not 12483 // available -- just fire the post-install work request directly. 12484 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token); 12485 12486 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token); 12487 12488 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 12489 mHandler.sendMessage(msg); 12490 } 12491 } 12492 }); 12493 } 12494 12495 /** 12496 * Callback from PackageSettings whenever an app is first transitioned out of the 12497 * 'stopped' state. Normally we just issue the broadcast, but we can't do that if 12498 * the app was "launched" for a restoreAtInstall operation. Therefore we check 12499 * here whether the app is the target of an ongoing install, and only send the 12500 * broadcast immediately if it is not in that state. If it *is* undergoing a restore, 12501 * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL 12502 * handling. 12503 */ 12504 void notifyFirstLaunch(final String pkgName, final String installerPackage, final int userId) { 12505 // Serialize this with the rest of the install-process message chain. In the 12506 // restore-at-install case, this Runnable will necessarily run before the 12507 // POST_INSTALL message is processed, so the contents of mRunningInstalls 12508 // are coherent. In the non-restore case, the app has already completed install 12509 // and been launched through some other means, so it is not in a problematic 12510 // state for observers to see the FIRST_LAUNCH signal. 12511 mHandler.post(new Runnable() { 12512 @Override 12513 public void run() { 12514 for (int i = 0; i < mRunningInstalls.size(); i++) { 12515 final PostInstallData data = mRunningInstalls.valueAt(i); 12516 if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 12517 continue; 12518 } 12519 if (pkgName.equals(data.res.pkg.applicationInfo.packageName)) { 12520 // right package; but is it for the right user? 12521 for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) { 12522 if (userId == data.res.newUsers[uIndex]) { 12523 if (DEBUG_BACKUP) { 12524 Slog.i(TAG, "Package " + pkgName 12525 + " being restored so deferring FIRST_LAUNCH"); 12526 } 12527 return; 12528 } 12529 } 12530 } 12531 } 12532 // didn't find it, so not being restored 12533 if (DEBUG_BACKUP) { 12534 Slog.i(TAG, "Package " + pkgName + " sending normal FIRST_LAUNCH"); 12535 } 12536 sendFirstLaunchBroadcast(pkgName, installerPackage, new int[] {userId}); 12537 } 12538 }); 12539 } 12540 12541 private void sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds) { 12542 sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0, 12543 installerPkg, null, userIds); 12544 } 12545 12546 private abstract class HandlerParams { 12547 private static final int MAX_RETRIES = 4; 12548 12549 /** 12550 * Number of times startCopy() has been attempted and had a non-fatal 12551 * error. 12552 */ 12553 private int mRetries = 0; 12554 12555 /** User handle for the user requesting the information or installation. */ 12556 private final UserHandle mUser; 12557 String traceMethod; 12558 int traceCookie; 12559 12560 HandlerParams(UserHandle user) { 12561 mUser = user; 12562 } 12563 12564 UserHandle getUser() { 12565 return mUser; 12566 } 12567 12568 HandlerParams setTraceMethod(String traceMethod) { 12569 this.traceMethod = traceMethod; 12570 return this; 12571 } 12572 12573 HandlerParams setTraceCookie(int traceCookie) { 12574 this.traceCookie = traceCookie; 12575 return this; 12576 } 12577 12578 final boolean startCopy() { 12579 boolean res; 12580 try { 12581 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this); 12582 12583 if (++mRetries > MAX_RETRIES) { 12584 Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up"); 12585 mHandler.sendEmptyMessage(MCS_GIVE_UP); 12586 handleServiceError(); 12587 return false; 12588 } else { 12589 handleStartCopy(); 12590 res = true; 12591 } 12592 } catch (RemoteException e) { 12593 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT"); 12594 mHandler.sendEmptyMessage(MCS_RECONNECT); 12595 res = false; 12596 } 12597 handleReturnCode(); 12598 return res; 12599 } 12600 12601 final void serviceError() { 12602 if (DEBUG_INSTALL) Slog.i(TAG, "serviceError"); 12603 handleServiceError(); 12604 handleReturnCode(); 12605 } 12606 12607 abstract void handleStartCopy() throws RemoteException; 12608 abstract void handleServiceError(); 12609 abstract void handleReturnCode(); 12610 } 12611 12612 class MeasureParams extends HandlerParams { 12613 private final PackageStats mStats; 12614 private boolean mSuccess; 12615 12616 private final IPackageStatsObserver mObserver; 12617 12618 public MeasureParams(PackageStats stats, IPackageStatsObserver observer) { 12619 super(new UserHandle(stats.userHandle)); 12620 mObserver = observer; 12621 mStats = stats; 12622 } 12623 12624 @Override 12625 public String toString() { 12626 return "MeasureParams{" 12627 + Integer.toHexString(System.identityHashCode(this)) 12628 + " " + mStats.packageName + "}"; 12629 } 12630 12631 @Override 12632 void handleStartCopy() throws RemoteException { 12633 synchronized (mInstallLock) { 12634 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats); 12635 } 12636 12637 if (mSuccess) { 12638 boolean mounted = false; 12639 try { 12640 final String status = Environment.getExternalStorageState(); 12641 mounted = (Environment.MEDIA_MOUNTED.equals(status) 12642 || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status)); 12643 } catch (Exception e) { 12644 } 12645 12646 if (mounted) { 12647 final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle); 12648 12649 mStats.externalCacheSize = calculateDirectorySize(mContainerService, 12650 userEnv.buildExternalStorageAppCacheDirs(mStats.packageName)); 12651 12652 mStats.externalDataSize = calculateDirectorySize(mContainerService, 12653 userEnv.buildExternalStorageAppDataDirs(mStats.packageName)); 12654 12655 // Always subtract cache size, since it's a subdirectory 12656 mStats.externalDataSize -= mStats.externalCacheSize; 12657 12658 mStats.externalMediaSize = calculateDirectorySize(mContainerService, 12659 userEnv.buildExternalStorageAppMediaDirs(mStats.packageName)); 12660 12661 mStats.externalObbSize = calculateDirectorySize(mContainerService, 12662 userEnv.buildExternalStorageAppObbDirs(mStats.packageName)); 12663 } 12664 } 12665 } 12666 12667 @Override 12668 void handleReturnCode() { 12669 if (mObserver != null) { 12670 try { 12671 mObserver.onGetStatsCompleted(mStats, mSuccess); 12672 } catch (RemoteException e) { 12673 Slog.i(TAG, "Observer no longer exists."); 12674 } 12675 } 12676 } 12677 12678 @Override 12679 void handleServiceError() { 12680 Slog.e(TAG, "Could not measure application " + mStats.packageName 12681 + " external storage"); 12682 } 12683 } 12684 12685 private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths) 12686 throws RemoteException { 12687 long result = 0; 12688 for (File path : paths) { 12689 result += mcs.calculateDirectorySize(path.getAbsolutePath()); 12690 } 12691 return result; 12692 } 12693 12694 private static void clearDirectory(IMediaContainerService mcs, File[] paths) { 12695 for (File path : paths) { 12696 try { 12697 mcs.clearDirectory(path.getAbsolutePath()); 12698 } catch (RemoteException e) { 12699 } 12700 } 12701 } 12702 12703 static class OriginInfo { 12704 /** 12705 * Location where install is coming from, before it has been 12706 * copied/renamed into place. This could be a single monolithic APK 12707 * file, or a cluster directory. This location may be untrusted. 12708 */ 12709 final File file; 12710 final String cid; 12711 12712 /** 12713 * Flag indicating that {@link #file} or {@link #cid} has already been 12714 * staged, meaning downstream users don't need to defensively copy the 12715 * contents. 12716 */ 12717 final boolean staged; 12718 12719 /** 12720 * Flag indicating that {@link #file} or {@link #cid} is an already 12721 * installed app that is being moved. 12722 */ 12723 final boolean existing; 12724 12725 final String resolvedPath; 12726 final File resolvedFile; 12727 12728 static OriginInfo fromNothing() { 12729 return new OriginInfo(null, null, false, false); 12730 } 12731 12732 static OriginInfo fromUntrustedFile(File file) { 12733 return new OriginInfo(file, null, false, false); 12734 } 12735 12736 static OriginInfo fromExistingFile(File file) { 12737 return new OriginInfo(file, null, false, true); 12738 } 12739 12740 static OriginInfo fromStagedFile(File file) { 12741 return new OriginInfo(file, null, true, false); 12742 } 12743 12744 static OriginInfo fromStagedContainer(String cid) { 12745 return new OriginInfo(null, cid, true, false); 12746 } 12747 12748 private OriginInfo(File file, String cid, boolean staged, boolean existing) { 12749 this.file = file; 12750 this.cid = cid; 12751 this.staged = staged; 12752 this.existing = existing; 12753 12754 if (cid != null) { 12755 resolvedPath = PackageHelper.getSdDir(cid); 12756 resolvedFile = new File(resolvedPath); 12757 } else if (file != null) { 12758 resolvedPath = file.getAbsolutePath(); 12759 resolvedFile = file; 12760 } else { 12761 resolvedPath = null; 12762 resolvedFile = null; 12763 } 12764 } 12765 } 12766 12767 static class MoveInfo { 12768 final int moveId; 12769 final String fromUuid; 12770 final String toUuid; 12771 final String packageName; 12772 final String dataAppName; 12773 final int appId; 12774 final String seinfo; 12775 final int targetSdkVersion; 12776 12777 public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName, 12778 String dataAppName, int appId, String seinfo, int targetSdkVersion) { 12779 this.moveId = moveId; 12780 this.fromUuid = fromUuid; 12781 this.toUuid = toUuid; 12782 this.packageName = packageName; 12783 this.dataAppName = dataAppName; 12784 this.appId = appId; 12785 this.seinfo = seinfo; 12786 this.targetSdkVersion = targetSdkVersion; 12787 } 12788 } 12789 12790 static class VerificationInfo { 12791 /** A constant used to indicate that a uid value is not present. */ 12792 public static final int NO_UID = -1; 12793 12794 /** URI referencing where the package was downloaded from. */ 12795 final Uri originatingUri; 12796 12797 /** HTTP referrer URI associated with the originatingURI. */ 12798 final Uri referrer; 12799 12800 /** UID of the application that the install request originated from. */ 12801 final int originatingUid; 12802 12803 /** UID of application requesting the install */ 12804 final int installerUid; 12805 12806 VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) { 12807 this.originatingUri = originatingUri; 12808 this.referrer = referrer; 12809 this.originatingUid = originatingUid; 12810 this.installerUid = installerUid; 12811 } 12812 } 12813 12814 class InstallParams extends HandlerParams { 12815 final OriginInfo origin; 12816 final MoveInfo move; 12817 final IPackageInstallObserver2 observer; 12818 int installFlags; 12819 final String installerPackageName; 12820 final String volumeUuid; 12821 private InstallArgs mArgs; 12822 private int mRet; 12823 final String packageAbiOverride; 12824 final String[] grantedRuntimePermissions; 12825 final VerificationInfo verificationInfo; 12826 final Certificate[][] certificates; 12827 12828 InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 12829 int installFlags, String installerPackageName, String volumeUuid, 12830 VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride, 12831 String[] grantedPermissions, Certificate[][] certificates) { 12832 super(user); 12833 this.origin = origin; 12834 this.move = move; 12835 this.observer = observer; 12836 this.installFlags = installFlags; 12837 this.installerPackageName = installerPackageName; 12838 this.volumeUuid = volumeUuid; 12839 this.verificationInfo = verificationInfo; 12840 this.packageAbiOverride = packageAbiOverride; 12841 this.grantedRuntimePermissions = grantedPermissions; 12842 this.certificates = certificates; 12843 } 12844 12845 @Override 12846 public String toString() { 12847 return "InstallParams{" + Integer.toHexString(System.identityHashCode(this)) 12848 + " file=" + origin.file + " cid=" + origin.cid + "}"; 12849 } 12850 12851 private int installLocationPolicy(PackageInfoLite pkgLite) { 12852 String packageName = pkgLite.packageName; 12853 int installLocation = pkgLite.installLocation; 12854 boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 12855 // reader 12856 synchronized (mPackages) { 12857 // Currently installed package which the new package is attempting to replace or 12858 // null if no such package is installed. 12859 PackageParser.Package installedPkg = mPackages.get(packageName); 12860 // Package which currently owns the data which the new package will own if installed. 12861 // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg 12862 // will be null whereas dataOwnerPkg will contain information about the package 12863 // which was uninstalled while keeping its data. 12864 PackageParser.Package dataOwnerPkg = installedPkg; 12865 if (dataOwnerPkg == null) { 12866 PackageSetting ps = mSettings.mPackages.get(packageName); 12867 if (ps != null) { 12868 dataOwnerPkg = ps.pkg; 12869 } 12870 } 12871 12872 if (dataOwnerPkg != null) { 12873 // If installed, the package will get access to data left on the device by its 12874 // predecessor. As a security measure, this is permited only if this is not a 12875 // version downgrade or if the predecessor package is marked as debuggable and 12876 // a downgrade is explicitly requested. 12877 // 12878 // On debuggable platform builds, downgrades are permitted even for 12879 // non-debuggable packages to make testing easier. Debuggable platform builds do 12880 // not offer security guarantees and thus it's OK to disable some security 12881 // mechanisms to make debugging/testing easier on those builds. However, even on 12882 // debuggable builds downgrades of packages are permitted only if requested via 12883 // installFlags. This is because we aim to keep the behavior of debuggable 12884 // platform builds as close as possible to the behavior of non-debuggable 12885 // platform builds. 12886 final boolean downgradeRequested = 12887 (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0; 12888 final boolean packageDebuggable = 12889 (dataOwnerPkg.applicationInfo.flags 12890 & ApplicationInfo.FLAG_DEBUGGABLE) != 0; 12891 final boolean downgradePermitted = 12892 (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable)); 12893 if (!downgradePermitted) { 12894 try { 12895 checkDowngrade(dataOwnerPkg, pkgLite); 12896 } catch (PackageManagerException e) { 12897 Slog.w(TAG, "Downgrade detected: " + e.getMessage()); 12898 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE; 12899 } 12900 } 12901 } 12902 12903 if (installedPkg != null) { 12904 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 12905 // Check for updated system application. 12906 if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 12907 if (onSd) { 12908 Slog.w(TAG, "Cannot install update to system app on sdcard"); 12909 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION; 12910 } 12911 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 12912 } else { 12913 if (onSd) { 12914 // Install flag overrides everything. 12915 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 12916 } 12917 // If current upgrade specifies particular preference 12918 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) { 12919 // Application explicitly specified internal. 12920 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 12921 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) { 12922 // App explictly prefers external. Let policy decide 12923 } else { 12924 // Prefer previous location 12925 if (isExternal(installedPkg)) { 12926 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 12927 } 12928 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 12929 } 12930 } 12931 } else { 12932 // Invalid install. Return error code 12933 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS; 12934 } 12935 } 12936 } 12937 // All the special cases have been taken care of. 12938 // Return result based on recommended install location. 12939 if (onSd) { 12940 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 12941 } 12942 return pkgLite.recommendedInstallLocation; 12943 } 12944 12945 /* 12946 * Invoke remote method to get package information and install 12947 * location values. Override install location based on default 12948 * policy if needed and then create install arguments based 12949 * on the install location. 12950 */ 12951 public void handleStartCopy() throws RemoteException { 12952 int ret = PackageManager.INSTALL_SUCCEEDED; 12953 12954 // If we're already staged, we've firmly committed to an install location 12955 if (origin.staged) { 12956 if (origin.file != null) { 12957 installFlags |= PackageManager.INSTALL_INTERNAL; 12958 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 12959 } else if (origin.cid != null) { 12960 installFlags |= PackageManager.INSTALL_EXTERNAL; 12961 installFlags &= ~PackageManager.INSTALL_INTERNAL; 12962 } else { 12963 throw new IllegalStateException("Invalid stage location"); 12964 } 12965 } 12966 12967 final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 12968 final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0; 12969 final boolean ephemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; 12970 PackageInfoLite pkgLite = null; 12971 12972 if (onInt && onSd) { 12973 // Check if both bits are set. 12974 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external"); 12975 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 12976 } else if (onSd && ephemeral) { 12977 Slog.w(TAG, "Conflicting flags specified for installing ephemeral on external"); 12978 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 12979 } else { 12980 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags, 12981 packageAbiOverride); 12982 12983 if (DEBUG_EPHEMERAL && ephemeral) { 12984 Slog.v(TAG, "pkgLite for install: " + pkgLite); 12985 } 12986 12987 /* 12988 * If we have too little free space, try to free cache 12989 * before giving up. 12990 */ 12991 if (!origin.staged && pkgLite.recommendedInstallLocation 12992 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 12993 // TODO: focus freeing disk space on the target device 12994 final StorageManager storage = StorageManager.from(mContext); 12995 final long lowThreshold = storage.getStorageLowBytes( 12996 Environment.getDataDirectory()); 12997 12998 final long sizeBytes = mContainerService.calculateInstalledSize( 12999 origin.resolvedPath, isForwardLocked(), packageAbiOverride); 13000 13001 try { 13002 mInstaller.freeCache(null, sizeBytes + lowThreshold); 13003 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, 13004 installFlags, packageAbiOverride); 13005 } catch (InstallerException e) { 13006 Slog.w(TAG, "Failed to free cache", e); 13007 } 13008 13009 /* 13010 * The cache free must have deleted the file we 13011 * downloaded to install. 13012 * 13013 * TODO: fix the "freeCache" call to not delete 13014 * the file we care about. 13015 */ 13016 if (pkgLite.recommendedInstallLocation 13017 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 13018 pkgLite.recommendedInstallLocation 13019 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE; 13020 } 13021 } 13022 } 13023 13024 if (ret == PackageManager.INSTALL_SUCCEEDED) { 13025 int loc = pkgLite.recommendedInstallLocation; 13026 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) { 13027 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 13028 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) { 13029 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 13030 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 13031 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 13032 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) { 13033 ret = PackageManager.INSTALL_FAILED_INVALID_APK; 13034 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 13035 ret = PackageManager.INSTALL_FAILED_INVALID_URI; 13036 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) { 13037 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE; 13038 } else { 13039 // Override with defaults if needed. 13040 loc = installLocationPolicy(pkgLite); 13041 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) { 13042 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 13043 } else if (!onSd && !onInt) { 13044 // Override install location with flags 13045 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) { 13046 // Set the flag to install on external media. 13047 installFlags |= PackageManager.INSTALL_EXTERNAL; 13048 installFlags &= ~PackageManager.INSTALL_INTERNAL; 13049 } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) { 13050 if (DEBUG_EPHEMERAL) { 13051 Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag"); 13052 } 13053 installFlags |= PackageManager.INSTALL_EPHEMERAL; 13054 installFlags &= ~(PackageManager.INSTALL_EXTERNAL 13055 |PackageManager.INSTALL_INTERNAL); 13056 } else { 13057 // Make sure the flag for installing on external 13058 // media is unset 13059 installFlags |= PackageManager.INSTALL_INTERNAL; 13060 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 13061 } 13062 } 13063 } 13064 } 13065 13066 final InstallArgs args = createInstallArgs(this); 13067 mArgs = args; 13068 13069 if (ret == PackageManager.INSTALL_SUCCEEDED) { 13070 // TODO: http://b/22976637 13071 // Apps installed for "all" users use the device owner to verify the app 13072 UserHandle verifierUser = getUser(); 13073 if (verifierUser == UserHandle.ALL) { 13074 verifierUser = UserHandle.SYSTEM; 13075 } 13076 13077 /* 13078 * Determine if we have any installed package verifiers. If we 13079 * do, then we'll defer to them to verify the packages. 13080 */ 13081 final int requiredUid = mRequiredVerifierPackage == null ? -1 13082 : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 13083 verifierUser.getIdentifier()); 13084 if (!origin.existing && requiredUid != -1 13085 && isVerificationEnabled(verifierUser.getIdentifier(), installFlags)) { 13086 final Intent verification = new Intent( 13087 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 13088 verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 13089 verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)), 13090 PACKAGE_MIME_TYPE); 13091 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 13092 13093 // Query all live verifiers based on current user state 13094 final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification, 13095 PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier()); 13096 13097 if (DEBUG_VERIFY) { 13098 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent " 13099 + verification.toString() + " with " + pkgLite.verifiers.length 13100 + " optional verifiers"); 13101 } 13102 13103 final int verificationId = mPendingVerificationToken++; 13104 13105 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 13106 13107 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE, 13108 installerPackageName); 13109 13110 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, 13111 installFlags); 13112 13113 verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME, 13114 pkgLite.packageName); 13115 13116 verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE, 13117 pkgLite.versionCode); 13118 13119 if (verificationInfo != null) { 13120 if (verificationInfo.originatingUri != null) { 13121 verification.putExtra(Intent.EXTRA_ORIGINATING_URI, 13122 verificationInfo.originatingUri); 13123 } 13124 if (verificationInfo.referrer != null) { 13125 verification.putExtra(Intent.EXTRA_REFERRER, 13126 verificationInfo.referrer); 13127 } 13128 if (verificationInfo.originatingUid >= 0) { 13129 verification.putExtra(Intent.EXTRA_ORIGINATING_UID, 13130 verificationInfo.originatingUid); 13131 } 13132 if (verificationInfo.installerUid >= 0) { 13133 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID, 13134 verificationInfo.installerUid); 13135 } 13136 } 13137 13138 final PackageVerificationState verificationState = new PackageVerificationState( 13139 requiredUid, args); 13140 13141 mPendingVerification.append(verificationId, verificationState); 13142 13143 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite, 13144 receivers, verificationState); 13145 13146 /* 13147 * If any sufficient verifiers were listed in the package 13148 * manifest, attempt to ask them. 13149 */ 13150 if (sufficientVerifiers != null) { 13151 final int N = sufficientVerifiers.size(); 13152 if (N == 0) { 13153 Slog.i(TAG, "Additional verifiers required, but none installed."); 13154 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 13155 } else { 13156 for (int i = 0; i < N; i++) { 13157 final ComponentName verifierComponent = sufficientVerifiers.get(i); 13158 13159 final Intent sufficientIntent = new Intent(verification); 13160 sufficientIntent.setComponent(verifierComponent); 13161 mContext.sendBroadcastAsUser(sufficientIntent, verifierUser); 13162 } 13163 } 13164 } 13165 13166 final ComponentName requiredVerifierComponent = matchComponentForVerifier( 13167 mRequiredVerifierPackage, receivers); 13168 if (ret == PackageManager.INSTALL_SUCCEEDED 13169 && mRequiredVerifierPackage != null) { 13170 Trace.asyncTraceBegin( 13171 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 13172 /* 13173 * Send the intent to the required verification agent, 13174 * but only start the verification timeout after the 13175 * target BroadcastReceivers have run. 13176 */ 13177 verification.setComponent(requiredVerifierComponent); 13178 mContext.sendOrderedBroadcastAsUser(verification, verifierUser, 13179 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 13180 new BroadcastReceiver() { 13181 @Override 13182 public void onReceive(Context context, Intent intent) { 13183 final Message msg = mHandler 13184 .obtainMessage(CHECK_PENDING_VERIFICATION); 13185 msg.arg1 = verificationId; 13186 mHandler.sendMessageDelayed(msg, getVerificationTimeout()); 13187 } 13188 }, null, 0, null, null); 13189 13190 /* 13191 * We don't want the copy to proceed until verification 13192 * succeeds, so null out this field. 13193 */ 13194 mArgs = null; 13195 } 13196 } else { 13197 /* 13198 * No package verification is enabled, so immediately start 13199 * the remote call to initiate copy using temporary file. 13200 */ 13201 ret = args.copyApk(mContainerService, true); 13202 } 13203 } 13204 13205 mRet = ret; 13206 } 13207 13208 @Override 13209 void handleReturnCode() { 13210 // If mArgs is null, then MCS couldn't be reached. When it 13211 // reconnects, it will try again to install. At that point, this 13212 // will succeed. 13213 if (mArgs != null) { 13214 processPendingInstall(mArgs, mRet); 13215 } 13216 } 13217 13218 @Override 13219 void handleServiceError() { 13220 mArgs = createInstallArgs(this); 13221 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 13222 } 13223 13224 public boolean isForwardLocked() { 13225 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 13226 } 13227 } 13228 13229 /** 13230 * Used during creation of InstallArgs 13231 * 13232 * @param installFlags package installation flags 13233 * @return true if should be installed on external storage 13234 */ 13235 private static boolean installOnExternalAsec(int installFlags) { 13236 if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) { 13237 return false; 13238 } 13239 if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) { 13240 return true; 13241 } 13242 return false; 13243 } 13244 13245 /** 13246 * Used during creation of InstallArgs 13247 * 13248 * @param installFlags package installation flags 13249 * @return true if should be installed as forward locked 13250 */ 13251 private static boolean installForwardLocked(int installFlags) { 13252 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 13253 } 13254 13255 private InstallArgs createInstallArgs(InstallParams params) { 13256 if (params.move != null) { 13257 return new MoveInstallArgs(params); 13258 } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) { 13259 return new AsecInstallArgs(params); 13260 } else { 13261 return new FileInstallArgs(params); 13262 } 13263 } 13264 13265 /** 13266 * Create args that describe an existing installed package. Typically used 13267 * when cleaning up old installs, or used as a move source. 13268 */ 13269 private InstallArgs createInstallArgsForExisting(int installFlags, String codePath, 13270 String resourcePath, String[] instructionSets) { 13271 final boolean isInAsec; 13272 if (installOnExternalAsec(installFlags)) { 13273 /* Apps on SD card are always in ASEC containers. */ 13274 isInAsec = true; 13275 } else if (installForwardLocked(installFlags) 13276 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) { 13277 /* 13278 * Forward-locked apps are only in ASEC containers if they're the 13279 * new style 13280 */ 13281 isInAsec = true; 13282 } else { 13283 isInAsec = false; 13284 } 13285 13286 if (isInAsec) { 13287 return new AsecInstallArgs(codePath, instructionSets, 13288 installOnExternalAsec(installFlags), installForwardLocked(installFlags)); 13289 } else { 13290 return new FileInstallArgs(codePath, resourcePath, instructionSets); 13291 } 13292 } 13293 13294 static abstract class InstallArgs { 13295 /** @see InstallParams#origin */ 13296 final OriginInfo origin; 13297 /** @see InstallParams#move */ 13298 final MoveInfo move; 13299 13300 final IPackageInstallObserver2 observer; 13301 // Always refers to PackageManager flags only 13302 final int installFlags; 13303 final String installerPackageName; 13304 final String volumeUuid; 13305 final UserHandle user; 13306 final String abiOverride; 13307 final String[] installGrantPermissions; 13308 /** If non-null, drop an async trace when the install completes */ 13309 final String traceMethod; 13310 final int traceCookie; 13311 final Certificate[][] certificates; 13312 13313 // The list of instruction sets supported by this app. This is currently 13314 // only used during the rmdex() phase to clean up resources. We can get rid of this 13315 // if we move dex files under the common app path. 13316 /* nullable */ String[] instructionSets; 13317 13318 InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 13319 int installFlags, String installerPackageName, String volumeUuid, 13320 UserHandle user, String[] instructionSets, 13321 String abiOverride, String[] installGrantPermissions, 13322 String traceMethod, int traceCookie, Certificate[][] certificates) { 13323 this.origin = origin; 13324 this.move = move; 13325 this.installFlags = installFlags; 13326 this.observer = observer; 13327 this.installerPackageName = installerPackageName; 13328 this.volumeUuid = volumeUuid; 13329 this.user = user; 13330 this.instructionSets = instructionSets; 13331 this.abiOverride = abiOverride; 13332 this.installGrantPermissions = installGrantPermissions; 13333 this.traceMethod = traceMethod; 13334 this.traceCookie = traceCookie; 13335 this.certificates = certificates; 13336 } 13337 13338 abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException; 13339 abstract int doPreInstall(int status); 13340 13341 /** 13342 * Rename package into final resting place. All paths on the given 13343 * scanned package should be updated to reflect the rename. 13344 */ 13345 abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath); 13346 abstract int doPostInstall(int status, int uid); 13347 13348 /** @see PackageSettingBase#codePathString */ 13349 abstract String getCodePath(); 13350 /** @see PackageSettingBase#resourcePathString */ 13351 abstract String getResourcePath(); 13352 13353 // Need installer lock especially for dex file removal. 13354 abstract void cleanUpResourcesLI(); 13355 abstract boolean doPostDeleteLI(boolean delete); 13356 13357 /** 13358 * Called before the source arguments are copied. This is used mostly 13359 * for MoveParams when it needs to read the source file to put it in the 13360 * destination. 13361 */ 13362 int doPreCopy() { 13363 return PackageManager.INSTALL_SUCCEEDED; 13364 } 13365 13366 /** 13367 * Called after the source arguments are copied. This is used mostly for 13368 * MoveParams when it needs to read the source file to put it in the 13369 * destination. 13370 */ 13371 int doPostCopy(int uid) { 13372 return PackageManager.INSTALL_SUCCEEDED; 13373 } 13374 13375 protected boolean isFwdLocked() { 13376 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 13377 } 13378 13379 protected boolean isExternalAsec() { 13380 return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 13381 } 13382 13383 protected boolean isEphemeral() { 13384 return (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; 13385 } 13386 13387 UserHandle getUser() { 13388 return user; 13389 } 13390 } 13391 13392 private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) { 13393 if (!allCodePaths.isEmpty()) { 13394 if (instructionSets == null) { 13395 throw new IllegalStateException("instructionSet == null"); 13396 } 13397 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); 13398 for (String codePath : allCodePaths) { 13399 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 13400 try { 13401 mInstaller.rmdex(codePath, dexCodeInstructionSet); 13402 } catch (InstallerException ignored) { 13403 } 13404 } 13405 } 13406 } 13407 } 13408 13409 /** 13410 * Logic to handle installation of non-ASEC applications, including copying 13411 * and renaming logic. 13412 */ 13413 class FileInstallArgs extends InstallArgs { 13414 private File codeFile; 13415 private File resourceFile; 13416 13417 // Example topology: 13418 // /data/app/com.example/base.apk 13419 // /data/app/com.example/split_foo.apk 13420 // /data/app/com.example/lib/arm/libfoo.so 13421 // /data/app/com.example/lib/arm64/libfoo.so 13422 // /data/app/com.example/dalvik/arm/base.apk@classes.dex 13423 13424 /** New install */ 13425 FileInstallArgs(InstallParams params) { 13426 super(params.origin, params.move, params.observer, params.installFlags, 13427 params.installerPackageName, params.volumeUuid, 13428 params.getUser(), null /*instructionSets*/, params.packageAbiOverride, 13429 params.grantedRuntimePermissions, 13430 params.traceMethod, params.traceCookie, params.certificates); 13431 if (isFwdLocked()) { 13432 throw new IllegalArgumentException("Forward locking only supported in ASEC"); 13433 } 13434 } 13435 13436 /** Existing install */ 13437 FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) { 13438 super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets, 13439 null, null, null, 0, null /*certificates*/); 13440 this.codeFile = (codePath != null) ? new File(codePath) : null; 13441 this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null; 13442 } 13443 13444 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 13445 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk"); 13446 try { 13447 return doCopyApk(imcs, temp); 13448 } finally { 13449 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13450 } 13451 } 13452 13453 private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 13454 if (origin.staged) { 13455 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy"); 13456 codeFile = origin.file; 13457 resourceFile = origin.file; 13458 return PackageManager.INSTALL_SUCCEEDED; 13459 } 13460 13461 try { 13462 final boolean isEphemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; 13463 final File tempDir = 13464 mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral); 13465 codeFile = tempDir; 13466 resourceFile = tempDir; 13467 } catch (IOException e) { 13468 Slog.w(TAG, "Failed to create copy file: " + e); 13469 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 13470 } 13471 13472 final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() { 13473 @Override 13474 public ParcelFileDescriptor open(String name, int mode) throws RemoteException { 13475 if (!FileUtils.isValidExtFilename(name)) { 13476 throw new IllegalArgumentException("Invalid filename: " + name); 13477 } 13478 try { 13479 final File file = new File(codeFile, name); 13480 final FileDescriptor fd = Os.open(file.getAbsolutePath(), 13481 O_RDWR | O_CREAT, 0644); 13482 Os.chmod(file.getAbsolutePath(), 0644); 13483 return new ParcelFileDescriptor(fd); 13484 } catch (ErrnoException e) { 13485 throw new RemoteException("Failed to open: " + e.getMessage()); 13486 } 13487 } 13488 }; 13489 13490 int ret = PackageManager.INSTALL_SUCCEEDED; 13491 ret = imcs.copyPackage(origin.file.getAbsolutePath(), target); 13492 if (ret != PackageManager.INSTALL_SUCCEEDED) { 13493 Slog.e(TAG, "Failed to copy package"); 13494 return ret; 13495 } 13496 13497 final File libraryRoot = new File(codeFile, LIB_DIR_NAME); 13498 NativeLibraryHelper.Handle handle = null; 13499 try { 13500 handle = NativeLibraryHelper.Handle.create(codeFile); 13501 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot, 13502 abiOverride); 13503 } catch (IOException e) { 13504 Slog.e(TAG, "Copying native libraries failed", e); 13505 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 13506 } finally { 13507 IoUtils.closeQuietly(handle); 13508 } 13509 13510 return ret; 13511 } 13512 13513 int doPreInstall(int status) { 13514 if (status != PackageManager.INSTALL_SUCCEEDED) { 13515 cleanUp(); 13516 } 13517 return status; 13518 } 13519 13520 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 13521 if (status != PackageManager.INSTALL_SUCCEEDED) { 13522 cleanUp(); 13523 return false; 13524 } 13525 13526 final File targetDir = codeFile.getParentFile(); 13527 final File beforeCodeFile = codeFile; 13528 final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName); 13529 13530 if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile); 13531 try { 13532 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath()); 13533 } catch (ErrnoException e) { 13534 Slog.w(TAG, "Failed to rename", e); 13535 return false; 13536 } 13537 13538 if (!SELinux.restoreconRecursive(afterCodeFile)) { 13539 Slog.w(TAG, "Failed to restorecon"); 13540 return false; 13541 } 13542 13543 // Reflect the rename internally 13544 codeFile = afterCodeFile; 13545 resourceFile = afterCodeFile; 13546 13547 // Reflect the rename in scanned details 13548 pkg.setCodePath(afterCodeFile.getAbsolutePath()); 13549 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile, 13550 afterCodeFile, pkg.baseCodePath)); 13551 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile, 13552 afterCodeFile, pkg.splitCodePaths)); 13553 13554 // Reflect the rename in app info 13555 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 13556 pkg.setApplicationInfoCodePath(pkg.codePath); 13557 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 13558 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 13559 pkg.setApplicationInfoResourcePath(pkg.codePath); 13560 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 13561 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 13562 13563 return true; 13564 } 13565 13566 int doPostInstall(int status, int uid) { 13567 if (status != PackageManager.INSTALL_SUCCEEDED) { 13568 cleanUp(); 13569 } 13570 return status; 13571 } 13572 13573 @Override 13574 String getCodePath() { 13575 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 13576 } 13577 13578 @Override 13579 String getResourcePath() { 13580 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 13581 } 13582 13583 private boolean cleanUp() { 13584 if (codeFile == null || !codeFile.exists()) { 13585 return false; 13586 } 13587 13588 removeCodePathLI(codeFile); 13589 13590 if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) { 13591 resourceFile.delete(); 13592 } 13593 13594 return true; 13595 } 13596 13597 void cleanUpResourcesLI() { 13598 // Try enumerating all code paths before deleting 13599 List<String> allCodePaths = Collections.EMPTY_LIST; 13600 if (codeFile != null && codeFile.exists()) { 13601 try { 13602 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 13603 allCodePaths = pkg.getAllCodePaths(); 13604 } catch (PackageParserException e) { 13605 // Ignored; we tried our best 13606 } 13607 } 13608 13609 cleanUp(); 13610 removeDexFiles(allCodePaths, instructionSets); 13611 } 13612 13613 boolean doPostDeleteLI(boolean delete) { 13614 // XXX err, shouldn't we respect the delete flag? 13615 cleanUpResourcesLI(); 13616 return true; 13617 } 13618 } 13619 13620 private boolean isAsecExternal(String cid) { 13621 final String asecPath = PackageHelper.getSdFilesystem(cid); 13622 return !asecPath.startsWith(mAsecInternalPath); 13623 } 13624 13625 private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws 13626 PackageManagerException { 13627 if (copyRet < 0) { 13628 if (copyRet != PackageManager.NO_NATIVE_LIBRARIES && 13629 copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) { 13630 throw new PackageManagerException(copyRet, message); 13631 } 13632 } 13633 } 13634 13635 /** 13636 * Extract the MountService "container ID" from the full code path of an 13637 * .apk. 13638 */ 13639 static String cidFromCodePath(String fullCodePath) { 13640 int eidx = fullCodePath.lastIndexOf("/"); 13641 String subStr1 = fullCodePath.substring(0, eidx); 13642 int sidx = subStr1.lastIndexOf("/"); 13643 return subStr1.substring(sidx+1, eidx); 13644 } 13645 13646 /** 13647 * Logic to handle installation of ASEC applications, including copying and 13648 * renaming logic. 13649 */ 13650 class AsecInstallArgs extends InstallArgs { 13651 static final String RES_FILE_NAME = "pkg.apk"; 13652 static final String PUBLIC_RES_FILE_NAME = "res.zip"; 13653 13654 String cid; 13655 String packagePath; 13656 String resourcePath; 13657 13658 /** New install */ 13659 AsecInstallArgs(InstallParams params) { 13660 super(params.origin, params.move, params.observer, params.installFlags, 13661 params.installerPackageName, params.volumeUuid, 13662 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 13663 params.grantedRuntimePermissions, 13664 params.traceMethod, params.traceCookie, params.certificates); 13665 } 13666 13667 /** Existing install */ 13668 AsecInstallArgs(String fullCodePath, String[] instructionSets, 13669 boolean isExternal, boolean isForwardLocked) { 13670 super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0) 13671 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, 13672 instructionSets, null, null, null, 0, null /*certificates*/); 13673 // Hackily pretend we're still looking at a full code path 13674 if (!fullCodePath.endsWith(RES_FILE_NAME)) { 13675 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath(); 13676 } 13677 13678 // Extract cid from fullCodePath 13679 int eidx = fullCodePath.lastIndexOf("/"); 13680 String subStr1 = fullCodePath.substring(0, eidx); 13681 int sidx = subStr1.lastIndexOf("/"); 13682 cid = subStr1.substring(sidx+1, eidx); 13683 setMountPath(subStr1); 13684 } 13685 13686 AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) { 13687 super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0) 13688 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, 13689 instructionSets, null, null, null, 0, null /*certificates*/); 13690 this.cid = cid; 13691 setMountPath(PackageHelper.getSdDir(cid)); 13692 } 13693 13694 void createCopyFile() { 13695 cid = mInstallerService.allocateExternalStageCidLegacy(); 13696 } 13697 13698 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 13699 if (origin.staged && origin.cid != null) { 13700 if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy"); 13701 cid = origin.cid; 13702 setMountPath(PackageHelper.getSdDir(cid)); 13703 return PackageManager.INSTALL_SUCCEEDED; 13704 } 13705 13706 if (temp) { 13707 createCopyFile(); 13708 } else { 13709 /* 13710 * Pre-emptively destroy the container since it's destroyed if 13711 * copying fails due to it existing anyway. 13712 */ 13713 PackageHelper.destroySdDir(cid); 13714 } 13715 13716 final String newMountPath = imcs.copyPackageToContainer( 13717 origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(), 13718 isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */)); 13719 13720 if (newMountPath != null) { 13721 setMountPath(newMountPath); 13722 return PackageManager.INSTALL_SUCCEEDED; 13723 } else { 13724 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 13725 } 13726 } 13727 13728 @Override 13729 String getCodePath() { 13730 return packagePath; 13731 } 13732 13733 @Override 13734 String getResourcePath() { 13735 return resourcePath; 13736 } 13737 13738 int doPreInstall(int status) { 13739 if (status != PackageManager.INSTALL_SUCCEEDED) { 13740 // Destroy container 13741 PackageHelper.destroySdDir(cid); 13742 } else { 13743 boolean mounted = PackageHelper.isContainerMounted(cid); 13744 if (!mounted) { 13745 String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(), 13746 Process.SYSTEM_UID); 13747 if (newMountPath != null) { 13748 setMountPath(newMountPath); 13749 } else { 13750 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 13751 } 13752 } 13753 } 13754 return status; 13755 } 13756 13757 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 13758 String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME); 13759 String newMountPath = null; 13760 if (PackageHelper.isContainerMounted(cid)) { 13761 // Unmount the container 13762 if (!PackageHelper.unMountSdDir(cid)) { 13763 Slog.i(TAG, "Failed to unmount " + cid + " before renaming"); 13764 return false; 13765 } 13766 } 13767 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 13768 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId + 13769 " which might be stale. Will try to clean up."); 13770 // Clean up the stale container and proceed to recreate. 13771 if (!PackageHelper.destroySdDir(newCacheId)) { 13772 Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId); 13773 return false; 13774 } 13775 // Successfully cleaned up stale container. Try to rename again. 13776 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 13777 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId 13778 + " inspite of cleaning it up."); 13779 return false; 13780 } 13781 } 13782 if (!PackageHelper.isContainerMounted(newCacheId)) { 13783 Slog.w(TAG, "Mounting container " + newCacheId); 13784 newMountPath = PackageHelper.mountSdDir(newCacheId, 13785 getEncryptKey(), Process.SYSTEM_UID); 13786 } else { 13787 newMountPath = PackageHelper.getSdDir(newCacheId); 13788 } 13789 if (newMountPath == null) { 13790 Slog.w(TAG, "Failed to get cache path for " + newCacheId); 13791 return false; 13792 } 13793 Log.i(TAG, "Succesfully renamed " + cid + 13794 " to " + newCacheId + 13795 " at new path: " + newMountPath); 13796 cid = newCacheId; 13797 13798 final File beforeCodeFile = new File(packagePath); 13799 setMountPath(newMountPath); 13800 final File afterCodeFile = new File(packagePath); 13801 13802 // Reflect the rename in scanned details 13803 pkg.setCodePath(afterCodeFile.getAbsolutePath()); 13804 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile, 13805 afterCodeFile, pkg.baseCodePath)); 13806 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile, 13807 afterCodeFile, pkg.splitCodePaths)); 13808 13809 // Reflect the rename in app info 13810 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 13811 pkg.setApplicationInfoCodePath(pkg.codePath); 13812 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 13813 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 13814 pkg.setApplicationInfoResourcePath(pkg.codePath); 13815 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 13816 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 13817 13818 return true; 13819 } 13820 13821 private void setMountPath(String mountPath) { 13822 final File mountFile = new File(mountPath); 13823 13824 final File monolithicFile = new File(mountFile, RES_FILE_NAME); 13825 if (monolithicFile.exists()) { 13826 packagePath = monolithicFile.getAbsolutePath(); 13827 if (isFwdLocked()) { 13828 resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath(); 13829 } else { 13830 resourcePath = packagePath; 13831 } 13832 } else { 13833 packagePath = mountFile.getAbsolutePath(); 13834 resourcePath = packagePath; 13835 } 13836 } 13837 13838 int doPostInstall(int status, int uid) { 13839 if (status != PackageManager.INSTALL_SUCCEEDED) { 13840 cleanUp(); 13841 } else { 13842 final int groupOwner; 13843 final String protectedFile; 13844 if (isFwdLocked()) { 13845 groupOwner = UserHandle.getSharedAppGid(uid); 13846 protectedFile = RES_FILE_NAME; 13847 } else { 13848 groupOwner = -1; 13849 protectedFile = null; 13850 } 13851 13852 if (uid < Process.FIRST_APPLICATION_UID 13853 || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) { 13854 Slog.e(TAG, "Failed to finalize " + cid); 13855 PackageHelper.destroySdDir(cid); 13856 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 13857 } 13858 13859 boolean mounted = PackageHelper.isContainerMounted(cid); 13860 if (!mounted) { 13861 PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid()); 13862 } 13863 } 13864 return status; 13865 } 13866 13867 private void cleanUp() { 13868 if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp"); 13869 13870 // Destroy secure container 13871 PackageHelper.destroySdDir(cid); 13872 } 13873 13874 private List<String> getAllCodePaths() { 13875 final File codeFile = new File(getCodePath()); 13876 if (codeFile != null && codeFile.exists()) { 13877 try { 13878 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 13879 return pkg.getAllCodePaths(); 13880 } catch (PackageParserException e) { 13881 // Ignored; we tried our best 13882 } 13883 } 13884 return Collections.EMPTY_LIST; 13885 } 13886 13887 void cleanUpResourcesLI() { 13888 // Enumerate all code paths before deleting 13889 cleanUpResourcesLI(getAllCodePaths()); 13890 } 13891 13892 private void cleanUpResourcesLI(List<String> allCodePaths) { 13893 cleanUp(); 13894 removeDexFiles(allCodePaths, instructionSets); 13895 } 13896 13897 String getPackageName() { 13898 return getAsecPackageName(cid); 13899 } 13900 13901 boolean doPostDeleteLI(boolean delete) { 13902 if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete); 13903 final List<String> allCodePaths = getAllCodePaths(); 13904 boolean mounted = PackageHelper.isContainerMounted(cid); 13905 if (mounted) { 13906 // Unmount first 13907 if (PackageHelper.unMountSdDir(cid)) { 13908 mounted = false; 13909 } 13910 } 13911 if (!mounted && delete) { 13912 cleanUpResourcesLI(allCodePaths); 13913 } 13914 return !mounted; 13915 } 13916 13917 @Override 13918 int doPreCopy() { 13919 if (isFwdLocked()) { 13920 if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE, 13921 MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) { 13922 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 13923 } 13924 } 13925 13926 return PackageManager.INSTALL_SUCCEEDED; 13927 } 13928 13929 @Override 13930 int doPostCopy(int uid) { 13931 if (isFwdLocked()) { 13932 if (uid < Process.FIRST_APPLICATION_UID 13933 || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid), 13934 RES_FILE_NAME)) { 13935 Slog.e(TAG, "Failed to finalize " + cid); 13936 PackageHelper.destroySdDir(cid); 13937 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 13938 } 13939 } 13940 13941 return PackageManager.INSTALL_SUCCEEDED; 13942 } 13943 } 13944 13945 /** 13946 * Logic to handle movement of existing installed applications. 13947 */ 13948 class MoveInstallArgs extends InstallArgs { 13949 private File codeFile; 13950 private File resourceFile; 13951 13952 /** New install */ 13953 MoveInstallArgs(InstallParams params) { 13954 super(params.origin, params.move, params.observer, params.installFlags, 13955 params.installerPackageName, params.volumeUuid, 13956 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 13957 params.grantedRuntimePermissions, 13958 params.traceMethod, params.traceCookie, params.certificates); 13959 } 13960 13961 int copyApk(IMediaContainerService imcs, boolean temp) { 13962 if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from " 13963 + move.fromUuid + " to " + move.toUuid); 13964 synchronized (mInstaller) { 13965 try { 13966 mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName, 13967 move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion); 13968 } catch (InstallerException e) { 13969 Slog.w(TAG, "Failed to move app", e); 13970 return PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 13971 } 13972 } 13973 13974 codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName); 13975 resourceFile = codeFile; 13976 if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile); 13977 13978 return PackageManager.INSTALL_SUCCEEDED; 13979 } 13980 13981 int doPreInstall(int status) { 13982 if (status != PackageManager.INSTALL_SUCCEEDED) { 13983 cleanUp(move.toUuid); 13984 } 13985 return status; 13986 } 13987 13988 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 13989 if (status != PackageManager.INSTALL_SUCCEEDED) { 13990 cleanUp(move.toUuid); 13991 return false; 13992 } 13993 13994 // Reflect the move in app info 13995 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 13996 pkg.setApplicationInfoCodePath(pkg.codePath); 13997 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 13998 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 13999 pkg.setApplicationInfoResourcePath(pkg.codePath); 14000 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 14001 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 14002 14003 return true; 14004 } 14005 14006 int doPostInstall(int status, int uid) { 14007 if (status == PackageManager.INSTALL_SUCCEEDED) { 14008 cleanUp(move.fromUuid); 14009 } else { 14010 cleanUp(move.toUuid); 14011 } 14012 return status; 14013 } 14014 14015 @Override 14016 String getCodePath() { 14017 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 14018 } 14019 14020 @Override 14021 String getResourcePath() { 14022 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 14023 } 14024 14025 private boolean cleanUp(String volumeUuid) { 14026 final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid), 14027 move.dataAppName); 14028 Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid); 14029 final int[] userIds = sUserManager.getUserIds(); 14030 synchronized (mInstallLock) { 14031 // Clean up both app data and code 14032 // All package moves are frozen until finished 14033 for (int userId : userIds) { 14034 try { 14035 mInstaller.destroyAppData(volumeUuid, move.packageName, userId, 14036 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0); 14037 } catch (InstallerException e) { 14038 Slog.w(TAG, String.valueOf(e)); 14039 } 14040 } 14041 removeCodePathLI(codeFile); 14042 } 14043 return true; 14044 } 14045 14046 void cleanUpResourcesLI() { 14047 throw new UnsupportedOperationException(); 14048 } 14049 14050 boolean doPostDeleteLI(boolean delete) { 14051 throw new UnsupportedOperationException(); 14052 } 14053 } 14054 14055 static String getAsecPackageName(String packageCid) { 14056 int idx = packageCid.lastIndexOf("-"); 14057 if (idx == -1) { 14058 return packageCid; 14059 } 14060 return packageCid.substring(0, idx); 14061 } 14062 14063 // Utility method used to create code paths based on package name and available index. 14064 private static String getNextCodePath(String oldCodePath, String prefix, String suffix) { 14065 String idxStr = ""; 14066 int idx = 1; 14067 // Fall back to default value of idx=1 if prefix is not 14068 // part of oldCodePath 14069 if (oldCodePath != null) { 14070 String subStr = oldCodePath; 14071 // Drop the suffix right away 14072 if (suffix != null && subStr.endsWith(suffix)) { 14073 subStr = subStr.substring(0, subStr.length() - suffix.length()); 14074 } 14075 // If oldCodePath already contains prefix find out the 14076 // ending index to either increment or decrement. 14077 int sidx = subStr.lastIndexOf(prefix); 14078 if (sidx != -1) { 14079 subStr = subStr.substring(sidx + prefix.length()); 14080 if (subStr != null) { 14081 if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) { 14082 subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length()); 14083 } 14084 try { 14085 idx = Integer.parseInt(subStr); 14086 if (idx <= 1) { 14087 idx++; 14088 } else { 14089 idx--; 14090 } 14091 } catch(NumberFormatException e) { 14092 } 14093 } 14094 } 14095 } 14096 idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx); 14097 return prefix + idxStr; 14098 } 14099 14100 private File getNextCodePath(File targetDir, String packageName) { 14101 int suffix = 1; 14102 File result; 14103 do { 14104 result = new File(targetDir, packageName + "-" + suffix); 14105 suffix++; 14106 } while (result.exists()); 14107 return result; 14108 } 14109 14110 // Utility method that returns the relative package path with respect 14111 // to the installation directory. Like say for /data/data/com.test-1.apk 14112 // string com.test-1 is returned. 14113 static String deriveCodePathName(String codePath) { 14114 if (codePath == null) { 14115 return null; 14116 } 14117 final File codeFile = new File(codePath); 14118 final String name = codeFile.getName(); 14119 if (codeFile.isDirectory()) { 14120 return name; 14121 } else if (name.endsWith(".apk") || name.endsWith(".tmp")) { 14122 final int lastDot = name.lastIndexOf('.'); 14123 return name.substring(0, lastDot); 14124 } else { 14125 Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK"); 14126 return null; 14127 } 14128 } 14129 14130 static class PackageInstalledInfo { 14131 String name; 14132 int uid; 14133 // The set of users that originally had this package installed. 14134 int[] origUsers; 14135 // The set of users that now have this package installed. 14136 int[] newUsers; 14137 PackageParser.Package pkg; 14138 int returnCode; 14139 String returnMsg; 14140 PackageRemovedInfo removedInfo; 14141 ArrayMap<String, PackageInstalledInfo> addedChildPackages; 14142 14143 public void setError(int code, String msg) { 14144 setReturnCode(code); 14145 setReturnMessage(msg); 14146 Slog.w(TAG, msg); 14147 } 14148 14149 public void setError(String msg, PackageParserException e) { 14150 setReturnCode(e.error); 14151 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e)); 14152 Slog.w(TAG, msg, e); 14153 } 14154 14155 public void setError(String msg, PackageManagerException e) { 14156 returnCode = e.error; 14157 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e)); 14158 Slog.w(TAG, msg, e); 14159 } 14160 14161 public void setReturnCode(int returnCode) { 14162 this.returnCode = returnCode; 14163 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0; 14164 for (int i = 0; i < childCount; i++) { 14165 addedChildPackages.valueAt(i).returnCode = returnCode; 14166 } 14167 } 14168 14169 private void setReturnMessage(String returnMsg) { 14170 this.returnMsg = returnMsg; 14171 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0; 14172 for (int i = 0; i < childCount; i++) { 14173 addedChildPackages.valueAt(i).returnMsg = returnMsg; 14174 } 14175 } 14176 14177 // In some error cases we want to convey more info back to the observer 14178 String origPackage; 14179 String origPermission; 14180 } 14181 14182 /* 14183 * Install a non-existing package. 14184 */ 14185 private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags, 14186 int scanFlags, UserHandle user, String installerPackageName, String volumeUuid, 14187 PackageInstalledInfo res) { 14188 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage"); 14189 14190 // Remember this for later, in case we need to rollback this install 14191 String pkgName = pkg.packageName; 14192 14193 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg); 14194 14195 synchronized(mPackages) { 14196 if (mSettings.mRenamedPackages.containsKey(pkgName)) { 14197 // A package with the same name is already installed, though 14198 // it has been renamed to an older name. The package we 14199 // are trying to install should be installed as an update to 14200 // the existing one, but that has not been requested, so bail. 14201 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 14202 + " without first uninstalling package running as " 14203 + mSettings.mRenamedPackages.get(pkgName)); 14204 return; 14205 } 14206 if (mPackages.containsKey(pkgName)) { 14207 // Don't allow installation over an existing package with the same name. 14208 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 14209 + " without first uninstalling."); 14210 return; 14211 } 14212 } 14213 14214 try { 14215 PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 14216 System.currentTimeMillis(), user); 14217 14218 updateSettingsLI(newPackage, installerPackageName, null, res, user); 14219 14220 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 14221 prepareAppDataAfterInstallLIF(newPackage); 14222 14223 } else { 14224 // Remove package from internal structures, but keep around any 14225 // data that might have already existed 14226 deletePackageLIF(pkgName, UserHandle.ALL, false, null, 14227 PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null); 14228 } 14229 } catch (PackageManagerException e) { 14230 res.setError("Package couldn't be installed in " + pkg.codePath, e); 14231 } 14232 14233 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14234 } 14235 14236 private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) { 14237 // Can't rotate keys during boot or if sharedUser. 14238 if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null 14239 || !oldPs.keySetData.isUsingUpgradeKeySets()) { 14240 return false; 14241 } 14242 // app is using upgradeKeySets; make sure all are valid 14243 KeySetManagerService ksms = mSettings.mKeySetManagerService; 14244 long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets(); 14245 for (int i = 0; i < upgradeKeySets.length; i++) { 14246 if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) { 14247 Slog.wtf(TAG, "Package " 14248 + (oldPs.name != null ? oldPs.name : "<null>") 14249 + " contains upgrade-key-set reference to unknown key-set: " 14250 + upgradeKeySets[i] 14251 + " reverting to signatures check."); 14252 return false; 14253 } 14254 } 14255 return true; 14256 } 14257 14258 private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) { 14259 // Upgrade keysets are being used. Determine if new package has a superset of the 14260 // required keys. 14261 long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets(); 14262 KeySetManagerService ksms = mSettings.mKeySetManagerService; 14263 for (int i = 0; i < upgradeKeySets.length; i++) { 14264 Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]); 14265 if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) { 14266 return true; 14267 } 14268 } 14269 return false; 14270 } 14271 14272 private static void updateDigest(MessageDigest digest, File file) throws IOException { 14273 try (DigestInputStream digestStream = 14274 new DigestInputStream(new FileInputStream(file), digest)) { 14275 while (digestStream.read() != -1) {} // nothing to do; just plow through the file 14276 } 14277 } 14278 14279 private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags, 14280 UserHandle user, String installerPackageName, PackageInstalledInfo res) { 14281 final boolean isEphemeral = (policyFlags & PackageParser.PARSE_IS_EPHEMERAL) != 0; 14282 14283 final PackageParser.Package oldPackage; 14284 final String pkgName = pkg.packageName; 14285 final int[] allUsers; 14286 final int[] installedUsers; 14287 14288 synchronized(mPackages) { 14289 oldPackage = mPackages.get(pkgName); 14290 if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage); 14291 14292 // don't allow upgrade to target a release SDK from a pre-release SDK 14293 final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion 14294 == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT; 14295 final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion 14296 == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT; 14297 if (oldTargetsPreRelease 14298 && !newTargetsPreRelease 14299 && ((policyFlags & PackageParser.PARSE_FORCE_SDK) == 0)) { 14300 Slog.w(TAG, "Can't install package targeting released sdk"); 14301 res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE); 14302 return; 14303 } 14304 14305 // don't allow an upgrade from full to ephemeral 14306 final boolean oldIsEphemeral = oldPackage.applicationInfo.isEphemeralApp(); 14307 if (isEphemeral && !oldIsEphemeral) { 14308 // can't downgrade from full to ephemeral 14309 Slog.w(TAG, "Can't replace app with ephemeral: " + pkgName); 14310 res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID); 14311 return; 14312 } 14313 14314 // verify signatures are valid 14315 final PackageSetting ps = mSettings.mPackages.get(pkgName); 14316 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { 14317 if (!checkUpgradeKeySetLP(ps, pkg)) { 14318 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 14319 "New package not signed by keys specified by upgrade-keysets: " 14320 + pkgName); 14321 return; 14322 } 14323 } else { 14324 // default to original signature matching 14325 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures) 14326 != PackageManager.SIGNATURE_MATCH) { 14327 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 14328 "New package has a different signature: " + pkgName); 14329 return; 14330 } 14331 } 14332 14333 // don't allow a system upgrade unless the upgrade hash matches 14334 if (oldPackage.restrictUpdateHash != null && oldPackage.isSystemApp()) { 14335 byte[] digestBytes = null; 14336 try { 14337 final MessageDigest digest = MessageDigest.getInstance("SHA-512"); 14338 updateDigest(digest, new File(pkg.baseCodePath)); 14339 if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) { 14340 for (String path : pkg.splitCodePaths) { 14341 updateDigest(digest, new File(path)); 14342 } 14343 } 14344 digestBytes = digest.digest(); 14345 } catch (NoSuchAlgorithmException | IOException e) { 14346 res.setError(INSTALL_FAILED_INVALID_APK, 14347 "Could not compute hash: " + pkgName); 14348 return; 14349 } 14350 if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) { 14351 res.setError(INSTALL_FAILED_INVALID_APK, 14352 "New package fails restrict-update check: " + pkgName); 14353 return; 14354 } 14355 // retain upgrade restriction 14356 pkg.restrictUpdateHash = oldPackage.restrictUpdateHash; 14357 } 14358 14359 // Check for shared user id changes 14360 String invalidPackageName = 14361 getParentOrChildPackageChangedSharedUser(oldPackage, pkg); 14362 if (invalidPackageName != null) { 14363 res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 14364 "Package " + invalidPackageName + " tried to change user " 14365 + oldPackage.mSharedUserId); 14366 return; 14367 } 14368 14369 // In case of rollback, remember per-user/profile install state 14370 allUsers = sUserManager.getUserIds(); 14371 installedUsers = ps.queryInstalledUsers(allUsers, true); 14372 } 14373 14374 // Update what is removed 14375 res.removedInfo = new PackageRemovedInfo(); 14376 res.removedInfo.uid = oldPackage.applicationInfo.uid; 14377 res.removedInfo.removedPackage = oldPackage.packageName; 14378 res.removedInfo.isUpdate = true; 14379 res.removedInfo.origUsers = installedUsers; 14380 final int childCount = (oldPackage.childPackages != null) 14381 ? oldPackage.childPackages.size() : 0; 14382 for (int i = 0; i < childCount; i++) { 14383 boolean childPackageUpdated = false; 14384 PackageParser.Package childPkg = oldPackage.childPackages.get(i); 14385 if (res.addedChildPackages != null) { 14386 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName); 14387 if (childRes != null) { 14388 childRes.removedInfo.uid = childPkg.applicationInfo.uid; 14389 childRes.removedInfo.removedPackage = childPkg.packageName; 14390 childRes.removedInfo.isUpdate = true; 14391 childPackageUpdated = true; 14392 } 14393 } 14394 if (!childPackageUpdated) { 14395 PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(); 14396 childRemovedRes.removedPackage = childPkg.packageName; 14397 childRemovedRes.isUpdate = false; 14398 childRemovedRes.dataRemoved = true; 14399 synchronized (mPackages) { 14400 PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName); 14401 if (childPs != null) { 14402 childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true); 14403 } 14404 } 14405 if (res.removedInfo.removedChildPackages == null) { 14406 res.removedInfo.removedChildPackages = new ArrayMap<>(); 14407 } 14408 res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes); 14409 } 14410 } 14411 14412 boolean sysPkg = (isSystemApp(oldPackage)); 14413 if (sysPkg) { 14414 // Set the system/privileged flags as needed 14415 final boolean privileged = 14416 (oldPackage.applicationInfo.privateFlags 14417 & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; 14418 final int systemPolicyFlags = policyFlags 14419 | PackageParser.PARSE_IS_SYSTEM 14420 | (privileged ? PackageParser.PARSE_IS_PRIVILEGED : 0); 14421 14422 replaceSystemPackageLIF(oldPackage, pkg, systemPolicyFlags, scanFlags, 14423 user, allUsers, installerPackageName, res); 14424 } else { 14425 replaceNonSystemPackageLIF(oldPackage, pkg, policyFlags, scanFlags, 14426 user, allUsers, installerPackageName, res); 14427 } 14428 } 14429 14430 public List<String> getPreviousCodePaths(String packageName) { 14431 final PackageSetting ps = mSettings.mPackages.get(packageName); 14432 final List<String> result = new ArrayList<String>(); 14433 if (ps != null && ps.oldCodePaths != null) { 14434 result.addAll(ps.oldCodePaths); 14435 } 14436 return result; 14437 } 14438 14439 private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage, 14440 PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user, 14441 int[] allUsers, String installerPackageName, PackageInstalledInfo res) { 14442 if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old=" 14443 + deletedPackage); 14444 14445 String pkgName = deletedPackage.packageName; 14446 boolean deletedPkg = true; 14447 boolean addedPkg = false; 14448 boolean updatedSettings = false; 14449 final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0; 14450 final int deleteFlags = PackageManager.DELETE_KEEP_DATA 14451 | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP); 14452 14453 final long origUpdateTime = (pkg.mExtras != null) 14454 ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0; 14455 14456 // First delete the existing package while retaining the data directory 14457 if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags, 14458 res.removedInfo, true, pkg)) { 14459 // If the existing package wasn't successfully deleted 14460 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI"); 14461 deletedPkg = false; 14462 } else { 14463 // Successfully deleted the old package; proceed with replace. 14464 14465 // If deleted package lived in a container, give users a chance to 14466 // relinquish resources before killing. 14467 if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) { 14468 if (DEBUG_INSTALL) { 14469 Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE"); 14470 } 14471 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid }; 14472 final ArrayList<String> pkgList = new ArrayList<String>(1); 14473 pkgList.add(deletedPackage.applicationInfo.packageName); 14474 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null); 14475 } 14476 14477 clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE 14478 | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 14479 clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL); 14480 14481 try { 14482 final PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, 14483 scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user); 14484 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user); 14485 14486 // Update the in-memory copy of the previous code paths. 14487 PackageSetting ps = mSettings.mPackages.get(pkgName); 14488 if (!killApp) { 14489 if (ps.oldCodePaths == null) { 14490 ps.oldCodePaths = new ArraySet<>(); 14491 } 14492 Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath); 14493 if (deletedPackage.splitCodePaths != null) { 14494 Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths); 14495 } 14496 } else { 14497 ps.oldCodePaths = null; 14498 } 14499 if (ps.childPackageNames != null) { 14500 for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) { 14501 final String childPkgName = ps.childPackageNames.get(i); 14502 final PackageSetting childPs = mSettings.mPackages.get(childPkgName); 14503 childPs.oldCodePaths = ps.oldCodePaths; 14504 } 14505 } 14506 prepareAppDataAfterInstallLIF(newPackage); 14507 addedPkg = true; 14508 } catch (PackageManagerException e) { 14509 res.setError("Package couldn't be installed in " + pkg.codePath, e); 14510 } 14511 } 14512 14513 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 14514 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName); 14515 14516 // Revert all internal state mutations and added folders for the failed install 14517 if (addedPkg) { 14518 deletePackageLIF(pkgName, null, true, allUsers, deleteFlags, 14519 res.removedInfo, true, null); 14520 } 14521 14522 // Restore the old package 14523 if (deletedPkg) { 14524 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage); 14525 File restoreFile = new File(deletedPackage.codePath); 14526 // Parse old package 14527 boolean oldExternal = isExternal(deletedPackage); 14528 int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY | 14529 (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) | 14530 (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0); 14531 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME; 14532 try { 14533 scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, 14534 null); 14535 } catch (PackageManagerException e) { 14536 Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: " 14537 + e.getMessage()); 14538 return; 14539 } 14540 14541 synchronized (mPackages) { 14542 // Ensure the installer package name up to date 14543 setInstallerPackageNameLPw(deletedPackage, installerPackageName); 14544 14545 // Update permissions for restored package 14546 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL); 14547 14548 mSettings.writeLPr(); 14549 } 14550 14551 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade"); 14552 } 14553 } else { 14554 synchronized (mPackages) { 14555 PackageSetting ps = mSettings.peekPackageLPr(pkg.packageName); 14556 if (ps != null) { 14557 res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null; 14558 if (res.removedInfo.removedChildPackages != null) { 14559 final int childCount = res.removedInfo.removedChildPackages.size(); 14560 // Iterate in reverse as we may modify the collection 14561 for (int i = childCount - 1; i >= 0; i--) { 14562 String childPackageName = res.removedInfo.removedChildPackages.keyAt(i); 14563 if (res.addedChildPackages.containsKey(childPackageName)) { 14564 res.removedInfo.removedChildPackages.removeAt(i); 14565 } else { 14566 PackageRemovedInfo childInfo = res.removedInfo 14567 .removedChildPackages.valueAt(i); 14568 childInfo.removedForAllUsers = mPackages.get( 14569 childInfo.removedPackage) == null; 14570 } 14571 } 14572 } 14573 } 14574 } 14575 } 14576 } 14577 14578 private void replaceSystemPackageLIF(PackageParser.Package deletedPackage, 14579 PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user, 14580 int[] allUsers, String installerPackageName, PackageInstalledInfo res) { 14581 if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg 14582 + ", old=" + deletedPackage); 14583 14584 final boolean disabledSystem; 14585 14586 // Remove existing system package 14587 removePackageLI(deletedPackage, true); 14588 14589 synchronized (mPackages) { 14590 disabledSystem = disableSystemPackageLPw(deletedPackage, pkg); 14591 } 14592 if (!disabledSystem) { 14593 // We didn't need to disable the .apk as a current system package, 14594 // which means we are replacing another update that is already 14595 // installed. We need to make sure to delete the older one's .apk. 14596 res.removedInfo.args = createInstallArgsForExisting(0, 14597 deletedPackage.applicationInfo.getCodePath(), 14598 deletedPackage.applicationInfo.getResourcePath(), 14599 getAppDexInstructionSets(deletedPackage.applicationInfo)); 14600 } else { 14601 res.removedInfo.args = null; 14602 } 14603 14604 // Successfully disabled the old package. Now proceed with re-installation 14605 clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE 14606 | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 14607 clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL); 14608 14609 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 14610 pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP, 14611 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP); 14612 14613 PackageParser.Package newPackage = null; 14614 try { 14615 // Add the package to the internal data structures 14616 newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 0, user); 14617 14618 // Set the update and install times 14619 PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras; 14620 setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime, 14621 System.currentTimeMillis()); 14622 14623 // Update the package dynamic state if succeeded 14624 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 14625 // Now that the install succeeded make sure we remove data 14626 // directories for any child package the update removed. 14627 final int deletedChildCount = (deletedPackage.childPackages != null) 14628 ? deletedPackage.childPackages.size() : 0; 14629 final int newChildCount = (newPackage.childPackages != null) 14630 ? newPackage.childPackages.size() : 0; 14631 for (int i = 0; i < deletedChildCount; i++) { 14632 PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i); 14633 boolean childPackageDeleted = true; 14634 for (int j = 0; j < newChildCount; j++) { 14635 PackageParser.Package newChildPkg = newPackage.childPackages.get(j); 14636 if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) { 14637 childPackageDeleted = false; 14638 break; 14639 } 14640 } 14641 if (childPackageDeleted) { 14642 PackageSetting ps = mSettings.getDisabledSystemPkgLPr( 14643 deletedChildPkg.packageName); 14644 if (ps != null && res.removedInfo.removedChildPackages != null) { 14645 PackageRemovedInfo removedChildRes = res.removedInfo 14646 .removedChildPackages.get(deletedChildPkg.packageName); 14647 removePackageDataLIF(ps, allUsers, removedChildRes, 0, false); 14648 removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null; 14649 } 14650 } 14651 } 14652 14653 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user); 14654 prepareAppDataAfterInstallLIF(newPackage); 14655 } 14656 } catch (PackageManagerException e) { 14657 res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR); 14658 res.setError("Package couldn't be installed in " + pkg.codePath, e); 14659 } 14660 14661 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 14662 // Re installation failed. Restore old information 14663 // Remove new pkg information 14664 if (newPackage != null) { 14665 removeInstalledPackageLI(newPackage, true); 14666 } 14667 // Add back the old system package 14668 try { 14669 scanPackageTracedLI(deletedPackage, policyFlags, SCAN_UPDATE_SIGNATURE, 0, user); 14670 } catch (PackageManagerException e) { 14671 Slog.e(TAG, "Failed to restore original package: " + e.getMessage()); 14672 } 14673 14674 synchronized (mPackages) { 14675 if (disabledSystem) { 14676 enableSystemPackageLPw(deletedPackage); 14677 } 14678 14679 // Ensure the installer package name up to date 14680 setInstallerPackageNameLPw(deletedPackage, installerPackageName); 14681 14682 // Update permissions for restored package 14683 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL); 14684 14685 mSettings.writeLPr(); 14686 } 14687 14688 Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName 14689 + " after failed upgrade"); 14690 } 14691 } 14692 14693 /** 14694 * Checks whether the parent or any of the child packages have a change shared 14695 * user. For a package to be a valid update the shred users of the parent and 14696 * the children should match. We may later support changing child shared users. 14697 * @param oldPkg The updated package. 14698 * @param newPkg The update package. 14699 * @return The shared user that change between the versions. 14700 */ 14701 private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg, 14702 PackageParser.Package newPkg) { 14703 // Check parent shared user 14704 if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) { 14705 return newPkg.packageName; 14706 } 14707 // Check child shared users 14708 final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0; 14709 final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0; 14710 for (int i = 0; i < newChildCount; i++) { 14711 PackageParser.Package newChildPkg = newPkg.childPackages.get(i); 14712 // If this child was present, did it have the same shared user? 14713 for (int j = 0; j < oldChildCount; j++) { 14714 PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j); 14715 if (newChildPkg.packageName.equals(oldChildPkg.packageName) 14716 && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) { 14717 return newChildPkg.packageName; 14718 } 14719 } 14720 } 14721 return null; 14722 } 14723 14724 private void removeNativeBinariesLI(PackageSetting ps) { 14725 // Remove the lib path for the parent package 14726 if (ps != null) { 14727 NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString); 14728 // Remove the lib path for the child packages 14729 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0; 14730 for (int i = 0; i < childCount; i++) { 14731 PackageSetting childPs = null; 14732 synchronized (mPackages) { 14733 childPs = mSettings.peekPackageLPr(ps.childPackageNames.get(i)); 14734 } 14735 if (childPs != null) { 14736 NativeLibraryHelper.removeNativeBinariesLI(childPs 14737 .legacyNativeLibraryPathString); 14738 } 14739 } 14740 } 14741 } 14742 14743 private void enableSystemPackageLPw(PackageParser.Package pkg) { 14744 // Enable the parent package 14745 mSettings.enableSystemPackageLPw(pkg.packageName); 14746 // Enable the child packages 14747 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 14748 for (int i = 0; i < childCount; i++) { 14749 PackageParser.Package childPkg = pkg.childPackages.get(i); 14750 mSettings.enableSystemPackageLPw(childPkg.packageName); 14751 } 14752 } 14753 14754 private boolean disableSystemPackageLPw(PackageParser.Package oldPkg, 14755 PackageParser.Package newPkg) { 14756 // Disable the parent package (parent always replaced) 14757 boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true); 14758 // Disable the child packages 14759 final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0; 14760 for (int i = 0; i < childCount; i++) { 14761 PackageParser.Package childPkg = oldPkg.childPackages.get(i); 14762 final boolean replace = newPkg.hasChildPackage(childPkg.packageName); 14763 disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace); 14764 } 14765 return disabled; 14766 } 14767 14768 private void setInstallerPackageNameLPw(PackageParser.Package pkg, 14769 String installerPackageName) { 14770 // Enable the parent package 14771 mSettings.setInstallerPackageName(pkg.packageName, installerPackageName); 14772 // Enable the child packages 14773 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 14774 for (int i = 0; i < childCount; i++) { 14775 PackageParser.Package childPkg = pkg.childPackages.get(i); 14776 mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName); 14777 } 14778 } 14779 14780 private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) { 14781 // Collect all used permissions in the UID 14782 ArraySet<String> usedPermissions = new ArraySet<>(); 14783 final int packageCount = su.packages.size(); 14784 for (int i = 0; i < packageCount; i++) { 14785 PackageSetting ps = su.packages.valueAt(i); 14786 if (ps.pkg == null) { 14787 continue; 14788 } 14789 final int requestedPermCount = ps.pkg.requestedPermissions.size(); 14790 for (int j = 0; j < requestedPermCount; j++) { 14791 String permission = ps.pkg.requestedPermissions.get(j); 14792 BasePermission bp = mSettings.mPermissions.get(permission); 14793 if (bp != null) { 14794 usedPermissions.add(permission); 14795 } 14796 } 14797 } 14798 14799 PermissionsState permissionsState = su.getPermissionsState(); 14800 // Prune install permissions 14801 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates(); 14802 final int installPermCount = installPermStates.size(); 14803 for (int i = installPermCount - 1; i >= 0; i--) { 14804 PermissionState permissionState = installPermStates.get(i); 14805 if (!usedPermissions.contains(permissionState.getName())) { 14806 BasePermission bp = mSettings.mPermissions.get(permissionState.getName()); 14807 if (bp != null) { 14808 permissionsState.revokeInstallPermission(bp); 14809 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 14810 PackageManager.MASK_PERMISSION_FLAGS, 0); 14811 } 14812 } 14813 } 14814 14815 int[] runtimePermissionChangedUserIds = EmptyArray.INT; 14816 14817 // Prune runtime permissions 14818 for (int userId : allUserIds) { 14819 List<PermissionState> runtimePermStates = permissionsState 14820 .getRuntimePermissionStates(userId); 14821 final int runtimePermCount = runtimePermStates.size(); 14822 for (int i = runtimePermCount - 1; i >= 0; i--) { 14823 PermissionState permissionState = runtimePermStates.get(i); 14824 if (!usedPermissions.contains(permissionState.getName())) { 14825 BasePermission bp = mSettings.mPermissions.get(permissionState.getName()); 14826 if (bp != null) { 14827 permissionsState.revokeRuntimePermission(bp, userId); 14828 permissionsState.updatePermissionFlags(bp, userId, 14829 PackageManager.MASK_PERMISSION_FLAGS, 0); 14830 runtimePermissionChangedUserIds = ArrayUtils.appendInt( 14831 runtimePermissionChangedUserIds, userId); 14832 } 14833 } 14834 } 14835 } 14836 14837 return runtimePermissionChangedUserIds; 14838 } 14839 14840 private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, 14841 int[] allUsers, PackageInstalledInfo res, UserHandle user) { 14842 // Update the parent package setting 14843 updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers, 14844 res, user); 14845 // Update the child packages setting 14846 final int childCount = (newPackage.childPackages != null) 14847 ? newPackage.childPackages.size() : 0; 14848 for (int i = 0; i < childCount; i++) { 14849 PackageParser.Package childPackage = newPackage.childPackages.get(i); 14850 PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName); 14851 updateSettingsInternalLI(childPackage, installerPackageName, allUsers, 14852 childRes.origUsers, childRes, user); 14853 } 14854 } 14855 14856 private void updateSettingsInternalLI(PackageParser.Package newPackage, 14857 String installerPackageName, int[] allUsers, int[] installedForUsers, 14858 PackageInstalledInfo res, UserHandle user) { 14859 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 14860 14861 String pkgName = newPackage.packageName; 14862 synchronized (mPackages) { 14863 //write settings. the installStatus will be incomplete at this stage. 14864 //note that the new package setting would have already been 14865 //added to mPackages. It hasn't been persisted yet. 14866 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE); 14867 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings"); 14868 mSettings.writeLPr(); 14869 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14870 } 14871 14872 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath); 14873 synchronized (mPackages) { 14874 updatePermissionsLPw(newPackage.packageName, newPackage, 14875 UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0 14876 ? UPDATE_PERMISSIONS_ALL : 0)); 14877 // For system-bundled packages, we assume that installing an upgraded version 14878 // of the package implies that the user actually wants to run that new code, 14879 // so we enable the package. 14880 PackageSetting ps = mSettings.mPackages.get(pkgName); 14881 final int userId = user.getIdentifier(); 14882 if (ps != null) { 14883 if (isSystemApp(newPackage)) { 14884 if (DEBUG_INSTALL) { 14885 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName); 14886 } 14887 // Enable system package for requested users 14888 if (res.origUsers != null) { 14889 for (int origUserId : res.origUsers) { 14890 if (userId == UserHandle.USER_ALL || userId == origUserId) { 14891 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 14892 origUserId, installerPackageName); 14893 } 14894 } 14895 } 14896 // Also convey the prior install/uninstall state 14897 if (allUsers != null && installedForUsers != null) { 14898 for (int currentUserId : allUsers) { 14899 final boolean installed = ArrayUtils.contains( 14900 installedForUsers, currentUserId); 14901 if (DEBUG_INSTALL) { 14902 Slog.d(TAG, " user " + currentUserId + " => " + installed); 14903 } 14904 ps.setInstalled(installed, currentUserId); 14905 } 14906 // these install state changes will be persisted in the 14907 // upcoming call to mSettings.writeLPr(). 14908 } 14909 } 14910 // It's implied that when a user requests installation, they want the app to be 14911 // installed and enabled. 14912 if (userId != UserHandle.USER_ALL) { 14913 ps.setInstalled(true, userId); 14914 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName); 14915 } 14916 } 14917 res.name = pkgName; 14918 res.uid = newPackage.applicationInfo.uid; 14919 res.pkg = newPackage; 14920 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE); 14921 mSettings.setInstallerPackageName(pkgName, installerPackageName); 14922 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 14923 //to update install status 14924 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings"); 14925 mSettings.writeLPr(); 14926 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14927 } 14928 14929 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14930 } 14931 14932 private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) { 14933 try { 14934 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage"); 14935 installPackageLI(args, res); 14936 } finally { 14937 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14938 } 14939 } 14940 14941 private void installPackageLI(InstallArgs args, PackageInstalledInfo res) { 14942 final int installFlags = args.installFlags; 14943 final String installerPackageName = args.installerPackageName; 14944 final String volumeUuid = args.volumeUuid; 14945 final File tmpPackageFile = new File(args.getCodePath()); 14946 final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0); 14947 final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) 14948 || (args.volumeUuid != null)); 14949 final boolean ephemeral = ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0); 14950 final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0); 14951 boolean replace = false; 14952 int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE; 14953 if (args.move != null) { 14954 // moving a complete application; perform an initial scan on the new install location 14955 scanFlags |= SCAN_INITIAL; 14956 } 14957 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) { 14958 scanFlags |= SCAN_DONT_KILL_APP; 14959 } 14960 14961 // Result object to be returned 14962 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 14963 14964 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile); 14965 14966 // Sanity check 14967 if (ephemeral && (forwardLocked || onExternal)) { 14968 Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked 14969 + " external=" + onExternal); 14970 res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID); 14971 return; 14972 } 14973 14974 // Retrieve PackageSettings and parse package 14975 final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY 14976 | PackageParser.PARSE_ENFORCE_CODE 14977 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) 14978 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0) 14979 | (ephemeral ? PackageParser.PARSE_IS_EPHEMERAL : 0) 14980 | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0); 14981 PackageParser pp = new PackageParser(); 14982 pp.setSeparateProcesses(mSeparateProcesses); 14983 pp.setDisplayMetrics(mMetrics); 14984 14985 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage"); 14986 final PackageParser.Package pkg; 14987 try { 14988 pkg = pp.parsePackage(tmpPackageFile, parseFlags); 14989 } catch (PackageParserException e) { 14990 res.setError("Failed parse during installPackageLI", e); 14991 return; 14992 } finally { 14993 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14994 } 14995 14996 // If we are installing a clustered package add results for the children 14997 if (pkg.childPackages != null) { 14998 synchronized (mPackages) { 14999 final int childCount = pkg.childPackages.size(); 15000 for (int i = 0; i < childCount; i++) { 15001 PackageParser.Package childPkg = pkg.childPackages.get(i); 15002 PackageInstalledInfo childRes = new PackageInstalledInfo(); 15003 childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 15004 childRes.pkg = childPkg; 15005 childRes.name = childPkg.packageName; 15006 PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName); 15007 if (childPs != null) { 15008 childRes.origUsers = childPs.queryInstalledUsers( 15009 sUserManager.getUserIds(), true); 15010 } 15011 if ((mPackages.containsKey(childPkg.packageName))) { 15012 childRes.removedInfo = new PackageRemovedInfo(); 15013 childRes.removedInfo.removedPackage = childPkg.packageName; 15014 } 15015 if (res.addedChildPackages == null) { 15016 res.addedChildPackages = new ArrayMap<>(); 15017 } 15018 res.addedChildPackages.put(childPkg.packageName, childRes); 15019 } 15020 } 15021 } 15022 15023 // If package doesn't declare API override, mark that we have an install 15024 // time CPU ABI override. 15025 if (TextUtils.isEmpty(pkg.cpuAbiOverride)) { 15026 pkg.cpuAbiOverride = args.abiOverride; 15027 } 15028 15029 String pkgName = res.name = pkg.packageName; 15030 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) { 15031 if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) { 15032 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI"); 15033 return; 15034 } 15035 } 15036 15037 try { 15038 // either use what we've been given or parse directly from the APK 15039 if (args.certificates != null) { 15040 try { 15041 PackageParser.populateCertificates(pkg, args.certificates); 15042 } catch (PackageParserException e) { 15043 // there was something wrong with the certificates we were given; 15044 // try to pull them from the APK 15045 PackageParser.collectCertificates(pkg, parseFlags); 15046 } 15047 } else { 15048 PackageParser.collectCertificates(pkg, parseFlags); 15049 } 15050 } catch (PackageParserException e) { 15051 res.setError("Failed collect during installPackageLI", e); 15052 return; 15053 } 15054 15055 // Get rid of all references to package scan path via parser. 15056 pp = null; 15057 String oldCodePath = null; 15058 boolean systemApp = false; 15059 synchronized (mPackages) { 15060 // Check if installing already existing package 15061 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 15062 String oldName = mSettings.mRenamedPackages.get(pkgName); 15063 if (pkg.mOriginalPackages != null 15064 && pkg.mOriginalPackages.contains(oldName) 15065 && mPackages.containsKey(oldName)) { 15066 // This package is derived from an original package, 15067 // and this device has been updating from that original 15068 // name. We must continue using the original name, so 15069 // rename the new package here. 15070 pkg.setPackageName(oldName); 15071 pkgName = pkg.packageName; 15072 replace = true; 15073 if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName=" 15074 + oldName + " pkgName=" + pkgName); 15075 } else if (mPackages.containsKey(pkgName)) { 15076 // This package, under its official name, already exists 15077 // on the device; we should replace it. 15078 replace = true; 15079 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName); 15080 } 15081 15082 // Child packages are installed through the parent package 15083 if (pkg.parentPackage != null) { 15084 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME, 15085 "Package " + pkg.packageName + " is child of package " 15086 + pkg.parentPackage.parentPackage + ". Child packages " 15087 + "can be updated only through the parent package."); 15088 return; 15089 } 15090 15091 if (replace) { 15092 // Prevent apps opting out from runtime permissions 15093 PackageParser.Package oldPackage = mPackages.get(pkgName); 15094 final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion; 15095 final int newTargetSdk = pkg.applicationInfo.targetSdkVersion; 15096 if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1 15097 && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) { 15098 res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE, 15099 "Package " + pkg.packageName + " new target SDK " + newTargetSdk 15100 + " doesn't support runtime permissions but the old" 15101 + " target SDK " + oldTargetSdk + " does."); 15102 return; 15103 } 15104 15105 // Prevent installing of child packages 15106 if (oldPackage.parentPackage != null) { 15107 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME, 15108 "Package " + pkg.packageName + " is child of package " 15109 + oldPackage.parentPackage + ". Child packages " 15110 + "can be updated only through the parent package."); 15111 return; 15112 } 15113 } 15114 } 15115 15116 PackageSetting ps = mSettings.mPackages.get(pkgName); 15117 if (ps != null) { 15118 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps); 15119 15120 // Quick sanity check that we're signed correctly if updating; 15121 // we'll check this again later when scanning, but we want to 15122 // bail early here before tripping over redefined permissions. 15123 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { 15124 if (!checkUpgradeKeySetLP(ps, pkg)) { 15125 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 15126 + pkg.packageName + " upgrade keys do not match the " 15127 + "previously installed version"); 15128 return; 15129 } 15130 } else { 15131 try { 15132 verifySignaturesLP(ps, pkg); 15133 } catch (PackageManagerException e) { 15134 res.setError(e.error, e.getMessage()); 15135 return; 15136 } 15137 } 15138 15139 oldCodePath = mSettings.mPackages.get(pkgName).codePathString; 15140 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 15141 systemApp = (ps.pkg.applicationInfo.flags & 15142 ApplicationInfo.FLAG_SYSTEM) != 0; 15143 } 15144 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 15145 } 15146 15147 // Check whether the newly-scanned package wants to define an already-defined perm 15148 int N = pkg.permissions.size(); 15149 for (int i = N-1; i >= 0; i--) { 15150 PackageParser.Permission perm = pkg.permissions.get(i); 15151 BasePermission bp = mSettings.mPermissions.get(perm.info.name); 15152 if (bp != null) { 15153 // If the defining package is signed with our cert, it's okay. This 15154 // also includes the "updating the same package" case, of course. 15155 // "updating same package" could also involve key-rotation. 15156 final boolean sigsOk; 15157 if (bp.sourcePackage.equals(pkg.packageName) 15158 && (bp.packageSetting instanceof PackageSetting) 15159 && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting, 15160 scanFlags))) { 15161 sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg); 15162 } else { 15163 sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures, 15164 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 15165 } 15166 if (!sigsOk) { 15167 // If the owning package is the system itself, we log but allow 15168 // install to proceed; we fail the install on all other permission 15169 // redefinitions. 15170 if (!bp.sourcePackage.equals("android")) { 15171 res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package " 15172 + pkg.packageName + " attempting to redeclare permission " 15173 + perm.info.name + " already owned by " + bp.sourcePackage); 15174 res.origPermission = perm.info.name; 15175 res.origPackage = bp.sourcePackage; 15176 return; 15177 } else { 15178 Slog.w(TAG, "Package " + pkg.packageName 15179 + " attempting to redeclare system permission " 15180 + perm.info.name + "; ignoring new declaration"); 15181 pkg.permissions.remove(i); 15182 } 15183 } 15184 } 15185 } 15186 } 15187 15188 if (systemApp) { 15189 if (onExternal) { 15190 // Abort update; system app can't be replaced with app on sdcard 15191 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION, 15192 "Cannot install updates to system apps on sdcard"); 15193 return; 15194 } else if (ephemeral) { 15195 // Abort update; system app can't be replaced with an ephemeral app 15196 res.setError(INSTALL_FAILED_EPHEMERAL_INVALID, 15197 "Cannot update a system app with an ephemeral app"); 15198 return; 15199 } 15200 } 15201 15202 if (args.move != null) { 15203 // We did an in-place move, so dex is ready to roll 15204 scanFlags |= SCAN_NO_DEX; 15205 scanFlags |= SCAN_MOVE; 15206 15207 synchronized (mPackages) { 15208 final PackageSetting ps = mSettings.mPackages.get(pkgName); 15209 if (ps == null) { 15210 res.setError(INSTALL_FAILED_INTERNAL_ERROR, 15211 "Missing settings for moved package " + pkgName); 15212 } 15213 15214 // We moved the entire application as-is, so bring over the 15215 // previously derived ABI information. 15216 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString; 15217 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString; 15218 } 15219 15220 } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) { 15221 // Enable SCAN_NO_DEX flag to skip dexopt at a later stage 15222 scanFlags |= SCAN_NO_DEX; 15223 15224 try { 15225 String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ? 15226 args.abiOverride : pkg.cpuAbiOverride); 15227 derivePackageAbi(pkg, new File(pkg.codePath), abiOverride, 15228 true /* extract libs */); 15229 } catch (PackageManagerException pme) { 15230 Slog.e(TAG, "Error deriving application ABI", pme); 15231 res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI"); 15232 return; 15233 } 15234 15235 // Shared libraries for the package need to be updated. 15236 synchronized (mPackages) { 15237 try { 15238 updateSharedLibrariesLPw(pkg, null); 15239 } catch (PackageManagerException e) { 15240 Slog.e(TAG, "updateSharedLibrariesLPw failed: " + e.getMessage()); 15241 } 15242 } 15243 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 15244 // Do not run PackageDexOptimizer through the local performDexOpt 15245 // method because `pkg` may not be in `mPackages` yet. 15246 // 15247 // Also, don't fail application installs if the dexopt step fails. 15248 mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles, 15249 null /* instructionSets */, false /* checkProfiles */, 15250 getCompilerFilterForReason(REASON_INSTALL), 15251 getOrCreateCompilerPackageStats(pkg)); 15252 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 15253 15254 // Notify BackgroundDexOptService that the package has been changed. 15255 // If this is an update of a package which used to fail to compile, 15256 // BDOS will remove it from its blacklist. 15257 BackgroundDexOptService.notifyPackageChanged(pkg.packageName); 15258 } 15259 15260 if (!args.doRename(res.returnCode, pkg, oldCodePath)) { 15261 res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename"); 15262 return; 15263 } 15264 15265 startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg); 15266 15267 try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags, 15268 "installPackageLI")) { 15269 if (replace) { 15270 replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user, 15271 installerPackageName, res); 15272 } else { 15273 installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES, 15274 args.user, installerPackageName, volumeUuid, res); 15275 } 15276 } 15277 synchronized (mPackages) { 15278 final PackageSetting ps = mSettings.mPackages.get(pkgName); 15279 if (ps != null) { 15280 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 15281 } 15282 15283 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 15284 for (int i = 0; i < childCount; i++) { 15285 PackageParser.Package childPkg = pkg.childPackages.get(i); 15286 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName); 15287 PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName); 15288 if (childPs != null) { 15289 childRes.newUsers = childPs.queryInstalledUsers( 15290 sUserManager.getUserIds(), true); 15291 } 15292 } 15293 } 15294 } 15295 15296 private void startIntentFilterVerifications(int userId, boolean replacing, 15297 PackageParser.Package pkg) { 15298 if (mIntentFilterVerifierComponent == null) { 15299 Slog.w(TAG, "No IntentFilter verification will not be done as " 15300 + "there is no IntentFilterVerifier available!"); 15301 return; 15302 } 15303 15304 final int verifierUid = getPackageUid( 15305 mIntentFilterVerifierComponent.getPackageName(), 15306 MATCH_DEBUG_TRIAGED_MISSING, 15307 (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId); 15308 15309 Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 15310 msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid); 15311 mHandler.sendMessage(msg); 15312 15313 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 15314 for (int i = 0; i < childCount; i++) { 15315 PackageParser.Package childPkg = pkg.childPackages.get(i); 15316 msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 15317 msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid); 15318 mHandler.sendMessage(msg); 15319 } 15320 } 15321 15322 private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing, 15323 PackageParser.Package pkg) { 15324 int size = pkg.activities.size(); 15325 if (size == 0) { 15326 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 15327 "No activity, so no need to verify any IntentFilter!"); 15328 return; 15329 } 15330 15331 final boolean hasDomainURLs = hasDomainURLs(pkg); 15332 if (!hasDomainURLs) { 15333 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 15334 "No domain URLs, so no need to verify any IntentFilter!"); 15335 return; 15336 } 15337 15338 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId 15339 + " if any IntentFilter from the " + size 15340 + " Activities needs verification ..."); 15341 15342 int count = 0; 15343 final String packageName = pkg.packageName; 15344 15345 synchronized (mPackages) { 15346 // If this is a new install and we see that we've already run verification for this 15347 // package, we have nothing to do: it means the state was restored from backup. 15348 if (!replacing) { 15349 IntentFilterVerificationInfo ivi = 15350 mSettings.getIntentFilterVerificationLPr(packageName); 15351 if (ivi != null) { 15352 if (DEBUG_DOMAIN_VERIFICATION) { 15353 Slog.i(TAG, "Package " + packageName+ " already verified: status=" 15354 + ivi.getStatusString()); 15355 } 15356 return; 15357 } 15358 } 15359 15360 // If any filters need to be verified, then all need to be. 15361 boolean needToVerify = false; 15362 for (PackageParser.Activity a : pkg.activities) { 15363 for (ActivityIntentInfo filter : a.intents) { 15364 if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) { 15365 if (DEBUG_DOMAIN_VERIFICATION) { 15366 Slog.d(TAG, "Intent filter needs verification, so processing all filters"); 15367 } 15368 needToVerify = true; 15369 break; 15370 } 15371 } 15372 } 15373 15374 if (needToVerify) { 15375 final int verificationId = mIntentFilterVerificationToken++; 15376 for (PackageParser.Activity a : pkg.activities) { 15377 for (ActivityIntentInfo filter : a.intents) { 15378 if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) { 15379 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 15380 "Verification needed for IntentFilter:" + filter.toString()); 15381 mIntentFilterVerifier.addOneIntentFilterVerification( 15382 verifierUid, userId, verificationId, filter, packageName); 15383 count++; 15384 } 15385 } 15386 } 15387 } 15388 } 15389 15390 if (count > 0) { 15391 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count 15392 + " IntentFilter verification" + (count > 1 ? "s" : "") 15393 + " for userId:" + userId); 15394 mIntentFilterVerifier.startVerifications(userId); 15395 } else { 15396 if (DEBUG_DOMAIN_VERIFICATION) { 15397 Slog.d(TAG, "No filters or not all autoVerify for " + packageName); 15398 } 15399 } 15400 } 15401 15402 private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) { 15403 final ComponentName cn = filter.activity.getComponentName(); 15404 final String packageName = cn.getPackageName(); 15405 15406 IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr( 15407 packageName); 15408 if (ivi == null) { 15409 return true; 15410 } 15411 int status = ivi.getStatus(); 15412 switch (status) { 15413 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 15414 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 15415 return true; 15416 15417 default: 15418 // Nothing to do 15419 return false; 15420 } 15421 } 15422 15423 private static boolean isMultiArch(ApplicationInfo info) { 15424 return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0; 15425 } 15426 15427 private static boolean isExternal(PackageParser.Package pkg) { 15428 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 15429 } 15430 15431 private static boolean isExternal(PackageSetting ps) { 15432 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 15433 } 15434 15435 private static boolean isEphemeral(PackageParser.Package pkg) { 15436 return pkg.applicationInfo.isEphemeralApp(); 15437 } 15438 15439 private static boolean isEphemeral(PackageSetting ps) { 15440 return ps.pkg != null && isEphemeral(ps.pkg); 15441 } 15442 15443 private static boolean isSystemApp(PackageParser.Package pkg) { 15444 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 15445 } 15446 15447 private static boolean isPrivilegedApp(PackageParser.Package pkg) { 15448 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; 15449 } 15450 15451 private static boolean hasDomainURLs(PackageParser.Package pkg) { 15452 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0; 15453 } 15454 15455 private static boolean isSystemApp(PackageSetting ps) { 15456 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0; 15457 } 15458 15459 private static boolean isUpdatedSystemApp(PackageSetting ps) { 15460 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; 15461 } 15462 15463 private int packageFlagsToInstallFlags(PackageSetting ps) { 15464 int installFlags = 0; 15465 if (isEphemeral(ps)) { 15466 installFlags |= PackageManager.INSTALL_EPHEMERAL; 15467 } 15468 if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) { 15469 // This existing package was an external ASEC install when we have 15470 // the external flag without a UUID 15471 installFlags |= PackageManager.INSTALL_EXTERNAL; 15472 } 15473 if (ps.isForwardLocked()) { 15474 installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 15475 } 15476 return installFlags; 15477 } 15478 15479 private String getVolumeUuidForPackage(PackageParser.Package pkg) { 15480 if (isExternal(pkg)) { 15481 if (TextUtils.isEmpty(pkg.volumeUuid)) { 15482 return StorageManager.UUID_PRIMARY_PHYSICAL; 15483 } else { 15484 return pkg.volumeUuid; 15485 } 15486 } else { 15487 return StorageManager.UUID_PRIVATE_INTERNAL; 15488 } 15489 } 15490 15491 private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) { 15492 if (isExternal(pkg)) { 15493 if (TextUtils.isEmpty(pkg.volumeUuid)) { 15494 return mSettings.getExternalVersion(); 15495 } else { 15496 return mSettings.findOrCreateVersion(pkg.volumeUuid); 15497 } 15498 } else { 15499 return mSettings.getInternalVersion(); 15500 } 15501 } 15502 15503 private void deleteTempPackageFiles() { 15504 final FilenameFilter filter = new FilenameFilter() { 15505 public boolean accept(File dir, String name) { 15506 return name.startsWith("vmdl") && name.endsWith(".tmp"); 15507 } 15508 }; 15509 for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) { 15510 file.delete(); 15511 } 15512 } 15513 15514 @Override 15515 public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId, 15516 int flags) { 15517 deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId, 15518 flags); 15519 } 15520 15521 @Override 15522 public void deletePackage(final String packageName, 15523 final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) { 15524 mContext.enforceCallingOrSelfPermission( 15525 android.Manifest.permission.DELETE_PACKAGES, null); 15526 Preconditions.checkNotNull(packageName); 15527 Preconditions.checkNotNull(observer); 15528 final int uid = Binder.getCallingUid(); 15529 if (!isOrphaned(packageName) 15530 && !isCallerAllowedToSilentlyUninstall(uid, packageName)) { 15531 try { 15532 final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE); 15533 intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null)); 15534 intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder()); 15535 observer.onUserActionRequired(intent); 15536 } catch (RemoteException re) { 15537 } 15538 return; 15539 } 15540 final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0; 15541 final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId }; 15542 if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) { 15543 mContext.enforceCallingOrSelfPermission( 15544 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 15545 "deletePackage for user " + userId); 15546 } 15547 15548 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) { 15549 try { 15550 observer.onPackageDeleted(packageName, 15551 PackageManager.DELETE_FAILED_USER_RESTRICTED, null); 15552 } catch (RemoteException re) { 15553 } 15554 return; 15555 } 15556 15557 if (!deleteAllUsers && getBlockUninstallForUser(packageName, userId)) { 15558 try { 15559 observer.onPackageDeleted(packageName, 15560 PackageManager.DELETE_FAILED_OWNER_BLOCKED, null); 15561 } catch (RemoteException re) { 15562 } 15563 return; 15564 } 15565 15566 if (DEBUG_REMOVE) { 15567 Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId 15568 + " deleteAllUsers: " + deleteAllUsers ); 15569 } 15570 // Queue up an async operation since the package deletion may take a little while. 15571 mHandler.post(new Runnable() { 15572 public void run() { 15573 mHandler.removeCallbacks(this); 15574 int returnCode; 15575 if (!deleteAllUsers) { 15576 returnCode = deletePackageX(packageName, userId, deleteFlags); 15577 } else { 15578 int[] blockUninstallUserIds = getBlockUninstallForUsers(packageName, users); 15579 // If nobody is blocking uninstall, proceed with delete for all users 15580 if (ArrayUtils.isEmpty(blockUninstallUserIds)) { 15581 returnCode = deletePackageX(packageName, userId, deleteFlags); 15582 } else { 15583 // Otherwise uninstall individually for users with blockUninstalls=false 15584 final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS; 15585 for (int userId : users) { 15586 if (!ArrayUtils.contains(blockUninstallUserIds, userId)) { 15587 returnCode = deletePackageX(packageName, userId, userFlags); 15588 if (returnCode != PackageManager.DELETE_SUCCEEDED) { 15589 Slog.w(TAG, "Package delete failed for user " + userId 15590 + ", returnCode " + returnCode); 15591 } 15592 } 15593 } 15594 // The app has only been marked uninstalled for certain users. 15595 // We still need to report that delete was blocked 15596 returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED; 15597 } 15598 } 15599 try { 15600 observer.onPackageDeleted(packageName, returnCode, null); 15601 } catch (RemoteException e) { 15602 Log.i(TAG, "Observer no longer exists."); 15603 } //end catch 15604 } //end run 15605 }); 15606 } 15607 15608 private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) { 15609 if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID 15610 || callingUid == Process.SYSTEM_UID) { 15611 return true; 15612 } 15613 final int callingUserId = UserHandle.getUserId(callingUid); 15614 // If the caller installed the pkgName, then allow it to silently uninstall. 15615 if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) { 15616 return true; 15617 } 15618 15619 // Allow package verifier to silently uninstall. 15620 if (mRequiredVerifierPackage != null && 15621 callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) { 15622 return true; 15623 } 15624 15625 // Allow package uninstaller to silently uninstall. 15626 if (mRequiredUninstallerPackage != null && 15627 callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) { 15628 return true; 15629 } 15630 15631 // Allow storage manager to silently uninstall. 15632 if (mStorageManagerPackage != null && 15633 callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) { 15634 return true; 15635 } 15636 return false; 15637 } 15638 15639 private int[] getBlockUninstallForUsers(String packageName, int[] userIds) { 15640 int[] result = EMPTY_INT_ARRAY; 15641 for (int userId : userIds) { 15642 if (getBlockUninstallForUser(packageName, userId)) { 15643 result = ArrayUtils.appendInt(result, userId); 15644 } 15645 } 15646 return result; 15647 } 15648 15649 @Override 15650 public boolean isPackageDeviceAdminOnAnyUser(String packageName) { 15651 return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL); 15652 } 15653 15654 private boolean isPackageDeviceAdmin(String packageName, int userId) { 15655 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface( 15656 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); 15657 try { 15658 if (dpm != null) { 15659 final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent( 15660 /* callingUserOnly =*/ false); 15661 final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null 15662 : deviceOwnerComponentName.getPackageName(); 15663 // Does the package contains the device owner? 15664 // TODO Do we have to do it even if userId != UserHandle.USER_ALL? Otherwise, 15665 // this check is probably not needed, since DO should be registered as a device 15666 // admin on some user too. (Original bug for this: b/17657954) 15667 if (packageName.equals(deviceOwnerPackageName)) { 15668 return true; 15669 } 15670 // Does it contain a device admin for any user? 15671 int[] users; 15672 if (userId == UserHandle.USER_ALL) { 15673 users = sUserManager.getUserIds(); 15674 } else { 15675 users = new int[]{userId}; 15676 } 15677 for (int i = 0; i < users.length; ++i) { 15678 if (dpm.packageHasActiveAdmins(packageName, users[i])) { 15679 return true; 15680 } 15681 } 15682 } 15683 } catch (RemoteException e) { 15684 } 15685 return false; 15686 } 15687 15688 private boolean shouldKeepUninstalledPackageLPr(String packageName) { 15689 return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName); 15690 } 15691 15692 /** 15693 * This method is an internal method that could be get invoked either 15694 * to delete an installed package or to clean up a failed installation. 15695 * After deleting an installed package, a broadcast is sent to notify any 15696 * listeners that the package has been removed. For cleaning up a failed 15697 * installation, the broadcast is not necessary since the package's 15698 * installation wouldn't have sent the initial broadcast either 15699 * The key steps in deleting a package are 15700 * deleting the package information in internal structures like mPackages, 15701 * deleting the packages base directories through installd 15702 * updating mSettings to reflect current status 15703 * persisting settings for later use 15704 * sending a broadcast if necessary 15705 */ 15706 private int deletePackageX(String packageName, int userId, int deleteFlags) { 15707 final PackageRemovedInfo info = new PackageRemovedInfo(); 15708 final boolean res; 15709 15710 final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0 15711 ? UserHandle.USER_ALL : userId; 15712 15713 if (isPackageDeviceAdmin(packageName, removeUser)) { 15714 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin"); 15715 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER; 15716 } 15717 15718 PackageSetting uninstalledPs = null; 15719 15720 // for the uninstall-updates case and restricted profiles, remember the per- 15721 // user handle installed state 15722 int[] allUsers; 15723 synchronized (mPackages) { 15724 uninstalledPs = mSettings.mPackages.get(packageName); 15725 if (uninstalledPs == null) { 15726 Slog.w(TAG, "Not removing non-existent package " + packageName); 15727 return PackageManager.DELETE_FAILED_INTERNAL_ERROR; 15728 } 15729 allUsers = sUserManager.getUserIds(); 15730 info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true); 15731 } 15732 15733 final int freezeUser; 15734 if (isUpdatedSystemApp(uninstalledPs) 15735 && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) { 15736 // We're downgrading a system app, which will apply to all users, so 15737 // freeze them all during the downgrade 15738 freezeUser = UserHandle.USER_ALL; 15739 } else { 15740 freezeUser = removeUser; 15741 } 15742 15743 synchronized (mInstallLock) { 15744 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId); 15745 try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser, 15746 deleteFlags, "deletePackageX")) { 15747 res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers, 15748 deleteFlags | REMOVE_CHATTY, info, true, null); 15749 } 15750 synchronized (mPackages) { 15751 if (res) { 15752 mEphemeralApplicationRegistry.onPackageUninstalledLPw(uninstalledPs.pkg); 15753 } 15754 } 15755 } 15756 15757 if (res) { 15758 final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0; 15759 info.sendPackageRemovedBroadcasts(killApp); 15760 info.sendSystemPackageUpdatedBroadcasts(); 15761 info.sendSystemPackageAppearedBroadcasts(); 15762 } 15763 // Force a gc here. 15764 Runtime.getRuntime().gc(); 15765 // Delete the resources here after sending the broadcast to let 15766 // other processes clean up before deleting resources. 15767 if (info.args != null) { 15768 synchronized (mInstallLock) { 15769 info.args.doPostDeleteLI(true); 15770 } 15771 } 15772 15773 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR; 15774 } 15775 15776 class PackageRemovedInfo { 15777 String removedPackage; 15778 int uid = -1; 15779 int removedAppId = -1; 15780 int[] origUsers; 15781 int[] removedUsers = null; 15782 boolean isRemovedPackageSystemUpdate = false; 15783 boolean isUpdate; 15784 boolean dataRemoved; 15785 boolean removedForAllUsers; 15786 // Clean up resources deleted packages. 15787 InstallArgs args = null; 15788 ArrayMap<String, PackageRemovedInfo> removedChildPackages; 15789 ArrayMap<String, PackageInstalledInfo> appearedChildPackages; 15790 15791 void sendPackageRemovedBroadcasts(boolean killApp) { 15792 sendPackageRemovedBroadcastInternal(killApp); 15793 final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0; 15794 for (int i = 0; i < childCount; i++) { 15795 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i); 15796 childInfo.sendPackageRemovedBroadcastInternal(killApp); 15797 } 15798 } 15799 15800 void sendSystemPackageUpdatedBroadcasts() { 15801 if (isRemovedPackageSystemUpdate) { 15802 sendSystemPackageUpdatedBroadcastsInternal(); 15803 final int childCount = (removedChildPackages != null) 15804 ? removedChildPackages.size() : 0; 15805 for (int i = 0; i < childCount; i++) { 15806 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i); 15807 if (childInfo.isRemovedPackageSystemUpdate) { 15808 childInfo.sendSystemPackageUpdatedBroadcastsInternal(); 15809 } 15810 } 15811 } 15812 } 15813 15814 void sendSystemPackageAppearedBroadcasts() { 15815 final int packageCount = (appearedChildPackages != null) 15816 ? appearedChildPackages.size() : 0; 15817 for (int i = 0; i < packageCount; i++) { 15818 PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i); 15819 for (int userId : installedInfo.newUsers) { 15820 sendPackageAddedForUser(installedInfo.name, true, 15821 UserHandle.getAppId(installedInfo.uid), userId); 15822 } 15823 } 15824 } 15825 15826 private void sendSystemPackageUpdatedBroadcastsInternal() { 15827 Bundle extras = new Bundle(2); 15828 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 15829 extras.putBoolean(Intent.EXTRA_REPLACING, true); 15830 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, removedPackage, 15831 extras, 0, null, null, null); 15832 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, removedPackage, 15833 extras, 0, null, null, null); 15834 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null, 15835 null, 0, removedPackage, null, null); 15836 } 15837 15838 private void sendPackageRemovedBroadcastInternal(boolean killApp) { 15839 Bundle extras = new Bundle(2); 15840 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 15841 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved); 15842 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp); 15843 if (isUpdate || isRemovedPackageSystemUpdate) { 15844 extras.putBoolean(Intent.EXTRA_REPLACING, true); 15845 } 15846 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers); 15847 if (removedPackage != null) { 15848 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, 15849 extras, 0, null, null, removedUsers); 15850 if (dataRemoved && !isRemovedPackageSystemUpdate) { 15851 sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, 15852 removedPackage, extras, 0, null, null, removedUsers); 15853 } 15854 } 15855 if (removedAppId >= 0) { 15856 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, 0, null, null, 15857 removedUsers); 15858 } 15859 } 15860 } 15861 15862 /* 15863 * This method deletes the package from internal data structures. If the DONT_DELETE_DATA 15864 * flag is not set, the data directory is removed as well. 15865 * make sure this flag is set for partially installed apps. If not its meaningless to 15866 * delete a partially installed application. 15867 */ 15868 private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles, 15869 PackageRemovedInfo outInfo, int flags, boolean writeSettings) { 15870 String packageName = ps.name; 15871 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps); 15872 // Retrieve object to delete permissions for shared user later on 15873 final PackageParser.Package deletedPkg; 15874 final PackageSetting deletedPs; 15875 // reader 15876 synchronized (mPackages) { 15877 deletedPkg = mPackages.get(packageName); 15878 deletedPs = mSettings.mPackages.get(packageName); 15879 if (outInfo != null) { 15880 outInfo.removedPackage = packageName; 15881 outInfo.removedUsers = deletedPs != null 15882 ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true) 15883 : null; 15884 } 15885 } 15886 15887 removePackageLI(ps, (flags & REMOVE_CHATTY) != 0); 15888 15889 if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) { 15890 final PackageParser.Package resolvedPkg; 15891 if (deletedPkg != null) { 15892 resolvedPkg = deletedPkg; 15893 } else { 15894 // We don't have a parsed package when it lives on an ejected 15895 // adopted storage device, so fake something together 15896 resolvedPkg = new PackageParser.Package(ps.name); 15897 resolvedPkg.setVolumeUuid(ps.volumeUuid); 15898 } 15899 destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL, 15900 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 15901 destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL); 15902 if (outInfo != null) { 15903 outInfo.dataRemoved = true; 15904 } 15905 schedulePackageCleaning(packageName, UserHandle.USER_ALL, true); 15906 } 15907 15908 // writer 15909 synchronized (mPackages) { 15910 if (deletedPs != null) { 15911 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 15912 clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL); 15913 clearDefaultBrowserIfNeeded(packageName); 15914 if (outInfo != null) { 15915 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName); 15916 outInfo.removedAppId = mSettings.removePackageLPw(packageName); 15917 } 15918 updatePermissionsLPw(deletedPs.name, null, 0); 15919 if (deletedPs.sharedUser != null) { 15920 // Remove permissions associated with package. Since runtime 15921 // permissions are per user we have to kill the removed package 15922 // or packages running under the shared user of the removed 15923 // package if revoking the permissions requested only by the removed 15924 // package is successful and this causes a change in gids. 15925 for (int userId : UserManagerService.getInstance().getUserIds()) { 15926 final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs, 15927 userId); 15928 if (userIdToKill == UserHandle.USER_ALL 15929 || userIdToKill >= UserHandle.USER_SYSTEM) { 15930 // If gids changed for this user, kill all affected packages. 15931 mHandler.post(new Runnable() { 15932 @Override 15933 public void run() { 15934 // This has to happen with no lock held. 15935 killApplication(deletedPs.name, deletedPs.appId, 15936 KILL_APP_REASON_GIDS_CHANGED); 15937 } 15938 }); 15939 break; 15940 } 15941 } 15942 } 15943 clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL); 15944 } 15945 // make sure to preserve per-user disabled state if this removal was just 15946 // a downgrade of a system app to the factory package 15947 if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) { 15948 if (DEBUG_REMOVE) { 15949 Slog.d(TAG, "Propagating install state across downgrade"); 15950 } 15951 for (int userId : allUserHandles) { 15952 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId); 15953 if (DEBUG_REMOVE) { 15954 Slog.d(TAG, " user " + userId + " => " + installed); 15955 } 15956 ps.setInstalled(installed, userId); 15957 } 15958 } 15959 } 15960 // can downgrade to reader 15961 if (writeSettings) { 15962 // Save settings now 15963 mSettings.writeLPr(); 15964 } 15965 } 15966 if (outInfo != null) { 15967 // A user ID was deleted here. Go through all users and remove it 15968 // from KeyStore. 15969 removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId); 15970 } 15971 } 15972 15973 static boolean locationIsPrivileged(File path) { 15974 try { 15975 final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app") 15976 .getCanonicalPath(); 15977 return path.getCanonicalPath().startsWith(privilegedAppDir); 15978 } catch (IOException e) { 15979 Slog.e(TAG, "Unable to access code path " + path); 15980 } 15981 return false; 15982 } 15983 15984 /* 15985 * Tries to delete system package. 15986 */ 15987 private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg, 15988 PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo, 15989 boolean writeSettings) { 15990 if (deletedPs.parentPackageName != null) { 15991 Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName); 15992 return false; 15993 } 15994 15995 final boolean applyUserRestrictions 15996 = (allUserHandles != null) && (outInfo.origUsers != null); 15997 final PackageSetting disabledPs; 15998 // Confirm if the system package has been updated 15999 // An updated system app can be deleted. This will also have to restore 16000 // the system pkg from system partition 16001 // reader 16002 synchronized (mPackages) { 16003 disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name); 16004 } 16005 16006 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName 16007 + " disabledPs=" + disabledPs); 16008 16009 if (disabledPs == null) { 16010 Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName); 16011 return false; 16012 } else if (DEBUG_REMOVE) { 16013 Slog.d(TAG, "Deleting system pkg from data partition"); 16014 } 16015 16016 if (DEBUG_REMOVE) { 16017 if (applyUserRestrictions) { 16018 Slog.d(TAG, "Remembering install states:"); 16019 for (int userId : allUserHandles) { 16020 final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId); 16021 Slog.d(TAG, " u=" + userId + " inst=" + finstalled); 16022 } 16023 } 16024 } 16025 16026 // Delete the updated package 16027 outInfo.isRemovedPackageSystemUpdate = true; 16028 if (outInfo.removedChildPackages != null) { 16029 final int childCount = (deletedPs.childPackageNames != null) 16030 ? deletedPs.childPackageNames.size() : 0; 16031 for (int i = 0; i < childCount; i++) { 16032 String childPackageName = deletedPs.childPackageNames.get(i); 16033 if (disabledPs.childPackageNames != null && disabledPs.childPackageNames 16034 .contains(childPackageName)) { 16035 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get( 16036 childPackageName); 16037 if (childInfo != null) { 16038 childInfo.isRemovedPackageSystemUpdate = true; 16039 } 16040 } 16041 } 16042 } 16043 16044 if (disabledPs.versionCode < deletedPs.versionCode) { 16045 // Delete data for downgrades 16046 flags &= ~PackageManager.DELETE_KEEP_DATA; 16047 } else { 16048 // Preserve data by setting flag 16049 flags |= PackageManager.DELETE_KEEP_DATA; 16050 } 16051 16052 boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles, 16053 outInfo, writeSettings, disabledPs.pkg); 16054 if (!ret) { 16055 return false; 16056 } 16057 16058 // writer 16059 synchronized (mPackages) { 16060 // Reinstate the old system package 16061 enableSystemPackageLPw(disabledPs.pkg); 16062 // Remove any native libraries from the upgraded package. 16063 removeNativeBinariesLI(deletedPs); 16064 } 16065 16066 // Install the system package 16067 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs); 16068 int parseFlags = mDefParseFlags 16069 | PackageParser.PARSE_MUST_BE_APK 16070 | PackageParser.PARSE_IS_SYSTEM 16071 | PackageParser.PARSE_IS_SYSTEM_DIR; 16072 if (locationIsPrivileged(disabledPs.codePath)) { 16073 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 16074 } 16075 16076 final PackageParser.Package newPkg; 16077 try { 16078 newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null); 16079 } catch (PackageManagerException e) { 16080 Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": " 16081 + e.getMessage()); 16082 return false; 16083 } 16084 try { 16085 // update shared libraries for the newly re-installed system package 16086 updateSharedLibrariesLPw(newPkg, null); 16087 } catch (PackageManagerException e) { 16088 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 16089 } 16090 16091 prepareAppDataAfterInstallLIF(newPkg); 16092 16093 // writer 16094 synchronized (mPackages) { 16095 PackageSetting ps = mSettings.mPackages.get(newPkg.packageName); 16096 16097 // Propagate the permissions state as we do not want to drop on the floor 16098 // runtime permissions. The update permissions method below will take 16099 // care of removing obsolete permissions and grant install permissions. 16100 ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState()); 16101 updatePermissionsLPw(newPkg.packageName, newPkg, 16102 UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG); 16103 16104 if (applyUserRestrictions) { 16105 if (DEBUG_REMOVE) { 16106 Slog.d(TAG, "Propagating install state across reinstall"); 16107 } 16108 for (int userId : allUserHandles) { 16109 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId); 16110 if (DEBUG_REMOVE) { 16111 Slog.d(TAG, " user " + userId + " => " + installed); 16112 } 16113 ps.setInstalled(installed, userId); 16114 16115 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 16116 } 16117 // Regardless of writeSettings we need to ensure that this restriction 16118 // state propagation is persisted 16119 mSettings.writeAllUsersPackageRestrictionsLPr(); 16120 } 16121 // can downgrade to reader here 16122 if (writeSettings) { 16123 mSettings.writeLPr(); 16124 } 16125 } 16126 return true; 16127 } 16128 16129 private boolean deleteInstalledPackageLIF(PackageSetting ps, 16130 boolean deleteCodeAndResources, int flags, int[] allUserHandles, 16131 PackageRemovedInfo outInfo, boolean writeSettings, 16132 PackageParser.Package replacingPackage) { 16133 synchronized (mPackages) { 16134 if (outInfo != null) { 16135 outInfo.uid = ps.appId; 16136 } 16137 16138 if (outInfo != null && outInfo.removedChildPackages != null) { 16139 final int childCount = (ps.childPackageNames != null) 16140 ? ps.childPackageNames.size() : 0; 16141 for (int i = 0; i < childCount; i++) { 16142 String childPackageName = ps.childPackageNames.get(i); 16143 PackageSetting childPs = mSettings.mPackages.get(childPackageName); 16144 if (childPs == null) { 16145 return false; 16146 } 16147 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get( 16148 childPackageName); 16149 if (childInfo != null) { 16150 childInfo.uid = childPs.appId; 16151 } 16152 } 16153 } 16154 } 16155 16156 // Delete package data from internal structures and also remove data if flag is set 16157 removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings); 16158 16159 // Delete the child packages data 16160 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0; 16161 for (int i = 0; i < childCount; i++) { 16162 PackageSetting childPs; 16163 synchronized (mPackages) { 16164 childPs = mSettings.peekPackageLPr(ps.childPackageNames.get(i)); 16165 } 16166 if (childPs != null) { 16167 PackageRemovedInfo childOutInfo = (outInfo != null 16168 && outInfo.removedChildPackages != null) 16169 ? outInfo.removedChildPackages.get(childPs.name) : null; 16170 final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0 16171 && (replacingPackage != null 16172 && !replacingPackage.hasChildPackage(childPs.name)) 16173 ? flags & ~DELETE_KEEP_DATA : flags; 16174 removePackageDataLIF(childPs, allUserHandles, childOutInfo, 16175 deleteFlags, writeSettings); 16176 } 16177 } 16178 16179 // Delete application code and resources only for parent packages 16180 if (ps.parentPackageName == null) { 16181 if (deleteCodeAndResources && (outInfo != null)) { 16182 outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 16183 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 16184 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args); 16185 } 16186 } 16187 16188 return true; 16189 } 16190 16191 @Override 16192 public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall, 16193 int userId) { 16194 mContext.enforceCallingOrSelfPermission( 16195 android.Manifest.permission.DELETE_PACKAGES, null); 16196 synchronized (mPackages) { 16197 PackageSetting ps = mSettings.mPackages.get(packageName); 16198 if (ps == null) { 16199 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName); 16200 return false; 16201 } 16202 if (!ps.getInstalled(userId)) { 16203 // Can't block uninstall for an app that is not installed or enabled. 16204 Log.i(TAG, "Package not installed in set block uninstall " + packageName); 16205 return false; 16206 } 16207 ps.setBlockUninstall(blockUninstall, userId); 16208 mSettings.writePackageRestrictionsLPr(userId); 16209 } 16210 return true; 16211 } 16212 16213 @Override 16214 public boolean getBlockUninstallForUser(String packageName, int userId) { 16215 synchronized (mPackages) { 16216 PackageSetting ps = mSettings.mPackages.get(packageName); 16217 if (ps == null) { 16218 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName); 16219 return false; 16220 } 16221 return ps.getBlockUninstall(userId); 16222 } 16223 } 16224 16225 @Override 16226 public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) { 16227 int callingUid = Binder.getCallingUid(); 16228 if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) { 16229 throw new SecurityException( 16230 "setRequiredForSystemUser can only be run by the system or root"); 16231 } 16232 synchronized (mPackages) { 16233 PackageSetting ps = mSettings.mPackages.get(packageName); 16234 if (ps == null) { 16235 Log.w(TAG, "Package doesn't exist: " + packageName); 16236 return false; 16237 } 16238 if (systemUserApp) { 16239 ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER; 16240 } else { 16241 ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER; 16242 } 16243 mSettings.writeLPr(); 16244 } 16245 return true; 16246 } 16247 16248 /* 16249 * This method handles package deletion in general 16250 */ 16251 private boolean deletePackageLIF(String packageName, UserHandle user, 16252 boolean deleteCodeAndResources, int[] allUserHandles, int flags, 16253 PackageRemovedInfo outInfo, boolean writeSettings, 16254 PackageParser.Package replacingPackage) { 16255 if (packageName == null) { 16256 Slog.w(TAG, "Attempt to delete null packageName."); 16257 return false; 16258 } 16259 16260 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user); 16261 16262 PackageSetting ps; 16263 16264 synchronized (mPackages) { 16265 ps = mSettings.mPackages.get(packageName); 16266 if (ps == null) { 16267 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 16268 return false; 16269 } 16270 16271 if (ps.parentPackageName != null && (!isSystemApp(ps) 16272 || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) { 16273 if (DEBUG_REMOVE) { 16274 Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:" 16275 + ((user == null) ? UserHandle.USER_ALL : user)); 16276 } 16277 final int removedUserId = (user != null) ? user.getIdentifier() 16278 : UserHandle.USER_ALL; 16279 if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) { 16280 return false; 16281 } 16282 markPackageUninstalledForUserLPw(ps, user); 16283 scheduleWritePackageRestrictionsLocked(user); 16284 return true; 16285 } 16286 } 16287 16288 if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null 16289 && user.getIdentifier() != UserHandle.USER_ALL)) { 16290 // The caller is asking that the package only be deleted for a single 16291 // user. To do this, we just mark its uninstalled state and delete 16292 // its data. If this is a system app, we only allow this to happen if 16293 // they have set the special DELETE_SYSTEM_APP which requests different 16294 // semantics than normal for uninstalling system apps. 16295 markPackageUninstalledForUserLPw(ps, user); 16296 16297 if (!isSystemApp(ps)) { 16298 // Do not uninstall the APK if an app should be cached 16299 boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName); 16300 if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) { 16301 // Other user still have this package installed, so all 16302 // we need to do is clear this user's data and save that 16303 // it is uninstalled. 16304 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users"); 16305 if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) { 16306 return false; 16307 } 16308 scheduleWritePackageRestrictionsLocked(user); 16309 return true; 16310 } else { 16311 // We need to set it back to 'installed' so the uninstall 16312 // broadcasts will be sent correctly. 16313 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete"); 16314 ps.setInstalled(true, user.getIdentifier()); 16315 } 16316 } else { 16317 // This is a system app, so we assume that the 16318 // other users still have this package installed, so all 16319 // we need to do is clear this user's data and save that 16320 // it is uninstalled. 16321 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app"); 16322 if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) { 16323 return false; 16324 } 16325 scheduleWritePackageRestrictionsLocked(user); 16326 return true; 16327 } 16328 } 16329 16330 // If we are deleting a composite package for all users, keep track 16331 // of result for each child. 16332 if (ps.childPackageNames != null && outInfo != null) { 16333 synchronized (mPackages) { 16334 final int childCount = ps.childPackageNames.size(); 16335 outInfo.removedChildPackages = new ArrayMap<>(childCount); 16336 for (int i = 0; i < childCount; i++) { 16337 String childPackageName = ps.childPackageNames.get(i); 16338 PackageRemovedInfo childInfo = new PackageRemovedInfo(); 16339 childInfo.removedPackage = childPackageName; 16340 outInfo.removedChildPackages.put(childPackageName, childInfo); 16341 PackageSetting childPs = mSettings.peekPackageLPr(childPackageName); 16342 if (childPs != null) { 16343 childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true); 16344 } 16345 } 16346 } 16347 } 16348 16349 boolean ret = false; 16350 if (isSystemApp(ps)) { 16351 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name); 16352 // When an updated system application is deleted we delete the existing resources 16353 // as well and fall back to existing code in system partition 16354 ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings); 16355 } else { 16356 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name); 16357 ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles, 16358 outInfo, writeSettings, replacingPackage); 16359 } 16360 16361 // Take a note whether we deleted the package for all users 16362 if (outInfo != null) { 16363 outInfo.removedForAllUsers = mPackages.get(ps.name) == null; 16364 if (outInfo.removedChildPackages != null) { 16365 synchronized (mPackages) { 16366 final int childCount = outInfo.removedChildPackages.size(); 16367 for (int i = 0; i < childCount; i++) { 16368 PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i); 16369 if (childInfo != null) { 16370 childInfo.removedForAllUsers = mPackages.get( 16371 childInfo.removedPackage) == null; 16372 } 16373 } 16374 } 16375 } 16376 // If we uninstalled an update to a system app there may be some 16377 // child packages that appeared as they are declared in the system 16378 // app but were not declared in the update. 16379 if (isSystemApp(ps)) { 16380 synchronized (mPackages) { 16381 PackageSetting updatedPs = mSettings.peekPackageLPr(ps.name); 16382 final int childCount = (updatedPs.childPackageNames != null) 16383 ? updatedPs.childPackageNames.size() : 0; 16384 for (int i = 0; i < childCount; i++) { 16385 String childPackageName = updatedPs.childPackageNames.get(i); 16386 if (outInfo.removedChildPackages == null 16387 || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) { 16388 PackageSetting childPs = mSettings.peekPackageLPr(childPackageName); 16389 if (childPs == null) { 16390 continue; 16391 } 16392 PackageInstalledInfo installRes = new PackageInstalledInfo(); 16393 installRes.name = childPackageName; 16394 installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true); 16395 installRes.pkg = mPackages.get(childPackageName); 16396 installRes.uid = childPs.pkg.applicationInfo.uid; 16397 if (outInfo.appearedChildPackages == null) { 16398 outInfo.appearedChildPackages = new ArrayMap<>(); 16399 } 16400 outInfo.appearedChildPackages.put(childPackageName, installRes); 16401 } 16402 } 16403 } 16404 } 16405 } 16406 16407 return ret; 16408 } 16409 16410 private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) { 16411 final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL) 16412 ? sUserManager.getUserIds() : new int[] {user.getIdentifier()}; 16413 for (int nextUserId : userIds) { 16414 if (DEBUG_REMOVE) { 16415 Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId); 16416 } 16417 ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT, 16418 false /*installed*/, true /*stopped*/, true /*notLaunched*/, 16419 false /*hidden*/, false /*suspended*/, null, null, null, 16420 false /*blockUninstall*/, 16421 ps.readUserState(nextUserId).domainVerificationStatus, 0); 16422 } 16423 } 16424 16425 private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId, 16426 PackageRemovedInfo outInfo) { 16427 final PackageParser.Package pkg; 16428 synchronized (mPackages) { 16429 pkg = mPackages.get(ps.name); 16430 } 16431 16432 final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() 16433 : new int[] {userId}; 16434 for (int nextUserId : userIds) { 16435 if (DEBUG_REMOVE) { 16436 Slog.d(TAG, "Updating package:" + ps.name + " install state for user:" 16437 + nextUserId); 16438 } 16439 16440 destroyAppDataLIF(pkg, userId, 16441 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 16442 destroyAppProfilesLIF(pkg, userId); 16443 removeKeystoreDataIfNeeded(nextUserId, ps.appId); 16444 schedulePackageCleaning(ps.name, nextUserId, false); 16445 synchronized (mPackages) { 16446 if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) { 16447 scheduleWritePackageRestrictionsLocked(nextUserId); 16448 } 16449 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId); 16450 } 16451 } 16452 16453 if (outInfo != null) { 16454 outInfo.removedPackage = ps.name; 16455 outInfo.removedAppId = ps.appId; 16456 outInfo.removedUsers = userIds; 16457 } 16458 16459 return true; 16460 } 16461 16462 private final class ClearStorageConnection implements ServiceConnection { 16463 IMediaContainerService mContainerService; 16464 16465 @Override 16466 public void onServiceConnected(ComponentName name, IBinder service) { 16467 synchronized (this) { 16468 mContainerService = IMediaContainerService.Stub.asInterface(service); 16469 notifyAll(); 16470 } 16471 } 16472 16473 @Override 16474 public void onServiceDisconnected(ComponentName name) { 16475 } 16476 } 16477 16478 private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) { 16479 if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return; 16480 16481 final boolean mounted; 16482 if (Environment.isExternalStorageEmulated()) { 16483 mounted = true; 16484 } else { 16485 final String status = Environment.getExternalStorageState(); 16486 16487 mounted = status.equals(Environment.MEDIA_MOUNTED) 16488 || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY); 16489 } 16490 16491 if (!mounted) { 16492 return; 16493 } 16494 16495 final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 16496 int[] users; 16497 if (userId == UserHandle.USER_ALL) { 16498 users = sUserManager.getUserIds(); 16499 } else { 16500 users = new int[] { userId }; 16501 } 16502 final ClearStorageConnection conn = new ClearStorageConnection(); 16503 if (mContext.bindServiceAsUser( 16504 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) { 16505 try { 16506 for (int curUser : users) { 16507 long timeout = SystemClock.uptimeMillis() + 5000; 16508 synchronized (conn) { 16509 long now; 16510 while (conn.mContainerService == null && 16511 (now = SystemClock.uptimeMillis()) < timeout) { 16512 try { 16513 conn.wait(timeout - now); 16514 } catch (InterruptedException e) { 16515 } 16516 } 16517 } 16518 if (conn.mContainerService == null) { 16519 return; 16520 } 16521 16522 final UserEnvironment userEnv = new UserEnvironment(curUser); 16523 clearDirectory(conn.mContainerService, 16524 userEnv.buildExternalStorageAppCacheDirs(packageName)); 16525 if (allData) { 16526 clearDirectory(conn.mContainerService, 16527 userEnv.buildExternalStorageAppDataDirs(packageName)); 16528 clearDirectory(conn.mContainerService, 16529 userEnv.buildExternalStorageAppMediaDirs(packageName)); 16530 } 16531 } 16532 } finally { 16533 mContext.unbindService(conn); 16534 } 16535 } 16536 } 16537 16538 @Override 16539 public void clearApplicationProfileData(String packageName) { 16540 enforceSystemOrRoot("Only the system can clear all profile data"); 16541 16542 final PackageParser.Package pkg; 16543 synchronized (mPackages) { 16544 pkg = mPackages.get(packageName); 16545 } 16546 16547 try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) { 16548 synchronized (mInstallLock) { 16549 clearAppProfilesLIF(pkg, UserHandle.USER_ALL); 16550 destroyAppReferenceProfileLeafLIF(pkg, UserHandle.USER_ALL, 16551 true /* removeBaseMarker */); 16552 } 16553 } 16554 } 16555 16556 @Override 16557 public void clearApplicationUserData(final String packageName, 16558 final IPackageDataObserver observer, final int userId) { 16559 mContext.enforceCallingOrSelfPermission( 16560 android.Manifest.permission.CLEAR_APP_USER_DATA, null); 16561 16562 enforceCrossUserPermission(Binder.getCallingUid(), userId, 16563 true /* requireFullPermission */, false /* checkShell */, "clear application data"); 16564 16565 if (mProtectedPackages.isPackageDataProtected(userId, packageName)) { 16566 throw new SecurityException("Cannot clear data for a protected package: " 16567 + packageName); 16568 } 16569 // Queue up an async operation since the package deletion may take a little while. 16570 mHandler.post(new Runnable() { 16571 public void run() { 16572 mHandler.removeCallbacks(this); 16573 final boolean succeeded; 16574 try (PackageFreezer freezer = freezePackage(packageName, 16575 "clearApplicationUserData")) { 16576 synchronized (mInstallLock) { 16577 succeeded = clearApplicationUserDataLIF(packageName, userId); 16578 } 16579 clearExternalStorageDataSync(packageName, userId, true); 16580 } 16581 if (succeeded) { 16582 // invoke DeviceStorageMonitor's update method to clear any notifications 16583 DeviceStorageMonitorInternal dsm = LocalServices 16584 .getService(DeviceStorageMonitorInternal.class); 16585 if (dsm != null) { 16586 dsm.checkMemory(); 16587 } 16588 } 16589 if(observer != null) { 16590 try { 16591 observer.onRemoveCompleted(packageName, succeeded); 16592 } catch (RemoteException e) { 16593 Log.i(TAG, "Observer no longer exists."); 16594 } 16595 } //end if observer 16596 } //end run 16597 }); 16598 } 16599 16600 private boolean clearApplicationUserDataLIF(String packageName, int userId) { 16601 if (packageName == null) { 16602 Slog.w(TAG, "Attempt to delete null packageName."); 16603 return false; 16604 } 16605 16606 // Try finding details about the requested package 16607 PackageParser.Package pkg; 16608 synchronized (mPackages) { 16609 pkg = mPackages.get(packageName); 16610 if (pkg == null) { 16611 final PackageSetting ps = mSettings.mPackages.get(packageName); 16612 if (ps != null) { 16613 pkg = ps.pkg; 16614 } 16615 } 16616 16617 if (pkg == null) { 16618 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 16619 return false; 16620 } 16621 16622 PackageSetting ps = (PackageSetting) pkg.mExtras; 16623 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 16624 } 16625 16626 clearAppDataLIF(pkg, userId, 16627 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 16628 16629 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); 16630 removeKeystoreDataIfNeeded(userId, appId); 16631 16632 UserManagerInternal umInternal = getUserManagerInternal(); 16633 final int flags; 16634 if (umInternal.isUserUnlockingOrUnlocked(userId)) { 16635 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 16636 } else if (umInternal.isUserRunning(userId)) { 16637 flags = StorageManager.FLAG_STORAGE_DE; 16638 } else { 16639 flags = 0; 16640 } 16641 prepareAppDataContentsLIF(pkg, userId, flags); 16642 16643 return true; 16644 } 16645 16646 /** 16647 * Reverts user permission state changes (permissions and flags) in 16648 * all packages for a given user. 16649 * 16650 * @param userId The device user for which to do a reset. 16651 */ 16652 private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) { 16653 final int packageCount = mPackages.size(); 16654 for (int i = 0; i < packageCount; i++) { 16655 PackageParser.Package pkg = mPackages.valueAt(i); 16656 PackageSetting ps = (PackageSetting) pkg.mExtras; 16657 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 16658 } 16659 } 16660 16661 private void resetNetworkPolicies(int userId) { 16662 LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId); 16663 } 16664 16665 /** 16666 * Reverts user permission state changes (permissions and flags). 16667 * 16668 * @param ps The package for which to reset. 16669 * @param userId The device user for which to do a reset. 16670 */ 16671 private void resetUserChangesToRuntimePermissionsAndFlagsLPw( 16672 final PackageSetting ps, final int userId) { 16673 if (ps.pkg == null) { 16674 return; 16675 } 16676 16677 // These are flags that can change base on user actions. 16678 final int userSettableMask = FLAG_PERMISSION_USER_SET 16679 | FLAG_PERMISSION_USER_FIXED 16680 | FLAG_PERMISSION_REVOKE_ON_UPGRADE 16681 | FLAG_PERMISSION_REVIEW_REQUIRED; 16682 16683 final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED 16684 | FLAG_PERMISSION_POLICY_FIXED; 16685 16686 boolean writeInstallPermissions = false; 16687 boolean writeRuntimePermissions = false; 16688 16689 final int permissionCount = ps.pkg.requestedPermissions.size(); 16690 for (int i = 0; i < permissionCount; i++) { 16691 String permission = ps.pkg.requestedPermissions.get(i); 16692 16693 BasePermission bp = mSettings.mPermissions.get(permission); 16694 if (bp == null) { 16695 continue; 16696 } 16697 16698 // If shared user we just reset the state to which only this app contributed. 16699 if (ps.sharedUser != null) { 16700 boolean used = false; 16701 final int packageCount = ps.sharedUser.packages.size(); 16702 for (int j = 0; j < packageCount; j++) { 16703 PackageSetting pkg = ps.sharedUser.packages.valueAt(j); 16704 if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName) 16705 && pkg.pkg.requestedPermissions.contains(permission)) { 16706 used = true; 16707 break; 16708 } 16709 } 16710 if (used) { 16711 continue; 16712 } 16713 } 16714 16715 PermissionsState permissionsState = ps.getPermissionsState(); 16716 16717 final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId); 16718 16719 // Always clear the user settable flags. 16720 final boolean hasInstallState = permissionsState.getInstallPermissionState( 16721 bp.name) != null; 16722 // If permission review is enabled and this is a legacy app, mark the 16723 // permission as requiring a review as this is the initial state. 16724 int flags = 0; 16725 if ((mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED) 16726 && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 16727 flags |= FLAG_PERMISSION_REVIEW_REQUIRED; 16728 } 16729 if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) { 16730 if (hasInstallState) { 16731 writeInstallPermissions = true; 16732 } else { 16733 writeRuntimePermissions = true; 16734 } 16735 } 16736 16737 // Below is only runtime permission handling. 16738 if (!bp.isRuntime()) { 16739 continue; 16740 } 16741 16742 // Never clobber system or policy. 16743 if ((oldFlags & policyOrSystemFlags) != 0) { 16744 continue; 16745 } 16746 16747 // If this permission was granted by default, make sure it is. 16748 if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) { 16749 if (permissionsState.grantRuntimePermission(bp, userId) 16750 != PERMISSION_OPERATION_FAILURE) { 16751 writeRuntimePermissions = true; 16752 } 16753 // If permission review is enabled the permissions for a legacy apps 16754 // are represented as constantly granted runtime ones, so don't revoke. 16755 } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) { 16756 // Otherwise, reset the permission. 16757 final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId); 16758 switch (revokeResult) { 16759 case PERMISSION_OPERATION_SUCCESS: 16760 case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 16761 writeRuntimePermissions = true; 16762 final int appId = ps.appId; 16763 mHandler.post(new Runnable() { 16764 @Override 16765 public void run() { 16766 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED); 16767 } 16768 }); 16769 } break; 16770 } 16771 } 16772 } 16773 16774 // Synchronously write as we are taking permissions away. 16775 if (writeRuntimePermissions) { 16776 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 16777 } 16778 16779 // Synchronously write as we are taking permissions away. 16780 if (writeInstallPermissions) { 16781 mSettings.writeLPr(); 16782 } 16783 } 16784 16785 /** 16786 * Remove entries from the keystore daemon. Will only remove it if the 16787 * {@code appId} is valid. 16788 */ 16789 private static void removeKeystoreDataIfNeeded(int userId, int appId) { 16790 if (appId < 0) { 16791 return; 16792 } 16793 16794 final KeyStore keyStore = KeyStore.getInstance(); 16795 if (keyStore != null) { 16796 if (userId == UserHandle.USER_ALL) { 16797 for (final int individual : sUserManager.getUserIds()) { 16798 keyStore.clearUid(UserHandle.getUid(individual, appId)); 16799 } 16800 } else { 16801 keyStore.clearUid(UserHandle.getUid(userId, appId)); 16802 } 16803 } else { 16804 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId); 16805 } 16806 } 16807 16808 @Override 16809 public void deleteApplicationCacheFiles(final String packageName, 16810 final IPackageDataObserver observer) { 16811 final int userId = UserHandle.getCallingUserId(); 16812 deleteApplicationCacheFilesAsUser(packageName, userId, observer); 16813 } 16814 16815 @Override 16816 public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId, 16817 final IPackageDataObserver observer) { 16818 mContext.enforceCallingOrSelfPermission( 16819 android.Manifest.permission.DELETE_CACHE_FILES, null); 16820 enforceCrossUserPermission(Binder.getCallingUid(), userId, 16821 /* requireFullPermission= */ true, /* checkShell= */ false, 16822 "delete application cache files"); 16823 16824 final PackageParser.Package pkg; 16825 synchronized (mPackages) { 16826 pkg = mPackages.get(packageName); 16827 } 16828 16829 // Queue up an async operation since the package deletion may take a little while. 16830 mHandler.post(new Runnable() { 16831 public void run() { 16832 synchronized (mInstallLock) { 16833 final int flags = StorageManager.FLAG_STORAGE_DE 16834 | StorageManager.FLAG_STORAGE_CE; 16835 // We're only clearing cache files, so we don't care if the 16836 // app is unfrozen and still able to run 16837 clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY); 16838 clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 16839 } 16840 clearExternalStorageDataSync(packageName, userId, false); 16841 if (observer != null) { 16842 try { 16843 observer.onRemoveCompleted(packageName, true); 16844 } catch (RemoteException e) { 16845 Log.i(TAG, "Observer no longer exists."); 16846 } 16847 } 16848 } 16849 }); 16850 } 16851 16852 @Override 16853 public void getPackageSizeInfo(final String packageName, int userHandle, 16854 final IPackageStatsObserver observer) { 16855 mContext.enforceCallingOrSelfPermission( 16856 android.Manifest.permission.GET_PACKAGE_SIZE, null); 16857 if (packageName == null) { 16858 throw new IllegalArgumentException("Attempt to get size of null packageName"); 16859 } 16860 16861 PackageStats stats = new PackageStats(packageName, userHandle); 16862 16863 /* 16864 * Queue up an async operation since the package measurement may take a 16865 * little while. 16866 */ 16867 Message msg = mHandler.obtainMessage(INIT_COPY); 16868 msg.obj = new MeasureParams(stats, observer); 16869 mHandler.sendMessage(msg); 16870 } 16871 16872 private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) { 16873 final PackageSetting ps; 16874 synchronized (mPackages) { 16875 ps = mSettings.mPackages.get(packageName); 16876 if (ps == null) { 16877 Slog.w(TAG, "Failed to find settings for " + packageName); 16878 return false; 16879 } 16880 } 16881 try { 16882 mInstaller.getAppSize(ps.volumeUuid, packageName, userId, 16883 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 16884 ps.getCeDataInode(userId), ps.codePathString, stats); 16885 } catch (InstallerException e) { 16886 Slog.w(TAG, String.valueOf(e)); 16887 return false; 16888 } 16889 16890 // For now, ignore code size of packages on system partition 16891 if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) { 16892 stats.codeSize = 0; 16893 } 16894 16895 return true; 16896 } 16897 16898 private int getUidTargetSdkVersionLockedLPr(int uid) { 16899 Object obj = mSettings.getUserIdLPr(uid); 16900 if (obj instanceof SharedUserSetting) { 16901 final SharedUserSetting sus = (SharedUserSetting) obj; 16902 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT; 16903 final Iterator<PackageSetting> it = sus.packages.iterator(); 16904 while (it.hasNext()) { 16905 final PackageSetting ps = it.next(); 16906 if (ps.pkg != null) { 16907 int v = ps.pkg.applicationInfo.targetSdkVersion; 16908 if (v < vers) vers = v; 16909 } 16910 } 16911 return vers; 16912 } else if (obj instanceof PackageSetting) { 16913 final PackageSetting ps = (PackageSetting) obj; 16914 if (ps.pkg != null) { 16915 return ps.pkg.applicationInfo.targetSdkVersion; 16916 } 16917 } 16918 return Build.VERSION_CODES.CUR_DEVELOPMENT; 16919 } 16920 16921 @Override 16922 public void addPreferredActivity(IntentFilter filter, int match, 16923 ComponentName[] set, ComponentName activity, int userId) { 16924 addPreferredActivityInternal(filter, match, set, activity, true, userId, 16925 "Adding preferred"); 16926 } 16927 16928 private void addPreferredActivityInternal(IntentFilter filter, int match, 16929 ComponentName[] set, ComponentName activity, boolean always, int userId, 16930 String opname) { 16931 // writer 16932 int callingUid = Binder.getCallingUid(); 16933 enforceCrossUserPermission(callingUid, userId, 16934 true /* requireFullPermission */, false /* checkShell */, "add preferred activity"); 16935 if (filter.countActions() == 0) { 16936 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 16937 return; 16938 } 16939 synchronized (mPackages) { 16940 if (mContext.checkCallingOrSelfPermission( 16941 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 16942 != PackageManager.PERMISSION_GRANTED) { 16943 if (getUidTargetSdkVersionLockedLPr(callingUid) 16944 < Build.VERSION_CODES.FROYO) { 16945 Slog.w(TAG, "Ignoring addPreferredActivity() from uid " 16946 + callingUid); 16947 return; 16948 } 16949 mContext.enforceCallingOrSelfPermission( 16950 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 16951 } 16952 16953 PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId); 16954 Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user " 16955 + userId + ":"); 16956 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 16957 pir.addFilter(new PreferredActivity(filter, match, set, activity, always)); 16958 scheduleWritePackageRestrictionsLocked(userId); 16959 postPreferredActivityChangedBroadcast(userId); 16960 } 16961 } 16962 16963 private void postPreferredActivityChangedBroadcast(int userId) { 16964 mHandler.post(() -> { 16965 final IActivityManager am = ActivityManagerNative.getDefault(); 16966 if (am == null) { 16967 return; 16968 } 16969 16970 final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED); 16971 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16972 try { 16973 am.broadcastIntent(null, intent, null, null, 16974 0, null, null, null, android.app.AppOpsManager.OP_NONE, 16975 null, false, false, userId); 16976 } catch (RemoteException e) { 16977 } 16978 }); 16979 } 16980 16981 @Override 16982 public void replacePreferredActivity(IntentFilter filter, int match, 16983 ComponentName[] set, ComponentName activity, int userId) { 16984 if (filter.countActions() != 1) { 16985 throw new IllegalArgumentException( 16986 "replacePreferredActivity expects filter to have only 1 action."); 16987 } 16988 if (filter.countDataAuthorities() != 0 16989 || filter.countDataPaths() != 0 16990 || filter.countDataSchemes() > 1 16991 || filter.countDataTypes() != 0) { 16992 throw new IllegalArgumentException( 16993 "replacePreferredActivity expects filter to have no data authorities, " + 16994 "paths, or types; and at most one scheme."); 16995 } 16996 16997 final int callingUid = Binder.getCallingUid(); 16998 enforceCrossUserPermission(callingUid, userId, 16999 true /* requireFullPermission */, false /* checkShell */, 17000 "replace preferred activity"); 17001 synchronized (mPackages) { 17002 if (mContext.checkCallingOrSelfPermission( 17003 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 17004 != PackageManager.PERMISSION_GRANTED) { 17005 if (getUidTargetSdkVersionLockedLPr(callingUid) 17006 < Build.VERSION_CODES.FROYO) { 17007 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid " 17008 + Binder.getCallingUid()); 17009 return; 17010 } 17011 mContext.enforceCallingOrSelfPermission( 17012 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 17013 } 17014 17015 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 17016 if (pir != null) { 17017 // Get all of the existing entries that exactly match this filter. 17018 ArrayList<PreferredActivity> existing = pir.findFilters(filter); 17019 if (existing != null && existing.size() == 1) { 17020 PreferredActivity cur = existing.get(0); 17021 if (DEBUG_PREFERRED) { 17022 Slog.i(TAG, "Checking replace of preferred:"); 17023 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 17024 if (!cur.mPref.mAlways) { 17025 Slog.i(TAG, " -- CUR; not mAlways!"); 17026 } else { 17027 Slog.i(TAG, " -- CUR: mMatch=" + cur.mPref.mMatch); 17028 Slog.i(TAG, " -- CUR: mSet=" 17029 + Arrays.toString(cur.mPref.mSetComponents)); 17030 Slog.i(TAG, " -- CUR: mComponent=" + cur.mPref.mShortComponent); 17031 Slog.i(TAG, " -- NEW: mMatch=" 17032 + (match&IntentFilter.MATCH_CATEGORY_MASK)); 17033 Slog.i(TAG, " -- CUR: mSet=" + Arrays.toString(set)); 17034 Slog.i(TAG, " -- CUR: mComponent=" + activity.flattenToShortString()); 17035 } 17036 } 17037 if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity) 17038 && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK) 17039 && cur.mPref.sameSet(set)) { 17040 // Setting the preferred activity to what it happens to be already 17041 if (DEBUG_PREFERRED) { 17042 Slog.i(TAG, "Replacing with same preferred activity " 17043 + cur.mPref.mShortComponent + " for user " 17044 + userId + ":"); 17045 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 17046 } 17047 return; 17048 } 17049 } 17050 17051 if (existing != null) { 17052 if (DEBUG_PREFERRED) { 17053 Slog.i(TAG, existing.size() + " existing preferred matches for:"); 17054 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 17055 } 17056 for (int i = 0; i < existing.size(); i++) { 17057 PreferredActivity pa = existing.get(i); 17058 if (DEBUG_PREFERRED) { 17059 Slog.i(TAG, "Removing existing preferred activity " 17060 + pa.mPref.mComponent + ":"); 17061 pa.dump(new LogPrinter(Log.INFO, TAG), " "); 17062 } 17063 pir.removeFilter(pa); 17064 } 17065 } 17066 } 17067 addPreferredActivityInternal(filter, match, set, activity, true, userId, 17068 "Replacing preferred"); 17069 } 17070 } 17071 17072 @Override 17073 public void clearPackagePreferredActivities(String packageName) { 17074 final int uid = Binder.getCallingUid(); 17075 // writer 17076 synchronized (mPackages) { 17077 PackageParser.Package pkg = mPackages.get(packageName); 17078 if (pkg == null || pkg.applicationInfo.uid != uid) { 17079 if (mContext.checkCallingOrSelfPermission( 17080 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 17081 != PackageManager.PERMISSION_GRANTED) { 17082 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid()) 17083 < Build.VERSION_CODES.FROYO) { 17084 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid " 17085 + Binder.getCallingUid()); 17086 return; 17087 } 17088 mContext.enforceCallingOrSelfPermission( 17089 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 17090 } 17091 } 17092 17093 int user = UserHandle.getCallingUserId(); 17094 if (clearPackagePreferredActivitiesLPw(packageName, user)) { 17095 scheduleWritePackageRestrictionsLocked(user); 17096 } 17097 } 17098 } 17099 17100 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 17101 boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) { 17102 ArrayList<PreferredActivity> removed = null; 17103 boolean changed = false; 17104 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 17105 final int thisUserId = mSettings.mPreferredActivities.keyAt(i); 17106 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 17107 if (userId != UserHandle.USER_ALL && userId != thisUserId) { 17108 continue; 17109 } 17110 Iterator<PreferredActivity> it = pir.filterIterator(); 17111 while (it.hasNext()) { 17112 PreferredActivity pa = it.next(); 17113 // Mark entry for removal only if it matches the package name 17114 // and the entry is of type "always". 17115 if (packageName == null || 17116 (pa.mPref.mComponent.getPackageName().equals(packageName) 17117 && pa.mPref.mAlways)) { 17118 if (removed == null) { 17119 removed = new ArrayList<PreferredActivity>(); 17120 } 17121 removed.add(pa); 17122 } 17123 } 17124 if (removed != null) { 17125 for (int j=0; j<removed.size(); j++) { 17126 PreferredActivity pa = removed.get(j); 17127 pir.removeFilter(pa); 17128 } 17129 changed = true; 17130 } 17131 } 17132 if (changed) { 17133 postPreferredActivityChangedBroadcast(userId); 17134 } 17135 return changed; 17136 } 17137 17138 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 17139 private void clearIntentFilterVerificationsLPw(int userId) { 17140 final int packageCount = mPackages.size(); 17141 for (int i = 0; i < packageCount; i++) { 17142 PackageParser.Package pkg = mPackages.valueAt(i); 17143 clearIntentFilterVerificationsLPw(pkg.packageName, userId); 17144 } 17145 } 17146 17147 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 17148 void clearIntentFilterVerificationsLPw(String packageName, int userId) { 17149 if (userId == UserHandle.USER_ALL) { 17150 if (mSettings.removeIntentFilterVerificationLPw(packageName, 17151 sUserManager.getUserIds())) { 17152 for (int oneUserId : sUserManager.getUserIds()) { 17153 scheduleWritePackageRestrictionsLocked(oneUserId); 17154 } 17155 } 17156 } else { 17157 if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) { 17158 scheduleWritePackageRestrictionsLocked(userId); 17159 } 17160 } 17161 } 17162 17163 void clearDefaultBrowserIfNeeded(String packageName) { 17164 for (int oneUserId : sUserManager.getUserIds()) { 17165 String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId); 17166 if (TextUtils.isEmpty(defaultBrowserPackageName)) continue; 17167 if (packageName.equals(defaultBrowserPackageName)) { 17168 setDefaultBrowserPackageName(null, oneUserId); 17169 } 17170 } 17171 } 17172 17173 @Override 17174 public void resetApplicationPreferences(int userId) { 17175 mContext.enforceCallingOrSelfPermission( 17176 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 17177 final long identity = Binder.clearCallingIdentity(); 17178 // writer 17179 try { 17180 synchronized (mPackages) { 17181 clearPackagePreferredActivitiesLPw(null, userId); 17182 mSettings.applyDefaultPreferredAppsLPw(this, userId); 17183 // TODO: We have to reset the default SMS and Phone. This requires 17184 // significant refactoring to keep all default apps in the package 17185 // manager (cleaner but more work) or have the services provide 17186 // callbacks to the package manager to request a default app reset. 17187 applyFactoryDefaultBrowserLPw(userId); 17188 clearIntentFilterVerificationsLPw(userId); 17189 primeDomainVerificationsLPw(userId); 17190 resetUserChangesToRuntimePermissionsAndFlagsLPw(userId); 17191 scheduleWritePackageRestrictionsLocked(userId); 17192 } 17193 resetNetworkPolicies(userId); 17194 } finally { 17195 Binder.restoreCallingIdentity(identity); 17196 } 17197 } 17198 17199 @Override 17200 public int getPreferredActivities(List<IntentFilter> outFilters, 17201 List<ComponentName> outActivities, String packageName) { 17202 17203 int num = 0; 17204 final int userId = UserHandle.getCallingUserId(); 17205 // reader 17206 synchronized (mPackages) { 17207 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 17208 if (pir != null) { 17209 final Iterator<PreferredActivity> it = pir.filterIterator(); 17210 while (it.hasNext()) { 17211 final PreferredActivity pa = it.next(); 17212 if (packageName == null 17213 || (pa.mPref.mComponent.getPackageName().equals(packageName) 17214 && pa.mPref.mAlways)) { 17215 if (outFilters != null) { 17216 outFilters.add(new IntentFilter(pa)); 17217 } 17218 if (outActivities != null) { 17219 outActivities.add(pa.mPref.mComponent); 17220 } 17221 } 17222 } 17223 } 17224 } 17225 17226 return num; 17227 } 17228 17229 @Override 17230 public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity, 17231 int userId) { 17232 int callingUid = Binder.getCallingUid(); 17233 if (callingUid != Process.SYSTEM_UID) { 17234 throw new SecurityException( 17235 "addPersistentPreferredActivity can only be run by the system"); 17236 } 17237 if (filter.countActions() == 0) { 17238 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 17239 return; 17240 } 17241 synchronized (mPackages) { 17242 Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId + 17243 ":"); 17244 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 17245 mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter( 17246 new PersistentPreferredActivity(filter, activity)); 17247 scheduleWritePackageRestrictionsLocked(userId); 17248 postPreferredActivityChangedBroadcast(userId); 17249 } 17250 } 17251 17252 @Override 17253 public void clearPackagePersistentPreferredActivities(String packageName, int userId) { 17254 int callingUid = Binder.getCallingUid(); 17255 if (callingUid != Process.SYSTEM_UID) { 17256 throw new SecurityException( 17257 "clearPackagePersistentPreferredActivities can only be run by the system"); 17258 } 17259 ArrayList<PersistentPreferredActivity> removed = null; 17260 boolean changed = false; 17261 synchronized (mPackages) { 17262 for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) { 17263 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i); 17264 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 17265 .valueAt(i); 17266 if (userId != thisUserId) { 17267 continue; 17268 } 17269 Iterator<PersistentPreferredActivity> it = ppir.filterIterator(); 17270 while (it.hasNext()) { 17271 PersistentPreferredActivity ppa = it.next(); 17272 // Mark entry for removal only if it matches the package name. 17273 if (ppa.mComponent.getPackageName().equals(packageName)) { 17274 if (removed == null) { 17275 removed = new ArrayList<PersistentPreferredActivity>(); 17276 } 17277 removed.add(ppa); 17278 } 17279 } 17280 if (removed != null) { 17281 for (int j=0; j<removed.size(); j++) { 17282 PersistentPreferredActivity ppa = removed.get(j); 17283 ppir.removeFilter(ppa); 17284 } 17285 changed = true; 17286 } 17287 } 17288 17289 if (changed) { 17290 scheduleWritePackageRestrictionsLocked(userId); 17291 postPreferredActivityChangedBroadcast(userId); 17292 } 17293 } 17294 } 17295 17296 /** 17297 * Common machinery for picking apart a restored XML blob and passing 17298 * it to a caller-supplied functor to be applied to the running system. 17299 */ 17300 private void restoreFromXml(XmlPullParser parser, int userId, 17301 String expectedStartTag, BlobXmlRestorer functor) 17302 throws IOException, XmlPullParserException { 17303 int type; 17304 while ((type = parser.next()) != XmlPullParser.START_TAG 17305 && type != XmlPullParser.END_DOCUMENT) { 17306 } 17307 if (type != XmlPullParser.START_TAG) { 17308 // oops didn't find a start tag?! 17309 if (DEBUG_BACKUP) { 17310 Slog.e(TAG, "Didn't find start tag during restore"); 17311 } 17312 return; 17313 } 17314Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName()); 17315 // this is supposed to be TAG_PREFERRED_BACKUP 17316 if (!expectedStartTag.equals(parser.getName())) { 17317 if (DEBUG_BACKUP) { 17318 Slog.e(TAG, "Found unexpected tag " + parser.getName()); 17319 } 17320 return; 17321 } 17322 17323 // skip interfering stuff, then we're aligned with the backing implementation 17324 while ((type = parser.next()) == XmlPullParser.TEXT) { } 17325Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); 17326 functor.apply(parser, userId); 17327 } 17328 17329 private interface BlobXmlRestorer { 17330 public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException; 17331 } 17332 17333 /** 17334 * Non-Binder method, support for the backup/restore mechanism: write the 17335 * full set of preferred activities in its canonical XML format. Returns the 17336 * XML output as a byte array, or null if there is none. 17337 */ 17338 @Override 17339 public byte[] getPreferredActivityBackup(int userId) { 17340 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17341 throw new SecurityException("Only the system may call getPreferredActivityBackup()"); 17342 } 17343 17344 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 17345 try { 17346 final XmlSerializer serializer = new FastXmlSerializer(); 17347 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 17348 serializer.startDocument(null, true); 17349 serializer.startTag(null, TAG_PREFERRED_BACKUP); 17350 17351 synchronized (mPackages) { 17352 mSettings.writePreferredActivitiesLPr(serializer, userId, true); 17353 } 17354 17355 serializer.endTag(null, TAG_PREFERRED_BACKUP); 17356 serializer.endDocument(); 17357 serializer.flush(); 17358 } catch (Exception e) { 17359 if (DEBUG_BACKUP) { 17360 Slog.e(TAG, "Unable to write preferred activities for backup", e); 17361 } 17362 return null; 17363 } 17364 17365 return dataStream.toByteArray(); 17366 } 17367 17368 @Override 17369 public void restorePreferredActivities(byte[] backup, int userId) { 17370 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17371 throw new SecurityException("Only the system may call restorePreferredActivities()"); 17372 } 17373 17374 try { 17375 final XmlPullParser parser = Xml.newPullParser(); 17376 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 17377 restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP, 17378 new BlobXmlRestorer() { 17379 @Override 17380 public void apply(XmlPullParser parser, int userId) 17381 throws XmlPullParserException, IOException { 17382 synchronized (mPackages) { 17383 mSettings.readPreferredActivitiesLPw(parser, userId); 17384 } 17385 } 17386 } ); 17387 } catch (Exception e) { 17388 if (DEBUG_BACKUP) { 17389 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 17390 } 17391 } 17392 } 17393 17394 /** 17395 * Non-Binder method, support for the backup/restore mechanism: write the 17396 * default browser (etc) settings in its canonical XML format. Returns the default 17397 * browser XML representation as a byte array, or null if there is none. 17398 */ 17399 @Override 17400 public byte[] getDefaultAppsBackup(int userId) { 17401 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17402 throw new SecurityException("Only the system may call getDefaultAppsBackup()"); 17403 } 17404 17405 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 17406 try { 17407 final XmlSerializer serializer = new FastXmlSerializer(); 17408 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 17409 serializer.startDocument(null, true); 17410 serializer.startTag(null, TAG_DEFAULT_APPS); 17411 17412 synchronized (mPackages) { 17413 mSettings.writeDefaultAppsLPr(serializer, userId); 17414 } 17415 17416 serializer.endTag(null, TAG_DEFAULT_APPS); 17417 serializer.endDocument(); 17418 serializer.flush(); 17419 } catch (Exception e) { 17420 if (DEBUG_BACKUP) { 17421 Slog.e(TAG, "Unable to write default apps for backup", e); 17422 } 17423 return null; 17424 } 17425 17426 return dataStream.toByteArray(); 17427 } 17428 17429 @Override 17430 public void restoreDefaultApps(byte[] backup, int userId) { 17431 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17432 throw new SecurityException("Only the system may call restoreDefaultApps()"); 17433 } 17434 17435 try { 17436 final XmlPullParser parser = Xml.newPullParser(); 17437 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 17438 restoreFromXml(parser, userId, TAG_DEFAULT_APPS, 17439 new BlobXmlRestorer() { 17440 @Override 17441 public void apply(XmlPullParser parser, int userId) 17442 throws XmlPullParserException, IOException { 17443 synchronized (mPackages) { 17444 mSettings.readDefaultAppsLPw(parser, userId); 17445 } 17446 } 17447 } ); 17448 } catch (Exception e) { 17449 if (DEBUG_BACKUP) { 17450 Slog.e(TAG, "Exception restoring default apps: " + e.getMessage()); 17451 } 17452 } 17453 } 17454 17455 @Override 17456 public byte[] getIntentFilterVerificationBackup(int userId) { 17457 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17458 throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()"); 17459 } 17460 17461 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 17462 try { 17463 final XmlSerializer serializer = new FastXmlSerializer(); 17464 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 17465 serializer.startDocument(null, true); 17466 serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION); 17467 17468 synchronized (mPackages) { 17469 mSettings.writeAllDomainVerificationsLPr(serializer, userId); 17470 } 17471 17472 serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION); 17473 serializer.endDocument(); 17474 serializer.flush(); 17475 } catch (Exception e) { 17476 if (DEBUG_BACKUP) { 17477 Slog.e(TAG, "Unable to write default apps for backup", e); 17478 } 17479 return null; 17480 } 17481 17482 return dataStream.toByteArray(); 17483 } 17484 17485 @Override 17486 public void restoreIntentFilterVerification(byte[] backup, int userId) { 17487 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17488 throw new SecurityException("Only the system may call restorePreferredActivities()"); 17489 } 17490 17491 try { 17492 final XmlPullParser parser = Xml.newPullParser(); 17493 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 17494 restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION, 17495 new BlobXmlRestorer() { 17496 @Override 17497 public void apply(XmlPullParser parser, int userId) 17498 throws XmlPullParserException, IOException { 17499 synchronized (mPackages) { 17500 mSettings.readAllDomainVerificationsLPr(parser, userId); 17501 mSettings.writeLPr(); 17502 } 17503 } 17504 } ); 17505 } catch (Exception e) { 17506 if (DEBUG_BACKUP) { 17507 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 17508 } 17509 } 17510 } 17511 17512 @Override 17513 public byte[] getPermissionGrantBackup(int userId) { 17514 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17515 throw new SecurityException("Only the system may call getPermissionGrantBackup()"); 17516 } 17517 17518 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 17519 try { 17520 final XmlSerializer serializer = new FastXmlSerializer(); 17521 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 17522 serializer.startDocument(null, true); 17523 serializer.startTag(null, TAG_PERMISSION_BACKUP); 17524 17525 synchronized (mPackages) { 17526 serializeRuntimePermissionGrantsLPr(serializer, userId); 17527 } 17528 17529 serializer.endTag(null, TAG_PERMISSION_BACKUP); 17530 serializer.endDocument(); 17531 serializer.flush(); 17532 } catch (Exception e) { 17533 if (DEBUG_BACKUP) { 17534 Slog.e(TAG, "Unable to write default apps for backup", e); 17535 } 17536 return null; 17537 } 17538 17539 return dataStream.toByteArray(); 17540 } 17541 17542 @Override 17543 public void restorePermissionGrants(byte[] backup, int userId) { 17544 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17545 throw new SecurityException("Only the system may call restorePermissionGrants()"); 17546 } 17547 17548 try { 17549 final XmlPullParser parser = Xml.newPullParser(); 17550 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 17551 restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP, 17552 new BlobXmlRestorer() { 17553 @Override 17554 public void apply(XmlPullParser parser, int userId) 17555 throws XmlPullParserException, IOException { 17556 synchronized (mPackages) { 17557 processRestoredPermissionGrantsLPr(parser, userId); 17558 } 17559 } 17560 } ); 17561 } catch (Exception e) { 17562 if (DEBUG_BACKUP) { 17563 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 17564 } 17565 } 17566 } 17567 17568 private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId) 17569 throws IOException { 17570 serializer.startTag(null, TAG_ALL_GRANTS); 17571 17572 final int N = mSettings.mPackages.size(); 17573 for (int i = 0; i < N; i++) { 17574 final PackageSetting ps = mSettings.mPackages.valueAt(i); 17575 boolean pkgGrantsKnown = false; 17576 17577 PermissionsState packagePerms = ps.getPermissionsState(); 17578 17579 for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) { 17580 final int grantFlags = state.getFlags(); 17581 // only look at grants that are not system/policy fixed 17582 if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) { 17583 final boolean isGranted = state.isGranted(); 17584 // And only back up the user-twiddled state bits 17585 if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) { 17586 final String packageName = mSettings.mPackages.keyAt(i); 17587 if (!pkgGrantsKnown) { 17588 serializer.startTag(null, TAG_GRANT); 17589 serializer.attribute(null, ATTR_PACKAGE_NAME, packageName); 17590 pkgGrantsKnown = true; 17591 } 17592 17593 final boolean userSet = 17594 (grantFlags & FLAG_PERMISSION_USER_SET) != 0; 17595 final boolean userFixed = 17596 (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0; 17597 final boolean revoke = 17598 (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0; 17599 17600 serializer.startTag(null, TAG_PERMISSION); 17601 serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName()); 17602 if (isGranted) { 17603 serializer.attribute(null, ATTR_IS_GRANTED, "true"); 17604 } 17605 if (userSet) { 17606 serializer.attribute(null, ATTR_USER_SET, "true"); 17607 } 17608 if (userFixed) { 17609 serializer.attribute(null, ATTR_USER_FIXED, "true"); 17610 } 17611 if (revoke) { 17612 serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true"); 17613 } 17614 serializer.endTag(null, TAG_PERMISSION); 17615 } 17616 } 17617 } 17618 17619 if (pkgGrantsKnown) { 17620 serializer.endTag(null, TAG_GRANT); 17621 } 17622 } 17623 17624 serializer.endTag(null, TAG_ALL_GRANTS); 17625 } 17626 17627 private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId) 17628 throws XmlPullParserException, IOException { 17629 String pkgName = null; 17630 int outerDepth = parser.getDepth(); 17631 int type; 17632 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 17633 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 17634 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 17635 continue; 17636 } 17637 17638 final String tagName = parser.getName(); 17639 if (tagName.equals(TAG_GRANT)) { 17640 pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME); 17641 if (DEBUG_BACKUP) { 17642 Slog.v(TAG, "+++ Restoring grants for package " + pkgName); 17643 } 17644 } else if (tagName.equals(TAG_PERMISSION)) { 17645 17646 final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED)); 17647 final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME); 17648 17649 int newFlagSet = 0; 17650 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) { 17651 newFlagSet |= FLAG_PERMISSION_USER_SET; 17652 } 17653 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) { 17654 newFlagSet |= FLAG_PERMISSION_USER_FIXED; 17655 } 17656 if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) { 17657 newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE; 17658 } 17659 if (DEBUG_BACKUP) { 17660 Slog.v(TAG, " + Restoring grant: pkg=" + pkgName + " perm=" + permName 17661 + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet)); 17662 } 17663 final PackageSetting ps = mSettings.mPackages.get(pkgName); 17664 if (ps != null) { 17665 // Already installed so we apply the grant immediately 17666 if (DEBUG_BACKUP) { 17667 Slog.v(TAG, " + already installed; applying"); 17668 } 17669 PermissionsState perms = ps.getPermissionsState(); 17670 BasePermission bp = mSettings.mPermissions.get(permName); 17671 if (bp != null) { 17672 if (isGranted) { 17673 perms.grantRuntimePermission(bp, userId); 17674 } 17675 if (newFlagSet != 0) { 17676 perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet); 17677 } 17678 } 17679 } else { 17680 // Need to wait for post-restore install to apply the grant 17681 if (DEBUG_BACKUP) { 17682 Slog.v(TAG, " - not yet installed; saving for later"); 17683 } 17684 mSettings.processRestoredPermissionGrantLPr(pkgName, permName, 17685 isGranted, newFlagSet, userId); 17686 } 17687 } else { 17688 PackageManagerService.reportSettingsProblem(Log.WARN, 17689 "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName); 17690 XmlUtils.skipCurrentTag(parser); 17691 } 17692 } 17693 17694 scheduleWriteSettingsLocked(); 17695 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 17696 } 17697 17698 @Override 17699 public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage, 17700 int sourceUserId, int targetUserId, int flags) { 17701 mContext.enforceCallingOrSelfPermission( 17702 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 17703 int callingUid = Binder.getCallingUid(); 17704 enforceOwnerRights(ownerPackage, callingUid); 17705 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 17706 if (intentFilter.countActions() == 0) { 17707 Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions"); 17708 return; 17709 } 17710 synchronized (mPackages) { 17711 CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter, 17712 ownerPackage, targetUserId, flags); 17713 CrossProfileIntentResolver resolver = 17714 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 17715 ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter); 17716 // We have all those whose filter is equal. Now checking if the rest is equal as well. 17717 if (existing != null) { 17718 int size = existing.size(); 17719 for (int i = 0; i < size; i++) { 17720 if (newFilter.equalsIgnoreFilter(existing.get(i))) { 17721 return; 17722 } 17723 } 17724 } 17725 resolver.addFilter(newFilter); 17726 scheduleWritePackageRestrictionsLocked(sourceUserId); 17727 } 17728 } 17729 17730 @Override 17731 public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) { 17732 mContext.enforceCallingOrSelfPermission( 17733 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 17734 int callingUid = Binder.getCallingUid(); 17735 enforceOwnerRights(ownerPackage, callingUid); 17736 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 17737 synchronized (mPackages) { 17738 CrossProfileIntentResolver resolver = 17739 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 17740 ArraySet<CrossProfileIntentFilter> set = 17741 new ArraySet<CrossProfileIntentFilter>(resolver.filterSet()); 17742 for (CrossProfileIntentFilter filter : set) { 17743 if (filter.getOwnerPackage().equals(ownerPackage)) { 17744 resolver.removeFilter(filter); 17745 } 17746 } 17747 scheduleWritePackageRestrictionsLocked(sourceUserId); 17748 } 17749 } 17750 17751 // Enforcing that callingUid is owning pkg on userId 17752 private void enforceOwnerRights(String pkg, int callingUid) { 17753 // The system owns everything. 17754 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) { 17755 return; 17756 } 17757 int callingUserId = UserHandle.getUserId(callingUid); 17758 PackageInfo pi = getPackageInfo(pkg, 0, callingUserId); 17759 if (pi == null) { 17760 throw new IllegalArgumentException("Unknown package " + pkg + " on user " 17761 + callingUserId); 17762 } 17763 if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) { 17764 throw new SecurityException("Calling uid " + callingUid 17765 + " does not own package " + pkg); 17766 } 17767 } 17768 17769 @Override 17770 public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) { 17771 return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId()); 17772 } 17773 17774 private Intent getHomeIntent() { 17775 Intent intent = new Intent(Intent.ACTION_MAIN); 17776 intent.addCategory(Intent.CATEGORY_HOME); 17777 intent.addCategory(Intent.CATEGORY_DEFAULT); 17778 return intent; 17779 } 17780 17781 private IntentFilter getHomeFilter() { 17782 IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN); 17783 filter.addCategory(Intent.CATEGORY_HOME); 17784 filter.addCategory(Intent.CATEGORY_DEFAULT); 17785 return filter; 17786 } 17787 17788 ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, 17789 int userId) { 17790 Intent intent = getHomeIntent(); 17791 List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null, 17792 PackageManager.GET_META_DATA, userId); 17793 ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0, 17794 true, false, false, userId); 17795 17796 allHomeCandidates.clear(); 17797 if (list != null) { 17798 for (ResolveInfo ri : list) { 17799 allHomeCandidates.add(ri); 17800 } 17801 } 17802 return (preferred == null || preferred.activityInfo == null) 17803 ? null 17804 : new ComponentName(preferred.activityInfo.packageName, 17805 preferred.activityInfo.name); 17806 } 17807 17808 @Override 17809 public void setHomeActivity(ComponentName comp, int userId) { 17810 ArrayList<ResolveInfo> homeActivities = new ArrayList<>(); 17811 getHomeActivitiesAsUser(homeActivities, userId); 17812 17813 boolean found = false; 17814 17815 final int size = homeActivities.size(); 17816 final ComponentName[] set = new ComponentName[size]; 17817 for (int i = 0; i < size; i++) { 17818 final ResolveInfo candidate = homeActivities.get(i); 17819 final ActivityInfo info = candidate.activityInfo; 17820 final ComponentName activityName = new ComponentName(info.packageName, info.name); 17821 set[i] = activityName; 17822 if (!found && activityName.equals(comp)) { 17823 found = true; 17824 } 17825 } 17826 if (!found) { 17827 throw new IllegalArgumentException("Component " + comp + " cannot be home on user " 17828 + userId); 17829 } 17830 replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY, 17831 set, comp, userId); 17832 } 17833 17834 private @Nullable String getSetupWizardPackageName() { 17835 final Intent intent = new Intent(Intent.ACTION_MAIN); 17836 intent.addCategory(Intent.CATEGORY_SETUP_WIZARD); 17837 17838 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, 17839 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE 17840 | MATCH_DISABLED_COMPONENTS, 17841 UserHandle.myUserId()); 17842 if (matches.size() == 1) { 17843 return matches.get(0).getComponentInfo().packageName; 17844 } else { 17845 Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size() 17846 + ": matches=" + matches); 17847 return null; 17848 } 17849 } 17850 17851 private @Nullable String getStorageManagerPackageName() { 17852 final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE); 17853 17854 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, 17855 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE 17856 | MATCH_DISABLED_COMPONENTS, 17857 UserHandle.myUserId()); 17858 if (matches.size() == 1) { 17859 return matches.get(0).getComponentInfo().packageName; 17860 } else { 17861 Slog.e(TAG, "There should probably be exactly one storage manager; found " 17862 + matches.size() + ": matches=" + matches); 17863 return null; 17864 } 17865 } 17866 17867 @Override 17868 public void setApplicationEnabledSetting(String appPackageName, 17869 int newState, int flags, int userId, String callingPackage) { 17870 if (!sUserManager.exists(userId)) return; 17871 if (callingPackage == null) { 17872 callingPackage = Integer.toString(Binder.getCallingUid()); 17873 } 17874 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage); 17875 } 17876 17877 @Override 17878 public void setComponentEnabledSetting(ComponentName componentName, 17879 int newState, int flags, int userId) { 17880 if (!sUserManager.exists(userId)) return; 17881 setEnabledSetting(componentName.getPackageName(), 17882 componentName.getClassName(), newState, flags, userId, null); 17883 } 17884 17885 private void setEnabledSetting(final String packageName, String className, int newState, 17886 final int flags, int userId, String callingPackage) { 17887 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT 17888 || newState == COMPONENT_ENABLED_STATE_ENABLED 17889 || newState == COMPONENT_ENABLED_STATE_DISABLED 17890 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER 17891 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) { 17892 throw new IllegalArgumentException("Invalid new component state: " 17893 + newState); 17894 } 17895 PackageSetting pkgSetting; 17896 final int uid = Binder.getCallingUid(); 17897 final int permission; 17898 if (uid == Process.SYSTEM_UID) { 17899 permission = PackageManager.PERMISSION_GRANTED; 17900 } else { 17901 permission = mContext.checkCallingOrSelfPermission( 17902 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 17903 } 17904 enforceCrossUserPermission(uid, userId, 17905 false /* requireFullPermission */, true /* checkShell */, "set enabled"); 17906 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 17907 boolean sendNow = false; 17908 boolean isApp = (className == null); 17909 String componentName = isApp ? packageName : className; 17910 int packageUid = -1; 17911 ArrayList<String> components; 17912 17913 // writer 17914 synchronized (mPackages) { 17915 pkgSetting = mSettings.mPackages.get(packageName); 17916 if (pkgSetting == null) { 17917 if (className == null) { 17918 throw new IllegalArgumentException("Unknown package: " + packageName); 17919 } 17920 throw new IllegalArgumentException( 17921 "Unknown component: " + packageName + "/" + className); 17922 } 17923 } 17924 17925 // Limit who can change which apps 17926 if (!UserHandle.isSameApp(uid, pkgSetting.appId)) { 17927 // Don't allow apps that don't have permission to modify other apps 17928 if (!allowedByPermission) { 17929 throw new SecurityException( 17930 "Permission Denial: attempt to change component state from pid=" 17931 + Binder.getCallingPid() 17932 + ", uid=" + uid + ", package uid=" + pkgSetting.appId); 17933 } 17934 // Don't allow changing protected packages. 17935 if (mProtectedPackages.isPackageStateProtected(userId, packageName)) { 17936 throw new SecurityException("Cannot disable a protected package: " + packageName); 17937 } 17938 } 17939 17940 synchronized (mPackages) { 17941 if (uid == Process.SHELL_UID) { 17942 // Shell can only change whole packages between ENABLED and DISABLED_USER states 17943 int oldState = pkgSetting.getEnabled(userId); 17944 if (className == null 17945 && 17946 (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER 17947 || oldState == COMPONENT_ENABLED_STATE_DEFAULT 17948 || oldState == COMPONENT_ENABLED_STATE_ENABLED) 17949 && 17950 (newState == COMPONENT_ENABLED_STATE_DISABLED_USER 17951 || newState == COMPONENT_ENABLED_STATE_DEFAULT 17952 || newState == COMPONENT_ENABLED_STATE_ENABLED)) { 17953 // ok 17954 } else { 17955 throw new SecurityException( 17956 "Shell cannot change component state for " + packageName + "/" 17957 + className + " to " + newState); 17958 } 17959 } 17960 if (className == null) { 17961 // We're dealing with an application/package level state change 17962 if (pkgSetting.getEnabled(userId) == newState) { 17963 // Nothing to do 17964 return; 17965 } 17966 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT 17967 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { 17968 // Don't care about who enables an app. 17969 callingPackage = null; 17970 } 17971 pkgSetting.setEnabled(newState, userId, callingPackage); 17972 // pkgSetting.pkg.mSetEnabled = newState; 17973 } else { 17974 // We're dealing with a component level state change 17975 // First, verify that this is a valid class name. 17976 PackageParser.Package pkg = pkgSetting.pkg; 17977 if (pkg == null || !pkg.hasComponentClassName(className)) { 17978 if (pkg != null && 17979 pkg.applicationInfo.targetSdkVersion >= 17980 Build.VERSION_CODES.JELLY_BEAN) { 17981 throw new IllegalArgumentException("Component class " + className 17982 + " does not exist in " + packageName); 17983 } else { 17984 Slog.w(TAG, "Failed setComponentEnabledSetting: component class " 17985 + className + " does not exist in " + packageName); 17986 } 17987 } 17988 switch (newState) { 17989 case COMPONENT_ENABLED_STATE_ENABLED: 17990 if (!pkgSetting.enableComponentLPw(className, userId)) { 17991 return; 17992 } 17993 break; 17994 case COMPONENT_ENABLED_STATE_DISABLED: 17995 if (!pkgSetting.disableComponentLPw(className, userId)) { 17996 return; 17997 } 17998 break; 17999 case COMPONENT_ENABLED_STATE_DEFAULT: 18000 if (!pkgSetting.restoreComponentLPw(className, userId)) { 18001 return; 18002 } 18003 break; 18004 default: 18005 Slog.e(TAG, "Invalid new component state: " + newState); 18006 return; 18007 } 18008 } 18009 scheduleWritePackageRestrictionsLocked(userId); 18010 components = mPendingBroadcasts.get(userId, packageName); 18011 final boolean newPackage = components == null; 18012 if (newPackage) { 18013 components = new ArrayList<String>(); 18014 } 18015 if (!components.contains(componentName)) { 18016 components.add(componentName); 18017 } 18018 if ((flags&PackageManager.DONT_KILL_APP) == 0) { 18019 sendNow = true; 18020 // Purge entry from pending broadcast list if another one exists already 18021 // since we are sending one right away. 18022 mPendingBroadcasts.remove(userId, packageName); 18023 } else { 18024 if (newPackage) { 18025 mPendingBroadcasts.put(userId, packageName, components); 18026 } 18027 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) { 18028 // Schedule a message 18029 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY); 18030 } 18031 } 18032 } 18033 18034 long callingId = Binder.clearCallingIdentity(); 18035 try { 18036 if (sendNow) { 18037 packageUid = UserHandle.getUid(userId, pkgSetting.appId); 18038 sendPackageChangedBroadcast(packageName, 18039 (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid); 18040 } 18041 } finally { 18042 Binder.restoreCallingIdentity(callingId); 18043 } 18044 } 18045 18046 @Override 18047 public void flushPackageRestrictionsAsUser(int userId) { 18048 if (!sUserManager.exists(userId)) { 18049 return; 18050 } 18051 enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/, 18052 false /* checkShell */, "flushPackageRestrictions"); 18053 synchronized (mPackages) { 18054 mSettings.writePackageRestrictionsLPr(userId); 18055 mDirtyUsers.remove(userId); 18056 if (mDirtyUsers.isEmpty()) { 18057 mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS); 18058 } 18059 } 18060 } 18061 18062 private void sendPackageChangedBroadcast(String packageName, 18063 boolean killFlag, ArrayList<String> componentNames, int packageUid) { 18064 if (DEBUG_INSTALL) 18065 Log.v(TAG, "Sending package changed: package=" + packageName + " components=" 18066 + componentNames); 18067 Bundle extras = new Bundle(4); 18068 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0)); 18069 String nameList[] = new String[componentNames.size()]; 18070 componentNames.toArray(nameList); 18071 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList); 18072 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag); 18073 extras.putInt(Intent.EXTRA_UID, packageUid); 18074 // If this is not reporting a change of the overall package, then only send it 18075 // to registered receivers. We don't want to launch a swath of apps for every 18076 // little component state change. 18077 final int flags = !componentNames.contains(packageName) 18078 ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0; 18079 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, flags, null, null, 18080 new int[] {UserHandle.getUserId(packageUid)}); 18081 } 18082 18083 @Override 18084 public void setPackageStoppedState(String packageName, boolean stopped, int userId) { 18085 if (!sUserManager.exists(userId)) return; 18086 final int uid = Binder.getCallingUid(); 18087 final int permission = mContext.checkCallingOrSelfPermission( 18088 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 18089 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 18090 enforceCrossUserPermission(uid, userId, 18091 true /* requireFullPermission */, true /* checkShell */, "stop package"); 18092 // writer 18093 synchronized (mPackages) { 18094 if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped, 18095 allowedByPermission, uid, userId)) { 18096 scheduleWritePackageRestrictionsLocked(userId); 18097 } 18098 } 18099 } 18100 18101 @Override 18102 public String getInstallerPackageName(String packageName) { 18103 // reader 18104 synchronized (mPackages) { 18105 return mSettings.getInstallerPackageNameLPr(packageName); 18106 } 18107 } 18108 18109 public boolean isOrphaned(String packageName) { 18110 // reader 18111 synchronized (mPackages) { 18112 return mSettings.isOrphaned(packageName); 18113 } 18114 } 18115 18116 @Override 18117 public int getApplicationEnabledSetting(String packageName, int userId) { 18118 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 18119 int uid = Binder.getCallingUid(); 18120 enforceCrossUserPermission(uid, userId, 18121 false /* requireFullPermission */, false /* checkShell */, "get enabled"); 18122 // reader 18123 synchronized (mPackages) { 18124 return mSettings.getApplicationEnabledSettingLPr(packageName, userId); 18125 } 18126 } 18127 18128 @Override 18129 public int getComponentEnabledSetting(ComponentName componentName, int userId) { 18130 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 18131 int uid = Binder.getCallingUid(); 18132 enforceCrossUserPermission(uid, userId, 18133 false /* requireFullPermission */, false /* checkShell */, "get component enabled"); 18134 // reader 18135 synchronized (mPackages) { 18136 return mSettings.getComponentEnabledSettingLPr(componentName, userId); 18137 } 18138 } 18139 18140 @Override 18141 public void enterSafeMode() { 18142 enforceSystemOrRoot("Only the system can request entering safe mode"); 18143 18144 if (!mSystemReady) { 18145 mSafeMode = true; 18146 } 18147 } 18148 18149 @Override 18150 public void systemReady() { 18151 mSystemReady = true; 18152 18153 // Disable any carrier apps. We do this very early in boot to prevent the apps from being 18154 // disabled after already being started. 18155 CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this, 18156 mContext.getContentResolver(), UserHandle.USER_SYSTEM); 18157 18158 // Read the compatibilty setting when the system is ready. 18159 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt( 18160 mContext.getContentResolver(), 18161 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1; 18162 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled); 18163 if (DEBUG_SETTINGS) { 18164 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled); 18165 } 18166 18167 int[] grantPermissionsUserIds = EMPTY_INT_ARRAY; 18168 18169 synchronized (mPackages) { 18170 // Verify that all of the preferred activity components actually 18171 // exist. It is possible for applications to be updated and at 18172 // that point remove a previously declared activity component that 18173 // had been set as a preferred activity. We try to clean this up 18174 // the next time we encounter that preferred activity, but it is 18175 // possible for the user flow to never be able to return to that 18176 // situation so here we do a sanity check to make sure we haven't 18177 // left any junk around. 18178 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>(); 18179 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 18180 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 18181 removed.clear(); 18182 for (PreferredActivity pa : pir.filterSet()) { 18183 if (mActivities.mActivities.get(pa.mPref.mComponent) == null) { 18184 removed.add(pa); 18185 } 18186 } 18187 if (removed.size() > 0) { 18188 for (int r=0; r<removed.size(); r++) { 18189 PreferredActivity pa = removed.get(r); 18190 Slog.w(TAG, "Removing dangling preferred activity: " 18191 + pa.mPref.mComponent); 18192 pir.removeFilter(pa); 18193 } 18194 mSettings.writePackageRestrictionsLPr( 18195 mSettings.mPreferredActivities.keyAt(i)); 18196 } 18197 } 18198 18199 for (int userId : UserManagerService.getInstance().getUserIds()) { 18200 if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) { 18201 grantPermissionsUserIds = ArrayUtils.appendInt( 18202 grantPermissionsUserIds, userId); 18203 } 18204 } 18205 } 18206 sUserManager.systemReady(); 18207 18208 // If we upgraded grant all default permissions before kicking off. 18209 for (int userId : grantPermissionsUserIds) { 18210 mDefaultPermissionPolicy.grantDefaultPermissions(userId); 18211 } 18212 18213 // If we did not grant default permissions, we preload from this the 18214 // default permission exceptions lazily to ensure we don't hit the 18215 // disk on a new user creation. 18216 if (grantPermissionsUserIds == EMPTY_INT_ARRAY) { 18217 mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions(); 18218 } 18219 18220 // Kick off any messages waiting for system ready 18221 if (mPostSystemReadyMessages != null) { 18222 for (Message msg : mPostSystemReadyMessages) { 18223 msg.sendToTarget(); 18224 } 18225 mPostSystemReadyMessages = null; 18226 } 18227 18228 // Watch for external volumes that come and go over time 18229 final StorageManager storage = mContext.getSystemService(StorageManager.class); 18230 storage.registerListener(mStorageListener); 18231 18232 mInstallerService.systemReady(); 18233 mPackageDexOptimizer.systemReady(); 18234 18235 MountServiceInternal mountServiceInternal = LocalServices.getService( 18236 MountServiceInternal.class); 18237 mountServiceInternal.addExternalStoragePolicy( 18238 new MountServiceInternal.ExternalStorageMountPolicy() { 18239 @Override 18240 public int getMountMode(int uid, String packageName) { 18241 if (Process.isIsolated(uid)) { 18242 return Zygote.MOUNT_EXTERNAL_NONE; 18243 } 18244 if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) { 18245 return Zygote.MOUNT_EXTERNAL_DEFAULT; 18246 } 18247 if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { 18248 return Zygote.MOUNT_EXTERNAL_DEFAULT; 18249 } 18250 if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { 18251 return Zygote.MOUNT_EXTERNAL_READ; 18252 } 18253 return Zygote.MOUNT_EXTERNAL_WRITE; 18254 } 18255 18256 @Override 18257 public boolean hasExternalStorage(int uid, String packageName) { 18258 return true; 18259 } 18260 }); 18261 18262 // Now that we're mostly running, clean up stale users and apps 18263 reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL); 18264 reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL); 18265 } 18266 18267 @Override 18268 public boolean isSafeMode() { 18269 return mSafeMode; 18270 } 18271 18272 @Override 18273 public boolean hasSystemUidErrors() { 18274 return mHasSystemUidErrors; 18275 } 18276 18277 static String arrayToString(int[] array) { 18278 StringBuffer buf = new StringBuffer(128); 18279 buf.append('['); 18280 if (array != null) { 18281 for (int i=0; i<array.length; i++) { 18282 if (i > 0) buf.append(", "); 18283 buf.append(array[i]); 18284 } 18285 } 18286 buf.append(']'); 18287 return buf.toString(); 18288 } 18289 18290 static class DumpState { 18291 public static final int DUMP_LIBS = 1 << 0; 18292 public static final int DUMP_FEATURES = 1 << 1; 18293 public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2; 18294 public static final int DUMP_SERVICE_RESOLVERS = 1 << 3; 18295 public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4; 18296 public static final int DUMP_CONTENT_RESOLVERS = 1 << 5; 18297 public static final int DUMP_PERMISSIONS = 1 << 6; 18298 public static final int DUMP_PACKAGES = 1 << 7; 18299 public static final int DUMP_SHARED_USERS = 1 << 8; 18300 public static final int DUMP_MESSAGES = 1 << 9; 18301 public static final int DUMP_PROVIDERS = 1 << 10; 18302 public static final int DUMP_VERIFIERS = 1 << 11; 18303 public static final int DUMP_PREFERRED = 1 << 12; 18304 public static final int DUMP_PREFERRED_XML = 1 << 13; 18305 public static final int DUMP_KEYSETS = 1 << 14; 18306 public static final int DUMP_VERSION = 1 << 15; 18307 public static final int DUMP_INSTALLS = 1 << 16; 18308 public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17; 18309 public static final int DUMP_DOMAIN_PREFERRED = 1 << 18; 18310 public static final int DUMP_FROZEN = 1 << 19; 18311 public static final int DUMP_DEXOPT = 1 << 20; 18312 public static final int DUMP_COMPILER_STATS = 1 << 21; 18313 18314 public static final int OPTION_SHOW_FILTERS = 1 << 0; 18315 18316 private int mTypes; 18317 18318 private int mOptions; 18319 18320 private boolean mTitlePrinted; 18321 18322 private SharedUserSetting mSharedUser; 18323 18324 public boolean isDumping(int type) { 18325 if (mTypes == 0 && type != DUMP_PREFERRED_XML) { 18326 return true; 18327 } 18328 18329 return (mTypes & type) != 0; 18330 } 18331 18332 public void setDump(int type) { 18333 mTypes |= type; 18334 } 18335 18336 public boolean isOptionEnabled(int option) { 18337 return (mOptions & option) != 0; 18338 } 18339 18340 public void setOptionEnabled(int option) { 18341 mOptions |= option; 18342 } 18343 18344 public boolean onTitlePrinted() { 18345 final boolean printed = mTitlePrinted; 18346 mTitlePrinted = true; 18347 return printed; 18348 } 18349 18350 public boolean getTitlePrinted() { 18351 return mTitlePrinted; 18352 } 18353 18354 public void setTitlePrinted(boolean enabled) { 18355 mTitlePrinted = enabled; 18356 } 18357 18358 public SharedUserSetting getSharedUser() { 18359 return mSharedUser; 18360 } 18361 18362 public void setSharedUser(SharedUserSetting user) { 18363 mSharedUser = user; 18364 } 18365 } 18366 18367 @Override 18368 public void onShellCommand(FileDescriptor in, FileDescriptor out, 18369 FileDescriptor err, String[] args, ResultReceiver resultReceiver) { 18370 (new PackageManagerShellCommand(this)).exec( 18371 this, in, out, err, args, resultReceiver); 18372 } 18373 18374 @Override 18375 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 18376 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 18377 != PackageManager.PERMISSION_GRANTED) { 18378 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 18379 + Binder.getCallingPid() 18380 + ", uid=" + Binder.getCallingUid() 18381 + " without permission " 18382 + android.Manifest.permission.DUMP); 18383 return; 18384 } 18385 18386 DumpState dumpState = new DumpState(); 18387 boolean fullPreferred = false; 18388 boolean checkin = false; 18389 18390 String packageName = null; 18391 ArraySet<String> permissionNames = null; 18392 18393 int opti = 0; 18394 while (opti < args.length) { 18395 String opt = args[opti]; 18396 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 18397 break; 18398 } 18399 opti++; 18400 18401 if ("-a".equals(opt)) { 18402 // Right now we only know how to print all. 18403 } else if ("-h".equals(opt)) { 18404 pw.println("Package manager dump options:"); 18405 pw.println(" [-h] [-f] [--checkin] [cmd] ..."); 18406 pw.println(" --checkin: dump for a checkin"); 18407 pw.println(" -f: print details of intent filters"); 18408 pw.println(" -h: print this help"); 18409 pw.println(" cmd may be one of:"); 18410 pw.println(" l[ibraries]: list known shared libraries"); 18411 pw.println(" f[eatures]: list device features"); 18412 pw.println(" k[eysets]: print known keysets"); 18413 pw.println(" r[esolvers] [activity|service|receiver|content]: dump intent resolvers"); 18414 pw.println(" perm[issions]: dump permissions"); 18415 pw.println(" permission [name ...]: dump declaration and use of given permission"); 18416 pw.println(" pref[erred]: print preferred package settings"); 18417 pw.println(" preferred-xml [--full]: print preferred package settings as xml"); 18418 pw.println(" prov[iders]: dump content providers"); 18419 pw.println(" p[ackages]: dump installed packages"); 18420 pw.println(" s[hared-users]: dump shared user IDs"); 18421 pw.println(" m[essages]: print collected runtime messages"); 18422 pw.println(" v[erifiers]: print package verifier info"); 18423 pw.println(" d[omain-preferred-apps]: print domains preferred apps"); 18424 pw.println(" i[ntent-filter-verifiers]|ifv: print intent filter verifier info"); 18425 pw.println(" version: print database version info"); 18426 pw.println(" write: write current settings now"); 18427 pw.println(" installs: details about install sessions"); 18428 pw.println(" check-permission <permission> <package> [<user>]: does pkg hold perm?"); 18429 pw.println(" dexopt: dump dexopt state"); 18430 pw.println(" compiler-stats: dump compiler statistics"); 18431 pw.println(" <package.name>: info about given package"); 18432 return; 18433 } else if ("--checkin".equals(opt)) { 18434 checkin = true; 18435 } else if ("-f".equals(opt)) { 18436 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 18437 } else { 18438 pw.println("Unknown argument: " + opt + "; use -h for help"); 18439 } 18440 } 18441 18442 // Is the caller requesting to dump a particular piece of data? 18443 if (opti < args.length) { 18444 String cmd = args[opti]; 18445 opti++; 18446 // Is this a package name? 18447 if ("android".equals(cmd) || cmd.contains(".")) { 18448 packageName = cmd; 18449 // When dumping a single package, we always dump all of its 18450 // filter information since the amount of data will be reasonable. 18451 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 18452 } else if ("check-permission".equals(cmd)) { 18453 if (opti >= args.length) { 18454 pw.println("Error: check-permission missing permission argument"); 18455 return; 18456 } 18457 String perm = args[opti]; 18458 opti++; 18459 if (opti >= args.length) { 18460 pw.println("Error: check-permission missing package argument"); 18461 return; 18462 } 18463 String pkg = args[opti]; 18464 opti++; 18465 int user = UserHandle.getUserId(Binder.getCallingUid()); 18466 if (opti < args.length) { 18467 try { 18468 user = Integer.parseInt(args[opti]); 18469 } catch (NumberFormatException e) { 18470 pw.println("Error: check-permission user argument is not a number: " 18471 + args[opti]); 18472 return; 18473 } 18474 } 18475 pw.println(checkPermission(perm, pkg, user)); 18476 return; 18477 } else if ("l".equals(cmd) || "libraries".equals(cmd)) { 18478 dumpState.setDump(DumpState.DUMP_LIBS); 18479 } else if ("f".equals(cmd) || "features".equals(cmd)) { 18480 dumpState.setDump(DumpState.DUMP_FEATURES); 18481 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) { 18482 if (opti >= args.length) { 18483 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS 18484 | DumpState.DUMP_SERVICE_RESOLVERS 18485 | DumpState.DUMP_RECEIVER_RESOLVERS 18486 | DumpState.DUMP_CONTENT_RESOLVERS); 18487 } else { 18488 while (opti < args.length) { 18489 String name = args[opti]; 18490 if ("a".equals(name) || "activity".equals(name)) { 18491 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS); 18492 } else if ("s".equals(name) || "service".equals(name)) { 18493 dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS); 18494 } else if ("r".equals(name) || "receiver".equals(name)) { 18495 dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS); 18496 } else if ("c".equals(name) || "content".equals(name)) { 18497 dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS); 18498 } else { 18499 pw.println("Error: unknown resolver table type: " + name); 18500 return; 18501 } 18502 opti++; 18503 } 18504 } 18505 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) { 18506 dumpState.setDump(DumpState.DUMP_PERMISSIONS); 18507 } else if ("permission".equals(cmd)) { 18508 if (opti >= args.length) { 18509 pw.println("Error: permission requires permission name"); 18510 return; 18511 } 18512 permissionNames = new ArraySet<>(); 18513 while (opti < args.length) { 18514 permissionNames.add(args[opti]); 18515 opti++; 18516 } 18517 dumpState.setDump(DumpState.DUMP_PERMISSIONS 18518 | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS); 18519 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) { 18520 dumpState.setDump(DumpState.DUMP_PREFERRED); 18521 } else if ("preferred-xml".equals(cmd)) { 18522 dumpState.setDump(DumpState.DUMP_PREFERRED_XML); 18523 if (opti < args.length && "--full".equals(args[opti])) { 18524 fullPreferred = true; 18525 opti++; 18526 } 18527 } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) { 18528 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED); 18529 } else if ("p".equals(cmd) || "packages".equals(cmd)) { 18530 dumpState.setDump(DumpState.DUMP_PACKAGES); 18531 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) { 18532 dumpState.setDump(DumpState.DUMP_SHARED_USERS); 18533 } else if ("prov".equals(cmd) || "providers".equals(cmd)) { 18534 dumpState.setDump(DumpState.DUMP_PROVIDERS); 18535 } else if ("m".equals(cmd) || "messages".equals(cmd)) { 18536 dumpState.setDump(DumpState.DUMP_MESSAGES); 18537 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) { 18538 dumpState.setDump(DumpState.DUMP_VERIFIERS); 18539 } else if ("i".equals(cmd) || "ifv".equals(cmd) 18540 || "intent-filter-verifiers".equals(cmd)) { 18541 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS); 18542 } else if ("version".equals(cmd)) { 18543 dumpState.setDump(DumpState.DUMP_VERSION); 18544 } else if ("k".equals(cmd) || "keysets".equals(cmd)) { 18545 dumpState.setDump(DumpState.DUMP_KEYSETS); 18546 } else if ("installs".equals(cmd)) { 18547 dumpState.setDump(DumpState.DUMP_INSTALLS); 18548 } else if ("frozen".equals(cmd)) { 18549 dumpState.setDump(DumpState.DUMP_FROZEN); 18550 } else if ("dexopt".equals(cmd)) { 18551 dumpState.setDump(DumpState.DUMP_DEXOPT); 18552 } else if ("compiler-stats".equals(cmd)) { 18553 dumpState.setDump(DumpState.DUMP_COMPILER_STATS); 18554 } else if ("write".equals(cmd)) { 18555 synchronized (mPackages) { 18556 mSettings.writeLPr(); 18557 pw.println("Settings written."); 18558 return; 18559 } 18560 } 18561 } 18562 18563 if (checkin) { 18564 pw.println("vers,1"); 18565 } 18566 18567 // reader 18568 synchronized (mPackages) { 18569 if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) { 18570 if (!checkin) { 18571 if (dumpState.onTitlePrinted()) 18572 pw.println(); 18573 pw.println("Database versions:"); 18574 mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, " ")); 18575 } 18576 } 18577 18578 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) { 18579 if (!checkin) { 18580 if (dumpState.onTitlePrinted()) 18581 pw.println(); 18582 pw.println("Verifiers:"); 18583 pw.print(" Required: "); 18584 pw.print(mRequiredVerifierPackage); 18585 pw.print(" (uid="); 18586 pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 18587 UserHandle.USER_SYSTEM)); 18588 pw.println(")"); 18589 } else if (mRequiredVerifierPackage != null) { 18590 pw.print("vrfy,"); pw.print(mRequiredVerifierPackage); 18591 pw.print(","); 18592 pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 18593 UserHandle.USER_SYSTEM)); 18594 } 18595 } 18596 18597 if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) && 18598 packageName == null) { 18599 if (mIntentFilterVerifierComponent != null) { 18600 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName(); 18601 if (!checkin) { 18602 if (dumpState.onTitlePrinted()) 18603 pw.println(); 18604 pw.println("Intent Filter Verifier:"); 18605 pw.print(" Using: "); 18606 pw.print(verifierPackageName); 18607 pw.print(" (uid="); 18608 pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING, 18609 UserHandle.USER_SYSTEM)); 18610 pw.println(")"); 18611 } else if (verifierPackageName != null) { 18612 pw.print("ifv,"); pw.print(verifierPackageName); 18613 pw.print(","); 18614 pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING, 18615 UserHandle.USER_SYSTEM)); 18616 } 18617 } else { 18618 pw.println(); 18619 pw.println("No Intent Filter Verifier available!"); 18620 } 18621 } 18622 18623 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) { 18624 boolean printedHeader = false; 18625 final Iterator<String> it = mSharedLibraries.keySet().iterator(); 18626 while (it.hasNext()) { 18627 String name = it.next(); 18628 SharedLibraryEntry ent = mSharedLibraries.get(name); 18629 if (!checkin) { 18630 if (!printedHeader) { 18631 if (dumpState.onTitlePrinted()) 18632 pw.println(); 18633 pw.println("Libraries:"); 18634 printedHeader = true; 18635 } 18636 pw.print(" "); 18637 } else { 18638 pw.print("lib,"); 18639 } 18640 pw.print(name); 18641 if (!checkin) { 18642 pw.print(" -> "); 18643 } 18644 if (ent.path != null) { 18645 if (!checkin) { 18646 pw.print("(jar) "); 18647 pw.print(ent.path); 18648 } else { 18649 pw.print(",jar,"); 18650 pw.print(ent.path); 18651 } 18652 } else { 18653 if (!checkin) { 18654 pw.print("(apk) "); 18655 pw.print(ent.apk); 18656 } else { 18657 pw.print(",apk,"); 18658 pw.print(ent.apk); 18659 } 18660 } 18661 pw.println(); 18662 } 18663 } 18664 18665 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) { 18666 if (dumpState.onTitlePrinted()) 18667 pw.println(); 18668 if (!checkin) { 18669 pw.println("Features:"); 18670 } 18671 18672 for (FeatureInfo feat : mAvailableFeatures.values()) { 18673 if (checkin) { 18674 pw.print("feat,"); 18675 pw.print(feat.name); 18676 pw.print(","); 18677 pw.println(feat.version); 18678 } else { 18679 pw.print(" "); 18680 pw.print(feat.name); 18681 if (feat.version > 0) { 18682 pw.print(" version="); 18683 pw.print(feat.version); 18684 } 18685 pw.println(); 18686 } 18687 } 18688 } 18689 18690 if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) { 18691 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:" 18692 : "Activity Resolver Table:", " ", packageName, 18693 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 18694 dumpState.setTitlePrinted(true); 18695 } 18696 } 18697 if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) { 18698 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:" 18699 : "Receiver Resolver Table:", " ", packageName, 18700 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 18701 dumpState.setTitlePrinted(true); 18702 } 18703 } 18704 if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) { 18705 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:" 18706 : "Service Resolver Table:", " ", packageName, 18707 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 18708 dumpState.setTitlePrinted(true); 18709 } 18710 } 18711 if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) { 18712 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:" 18713 : "Provider Resolver Table:", " ", packageName, 18714 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 18715 dumpState.setTitlePrinted(true); 18716 } 18717 } 18718 18719 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) { 18720 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 18721 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 18722 int user = mSettings.mPreferredActivities.keyAt(i); 18723 if (pir.dump(pw, 18724 dumpState.getTitlePrinted() 18725 ? "\nPreferred Activities User " + user + ":" 18726 : "Preferred Activities User " + user + ":", " ", 18727 packageName, true, false)) { 18728 dumpState.setTitlePrinted(true); 18729 } 18730 } 18731 } 18732 18733 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) { 18734 pw.flush(); 18735 FileOutputStream fout = new FileOutputStream(fd); 18736 BufferedOutputStream str = new BufferedOutputStream(fout); 18737 XmlSerializer serializer = new FastXmlSerializer(); 18738 try { 18739 serializer.setOutput(str, StandardCharsets.UTF_8.name()); 18740 serializer.startDocument(null, true); 18741 serializer.setFeature( 18742 "http://xmlpull.org/v1/doc/features.html#indent-output", true); 18743 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred); 18744 serializer.endDocument(); 18745 serializer.flush(); 18746 } catch (IllegalArgumentException e) { 18747 pw.println("Failed writing: " + e); 18748 } catch (IllegalStateException e) { 18749 pw.println("Failed writing: " + e); 18750 } catch (IOException e) { 18751 pw.println("Failed writing: " + e); 18752 } 18753 } 18754 18755 if (!checkin 18756 && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED) 18757 && packageName == null) { 18758 pw.println(); 18759 int count = mSettings.mPackages.size(); 18760 if (count == 0) { 18761 pw.println("No applications!"); 18762 pw.println(); 18763 } else { 18764 final String prefix = " "; 18765 Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values(); 18766 if (allPackageSettings.size() == 0) { 18767 pw.println("No domain preferred apps!"); 18768 pw.println(); 18769 } else { 18770 pw.println("App verification status:"); 18771 pw.println(); 18772 count = 0; 18773 for (PackageSetting ps : allPackageSettings) { 18774 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo(); 18775 if (ivi == null || ivi.getPackageName() == null) continue; 18776 pw.println(prefix + "Package: " + ivi.getPackageName()); 18777 pw.println(prefix + "Domains: " + ivi.getDomainsString()); 18778 pw.println(prefix + "Status: " + ivi.getStatusString()); 18779 pw.println(); 18780 count++; 18781 } 18782 if (count == 0) { 18783 pw.println(prefix + "No app verification established."); 18784 pw.println(); 18785 } 18786 for (int userId : sUserManager.getUserIds()) { 18787 pw.println("App linkages for user " + userId + ":"); 18788 pw.println(); 18789 count = 0; 18790 for (PackageSetting ps : allPackageSettings) { 18791 final long status = ps.getDomainVerificationStatusForUser(userId); 18792 if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 18793 continue; 18794 } 18795 pw.println(prefix + "Package: " + ps.name); 18796 pw.println(prefix + "Domains: " + dumpDomainString(ps.name)); 18797 String statusStr = IntentFilterVerificationInfo. 18798 getStatusStringFromValue(status); 18799 pw.println(prefix + "Status: " + statusStr); 18800 pw.println(); 18801 count++; 18802 } 18803 if (count == 0) { 18804 pw.println(prefix + "No configured app linkages."); 18805 pw.println(); 18806 } 18807 } 18808 } 18809 } 18810 } 18811 18812 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) { 18813 mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState); 18814 if (packageName == null && permissionNames == null) { 18815 for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) { 18816 if (iperm == 0) { 18817 if (dumpState.onTitlePrinted()) 18818 pw.println(); 18819 pw.println("AppOp Permissions:"); 18820 } 18821 pw.print(" AppOp Permission "); 18822 pw.print(mAppOpPermissionPackages.keyAt(iperm)); 18823 pw.println(":"); 18824 ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm); 18825 for (int ipkg=0; ipkg<pkgs.size(); ipkg++) { 18826 pw.print(" "); pw.println(pkgs.valueAt(ipkg)); 18827 } 18828 } 18829 } 18830 } 18831 18832 if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) { 18833 boolean printedSomething = false; 18834 for (PackageParser.Provider p : mProviders.mProviders.values()) { 18835 if (packageName != null && !packageName.equals(p.info.packageName)) { 18836 continue; 18837 } 18838 if (!printedSomething) { 18839 if (dumpState.onTitlePrinted()) 18840 pw.println(); 18841 pw.println("Registered ContentProviders:"); 18842 printedSomething = true; 18843 } 18844 pw.print(" "); p.printComponentShortName(pw); pw.println(":"); 18845 pw.print(" "); pw.println(p.toString()); 18846 } 18847 printedSomething = false; 18848 for (Map.Entry<String, PackageParser.Provider> entry : 18849 mProvidersByAuthority.entrySet()) { 18850 PackageParser.Provider p = entry.getValue(); 18851 if (packageName != null && !packageName.equals(p.info.packageName)) { 18852 continue; 18853 } 18854 if (!printedSomething) { 18855 if (dumpState.onTitlePrinted()) 18856 pw.println(); 18857 pw.println("ContentProvider Authorities:"); 18858 printedSomething = true; 18859 } 18860 pw.print(" ["); pw.print(entry.getKey()); pw.println("]:"); 18861 pw.print(" "); pw.println(p.toString()); 18862 if (p.info != null && p.info.applicationInfo != null) { 18863 final String appInfo = p.info.applicationInfo.toString(); 18864 pw.print(" applicationInfo="); pw.println(appInfo); 18865 } 18866 } 18867 } 18868 18869 if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) { 18870 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState); 18871 } 18872 18873 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) { 18874 mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin); 18875 } 18876 18877 if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) { 18878 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin); 18879 } 18880 18881 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) { 18882 mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState); 18883 } 18884 18885 if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) { 18886 // XXX should handle packageName != null by dumping only install data that 18887 // the given package is involved with. 18888 if (dumpState.onTitlePrinted()) pw.println(); 18889 mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120)); 18890 } 18891 18892 if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) { 18893 // XXX should handle packageName != null by dumping only install data that 18894 // the given package is involved with. 18895 if (dumpState.onTitlePrinted()) pw.println(); 18896 18897 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120); 18898 ipw.println(); 18899 ipw.println("Frozen packages:"); 18900 ipw.increaseIndent(); 18901 if (mFrozenPackages.size() == 0) { 18902 ipw.println("(none)"); 18903 } else { 18904 for (int i = 0; i < mFrozenPackages.size(); i++) { 18905 ipw.println(mFrozenPackages.valueAt(i)); 18906 } 18907 } 18908 ipw.decreaseIndent(); 18909 } 18910 18911 if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) { 18912 if (dumpState.onTitlePrinted()) pw.println(); 18913 dumpDexoptStateLPr(pw, packageName); 18914 } 18915 18916 if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) { 18917 if (dumpState.onTitlePrinted()) pw.println(); 18918 dumpCompilerStatsLPr(pw, packageName); 18919 } 18920 18921 if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) { 18922 if (dumpState.onTitlePrinted()) pw.println(); 18923 mSettings.dumpReadMessagesLPr(pw, dumpState); 18924 18925 pw.println(); 18926 pw.println("Package warning messages:"); 18927 BufferedReader in = null; 18928 String line = null; 18929 try { 18930 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 18931 while ((line = in.readLine()) != null) { 18932 if (line.contains("ignored: updated version")) continue; 18933 pw.println(line); 18934 } 18935 } catch (IOException ignored) { 18936 } finally { 18937 IoUtils.closeQuietly(in); 18938 } 18939 } 18940 18941 if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) { 18942 BufferedReader in = null; 18943 String line = null; 18944 try { 18945 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 18946 while ((line = in.readLine()) != null) { 18947 if (line.contains("ignored: updated version")) continue; 18948 pw.print("msg,"); 18949 pw.println(line); 18950 } 18951 } catch (IOException ignored) { 18952 } finally { 18953 IoUtils.closeQuietly(in); 18954 } 18955 } 18956 } 18957 } 18958 18959 private void dumpDexoptStateLPr(PrintWriter pw, String packageName) { 18960 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120); 18961 ipw.println(); 18962 ipw.println("Dexopt state:"); 18963 ipw.increaseIndent(); 18964 Collection<PackageParser.Package> packages = null; 18965 if (packageName != null) { 18966 PackageParser.Package targetPackage = mPackages.get(packageName); 18967 if (targetPackage != null) { 18968 packages = Collections.singletonList(targetPackage); 18969 } else { 18970 ipw.println("Unable to find package: " + packageName); 18971 return; 18972 } 18973 } else { 18974 packages = mPackages.values(); 18975 } 18976 18977 for (PackageParser.Package pkg : packages) { 18978 ipw.println("[" + pkg.packageName + "]"); 18979 ipw.increaseIndent(); 18980 mPackageDexOptimizer.dumpDexoptState(ipw, pkg); 18981 ipw.decreaseIndent(); 18982 } 18983 } 18984 18985 private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) { 18986 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120); 18987 ipw.println(); 18988 ipw.println("Compiler stats:"); 18989 ipw.increaseIndent(); 18990 Collection<PackageParser.Package> packages = null; 18991 if (packageName != null) { 18992 PackageParser.Package targetPackage = mPackages.get(packageName); 18993 if (targetPackage != null) { 18994 packages = Collections.singletonList(targetPackage); 18995 } else { 18996 ipw.println("Unable to find package: " + packageName); 18997 return; 18998 } 18999 } else { 19000 packages = mPackages.values(); 19001 } 19002 19003 for (PackageParser.Package pkg : packages) { 19004 ipw.println("[" + pkg.packageName + "]"); 19005 ipw.increaseIndent(); 19006 19007 CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName); 19008 if (stats == null) { 19009 ipw.println("(No recorded stats)"); 19010 } else { 19011 stats.dump(ipw); 19012 } 19013 ipw.decreaseIndent(); 19014 } 19015 } 19016 19017 private String dumpDomainString(String packageName) { 19018 List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName) 19019 .getList(); 19020 List<IntentFilter> filters = getAllIntentFilters(packageName).getList(); 19021 19022 ArraySet<String> result = new ArraySet<>(); 19023 if (iviList.size() > 0) { 19024 for (IntentFilterVerificationInfo ivi : iviList) { 19025 for (String host : ivi.getDomains()) { 19026 result.add(host); 19027 } 19028 } 19029 } 19030 if (filters != null && filters.size() > 0) { 19031 for (IntentFilter filter : filters) { 19032 if (filter.hasCategory(Intent.CATEGORY_BROWSABLE) 19033 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 19034 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) { 19035 result.addAll(filter.getHostsList()); 19036 } 19037 } 19038 } 19039 19040 StringBuilder sb = new StringBuilder(result.size() * 16); 19041 for (String domain : result) { 19042 if (sb.length() > 0) sb.append(" "); 19043 sb.append(domain); 19044 } 19045 return sb.toString(); 19046 } 19047 19048 // ------- apps on sdcard specific code ------- 19049 static final boolean DEBUG_SD_INSTALL = false; 19050 19051 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD"; 19052 19053 private static final String SD_ENCRYPTION_ALGORITHM = "AES"; 19054 19055 private boolean mMediaMounted = false; 19056 19057 static String getEncryptKey() { 19058 try { 19059 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString( 19060 SD_ENCRYPTION_KEYSTORE_NAME); 19061 if (sdEncKey == null) { 19062 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128, 19063 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME); 19064 if (sdEncKey == null) { 19065 Slog.e(TAG, "Failed to create encryption keys"); 19066 return null; 19067 } 19068 } 19069 return sdEncKey; 19070 } catch (NoSuchAlgorithmException nsae) { 19071 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae); 19072 return null; 19073 } catch (IOException ioe) { 19074 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe); 19075 return null; 19076 } 19077 } 19078 19079 /* 19080 * Update media status on PackageManager. 19081 */ 19082 @Override 19083 public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) { 19084 int callingUid = Binder.getCallingUid(); 19085 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 19086 throw new SecurityException("Media status can only be updated by the system"); 19087 } 19088 // reader; this apparently protects mMediaMounted, but should probably 19089 // be a different lock in that case. 19090 synchronized (mPackages) { 19091 Log.i(TAG, "Updating external media status from " 19092 + (mMediaMounted ? "mounted" : "unmounted") + " to " 19093 + (mediaStatus ? "mounted" : "unmounted")); 19094 if (DEBUG_SD_INSTALL) 19095 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus 19096 + ", mMediaMounted=" + mMediaMounted); 19097 if (mediaStatus == mMediaMounted) { 19098 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 19099 : 0, -1); 19100 mHandler.sendMessage(msg); 19101 return; 19102 } 19103 mMediaMounted = mediaStatus; 19104 } 19105 // Queue up an async operation since the package installation may take a 19106 // little while. 19107 mHandler.post(new Runnable() { 19108 public void run() { 19109 updateExternalMediaStatusInner(mediaStatus, reportStatus, true); 19110 } 19111 }); 19112 } 19113 19114 /** 19115 * Called by MountService when the initial ASECs to scan are available. 19116 * Should block until all the ASEC containers are finished being scanned. 19117 */ 19118 public void scanAvailableAsecs() { 19119 updateExternalMediaStatusInner(true, false, false); 19120 } 19121 19122 /* 19123 * Collect information of applications on external media, map them against 19124 * existing containers and update information based on current mount status. 19125 * Please note that we always have to report status if reportStatus has been 19126 * set to true especially when unloading packages. 19127 */ 19128 private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus, 19129 boolean externalStorage) { 19130 ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>(); 19131 int[] uidArr = EmptyArray.INT; 19132 19133 final String[] list = PackageHelper.getSecureContainerList(); 19134 if (ArrayUtils.isEmpty(list)) { 19135 Log.i(TAG, "No secure containers found"); 19136 } else { 19137 // Process list of secure containers and categorize them 19138 // as active or stale based on their package internal state. 19139 19140 // reader 19141 synchronized (mPackages) { 19142 for (String cid : list) { 19143 // Leave stages untouched for now; installer service owns them 19144 if (PackageInstallerService.isStageName(cid)) continue; 19145 19146 if (DEBUG_SD_INSTALL) 19147 Log.i(TAG, "Processing container " + cid); 19148 String pkgName = getAsecPackageName(cid); 19149 if (pkgName == null) { 19150 Slog.i(TAG, "Found stale container " + cid + " with no package name"); 19151 continue; 19152 } 19153 if (DEBUG_SD_INSTALL) 19154 Log.i(TAG, "Looking for pkg : " + pkgName); 19155 19156 final PackageSetting ps = mSettings.mPackages.get(pkgName); 19157 if (ps == null) { 19158 Slog.i(TAG, "Found stale container " + cid + " with no matching settings"); 19159 continue; 19160 } 19161 19162 /* 19163 * Skip packages that are not external if we're unmounting 19164 * external storage. 19165 */ 19166 if (externalStorage && !isMounted && !isExternal(ps)) { 19167 continue; 19168 } 19169 19170 final AsecInstallArgs args = new AsecInstallArgs(cid, 19171 getAppDexInstructionSets(ps), ps.isForwardLocked()); 19172 // The package status is changed only if the code path 19173 // matches between settings and the container id. 19174 if (ps.codePathString != null 19175 && ps.codePathString.startsWith(args.getCodePath())) { 19176 if (DEBUG_SD_INSTALL) { 19177 Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName 19178 + " at code path: " + ps.codePathString); 19179 } 19180 19181 // We do have a valid package installed on sdcard 19182 processCids.put(args, ps.codePathString); 19183 final int uid = ps.appId; 19184 if (uid != -1) { 19185 uidArr = ArrayUtils.appendInt(uidArr, uid); 19186 } 19187 } else { 19188 Slog.i(TAG, "Found stale container " + cid + ": expected codePath=" 19189 + ps.codePathString); 19190 } 19191 } 19192 } 19193 19194 Arrays.sort(uidArr); 19195 } 19196 19197 // Process packages with valid entries. 19198 if (isMounted) { 19199 if (DEBUG_SD_INSTALL) 19200 Log.i(TAG, "Loading packages"); 19201 loadMediaPackages(processCids, uidArr, externalStorage); 19202 startCleaningPackages(); 19203 mInstallerService.onSecureContainersAvailable(); 19204 } else { 19205 if (DEBUG_SD_INSTALL) 19206 Log.i(TAG, "Unloading packages"); 19207 unloadMediaPackages(processCids, uidArr, reportStatus); 19208 } 19209 } 19210 19211 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 19212 ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) { 19213 final int size = infos.size(); 19214 final String[] packageNames = new String[size]; 19215 final int[] packageUids = new int[size]; 19216 for (int i = 0; i < size; i++) { 19217 final ApplicationInfo info = infos.get(i); 19218 packageNames[i] = info.packageName; 19219 packageUids[i] = info.uid; 19220 } 19221 sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids, 19222 finishedReceiver); 19223 } 19224 19225 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 19226 ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 19227 sendResourcesChangedBroadcast(mediaStatus, replacing, 19228 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver); 19229 } 19230 19231 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 19232 String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 19233 int size = pkgList.length; 19234 if (size > 0) { 19235 // Send broadcasts here 19236 Bundle extras = new Bundle(); 19237 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 19238 if (uidArr != null) { 19239 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr); 19240 } 19241 if (replacing) { 19242 extras.putBoolean(Intent.EXTRA_REPLACING, replacing); 19243 } 19244 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE 19245 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE; 19246 sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null); 19247 } 19248 } 19249 19250 /* 19251 * Look at potentially valid container ids from processCids If package 19252 * information doesn't match the one on record or package scanning fails, 19253 * the cid is added to list of removeCids. We currently don't delete stale 19254 * containers. 19255 */ 19256 private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr, 19257 boolean externalStorage) { 19258 ArrayList<String> pkgList = new ArrayList<String>(); 19259 Set<AsecInstallArgs> keys = processCids.keySet(); 19260 19261 for (AsecInstallArgs args : keys) { 19262 String codePath = processCids.get(args); 19263 if (DEBUG_SD_INSTALL) 19264 Log.i(TAG, "Loading container : " + args.cid); 19265 int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 19266 try { 19267 // Make sure there are no container errors first. 19268 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) { 19269 Slog.e(TAG, "Failed to mount cid : " + args.cid 19270 + " when installing from sdcard"); 19271 continue; 19272 } 19273 // Check code path here. 19274 if (codePath == null || !codePath.startsWith(args.getCodePath())) { 19275 Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath() 19276 + " does not match one in settings " + codePath); 19277 continue; 19278 } 19279 // Parse package 19280 int parseFlags = mDefParseFlags; 19281 if (args.isExternalAsec()) { 19282 parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE; 19283 } 19284 if (args.isFwdLocked()) { 19285 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 19286 } 19287 19288 synchronized (mInstallLock) { 19289 PackageParser.Package pkg = null; 19290 try { 19291 // Sadly we don't know the package name yet to freeze it 19292 pkg = scanPackageTracedLI(new File(codePath), parseFlags, 19293 SCAN_IGNORE_FROZEN, 0, null); 19294 } catch (PackageManagerException e) { 19295 Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage()); 19296 } 19297 // Scan the package 19298 if (pkg != null) { 19299 /* 19300 * TODO why is the lock being held? doPostInstall is 19301 * called in other places without the lock. This needs 19302 * to be straightened out. 19303 */ 19304 // writer 19305 synchronized (mPackages) { 19306 retCode = PackageManager.INSTALL_SUCCEEDED; 19307 pkgList.add(pkg.packageName); 19308 // Post process args 19309 args.doPostInstall(PackageManager.INSTALL_SUCCEEDED, 19310 pkg.applicationInfo.uid); 19311 } 19312 } else { 19313 Slog.i(TAG, "Failed to install pkg from " + codePath + " from sdcard"); 19314 } 19315 } 19316 19317 } finally { 19318 if (retCode != PackageManager.INSTALL_SUCCEEDED) { 19319 Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode); 19320 } 19321 } 19322 } 19323 // writer 19324 synchronized (mPackages) { 19325 // If the platform SDK has changed since the last time we booted, 19326 // we need to re-grant app permission to catch any new ones that 19327 // appear. This is really a hack, and means that apps can in some 19328 // cases get permissions that the user didn't initially explicitly 19329 // allow... it would be nice to have some better way to handle 19330 // this situation. 19331 final VersionInfo ver = externalStorage ? mSettings.getExternalVersion() 19332 : mSettings.getInternalVersion(); 19333 final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL 19334 : StorageManager.UUID_PRIVATE_INTERNAL; 19335 19336 int updateFlags = UPDATE_PERMISSIONS_ALL; 19337 if (ver.sdkVersion != mSdkVersion) { 19338 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " 19339 + mSdkVersion + "; regranting permissions for external"); 19340 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 19341 } 19342 updatePermissionsLPw(null, null, volumeUuid, updateFlags); 19343 19344 // Yay, everything is now upgraded 19345 ver.forceCurrent(); 19346 19347 // can downgrade to reader 19348 // Persist settings 19349 mSettings.writeLPr(); 19350 } 19351 // Send a broadcast to let everyone know we are done processing 19352 if (pkgList.size() > 0) { 19353 sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null); 19354 } 19355 } 19356 19357 /* 19358 * Utility method to unload a list of specified containers 19359 */ 19360 private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) { 19361 // Just unmount all valid containers. 19362 for (AsecInstallArgs arg : cidArgs) { 19363 synchronized (mInstallLock) { 19364 arg.doPostDeleteLI(false); 19365 } 19366 } 19367 } 19368 19369 /* 19370 * Unload packages mounted on external media. This involves deleting package 19371 * data from internal structures, sending broadcasts about disabled packages, 19372 * gc'ing to free up references, unmounting all secure containers 19373 * corresponding to packages on external media, and posting a 19374 * UPDATED_MEDIA_STATUS message if status has been requested. Please note 19375 * that we always have to post this message if status has been requested no 19376 * matter what. 19377 */ 19378 private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[], 19379 final boolean reportStatus) { 19380 if (DEBUG_SD_INSTALL) 19381 Log.i(TAG, "unloading media packages"); 19382 ArrayList<String> pkgList = new ArrayList<String>(); 19383 ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>(); 19384 final Set<AsecInstallArgs> keys = processCids.keySet(); 19385 for (AsecInstallArgs args : keys) { 19386 String pkgName = args.getPackageName(); 19387 if (DEBUG_SD_INSTALL) 19388 Log.i(TAG, "Trying to unload pkg : " + pkgName); 19389 // Delete package internally 19390 PackageRemovedInfo outInfo = new PackageRemovedInfo(); 19391 synchronized (mInstallLock) { 19392 final int deleteFlags = PackageManager.DELETE_KEEP_DATA; 19393 final boolean res; 19394 try (PackageFreezer freezer = freezePackageForDelete(pkgName, deleteFlags, 19395 "unloadMediaPackages")) { 19396 res = deletePackageLIF(pkgName, null, false, null, deleteFlags, outInfo, false, 19397 null); 19398 } 19399 if (res) { 19400 pkgList.add(pkgName); 19401 } else { 19402 Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName); 19403 failedList.add(args); 19404 } 19405 } 19406 } 19407 19408 // reader 19409 synchronized (mPackages) { 19410 // We didn't update the settings after removing each package; 19411 // write them now for all packages. 19412 mSettings.writeLPr(); 19413 } 19414 19415 // We have to absolutely send UPDATED_MEDIA_STATUS only 19416 // after confirming that all the receivers processed the ordered 19417 // broadcast when packages get disabled, force a gc to clean things up. 19418 // and unload all the containers. 19419 if (pkgList.size() > 0) { 19420 sendResourcesChangedBroadcast(false, false, pkgList, uidArr, 19421 new IIntentReceiver.Stub() { 19422 public void performReceive(Intent intent, int resultCode, String data, 19423 Bundle extras, boolean ordered, boolean sticky, 19424 int sendingUser) throws RemoteException { 19425 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, 19426 reportStatus ? 1 : 0, 1, keys); 19427 mHandler.sendMessage(msg); 19428 } 19429 }); 19430 } else { 19431 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1, 19432 keys); 19433 mHandler.sendMessage(msg); 19434 } 19435 } 19436 19437 private void loadPrivatePackages(final VolumeInfo vol) { 19438 mHandler.post(new Runnable() { 19439 @Override 19440 public void run() { 19441 loadPrivatePackagesInner(vol); 19442 } 19443 }); 19444 } 19445 19446 private void loadPrivatePackagesInner(VolumeInfo vol) { 19447 final String volumeUuid = vol.fsUuid; 19448 if (TextUtils.isEmpty(volumeUuid)) { 19449 Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring"); 19450 return; 19451 } 19452 19453 final ArrayList<PackageFreezer> freezers = new ArrayList<>(); 19454 final ArrayList<ApplicationInfo> loaded = new ArrayList<>(); 19455 final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE; 19456 19457 final VersionInfo ver; 19458 final List<PackageSetting> packages; 19459 synchronized (mPackages) { 19460 ver = mSettings.findOrCreateVersion(volumeUuid); 19461 packages = mSettings.getVolumePackagesLPr(volumeUuid); 19462 } 19463 19464 for (PackageSetting ps : packages) { 19465 freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner")); 19466 synchronized (mInstallLock) { 19467 final PackageParser.Package pkg; 19468 try { 19469 pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null); 19470 loaded.add(pkg.applicationInfo); 19471 19472 } catch (PackageManagerException e) { 19473 Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage()); 19474 } 19475 19476 if (!Build.FINGERPRINT.equals(ver.fingerprint)) { 19477 clearAppDataLIF(ps.pkg, UserHandle.USER_ALL, 19478 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE 19479 | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 19480 } 19481 } 19482 } 19483 19484 // Reconcile app data for all started/unlocked users 19485 final StorageManager sm = mContext.getSystemService(StorageManager.class); 19486 final UserManager um = mContext.getSystemService(UserManager.class); 19487 UserManagerInternal umInternal = getUserManagerInternal(); 19488 for (UserInfo user : um.getUsers()) { 19489 final int flags; 19490 if (umInternal.isUserUnlockingOrUnlocked(user.id)) { 19491 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 19492 } else if (umInternal.isUserRunning(user.id)) { 19493 flags = StorageManager.FLAG_STORAGE_DE; 19494 } else { 19495 continue; 19496 } 19497 19498 try { 19499 sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags); 19500 synchronized (mInstallLock) { 19501 reconcileAppsDataLI(volumeUuid, user.id, flags); 19502 } 19503 } catch (IllegalStateException e) { 19504 // Device was probably ejected, and we'll process that event momentarily 19505 Slog.w(TAG, "Failed to prepare storage: " + e); 19506 } 19507 } 19508 19509 synchronized (mPackages) { 19510 int updateFlags = UPDATE_PERMISSIONS_ALL; 19511 if (ver.sdkVersion != mSdkVersion) { 19512 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " 19513 + mSdkVersion + "; regranting permissions for " + volumeUuid); 19514 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 19515 } 19516 updatePermissionsLPw(null, null, volumeUuid, updateFlags); 19517 19518 // Yay, everything is now upgraded 19519 ver.forceCurrent(); 19520 19521 mSettings.writeLPr(); 19522 } 19523 19524 for (PackageFreezer freezer : freezers) { 19525 freezer.close(); 19526 } 19527 19528 if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded); 19529 sendResourcesChangedBroadcast(true, false, loaded, null); 19530 } 19531 19532 private void unloadPrivatePackages(final VolumeInfo vol) { 19533 mHandler.post(new Runnable() { 19534 @Override 19535 public void run() { 19536 unloadPrivatePackagesInner(vol); 19537 } 19538 }); 19539 } 19540 19541 private void unloadPrivatePackagesInner(VolumeInfo vol) { 19542 final String volumeUuid = vol.fsUuid; 19543 if (TextUtils.isEmpty(volumeUuid)) { 19544 Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring"); 19545 return; 19546 } 19547 19548 final ArrayList<ApplicationInfo> unloaded = new ArrayList<>(); 19549 synchronized (mInstallLock) { 19550 synchronized (mPackages) { 19551 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid); 19552 for (PackageSetting ps : packages) { 19553 if (ps.pkg == null) continue; 19554 19555 final ApplicationInfo info = ps.pkg.applicationInfo; 19556 final int deleteFlags = PackageManager.DELETE_KEEP_DATA; 19557 final PackageRemovedInfo outInfo = new PackageRemovedInfo(); 19558 19559 try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags, 19560 "unloadPrivatePackagesInner")) { 19561 if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo, 19562 false, null)) { 19563 unloaded.add(info); 19564 } else { 19565 Slog.w(TAG, "Failed to unload " + ps.codePath); 19566 } 19567 } 19568 19569 // Try very hard to release any references to this package 19570 // so we don't risk the system server being killed due to 19571 // open FDs 19572 AttributeCache.instance().removePackage(ps.name); 19573 } 19574 19575 mSettings.writeLPr(); 19576 } 19577 } 19578 19579 if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded); 19580 sendResourcesChangedBroadcast(false, false, unloaded, null); 19581 19582 // Try very hard to release any references to this path so we don't risk 19583 // the system server being killed due to open FDs 19584 ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath()); 19585 19586 for (int i = 0; i < 3; i++) { 19587 System.gc(); 19588 System.runFinalization(); 19589 } 19590 } 19591 19592 /** 19593 * Prepare storage areas for given user on all mounted devices. 19594 */ 19595 void prepareUserData(int userId, int userSerial, int flags) { 19596 synchronized (mInstallLock) { 19597 final StorageManager storage = mContext.getSystemService(StorageManager.class); 19598 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 19599 final String volumeUuid = vol.getFsUuid(); 19600 prepareUserDataLI(volumeUuid, userId, userSerial, flags, true); 19601 } 19602 } 19603 } 19604 19605 private void prepareUserDataLI(String volumeUuid, int userId, int userSerial, int flags, 19606 boolean allowRecover) { 19607 // Prepare storage and verify that serial numbers are consistent; if 19608 // there's a mismatch we need to destroy to avoid leaking data 19609 final StorageManager storage = mContext.getSystemService(StorageManager.class); 19610 try { 19611 storage.prepareUserStorage(volumeUuid, userId, userSerial, flags); 19612 19613 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0 && !mOnlyCore) { 19614 UserManagerService.enforceSerialNumber( 19615 Environment.getDataUserDeDirectory(volumeUuid, userId), userSerial); 19616 if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) { 19617 UserManagerService.enforceSerialNumber( 19618 Environment.getDataSystemDeDirectory(userId), userSerial); 19619 } 19620 } 19621 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && !mOnlyCore) { 19622 UserManagerService.enforceSerialNumber( 19623 Environment.getDataUserCeDirectory(volumeUuid, userId), userSerial); 19624 if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) { 19625 UserManagerService.enforceSerialNumber( 19626 Environment.getDataSystemCeDirectory(userId), userSerial); 19627 } 19628 } 19629 19630 synchronized (mInstallLock) { 19631 mInstaller.createUserData(volumeUuid, userId, userSerial, flags); 19632 } 19633 } catch (Exception e) { 19634 logCriticalInfo(Log.WARN, "Destroying user " + userId + " on volume " + volumeUuid 19635 + " because we failed to prepare: " + e); 19636 destroyUserDataLI(volumeUuid, userId, 19637 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 19638 19639 if (allowRecover) { 19640 // Try one last time; if we fail again we're really in trouble 19641 prepareUserDataLI(volumeUuid, userId, userSerial, flags, false); 19642 } 19643 } 19644 } 19645 19646 /** 19647 * Destroy storage areas for given user on all mounted devices. 19648 */ 19649 void destroyUserData(int userId, int flags) { 19650 synchronized (mInstallLock) { 19651 final StorageManager storage = mContext.getSystemService(StorageManager.class); 19652 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 19653 final String volumeUuid = vol.getFsUuid(); 19654 destroyUserDataLI(volumeUuid, userId, flags); 19655 } 19656 } 19657 } 19658 19659 private void destroyUserDataLI(String volumeUuid, int userId, int flags) { 19660 final StorageManager storage = mContext.getSystemService(StorageManager.class); 19661 try { 19662 // Clean up app data, profile data, and media data 19663 mInstaller.destroyUserData(volumeUuid, userId, flags); 19664 19665 // Clean up system data 19666 if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) { 19667 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) { 19668 FileUtils.deleteContentsAndDir(Environment.getUserSystemDirectory(userId)); 19669 FileUtils.deleteContentsAndDir(Environment.getDataSystemDeDirectory(userId)); 19670 } 19671 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 19672 FileUtils.deleteContentsAndDir(Environment.getDataSystemCeDirectory(userId)); 19673 } 19674 } 19675 19676 // Data with special labels is now gone, so finish the job 19677 storage.destroyUserStorage(volumeUuid, userId, flags); 19678 19679 } catch (Exception e) { 19680 logCriticalInfo(Log.WARN, 19681 "Failed to destroy user " + userId + " on volume " + volumeUuid + ": " + e); 19682 } 19683 } 19684 19685 /** 19686 * Examine all users present on given mounted volume, and destroy data 19687 * belonging to users that are no longer valid, or whose user ID has been 19688 * recycled. 19689 */ 19690 private void reconcileUsers(String volumeUuid) { 19691 final List<File> files = new ArrayList<>(); 19692 Collections.addAll(files, FileUtils 19693 .listFilesOrEmpty(Environment.getDataUserDeDirectory(volumeUuid))); 19694 Collections.addAll(files, FileUtils 19695 .listFilesOrEmpty(Environment.getDataUserCeDirectory(volumeUuid))); 19696 Collections.addAll(files, FileUtils 19697 .listFilesOrEmpty(Environment.getDataSystemDeDirectory())); 19698 Collections.addAll(files, FileUtils 19699 .listFilesOrEmpty(Environment.getDataSystemCeDirectory())); 19700 for (File file : files) { 19701 if (!file.isDirectory()) continue; 19702 19703 final int userId; 19704 final UserInfo info; 19705 try { 19706 userId = Integer.parseInt(file.getName()); 19707 info = sUserManager.getUserInfo(userId); 19708 } catch (NumberFormatException e) { 19709 Slog.w(TAG, "Invalid user directory " + file); 19710 continue; 19711 } 19712 19713 boolean destroyUser = false; 19714 if (info == null) { 19715 logCriticalInfo(Log.WARN, "Destroying user directory " + file 19716 + " because no matching user was found"); 19717 destroyUser = true; 19718 } else if (!mOnlyCore) { 19719 try { 19720 UserManagerService.enforceSerialNumber(file, info.serialNumber); 19721 } catch (IOException e) { 19722 logCriticalInfo(Log.WARN, "Destroying user directory " + file 19723 + " because we failed to enforce serial number: " + e); 19724 destroyUser = true; 19725 } 19726 } 19727 19728 if (destroyUser) { 19729 synchronized (mInstallLock) { 19730 destroyUserDataLI(volumeUuid, userId, 19731 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 19732 } 19733 } 19734 } 19735 } 19736 19737 private void assertPackageKnown(String volumeUuid, String packageName) 19738 throws PackageManagerException { 19739 synchronized (mPackages) { 19740 final PackageSetting ps = mSettings.mPackages.get(packageName); 19741 if (ps == null) { 19742 throw new PackageManagerException("Package " + packageName + " is unknown"); 19743 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) { 19744 throw new PackageManagerException( 19745 "Package " + packageName + " found on unknown volume " + volumeUuid 19746 + "; expected volume " + ps.volumeUuid); 19747 } 19748 } 19749 } 19750 19751 private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId) 19752 throws PackageManagerException { 19753 synchronized (mPackages) { 19754 final PackageSetting ps = mSettings.mPackages.get(packageName); 19755 if (ps == null) { 19756 throw new PackageManagerException("Package " + packageName + " is unknown"); 19757 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) { 19758 throw new PackageManagerException( 19759 "Package " + packageName + " found on unknown volume " + volumeUuid 19760 + "; expected volume " + ps.volumeUuid); 19761 } else if (!ps.getInstalled(userId)) { 19762 throw new PackageManagerException( 19763 "Package " + packageName + " not installed for user " + userId); 19764 } 19765 } 19766 } 19767 19768 /** 19769 * Examine all apps present on given mounted volume, and destroy apps that 19770 * aren't expected, either due to uninstallation or reinstallation on 19771 * another volume. 19772 */ 19773 private void reconcileApps(String volumeUuid) { 19774 final File[] files = FileUtils 19775 .listFilesOrEmpty(Environment.getDataAppDirectory(volumeUuid)); 19776 for (File file : files) { 19777 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 19778 && !PackageInstallerService.isStageName(file.getName()); 19779 if (!isPackage) { 19780 // Ignore entries which are not packages 19781 continue; 19782 } 19783 19784 try { 19785 final PackageLite pkg = PackageParser.parsePackageLite(file, 19786 PackageParser.PARSE_MUST_BE_APK); 19787 assertPackageKnown(volumeUuid, pkg.packageName); 19788 19789 } catch (PackageParserException | PackageManagerException e) { 19790 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 19791 synchronized (mInstallLock) { 19792 removeCodePathLI(file); 19793 } 19794 } 19795 } 19796 } 19797 19798 /** 19799 * Reconcile all app data for the given user. 19800 * <p> 19801 * Verifies that directories exist and that ownership and labeling is 19802 * correct for all installed apps on all mounted volumes. 19803 */ 19804 void reconcileAppsData(int userId, int flags) { 19805 final StorageManager storage = mContext.getSystemService(StorageManager.class); 19806 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 19807 final String volumeUuid = vol.getFsUuid(); 19808 synchronized (mInstallLock) { 19809 reconcileAppsDataLI(volumeUuid, userId, flags); 19810 } 19811 } 19812 } 19813 19814 /** 19815 * Reconcile all app data on given mounted volume. 19816 * <p> 19817 * Destroys app data that isn't expected, either due to uninstallation or 19818 * reinstallation on another volume. 19819 * <p> 19820 * Verifies that directories exist and that ownership and labeling is 19821 * correct for all installed apps. 19822 */ 19823 private void reconcileAppsDataLI(String volumeUuid, int userId, int flags) { 19824 Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x" 19825 + Integer.toHexString(flags)); 19826 19827 final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId); 19828 final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId); 19829 19830 // First look for stale data that doesn't belong, and check if things 19831 // have changed since we did our last restorecon 19832 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 19833 if (StorageManager.isFileEncryptedNativeOrEmulated() 19834 && !StorageManager.isUserKeyUnlocked(userId)) { 19835 throw new RuntimeException( 19836 "Yikes, someone asked us to reconcile CE storage while " + userId 19837 + " was still locked; this would have caused massive data loss!"); 19838 } 19839 19840 final File[] files = FileUtils.listFilesOrEmpty(ceDir); 19841 for (File file : files) { 19842 final String packageName = file.getName(); 19843 try { 19844 assertPackageKnownAndInstalled(volumeUuid, packageName, userId); 19845 } catch (PackageManagerException e) { 19846 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 19847 try { 19848 mInstaller.destroyAppData(volumeUuid, packageName, userId, 19849 StorageManager.FLAG_STORAGE_CE, 0); 19850 } catch (InstallerException e2) { 19851 logCriticalInfo(Log.WARN, "Failed to destroy: " + e2); 19852 } 19853 } 19854 } 19855 } 19856 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) { 19857 final File[] files = FileUtils.listFilesOrEmpty(deDir); 19858 for (File file : files) { 19859 final String packageName = file.getName(); 19860 try { 19861 assertPackageKnownAndInstalled(volumeUuid, packageName, userId); 19862 } catch (PackageManagerException e) { 19863 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 19864 try { 19865 mInstaller.destroyAppData(volumeUuid, packageName, userId, 19866 StorageManager.FLAG_STORAGE_DE, 0); 19867 } catch (InstallerException e2) { 19868 logCriticalInfo(Log.WARN, "Failed to destroy: " + e2); 19869 } 19870 } 19871 } 19872 } 19873 19874 // Ensure that data directories are ready to roll for all packages 19875 // installed for this volume and user 19876 final List<PackageSetting> packages; 19877 synchronized (mPackages) { 19878 packages = mSettings.getVolumePackagesLPr(volumeUuid); 19879 } 19880 int preparedCount = 0; 19881 for (PackageSetting ps : packages) { 19882 final String packageName = ps.name; 19883 if (ps.pkg == null) { 19884 Slog.w(TAG, "Odd, missing scanned package " + packageName); 19885 // TODO: might be due to legacy ASEC apps; we should circle back 19886 // and reconcile again once they're scanned 19887 continue; 19888 } 19889 19890 if (ps.getInstalled(userId)) { 19891 prepareAppDataLIF(ps.pkg, userId, flags); 19892 19893 if (maybeMigrateAppDataLIF(ps.pkg, userId)) { 19894 // We may have just shuffled around app data directories, so 19895 // prepare them one more time 19896 prepareAppDataLIF(ps.pkg, userId, flags); 19897 } 19898 19899 preparedCount++; 19900 } 19901 } 19902 19903 Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages"); 19904 } 19905 19906 /** 19907 * Prepare app data for the given app just after it was installed or 19908 * upgraded. This method carefully only touches users that it's installed 19909 * for, and it forces a restorecon to handle any seinfo changes. 19910 * <p> 19911 * Verifies that directories exist and that ownership and labeling is 19912 * correct for all installed apps. If there is an ownership mismatch, it 19913 * will try recovering system apps by wiping data; third-party app data is 19914 * left intact. 19915 * <p> 19916 * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em> 19917 */ 19918 private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) { 19919 final PackageSetting ps; 19920 synchronized (mPackages) { 19921 ps = mSettings.mPackages.get(pkg.packageName); 19922 mSettings.writeKernelMappingLPr(ps); 19923 } 19924 19925 final UserManager um = mContext.getSystemService(UserManager.class); 19926 UserManagerInternal umInternal = getUserManagerInternal(); 19927 for (UserInfo user : um.getUsers()) { 19928 final int flags; 19929 if (umInternal.isUserUnlockingOrUnlocked(user.id)) { 19930 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 19931 } else if (umInternal.isUserRunning(user.id)) { 19932 flags = StorageManager.FLAG_STORAGE_DE; 19933 } else { 19934 continue; 19935 } 19936 19937 if (ps.getInstalled(user.id)) { 19938 // TODO: when user data is locked, mark that we're still dirty 19939 prepareAppDataLIF(pkg, user.id, flags); 19940 } 19941 } 19942 } 19943 19944 /** 19945 * Prepare app data for the given app. 19946 * <p> 19947 * Verifies that directories exist and that ownership and labeling is 19948 * correct for all installed apps. If there is an ownership mismatch, this 19949 * will try recovering system apps by wiping data; third-party app data is 19950 * left intact. 19951 */ 19952 private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) { 19953 if (pkg == null) { 19954 Slog.wtf(TAG, "Package was null!", new Throwable()); 19955 return; 19956 } 19957 prepareAppDataLeafLIF(pkg, userId, flags); 19958 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 19959 for (int i = 0; i < childCount; i++) { 19960 prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags); 19961 } 19962 } 19963 19964 private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) { 19965 if (DEBUG_APP_DATA) { 19966 Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x" 19967 + Integer.toHexString(flags)); 19968 } 19969 19970 final String volumeUuid = pkg.volumeUuid; 19971 final String packageName = pkg.packageName; 19972 final ApplicationInfo app = pkg.applicationInfo; 19973 final int appId = UserHandle.getAppId(app.uid); 19974 19975 Preconditions.checkNotNull(app.seinfo); 19976 19977 try { 19978 mInstaller.createAppData(volumeUuid, packageName, userId, flags, 19979 appId, app.seinfo, app.targetSdkVersion); 19980 } catch (InstallerException e) { 19981 if (app.isSystemApp()) { 19982 logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName 19983 + ", but trying to recover: " + e); 19984 destroyAppDataLeafLIF(pkg, userId, flags); 19985 try { 19986 mInstaller.createAppData(volumeUuid, packageName, userId, flags, 19987 appId, app.seinfo, app.targetSdkVersion); 19988 logCriticalInfo(Log.DEBUG, "Recovery succeeded!"); 19989 } catch (InstallerException e2) { 19990 logCriticalInfo(Log.DEBUG, "Recovery failed!"); 19991 } 19992 } else { 19993 Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e); 19994 } 19995 } 19996 19997 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 19998 try { 19999 // CE storage is unlocked right now, so read out the inode and 20000 // remember for use later when it's locked 20001 // TODO: mark this structure as dirty so we persist it! 20002 final long ceDataInode = mInstaller.getAppDataInode(volumeUuid, packageName, userId, 20003 StorageManager.FLAG_STORAGE_CE); 20004 synchronized (mPackages) { 20005 final PackageSetting ps = mSettings.mPackages.get(packageName); 20006 if (ps != null) { 20007 ps.setCeDataInode(ceDataInode, userId); 20008 } 20009 } 20010 } catch (InstallerException e) { 20011 Slog.e(TAG, "Failed to find inode for " + packageName + ": " + e); 20012 } 20013 } 20014 20015 prepareAppDataContentsLeafLIF(pkg, userId, flags); 20016 } 20017 20018 private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) { 20019 if (pkg == null) { 20020 Slog.wtf(TAG, "Package was null!", new Throwable()); 20021 return; 20022 } 20023 prepareAppDataContentsLeafLIF(pkg, userId, flags); 20024 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 20025 for (int i = 0; i < childCount; i++) { 20026 prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags); 20027 } 20028 } 20029 20030 private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) { 20031 final String volumeUuid = pkg.volumeUuid; 20032 final String packageName = pkg.packageName; 20033 final ApplicationInfo app = pkg.applicationInfo; 20034 20035 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 20036 // Create a native library symlink only if we have native libraries 20037 // and if the native libraries are 32 bit libraries. We do not provide 20038 // this symlink for 64 bit libraries. 20039 if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) { 20040 final String nativeLibPath = app.nativeLibraryDir; 20041 try { 20042 mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName, 20043 nativeLibPath, userId); 20044 } catch (InstallerException e) { 20045 Slog.e(TAG, "Failed to link native for " + packageName + ": " + e); 20046 } 20047 } 20048 } 20049 } 20050 20051 /** 20052 * For system apps on non-FBE devices, this method migrates any existing 20053 * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag 20054 * requested by the app. 20055 */ 20056 private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) { 20057 if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated() 20058 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) { 20059 final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage() 20060 ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE; 20061 try { 20062 mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId, 20063 storageTarget); 20064 } catch (InstallerException e) { 20065 logCriticalInfo(Log.WARN, 20066 "Failed to migrate " + pkg.packageName + ": " + e.getMessage()); 20067 } 20068 return true; 20069 } else { 20070 return false; 20071 } 20072 } 20073 20074 public PackageFreezer freezePackage(String packageName, String killReason) { 20075 return freezePackage(packageName, UserHandle.USER_ALL, killReason); 20076 } 20077 20078 public PackageFreezer freezePackage(String packageName, int userId, String killReason) { 20079 return new PackageFreezer(packageName, userId, killReason); 20080 } 20081 20082 public PackageFreezer freezePackageForInstall(String packageName, int installFlags, 20083 String killReason) { 20084 return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason); 20085 } 20086 20087 public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags, 20088 String killReason) { 20089 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) { 20090 return new PackageFreezer(); 20091 } else { 20092 return freezePackage(packageName, userId, killReason); 20093 } 20094 } 20095 20096 public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags, 20097 String killReason) { 20098 return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason); 20099 } 20100 20101 public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags, 20102 String killReason) { 20103 if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) { 20104 return new PackageFreezer(); 20105 } else { 20106 return freezePackage(packageName, userId, killReason); 20107 } 20108 } 20109 20110 /** 20111 * Class that freezes and kills the given package upon creation, and 20112 * unfreezes it upon closing. This is typically used when doing surgery on 20113 * app code/data to prevent the app from running while you're working. 20114 */ 20115 private class PackageFreezer implements AutoCloseable { 20116 private final String mPackageName; 20117 private final PackageFreezer[] mChildren; 20118 20119 private final boolean mWeFroze; 20120 20121 private final AtomicBoolean mClosed = new AtomicBoolean(); 20122 private final CloseGuard mCloseGuard = CloseGuard.get(); 20123 20124 /** 20125 * Create and return a stub freezer that doesn't actually do anything, 20126 * typically used when someone requested 20127 * {@link PackageManager#INSTALL_DONT_KILL_APP} or 20128 * {@link PackageManager#DELETE_DONT_KILL_APP}. 20129 */ 20130 public PackageFreezer() { 20131 mPackageName = null; 20132 mChildren = null; 20133 mWeFroze = false; 20134 mCloseGuard.open("close"); 20135 } 20136 20137 public PackageFreezer(String packageName, int userId, String killReason) { 20138 synchronized (mPackages) { 20139 mPackageName = packageName; 20140 mWeFroze = mFrozenPackages.add(mPackageName); 20141 20142 final PackageSetting ps = mSettings.mPackages.get(mPackageName); 20143 if (ps != null) { 20144 killApplication(ps.name, ps.appId, userId, killReason); 20145 } 20146 20147 final PackageParser.Package p = mPackages.get(packageName); 20148 if (p != null && p.childPackages != null) { 20149 final int N = p.childPackages.size(); 20150 mChildren = new PackageFreezer[N]; 20151 for (int i = 0; i < N; i++) { 20152 mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName, 20153 userId, killReason); 20154 } 20155 } else { 20156 mChildren = null; 20157 } 20158 } 20159 mCloseGuard.open("close"); 20160 } 20161 20162 @Override 20163 protected void finalize() throws Throwable { 20164 try { 20165 mCloseGuard.warnIfOpen(); 20166 close(); 20167 } finally { 20168 super.finalize(); 20169 } 20170 } 20171 20172 @Override 20173 public void close() { 20174 mCloseGuard.close(); 20175 if (mClosed.compareAndSet(false, true)) { 20176 synchronized (mPackages) { 20177 if (mWeFroze) { 20178 mFrozenPackages.remove(mPackageName); 20179 } 20180 20181 if (mChildren != null) { 20182 for (PackageFreezer freezer : mChildren) { 20183 freezer.close(); 20184 } 20185 } 20186 } 20187 } 20188 } 20189 } 20190 20191 /** 20192 * Verify that given package is currently frozen. 20193 */ 20194 private void checkPackageFrozen(String packageName) { 20195 synchronized (mPackages) { 20196 if (!mFrozenPackages.contains(packageName)) { 20197 Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable()); 20198 } 20199 } 20200 } 20201 20202 @Override 20203 public int movePackage(final String packageName, final String volumeUuid) { 20204 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 20205 20206 final UserHandle user = new UserHandle(UserHandle.getCallingUserId()); 20207 final int moveId = mNextMoveId.getAndIncrement(); 20208 mHandler.post(new Runnable() { 20209 @Override 20210 public void run() { 20211 try { 20212 movePackageInternal(packageName, volumeUuid, moveId, user); 20213 } catch (PackageManagerException e) { 20214 Slog.w(TAG, "Failed to move " + packageName, e); 20215 mMoveCallbacks.notifyStatusChanged(moveId, 20216 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 20217 } 20218 } 20219 }); 20220 return moveId; 20221 } 20222 20223 private void movePackageInternal(final String packageName, final String volumeUuid, 20224 final int moveId, UserHandle user) throws PackageManagerException { 20225 final StorageManager storage = mContext.getSystemService(StorageManager.class); 20226 final PackageManager pm = mContext.getPackageManager(); 20227 20228 final boolean currentAsec; 20229 final String currentVolumeUuid; 20230 final File codeFile; 20231 final String installerPackageName; 20232 final String packageAbiOverride; 20233 final int appId; 20234 final String seinfo; 20235 final String label; 20236 final int targetSdkVersion; 20237 final PackageFreezer freezer; 20238 final int[] installedUserIds; 20239 20240 // reader 20241 synchronized (mPackages) { 20242 final PackageParser.Package pkg = mPackages.get(packageName); 20243 final PackageSetting ps = mSettings.mPackages.get(packageName); 20244 if (pkg == null || ps == null) { 20245 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package"); 20246 } 20247 20248 if (pkg.applicationInfo.isSystemApp()) { 20249 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE, 20250 "Cannot move system application"); 20251 } 20252 20253 if (pkg.applicationInfo.isExternalAsec()) { 20254 currentAsec = true; 20255 currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL; 20256 } else if (pkg.applicationInfo.isForwardLocked()) { 20257 currentAsec = true; 20258 currentVolumeUuid = "forward_locked"; 20259 } else { 20260 currentAsec = false; 20261 currentVolumeUuid = ps.volumeUuid; 20262 20263 final File probe = new File(pkg.codePath); 20264 final File probeOat = new File(probe, "oat"); 20265 if (!probe.isDirectory() || !probeOat.isDirectory()) { 20266 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 20267 "Move only supported for modern cluster style installs"); 20268 } 20269 } 20270 20271 if (Objects.equals(currentVolumeUuid, volumeUuid)) { 20272 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 20273 "Package already moved to " + volumeUuid); 20274 } 20275 if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) { 20276 throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN, 20277 "Device admin cannot be moved"); 20278 } 20279 20280 if (mFrozenPackages.contains(packageName)) { 20281 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING, 20282 "Failed to move already frozen package"); 20283 } 20284 20285 codeFile = new File(pkg.codePath); 20286 installerPackageName = ps.installerPackageName; 20287 packageAbiOverride = ps.cpuAbiOverrideString; 20288 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 20289 seinfo = pkg.applicationInfo.seinfo; 20290 label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo)); 20291 targetSdkVersion = pkg.applicationInfo.targetSdkVersion; 20292 freezer = freezePackage(packageName, "movePackageInternal"); 20293 installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 20294 } 20295 20296 final Bundle extras = new Bundle(); 20297 extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName); 20298 extras.putString(Intent.EXTRA_TITLE, label); 20299 mMoveCallbacks.notifyCreated(moveId, extras); 20300 20301 int installFlags; 20302 final boolean moveCompleteApp; 20303 final File measurePath; 20304 20305 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) { 20306 installFlags = INSTALL_INTERNAL; 20307 moveCompleteApp = !currentAsec; 20308 measurePath = Environment.getDataAppDirectory(volumeUuid); 20309 } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) { 20310 installFlags = INSTALL_EXTERNAL; 20311 moveCompleteApp = false; 20312 measurePath = storage.getPrimaryPhysicalVolume().getPath(); 20313 } else { 20314 final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid); 20315 if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE 20316 || !volume.isMountedWritable()) { 20317 freezer.close(); 20318 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 20319 "Move location not mounted private volume"); 20320 } 20321 20322 Preconditions.checkState(!currentAsec); 20323 20324 installFlags = INSTALL_INTERNAL; 20325 moveCompleteApp = true; 20326 measurePath = Environment.getDataAppDirectory(volumeUuid); 20327 } 20328 20329 final PackageStats stats = new PackageStats(null, -1); 20330 synchronized (mInstaller) { 20331 for (int userId : installedUserIds) { 20332 if (!getPackageSizeInfoLI(packageName, userId, stats)) { 20333 freezer.close(); 20334 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 20335 "Failed to measure package size"); 20336 } 20337 } 20338 } 20339 20340 if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size " 20341 + stats.dataSize); 20342 20343 final long startFreeBytes = measurePath.getFreeSpace(); 20344 final long sizeBytes; 20345 if (moveCompleteApp) { 20346 sizeBytes = stats.codeSize + stats.dataSize; 20347 } else { 20348 sizeBytes = stats.codeSize; 20349 } 20350 20351 if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) { 20352 freezer.close(); 20353 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 20354 "Not enough free space to move"); 20355 } 20356 20357 mMoveCallbacks.notifyStatusChanged(moveId, 10); 20358 20359 final CountDownLatch installedLatch = new CountDownLatch(1); 20360 final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() { 20361 @Override 20362 public void onUserActionRequired(Intent intent) throws RemoteException { 20363 throw new IllegalStateException(); 20364 } 20365 20366 @Override 20367 public void onPackageInstalled(String basePackageName, int returnCode, String msg, 20368 Bundle extras) throws RemoteException { 20369 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: " 20370 + PackageManager.installStatusToString(returnCode, msg)); 20371 20372 installedLatch.countDown(); 20373 freezer.close(); 20374 20375 final int status = PackageManager.installStatusToPublicStatus(returnCode); 20376 switch (status) { 20377 case PackageInstaller.STATUS_SUCCESS: 20378 mMoveCallbacks.notifyStatusChanged(moveId, 20379 PackageManager.MOVE_SUCCEEDED); 20380 break; 20381 case PackageInstaller.STATUS_FAILURE_STORAGE: 20382 mMoveCallbacks.notifyStatusChanged(moveId, 20383 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE); 20384 break; 20385 default: 20386 mMoveCallbacks.notifyStatusChanged(moveId, 20387 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 20388 break; 20389 } 20390 } 20391 }; 20392 20393 final MoveInfo move; 20394 if (moveCompleteApp) { 20395 // Kick off a thread to report progress estimates 20396 new Thread() { 20397 @Override 20398 public void run() { 20399 while (true) { 20400 try { 20401 if (installedLatch.await(1, TimeUnit.SECONDS)) { 20402 break; 20403 } 20404 } catch (InterruptedException ignored) { 20405 } 20406 20407 final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace(); 20408 final int progress = 10 + (int) MathUtils.constrain( 20409 ((deltaFreeBytes * 80) / sizeBytes), 0, 80); 20410 mMoveCallbacks.notifyStatusChanged(moveId, progress); 20411 } 20412 } 20413 }.start(); 20414 20415 final String dataAppName = codeFile.getName(); 20416 move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName, 20417 dataAppName, appId, seinfo, targetSdkVersion); 20418 } else { 20419 move = null; 20420 } 20421 20422 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 20423 20424 final Message msg = mHandler.obtainMessage(INIT_COPY); 20425 final OriginInfo origin = OriginInfo.fromExistingFile(codeFile); 20426 final InstallParams params = new InstallParams(origin, move, installObserver, installFlags, 20427 installerPackageName, volumeUuid, null /*verificationInfo*/, user, 20428 packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/); 20429 params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params)); 20430 msg.obj = params; 20431 20432 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage", 20433 System.identityHashCode(msg.obj)); 20434 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 20435 System.identityHashCode(msg.obj)); 20436 20437 mHandler.sendMessage(msg); 20438 } 20439 20440 @Override 20441 public int movePrimaryStorage(String volumeUuid) throws RemoteException { 20442 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 20443 20444 final int realMoveId = mNextMoveId.getAndIncrement(); 20445 final Bundle extras = new Bundle(); 20446 extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid); 20447 mMoveCallbacks.notifyCreated(realMoveId, extras); 20448 20449 final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() { 20450 @Override 20451 public void onCreated(int moveId, Bundle extras) { 20452 // Ignored 20453 } 20454 20455 @Override 20456 public void onStatusChanged(int moveId, int status, long estMillis) { 20457 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis); 20458 } 20459 }; 20460 20461 final StorageManager storage = mContext.getSystemService(StorageManager.class); 20462 storage.setPrimaryStorageUuid(volumeUuid, callback); 20463 return realMoveId; 20464 } 20465 20466 @Override 20467 public int getMoveStatus(int moveId) { 20468 mContext.enforceCallingOrSelfPermission( 20469 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 20470 return mMoveCallbacks.mLastStatus.get(moveId); 20471 } 20472 20473 @Override 20474 public void registerMoveCallback(IPackageMoveObserver callback) { 20475 mContext.enforceCallingOrSelfPermission( 20476 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 20477 mMoveCallbacks.register(callback); 20478 } 20479 20480 @Override 20481 public void unregisterMoveCallback(IPackageMoveObserver callback) { 20482 mContext.enforceCallingOrSelfPermission( 20483 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 20484 mMoveCallbacks.unregister(callback); 20485 } 20486 20487 @Override 20488 public boolean setInstallLocation(int loc) { 20489 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, 20490 null); 20491 if (getInstallLocation() == loc) { 20492 return true; 20493 } 20494 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL 20495 || loc == PackageHelper.APP_INSTALL_EXTERNAL) { 20496 android.provider.Settings.Global.putInt(mContext.getContentResolver(), 20497 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc); 20498 return true; 20499 } 20500 return false; 20501 } 20502 20503 @Override 20504 public int getInstallLocation() { 20505 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 20506 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, 20507 PackageHelper.APP_INSTALL_AUTO); 20508 } 20509 20510 /** Called by UserManagerService */ 20511 void cleanUpUser(UserManagerService userManager, int userHandle) { 20512 synchronized (mPackages) { 20513 mDirtyUsers.remove(userHandle); 20514 mUserNeedsBadging.delete(userHandle); 20515 mSettings.removeUserLPw(userHandle); 20516 mPendingBroadcasts.remove(userHandle); 20517 mEphemeralApplicationRegistry.onUserRemovedLPw(userHandle); 20518 removeUnusedPackagesLPw(userManager, userHandle); 20519 } 20520 } 20521 20522 /** 20523 * We're removing userHandle and would like to remove any downloaded packages 20524 * that are no longer in use by any other user. 20525 * @param userHandle the user being removed 20526 */ 20527 private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) { 20528 final boolean DEBUG_CLEAN_APKS = false; 20529 int [] users = userManager.getUserIds(); 20530 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 20531 while (psit.hasNext()) { 20532 PackageSetting ps = psit.next(); 20533 if (ps.pkg == null) { 20534 continue; 20535 } 20536 final String packageName = ps.pkg.packageName; 20537 // Skip over if system app 20538 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) { 20539 continue; 20540 } 20541 if (DEBUG_CLEAN_APKS) { 20542 Slog.i(TAG, "Checking package " + packageName); 20543 } 20544 boolean keep = shouldKeepUninstalledPackageLPr(packageName); 20545 if (keep) { 20546 if (DEBUG_CLEAN_APKS) { 20547 Slog.i(TAG, " Keeping package " + packageName + " - requested by DO"); 20548 } 20549 } else { 20550 for (int i = 0; i < users.length; i++) { 20551 if (users[i] != userHandle && ps.getInstalled(users[i])) { 20552 keep = true; 20553 if (DEBUG_CLEAN_APKS) { 20554 Slog.i(TAG, " Keeping package " + packageName + " for user " 20555 + users[i]); 20556 } 20557 break; 20558 } 20559 } 20560 } 20561 if (!keep) { 20562 if (DEBUG_CLEAN_APKS) { 20563 Slog.i(TAG, " Removing package " + packageName); 20564 } 20565 mHandler.post(new Runnable() { 20566 public void run() { 20567 deletePackageX(packageName, userHandle, 0); 20568 } //end run 20569 }); 20570 } 20571 } 20572 } 20573 20574 /** Called by UserManagerService */ 20575 void createNewUser(int userId) { 20576 synchronized (mInstallLock) { 20577 mSettings.createNewUserLI(this, mInstaller, userId); 20578 } 20579 synchronized (mPackages) { 20580 scheduleWritePackageRestrictionsLocked(userId); 20581 scheduleWritePackageListLocked(userId); 20582 applyFactoryDefaultBrowserLPw(userId); 20583 primeDomainVerificationsLPw(userId); 20584 } 20585 } 20586 20587 void onNewUserCreated(final int userId) { 20588 mDefaultPermissionPolicy.grantDefaultPermissions(userId); 20589 // If permission review for legacy apps is required, we represent 20590 // dagerous permissions for such apps as always granted runtime 20591 // permissions to keep per user flag state whether review is needed. 20592 // Hence, if a new user is added we have to propagate dangerous 20593 // permission grants for these legacy apps. 20594 if (mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED) { 20595 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL 20596 | UPDATE_PERMISSIONS_REPLACE_ALL); 20597 } 20598 } 20599 20600 @Override 20601 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException { 20602 mContext.enforceCallingOrSelfPermission( 20603 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 20604 "Only package verification agents can read the verifier device identity"); 20605 20606 synchronized (mPackages) { 20607 return mSettings.getVerifierDeviceIdentityLPw(); 20608 } 20609 } 20610 20611 @Override 20612 public void setPermissionEnforced(String permission, boolean enforced) { 20613 // TODO: Now that we no longer change GID for storage, this should to away. 20614 mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 20615 "setPermissionEnforced"); 20616 if (READ_EXTERNAL_STORAGE.equals(permission)) { 20617 synchronized (mPackages) { 20618 if (mSettings.mReadExternalStorageEnforced == null 20619 || mSettings.mReadExternalStorageEnforced != enforced) { 20620 mSettings.mReadExternalStorageEnforced = enforced; 20621 mSettings.writeLPr(); 20622 } 20623 } 20624 // kill any non-foreground processes so we restart them and 20625 // grant/revoke the GID. 20626 final IActivityManager am = ActivityManagerNative.getDefault(); 20627 if (am != null) { 20628 final long token = Binder.clearCallingIdentity(); 20629 try { 20630 am.killProcessesBelowForeground("setPermissionEnforcement"); 20631 } catch (RemoteException e) { 20632 } finally { 20633 Binder.restoreCallingIdentity(token); 20634 } 20635 } 20636 } else { 20637 throw new IllegalArgumentException("No selective enforcement for " + permission); 20638 } 20639 } 20640 20641 @Override 20642 @Deprecated 20643 public boolean isPermissionEnforced(String permission) { 20644 return true; 20645 } 20646 20647 @Override 20648 public boolean isStorageLow() { 20649 final long token = Binder.clearCallingIdentity(); 20650 try { 20651 final DeviceStorageMonitorInternal 20652 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 20653 if (dsm != null) { 20654 return dsm.isMemoryLow(); 20655 } else { 20656 return false; 20657 } 20658 } finally { 20659 Binder.restoreCallingIdentity(token); 20660 } 20661 } 20662 20663 @Override 20664 public IPackageInstaller getPackageInstaller() { 20665 return mInstallerService; 20666 } 20667 20668 private boolean userNeedsBadging(int userId) { 20669 int index = mUserNeedsBadging.indexOfKey(userId); 20670 if (index < 0) { 20671 final UserInfo userInfo; 20672 final long token = Binder.clearCallingIdentity(); 20673 try { 20674 userInfo = sUserManager.getUserInfo(userId); 20675 } finally { 20676 Binder.restoreCallingIdentity(token); 20677 } 20678 final boolean b; 20679 if (userInfo != null && userInfo.isManagedProfile()) { 20680 b = true; 20681 } else { 20682 b = false; 20683 } 20684 mUserNeedsBadging.put(userId, b); 20685 return b; 20686 } 20687 return mUserNeedsBadging.valueAt(index); 20688 } 20689 20690 @Override 20691 public KeySet getKeySetByAlias(String packageName, String alias) { 20692 if (packageName == null || alias == null) { 20693 return null; 20694 } 20695 synchronized(mPackages) { 20696 final PackageParser.Package pkg = mPackages.get(packageName); 20697 if (pkg == null) { 20698 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 20699 throw new IllegalArgumentException("Unknown package: " + packageName); 20700 } 20701 KeySetManagerService ksms = mSettings.mKeySetManagerService; 20702 return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias)); 20703 } 20704 } 20705 20706 @Override 20707 public KeySet getSigningKeySet(String packageName) { 20708 if (packageName == null) { 20709 return null; 20710 } 20711 synchronized(mPackages) { 20712 final PackageParser.Package pkg = mPackages.get(packageName); 20713 if (pkg == null) { 20714 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 20715 throw new IllegalArgumentException("Unknown package: " + packageName); 20716 } 20717 if (pkg.applicationInfo.uid != Binder.getCallingUid() 20718 && Process.SYSTEM_UID != Binder.getCallingUid()) { 20719 throw new SecurityException("May not access signing KeySet of other apps."); 20720 } 20721 KeySetManagerService ksms = mSettings.mKeySetManagerService; 20722 return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName)); 20723 } 20724 } 20725 20726 @Override 20727 public boolean isPackageSignedByKeySet(String packageName, KeySet ks) { 20728 if (packageName == null || ks == null) { 20729 return false; 20730 } 20731 synchronized(mPackages) { 20732 final PackageParser.Package pkg = mPackages.get(packageName); 20733 if (pkg == null) { 20734 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 20735 throw new IllegalArgumentException("Unknown package: " + packageName); 20736 } 20737 IBinder ksh = ks.getToken(); 20738 if (ksh instanceof KeySetHandle) { 20739 KeySetManagerService ksms = mSettings.mKeySetManagerService; 20740 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh); 20741 } 20742 return false; 20743 } 20744 } 20745 20746 @Override 20747 public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) { 20748 if (packageName == null || ks == null) { 20749 return false; 20750 } 20751 synchronized(mPackages) { 20752 final PackageParser.Package pkg = mPackages.get(packageName); 20753 if (pkg == null) { 20754 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 20755 throw new IllegalArgumentException("Unknown package: " + packageName); 20756 } 20757 IBinder ksh = ks.getToken(); 20758 if (ksh instanceof KeySetHandle) { 20759 KeySetManagerService ksms = mSettings.mKeySetManagerService; 20760 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh); 20761 } 20762 return false; 20763 } 20764 } 20765 20766 private void deletePackageIfUnusedLPr(final String packageName) { 20767 PackageSetting ps = mSettings.mPackages.get(packageName); 20768 if (ps == null) { 20769 return; 20770 } 20771 if (!ps.isAnyInstalled(sUserManager.getUserIds())) { 20772 // TODO Implement atomic delete if package is unused 20773 // It is currently possible that the package will be deleted even if it is installed 20774 // after this method returns. 20775 mHandler.post(new Runnable() { 20776 public void run() { 20777 deletePackageX(packageName, 0, PackageManager.DELETE_ALL_USERS); 20778 } 20779 }); 20780 } 20781 } 20782 20783 /** 20784 * Check and throw if the given before/after packages would be considered a 20785 * downgrade. 20786 */ 20787 private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after) 20788 throws PackageManagerException { 20789 if (after.versionCode < before.mVersionCode) { 20790 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 20791 "Update version code " + after.versionCode + " is older than current " 20792 + before.mVersionCode); 20793 } else if (after.versionCode == before.mVersionCode) { 20794 if (after.baseRevisionCode < before.baseRevisionCode) { 20795 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 20796 "Update base revision code " + after.baseRevisionCode 20797 + " is older than current " + before.baseRevisionCode); 20798 } 20799 20800 if (!ArrayUtils.isEmpty(after.splitNames)) { 20801 for (int i = 0; i < after.splitNames.length; i++) { 20802 final String splitName = after.splitNames[i]; 20803 final int j = ArrayUtils.indexOf(before.splitNames, splitName); 20804 if (j != -1) { 20805 if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) { 20806 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 20807 "Update split " + splitName + " revision code " 20808 + after.splitRevisionCodes[i] + " is older than current " 20809 + before.splitRevisionCodes[j]); 20810 } 20811 } 20812 } 20813 } 20814 } 20815 } 20816 20817 private static class MoveCallbacks extends Handler { 20818 private static final int MSG_CREATED = 1; 20819 private static final int MSG_STATUS_CHANGED = 2; 20820 20821 private final RemoteCallbackList<IPackageMoveObserver> 20822 mCallbacks = new RemoteCallbackList<>(); 20823 20824 private final SparseIntArray mLastStatus = new SparseIntArray(); 20825 20826 public MoveCallbacks(Looper looper) { 20827 super(looper); 20828 } 20829 20830 public void register(IPackageMoveObserver callback) { 20831 mCallbacks.register(callback); 20832 } 20833 20834 public void unregister(IPackageMoveObserver callback) { 20835 mCallbacks.unregister(callback); 20836 } 20837 20838 @Override 20839 public void handleMessage(Message msg) { 20840 final SomeArgs args = (SomeArgs) msg.obj; 20841 final int n = mCallbacks.beginBroadcast(); 20842 for (int i = 0; i < n; i++) { 20843 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i); 20844 try { 20845 invokeCallback(callback, msg.what, args); 20846 } catch (RemoteException ignored) { 20847 } 20848 } 20849 mCallbacks.finishBroadcast(); 20850 args.recycle(); 20851 } 20852 20853 private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args) 20854 throws RemoteException { 20855 switch (what) { 20856 case MSG_CREATED: { 20857 callback.onCreated(args.argi1, (Bundle) args.arg2); 20858 break; 20859 } 20860 case MSG_STATUS_CHANGED: { 20861 callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3); 20862 break; 20863 } 20864 } 20865 } 20866 20867 private void notifyCreated(int moveId, Bundle extras) { 20868 Slog.v(TAG, "Move " + moveId + " created " + extras.toString()); 20869 20870 final SomeArgs args = SomeArgs.obtain(); 20871 args.argi1 = moveId; 20872 args.arg2 = extras; 20873 obtainMessage(MSG_CREATED, args).sendToTarget(); 20874 } 20875 20876 private void notifyStatusChanged(int moveId, int status) { 20877 notifyStatusChanged(moveId, status, -1); 20878 } 20879 20880 private void notifyStatusChanged(int moveId, int status, long estMillis) { 20881 Slog.v(TAG, "Move " + moveId + " status " + status); 20882 20883 final SomeArgs args = SomeArgs.obtain(); 20884 args.argi1 = moveId; 20885 args.argi2 = status; 20886 args.arg3 = estMillis; 20887 obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget(); 20888 20889 synchronized (mLastStatus) { 20890 mLastStatus.put(moveId, status); 20891 } 20892 } 20893 } 20894 20895 private final static class OnPermissionChangeListeners extends Handler { 20896 private static final int MSG_ON_PERMISSIONS_CHANGED = 1; 20897 20898 private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners = 20899 new RemoteCallbackList<>(); 20900 20901 public OnPermissionChangeListeners(Looper looper) { 20902 super(looper); 20903 } 20904 20905 @Override 20906 public void handleMessage(Message msg) { 20907 switch (msg.what) { 20908 case MSG_ON_PERMISSIONS_CHANGED: { 20909 final int uid = msg.arg1; 20910 handleOnPermissionsChanged(uid); 20911 } break; 20912 } 20913 } 20914 20915 public void addListenerLocked(IOnPermissionsChangeListener listener) { 20916 mPermissionListeners.register(listener); 20917 20918 } 20919 20920 public void removeListenerLocked(IOnPermissionsChangeListener listener) { 20921 mPermissionListeners.unregister(listener); 20922 } 20923 20924 public void onPermissionsChanged(int uid) { 20925 if (mPermissionListeners.getRegisteredCallbackCount() > 0) { 20926 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget(); 20927 } 20928 } 20929 20930 private void handleOnPermissionsChanged(int uid) { 20931 final int count = mPermissionListeners.beginBroadcast(); 20932 try { 20933 for (int i = 0; i < count; i++) { 20934 IOnPermissionsChangeListener callback = mPermissionListeners 20935 .getBroadcastItem(i); 20936 try { 20937 callback.onPermissionsChanged(uid); 20938 } catch (RemoteException e) { 20939 Log.e(TAG, "Permission listener is dead", e); 20940 } 20941 } 20942 } finally { 20943 mPermissionListeners.finishBroadcast(); 20944 } 20945 } 20946 } 20947 20948 private class PackageManagerInternalImpl extends PackageManagerInternal { 20949 @Override 20950 public void setLocationPackagesProvider(PackagesProvider provider) { 20951 synchronized (mPackages) { 20952 mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider); 20953 } 20954 } 20955 20956 @Override 20957 public void setVoiceInteractionPackagesProvider(PackagesProvider provider) { 20958 synchronized (mPackages) { 20959 mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider); 20960 } 20961 } 20962 20963 @Override 20964 public void setSmsAppPackagesProvider(PackagesProvider provider) { 20965 synchronized (mPackages) { 20966 mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider); 20967 } 20968 } 20969 20970 @Override 20971 public void setDialerAppPackagesProvider(PackagesProvider provider) { 20972 synchronized (mPackages) { 20973 mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider); 20974 } 20975 } 20976 20977 @Override 20978 public void setSimCallManagerPackagesProvider(PackagesProvider provider) { 20979 synchronized (mPackages) { 20980 mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider); 20981 } 20982 } 20983 20984 @Override 20985 public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) { 20986 synchronized (mPackages) { 20987 mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider); 20988 } 20989 } 20990 20991 @Override 20992 public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) { 20993 synchronized (mPackages) { 20994 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr( 20995 packageName, userId); 20996 } 20997 } 20998 20999 @Override 21000 public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) { 21001 synchronized (mPackages) { 21002 mSettings.setDefaultDialerPackageNameLPw(packageName, userId); 21003 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr( 21004 packageName, userId); 21005 } 21006 } 21007 21008 @Override 21009 public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) { 21010 synchronized (mPackages) { 21011 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr( 21012 packageName, userId); 21013 } 21014 } 21015 21016 @Override 21017 public void setKeepUninstalledPackages(final List<String> packageList) { 21018 Preconditions.checkNotNull(packageList); 21019 List<String> removedFromList = null; 21020 synchronized (mPackages) { 21021 if (mKeepUninstalledPackages != null) { 21022 final int packagesCount = mKeepUninstalledPackages.size(); 21023 for (int i = 0; i < packagesCount; i++) { 21024 String oldPackage = mKeepUninstalledPackages.get(i); 21025 if (packageList != null && packageList.contains(oldPackage)) { 21026 continue; 21027 } 21028 if (removedFromList == null) { 21029 removedFromList = new ArrayList<>(); 21030 } 21031 removedFromList.add(oldPackage); 21032 } 21033 } 21034 mKeepUninstalledPackages = new ArrayList<>(packageList); 21035 if (removedFromList != null) { 21036 final int removedCount = removedFromList.size(); 21037 for (int i = 0; i < removedCount; i++) { 21038 deletePackageIfUnusedLPr(removedFromList.get(i)); 21039 } 21040 } 21041 } 21042 } 21043 21044 @Override 21045 public boolean isPermissionsReviewRequired(String packageName, int userId) { 21046 synchronized (mPackages) { 21047 // If we do not support permission review, done. 21048 if (!mPermissionReviewRequired && !Build.PERMISSIONS_REVIEW_REQUIRED) { 21049 return false; 21050 } 21051 21052 PackageSetting packageSetting = mSettings.mPackages.get(packageName); 21053 if (packageSetting == null) { 21054 return false; 21055 } 21056 21057 // Permission review applies only to apps not supporting the new permission model. 21058 if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) { 21059 return false; 21060 } 21061 21062 // Legacy apps have the permission and get user consent on launch. 21063 PermissionsState permissionsState = packageSetting.getPermissionsState(); 21064 return permissionsState.isPermissionReviewRequired(userId); 21065 } 21066 } 21067 21068 @Override 21069 public ApplicationInfo getApplicationInfo(String packageName, int userId) { 21070 return PackageManagerService.this.getApplicationInfo(packageName, 0 /*flags*/, userId); 21071 } 21072 21073 @Override 21074 public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, 21075 int userId) { 21076 return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId); 21077 } 21078 21079 @Override 21080 public void setDeviceAndProfileOwnerPackages( 21081 int deviceOwnerUserId, String deviceOwnerPackage, 21082 SparseArray<String> profileOwnerPackages) { 21083 mProtectedPackages.setDeviceAndProfileOwnerPackages( 21084 deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages); 21085 } 21086 21087 @Override 21088 public boolean isPackageDataProtected(int userId, String packageName) { 21089 return mProtectedPackages.isPackageDataProtected(userId, packageName); 21090 } 21091 21092 @Override 21093 public boolean wasPackageEverLaunched(String packageName, int userId) { 21094 synchronized (mPackages) { 21095 return mSettings.wasPackageEverLaunchedLPr(packageName, userId); 21096 } 21097 } 21098 } 21099 21100 @Override 21101 public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) { 21102 enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps"); 21103 synchronized (mPackages) { 21104 final long identity = Binder.clearCallingIdentity(); 21105 try { 21106 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr( 21107 packageNames, userId); 21108 } finally { 21109 Binder.restoreCallingIdentity(identity); 21110 } 21111 } 21112 } 21113 21114 private static void enforceSystemOrPhoneCaller(String tag) { 21115 int callingUid = Binder.getCallingUid(); 21116 if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) { 21117 throw new SecurityException( 21118 "Cannot call " + tag + " from UID " + callingUid); 21119 } 21120 } 21121 21122 boolean isHistoricalPackageUsageAvailable() { 21123 return mPackageUsage.isHistoricalPackageUsageAvailable(); 21124 } 21125 21126 /** 21127 * Return a <b>copy</b> of the collection of packages known to the package manager. 21128 * @return A copy of the values of mPackages. 21129 */ 21130 Collection<PackageParser.Package> getPackages() { 21131 synchronized (mPackages) { 21132 return new ArrayList<>(mPackages.values()); 21133 } 21134 } 21135 21136 /** 21137 * Logs process start information (including base APK hash) to the security log. 21138 * @hide 21139 */ 21140 public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo, 21141 String apkFile, int pid) { 21142 if (!SecurityLog.isLoggingEnabled()) { 21143 return; 21144 } 21145 Bundle data = new Bundle(); 21146 data.putLong("startTimestamp", System.currentTimeMillis()); 21147 data.putString("processName", processName); 21148 data.putInt("uid", uid); 21149 data.putString("seinfo", seinfo); 21150 data.putString("apkFile", apkFile); 21151 data.putInt("pid", pid); 21152 Message msg = mProcessLoggingHandler.obtainMessage( 21153 ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG); 21154 msg.setData(data); 21155 mProcessLoggingHandler.sendMessage(msg); 21156 } 21157 21158 public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) { 21159 return mCompilerStats.getPackageStats(pkgName); 21160 } 21161 21162 public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) { 21163 return getOrCreateCompilerPackageStats(pkg.packageName); 21164 } 21165 21166 public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) { 21167 return mCompilerStats.getOrCreatePackageStats(pkgName); 21168 } 21169 21170 public void deleteCompilerPackageStats(String pkgName) { 21171 mCompilerStats.deletePackageStats(pkgName); 21172 } 21173} 21174