PackageManagerService.java revision 43fc2447df2354fcb7b843a86b1c266946ca5702
1/* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.pm; 18 19import static android.Manifest.permission.READ_EXTERNAL_STORAGE; 20import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE; 21import static android.Manifest.permission.WRITE_MEDIA_STORAGE; 22import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 23import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED; 24import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED; 25import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER; 26import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; 27import static android.content.pm.PackageManager.DELETE_KEEP_DATA; 28import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 29import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED; 30import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 31import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE; 32import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 33import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED; 34import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET; 35import static android.content.pm.PackageManager.INSTALL_EXTERNAL; 36import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 37import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER; 38import static android.content.pm.PackageManager.INSTALL_FAILED_DEXOPT; 39import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE; 40import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION; 41import static android.content.pm.PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID; 42import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 43import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 44import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK; 45import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 46import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY; 47import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED; 48import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE; 49import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE; 50import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY; 51import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE; 52import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED; 53import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 54import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK; 55import static android.content.pm.PackageManager.INSTALL_INTERNAL; 56import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; 57import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 58import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK; 59import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 60import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER; 61import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 62import static android.content.pm.PackageManager.MATCH_ALL; 63import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING; 64import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE; 65import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE; 66import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS; 67import static android.content.pm.PackageManager.MATCH_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.Process.PACKAGE_INFO_GID; 79import static android.os.Process.SYSTEM_UID; 80import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; 81import static android.system.OsConstants.O_CREAT; 82import static android.system.OsConstants.O_RDWR; 83 84import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE; 85import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT; 86import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME; 87import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME; 88import static com.android.internal.util.ArrayUtils.appendInt; 89import static com.android.server.pm.Installer.DEXOPT_PUBLIC; 90import static com.android.server.pm.InstructionSets.getAppDexInstructionSets; 91import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet; 92import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets; 93import static com.android.server.pm.InstructionSets.getPreferredInstructionSet; 94import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet; 95import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason; 96import static com.android.server.pm.PackageManagerServiceCompilerMapping.getFullCompilerFilter; 97import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE; 98import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS; 99import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED; 100 101import android.Manifest; 102import android.annotation.NonNull; 103import android.annotation.Nullable; 104import android.app.ActivityManager; 105import android.app.ActivityManagerNative; 106import android.app.IActivityManager; 107import android.app.admin.DevicePolicyManagerInternal; 108import android.app.admin.IDevicePolicyManager; 109import android.app.backup.IBackupManager; 110import android.content.BroadcastReceiver; 111import android.content.ComponentName; 112import android.content.Context; 113import android.content.IIntentReceiver; 114import android.content.Intent; 115import android.content.IntentFilter; 116import android.content.IntentSender; 117import android.content.IntentSender.SendIntentException; 118import android.content.ServiceConnection; 119import android.content.pm.ActivityInfo; 120import android.content.pm.ApplicationInfo; 121import android.content.pm.AppsQueryHelper; 122import android.content.pm.ComponentInfo; 123import android.content.pm.EphemeralApplicationInfo; 124import android.content.pm.EphemeralResolveInfo; 125import android.content.pm.EphemeralResolveInfo.EphemeralResolveIntentInfo; 126import android.content.pm.FeatureInfo; 127import android.content.pm.IOnPermissionsChangeListener; 128import android.content.pm.IPackageDataObserver; 129import android.content.pm.IPackageDeleteObserver; 130import android.content.pm.IPackageDeleteObserver2; 131import android.content.pm.IPackageInstallObserver2; 132import android.content.pm.IPackageInstaller; 133import android.content.pm.IPackageManager; 134import android.content.pm.IPackageMoveObserver; 135import android.content.pm.IPackageStatsObserver; 136import android.content.pm.InstrumentationInfo; 137import android.content.pm.IntentFilterVerificationInfo; 138import android.content.pm.KeySet; 139import android.content.pm.PackageCleanItem; 140import android.content.pm.PackageInfo; 141import android.content.pm.PackageInfoLite; 142import android.content.pm.PackageInstaller; 143import android.content.pm.PackageManager; 144import android.content.pm.PackageManager.LegacyPackageDeleteObserver; 145import android.content.pm.PackageManagerInternal; 146import android.content.pm.PackageParser; 147import android.content.pm.PackageParser.ActivityIntentInfo; 148import android.content.pm.PackageParser.PackageLite; 149import android.content.pm.PackageParser.PackageParserException; 150import android.content.pm.PackageStats; 151import android.content.pm.PackageUserState; 152import android.content.pm.ParceledListSlice; 153import android.content.pm.PermissionGroupInfo; 154import android.content.pm.PermissionInfo; 155import android.content.pm.ProviderInfo; 156import android.content.pm.ResolveInfo; 157import android.content.pm.ServiceInfo; 158import android.content.pm.Signature; 159import android.content.pm.UserInfo; 160import android.content.pm.VerifierDeviceIdentity; 161import android.content.pm.VerifierInfo; 162import android.content.res.Resources; 163import android.graphics.Bitmap; 164import android.hardware.display.DisplayManager; 165import android.net.Uri; 166import android.os.Binder; 167import android.os.Build; 168import android.os.Bundle; 169import android.os.Debug; 170import android.os.Environment; 171import android.os.Environment.UserEnvironment; 172import android.os.FileUtils; 173import android.os.Handler; 174import android.os.IBinder; 175import android.os.Looper; 176import android.os.Message; 177import android.os.Parcel; 178import android.os.ParcelFileDescriptor; 179import android.os.Process; 180import android.os.RemoteCallbackList; 181import android.os.RemoteException; 182import android.os.ResultReceiver; 183import android.os.SELinux; 184import android.os.ServiceManager; 185import android.os.SystemClock; 186import android.os.SystemProperties; 187import android.os.Trace; 188import android.os.UserHandle; 189import android.os.UserManager; 190import android.os.storage.IMountService; 191import android.os.storage.MountServiceInternal; 192import android.os.storage.StorageEventListener; 193import android.os.storage.StorageManager; 194import android.os.storage.VolumeInfo; 195import android.os.storage.VolumeRecord; 196import android.security.KeyStore; 197import android.security.SystemKeyStore; 198import android.system.ErrnoException; 199import android.system.Os; 200import android.text.TextUtils; 201import android.text.format.DateUtils; 202import android.util.ArrayMap; 203import android.util.ArraySet; 204import android.util.AtomicFile; 205import android.util.DisplayMetrics; 206import android.util.EventLog; 207import android.util.ExceptionUtils; 208import android.util.Log; 209import android.util.LogPrinter; 210import android.util.MathUtils; 211import android.util.PrintStreamPrinter; 212import android.util.Slog; 213import android.util.SparseArray; 214import android.util.SparseBooleanArray; 215import android.util.SparseIntArray; 216import android.util.Xml; 217import android.view.Display; 218 219import com.android.internal.R; 220import com.android.internal.annotations.GuardedBy; 221import com.android.internal.app.IMediaContainerService; 222import com.android.internal.app.ResolverActivity; 223import com.android.internal.content.NativeLibraryHelper; 224import com.android.internal.content.PackageHelper; 225import com.android.internal.os.IParcelFileDescriptorFactory; 226import com.android.internal.os.InstallerConnection.InstallerException; 227import com.android.internal.os.SomeArgs; 228import com.android.internal.os.Zygote; 229import com.android.internal.util.ArrayUtils; 230import com.android.internal.util.FastPrintWriter; 231import com.android.internal.util.FastXmlSerializer; 232import com.android.internal.util.IndentingPrintWriter; 233import com.android.internal.util.Preconditions; 234import com.android.internal.util.XmlUtils; 235import com.android.server.EventLogTags; 236import com.android.server.FgThread; 237import com.android.server.IntentResolver; 238import com.android.server.LocalServices; 239import com.android.server.ServiceThread; 240import com.android.server.SystemConfig; 241import com.android.server.Watchdog; 242import com.android.server.pm.PermissionsState.PermissionState; 243import com.android.server.pm.Settings.DatabaseVersion; 244import com.android.server.pm.Settings.VersionInfo; 245import com.android.server.storage.DeviceStorageMonitorInternal; 246 247import dalvik.system.DexFile; 248import dalvik.system.VMRuntime; 249 250import libcore.io.IoUtils; 251import libcore.util.EmptyArray; 252 253import org.xmlpull.v1.XmlPullParser; 254import org.xmlpull.v1.XmlPullParserException; 255import org.xmlpull.v1.XmlSerializer; 256 257import java.io.BufferedInputStream; 258import java.io.BufferedOutputStream; 259import java.io.BufferedReader; 260import java.io.ByteArrayInputStream; 261import java.io.ByteArrayOutputStream; 262import java.io.File; 263import java.io.FileDescriptor; 264import java.io.FileNotFoundException; 265import java.io.FileOutputStream; 266import java.io.FileReader; 267import java.io.FilenameFilter; 268import java.io.IOException; 269import java.io.InputStream; 270import java.io.PrintWriter; 271import java.nio.charset.StandardCharsets; 272import java.security.MessageDigest; 273import java.security.NoSuchAlgorithmException; 274import java.security.PublicKey; 275import java.security.cert.CertificateEncodingException; 276import java.security.cert.CertificateException; 277import java.text.SimpleDateFormat; 278import java.util.ArrayList; 279import java.util.Arrays; 280import java.util.Collection; 281import java.util.Collections; 282import java.util.Comparator; 283import java.util.Date; 284import java.util.HashSet; 285import java.util.Iterator; 286import java.util.List; 287import java.util.Map; 288import java.util.Objects; 289import java.util.Set; 290import java.util.concurrent.CountDownLatch; 291import java.util.concurrent.TimeUnit; 292import java.util.concurrent.atomic.AtomicBoolean; 293import java.util.concurrent.atomic.AtomicInteger; 294import java.util.concurrent.atomic.AtomicLong; 295 296/** 297 * Keep track of all those .apks everywhere. 298 * 299 * This is very central to the platform's security; please run the unit 300 * tests whenever making modifications here: 301 * 302runtest -c android.content.pm.PackageManagerTests frameworks-core 303 * 304 * {@hide} 305 */ 306public class PackageManagerService extends IPackageManager.Stub { 307 static final String TAG = "PackageManager"; 308 static final boolean DEBUG_SETTINGS = false; 309 static final boolean DEBUG_PREFERRED = false; 310 static final boolean DEBUG_UPGRADE = false; 311 static final boolean DEBUG_DOMAIN_VERIFICATION = false; 312 private static final boolean DEBUG_BACKUP = false; 313 private static final boolean DEBUG_INSTALL = false; 314 private static final boolean DEBUG_REMOVE = false; 315 private static final boolean DEBUG_BROADCASTS = false; 316 private static final boolean DEBUG_SHOW_INFO = false; 317 private static final boolean DEBUG_PACKAGE_INFO = false; 318 private static final boolean DEBUG_INTENT_MATCHING = false; 319 private static final boolean DEBUG_PACKAGE_SCANNING = false; 320 private static final boolean DEBUG_VERIFY = false; 321 322 // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService 323 // and PackageDexOptimizer. All these classes have their own flag to allow switching a single 324 // user, but by default initialize to this. 325 static final boolean DEBUG_DEXOPT = false; 326 327 private static final boolean DEBUG_ABI_SELECTION = false; 328 private static final boolean DEBUG_EPHEMERAL = false; 329 private static final boolean DEBUG_TRIAGED_MISSING = false; 330 private static final boolean DEBUG_APP_DATA = false; 331 332 static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false; 333 334 private static final boolean DISABLE_EPHEMERAL_APPS = true; 335 336 private static final int RADIO_UID = Process.PHONE_UID; 337 private static final int LOG_UID = Process.LOG_UID; 338 private static final int NFC_UID = Process.NFC_UID; 339 private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID; 340 private static final int SHELL_UID = Process.SHELL_UID; 341 342 // Cap the size of permission trees that 3rd party apps can define 343 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768; // characters of text 344 345 // Suffix used during package installation when copying/moving 346 // package apks to install directory. 347 private static final String INSTALL_PACKAGE_SUFFIX = "-"; 348 349 static final int SCAN_NO_DEX = 1<<1; 350 static final int SCAN_FORCE_DEX = 1<<2; 351 static final int SCAN_UPDATE_SIGNATURE = 1<<3; 352 static final int SCAN_NEW_INSTALL = 1<<4; 353 static final int SCAN_NO_PATHS = 1<<5; 354 static final int SCAN_UPDATE_TIME = 1<<6; 355 static final int SCAN_DEFER_DEX = 1<<7; 356 static final int SCAN_BOOTING = 1<<8; 357 static final int SCAN_TRUSTED_OVERLAY = 1<<9; 358 static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10; 359 static final int SCAN_REPLACING = 1<<11; 360 static final int SCAN_REQUIRE_KNOWN = 1<<12; 361 static final int SCAN_MOVE = 1<<13; 362 static final int SCAN_INITIAL = 1<<14; 363 static final int SCAN_CHECK_ONLY = 1<<15; 364 static final int SCAN_DONT_KILL_APP = 1<<17; 365 366 static final int REMOVE_CHATTY = 1<<16; 367 368 private static final int[] EMPTY_INT_ARRAY = new int[0]; 369 370 /** 371 * Timeout (in milliseconds) after which the watchdog should declare that 372 * our handler thread is wedged. The usual default for such things is one 373 * minute but we sometimes do very lengthy I/O operations on this thread, 374 * such as installing multi-gigabyte applications, so ours needs to be longer. 375 */ 376 private static final long WATCHDOG_TIMEOUT = 1000*60*10; // ten minutes 377 378 /** 379 * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim 380 * be run on this device. We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL 381 * settings entry if available, otherwise we use the hardcoded default. If it's been 382 * more than this long since the last fstrim, we force one during the boot sequence. 383 * 384 * This backstops other fstrim scheduling: if the device is alive at midnight+idle, 385 * one gets run at the next available charging+idle time. This final mandatory 386 * no-fstrim check kicks in only of the other scheduling criteria is never met. 387 */ 388 private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS; 389 390 /** 391 * Whether verification is enabled by default. 392 */ 393 private static final boolean DEFAULT_VERIFY_ENABLE = true; 394 395 /** 396 * The default maximum time to wait for the verification agent to return in 397 * milliseconds. 398 */ 399 private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000; 400 401 /** 402 * The default response for package verification timeout. 403 * 404 * This can be either PackageManager.VERIFICATION_ALLOW or 405 * PackageManager.VERIFICATION_REJECT. 406 */ 407 private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW; 408 409 static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer"; 410 411 static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName( 412 DEFAULT_CONTAINER_PACKAGE, 413 "com.android.defcontainer.DefaultContainerService"); 414 415 private static final String KILL_APP_REASON_GIDS_CHANGED = 416 "permission grant or revoke changed gids"; 417 418 private static final String KILL_APP_REASON_PERMISSIONS_REVOKED = 419 "permissions revoked"; 420 421 private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive"; 422 423 private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay"; 424 425 /** Permission grant: not grant the permission. */ 426 private static final int GRANT_DENIED = 1; 427 428 /** Permission grant: grant the permission as an install permission. */ 429 private static final int GRANT_INSTALL = 2; 430 431 /** Permission grant: grant the permission as a runtime one. */ 432 private static final int GRANT_RUNTIME = 3; 433 434 /** Permission grant: grant as runtime a permission that was granted as an install time one. */ 435 private static final int GRANT_UPGRADE = 4; 436 437 /** Canonical intent used to identify what counts as a "web browser" app */ 438 private static final Intent sBrowserIntent; 439 static { 440 sBrowserIntent = new Intent(); 441 sBrowserIntent.setAction(Intent.ACTION_VIEW); 442 sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE); 443 sBrowserIntent.setData(Uri.parse("http:")); 444 } 445 446 // Compilation reasons. 447 public static final int REASON_BOOT = 0; 448 public static final int REASON_INSTALL = 1; 449 public static final int REASON_BACKGROUND_DEXOPT = 2; 450 public static final int REASON_AB_OTA = 3; 451 public static final int REASON_NON_SYSTEM_LIBRARY = 4; 452 public static final int REASON_SHARED_APK = 5; 453 public static final int REASON_FORCED_DEXOPT = 6; 454 455 public static final int REASON_LAST = REASON_FORCED_DEXOPT; 456 457 final ServiceThread mHandlerThread; 458 459 final PackageHandler mHandler; 460 461 /** 462 * Messages for {@link #mHandler} that need to wait for system ready before 463 * being dispatched. 464 */ 465 private ArrayList<Message> mPostSystemReadyMessages; 466 467 final int mSdkVersion = Build.VERSION.SDK_INT; 468 469 final Context mContext; 470 final boolean mFactoryTest; 471 final boolean mOnlyCore; 472 final DisplayMetrics mMetrics; 473 final int mDefParseFlags; 474 final String[] mSeparateProcesses; 475 final boolean mIsUpgrade; 476 477 /** The location for ASEC container files on internal storage. */ 478 final String mAsecInternalPath; 479 480 // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages 481 // LOCK HELD. Can be called with mInstallLock held. 482 @GuardedBy("mInstallLock") 483 final Installer mInstaller; 484 485 /** Directory where installed third-party apps stored */ 486 final File mAppInstallDir; 487 final File mEphemeralInstallDir; 488 489 /** 490 * Directory to which applications installed internally have their 491 * 32 bit native libraries copied. 492 */ 493 private File mAppLib32InstallDir; 494 495 // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked 496 // apps. 497 final File mDrmAppPrivateInstallDir; 498 499 // ---------------------------------------------------------------- 500 501 // Lock for state used when installing and doing other long running 502 // operations. Methods that must be called with this lock held have 503 // the suffix "LI". 504 final Object mInstallLock = new Object(); 505 506 // ---------------------------------------------------------------- 507 508 // Keys are String (package name), values are Package. This also serves 509 // as the lock for the global state. Methods that must be called with 510 // this lock held have the prefix "LP". 511 @GuardedBy("mPackages") 512 final ArrayMap<String, PackageParser.Package> mPackages = 513 new ArrayMap<String, PackageParser.Package>(); 514 515 final ArrayMap<String, Set<String>> mKnownCodebase = 516 new ArrayMap<String, Set<String>>(); 517 518 // Tracks available target package names -> overlay package paths. 519 final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays = 520 new ArrayMap<String, ArrayMap<String, PackageParser.Package>>(); 521 522 /** 523 * Tracks new system packages [received in an OTA] that we expect to 524 * find updated user-installed versions. Keys are package name, values 525 * are package location. 526 */ 527 final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>(); 528 529 /** 530 * Tracks existing system packages prior to receiving an OTA. Keys are package name. 531 */ 532 final private ArraySet<String> mExistingSystemPackages = new ArraySet<>(); 533 /** 534 * Whether or not system app permissions should be promoted from install to runtime. 535 */ 536 boolean mPromoteSystemApps; 537 538 final Settings mSettings; 539 boolean mRestoredSettings; 540 541 // System configuration read by SystemConfig. 542 final int[] mGlobalGids; 543 final SparseArray<ArraySet<String>> mSystemPermissions; 544 final ArrayMap<String, FeatureInfo> mAvailableFeatures; 545 546 // If mac_permissions.xml was found for seinfo labeling. 547 boolean mFoundPolicyFile; 548 549 private final EphemeralApplicationRegistry mEphemeralApplicationRegistry; 550 551 public static final class SharedLibraryEntry { 552 public final String path; 553 public final String apk; 554 555 SharedLibraryEntry(String _path, String _apk) { 556 path = _path; 557 apk = _apk; 558 } 559 } 560 561 // Currently known shared libraries. 562 final ArrayMap<String, SharedLibraryEntry> mSharedLibraries = 563 new ArrayMap<String, SharedLibraryEntry>(); 564 565 // All available activities, for your resolving pleasure. 566 final ActivityIntentResolver mActivities = 567 new ActivityIntentResolver(); 568 569 // All available receivers, for your resolving pleasure. 570 final ActivityIntentResolver mReceivers = 571 new ActivityIntentResolver(); 572 573 // All available services, for your resolving pleasure. 574 final ServiceIntentResolver mServices = new ServiceIntentResolver(); 575 576 // All available providers, for your resolving pleasure. 577 final ProviderIntentResolver mProviders = new ProviderIntentResolver(); 578 579 // Mapping from provider base names (first directory in content URI codePath) 580 // to the provider information. 581 final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority = 582 new ArrayMap<String, PackageParser.Provider>(); 583 584 // Mapping from instrumentation class names to info about them. 585 final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation = 586 new ArrayMap<ComponentName, PackageParser.Instrumentation>(); 587 588 // Mapping from permission names to info about them. 589 final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups = 590 new ArrayMap<String, PackageParser.PermissionGroup>(); 591 592 // Packages whose data we have transfered into another package, thus 593 // should no longer exist. 594 final ArraySet<String> mTransferedPackages = new ArraySet<String>(); 595 596 // Broadcast actions that are only available to the system. 597 final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>(); 598 599 /** List of packages waiting for verification. */ 600 final SparseArray<PackageVerificationState> mPendingVerification 601 = new SparseArray<PackageVerificationState>(); 602 603 /** Set of packages associated with each app op permission. */ 604 final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>(); 605 606 final PackageInstallerService mInstallerService; 607 608 private final PackageDexOptimizer mPackageDexOptimizer; 609 610 private AtomicInteger mNextMoveId = new AtomicInteger(); 611 private final MoveCallbacks mMoveCallbacks; 612 613 private final OnPermissionChangeListeners mOnPermissionChangeListeners; 614 615 // Cache of users who need badging. 616 SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray(); 617 618 /** Token for keys in mPendingVerification. */ 619 private int mPendingVerificationToken = 0; 620 621 volatile boolean mSystemReady; 622 volatile boolean mSafeMode; 623 volatile boolean mHasSystemUidErrors; 624 625 ApplicationInfo mAndroidApplication; 626 final ActivityInfo mResolveActivity = new ActivityInfo(); 627 final ResolveInfo mResolveInfo = new ResolveInfo(); 628 ComponentName mResolveComponentName; 629 PackageParser.Package mPlatformPackage; 630 ComponentName mCustomResolverComponentName; 631 632 boolean mResolverReplaced = false; 633 634 private final @Nullable ComponentName mIntentFilterVerifierComponent; 635 private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier; 636 637 private int mIntentFilterVerificationToken = 0; 638 639 /** Component that knows whether or not an ephemeral application exists */ 640 final ComponentName mEphemeralResolverComponent; 641 /** The service connection to the ephemeral resolver */ 642 final EphemeralResolverConnection mEphemeralResolverConnection; 643 644 /** Component used to install ephemeral applications */ 645 final ComponentName mEphemeralInstallerComponent; 646 final ActivityInfo mEphemeralInstallerActivity = new ActivityInfo(); 647 final ResolveInfo mEphemeralInstallerInfo = new ResolveInfo(); 648 649 final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates 650 = new SparseArray<IntentFilterVerificationState>(); 651 652 final DefaultPermissionGrantPolicy mDefaultPermissionPolicy = 653 new DefaultPermissionGrantPolicy(this); 654 655 // List of packages names to keep cached, even if they are uninstalled for all users 656 private List<String> mKeepUninstalledPackages; 657 658 private static class IFVerificationParams { 659 PackageParser.Package pkg; 660 boolean replacing; 661 int userId; 662 int verifierUid; 663 664 public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing, 665 int _userId, int _verifierUid) { 666 pkg = _pkg; 667 replacing = _replacing; 668 userId = _userId; 669 replacing = _replacing; 670 verifierUid = _verifierUid; 671 } 672 } 673 674 private interface IntentFilterVerifier<T extends IntentFilter> { 675 boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId, 676 T filter, String packageName); 677 void startVerifications(int userId); 678 void receiveVerificationResponse(int verificationId); 679 } 680 681 private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> { 682 private Context mContext; 683 private ComponentName mIntentFilterVerifierComponent; 684 private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>(); 685 686 public IntentVerifierProxy(Context context, ComponentName verifierComponent) { 687 mContext = context; 688 mIntentFilterVerifierComponent = verifierComponent; 689 } 690 691 private String getDefaultScheme() { 692 return IntentFilter.SCHEME_HTTPS; 693 } 694 695 @Override 696 public void startVerifications(int userId) { 697 // Launch verifications requests 698 int count = mCurrentIntentFilterVerifications.size(); 699 for (int n=0; n<count; n++) { 700 int verificationId = mCurrentIntentFilterVerifications.get(n); 701 final IntentFilterVerificationState ivs = 702 mIntentFilterVerificationStates.get(verificationId); 703 704 String packageName = ivs.getPackageName(); 705 706 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 707 final int filterCount = filters.size(); 708 ArraySet<String> domainsSet = new ArraySet<>(); 709 for (int m=0; m<filterCount; m++) { 710 PackageParser.ActivityIntentInfo filter = filters.get(m); 711 domainsSet.addAll(filter.getHostsList()); 712 } 713 ArrayList<String> domainsList = new ArrayList<>(domainsSet); 714 synchronized (mPackages) { 715 if (mSettings.createIntentFilterVerificationIfNeededLPw( 716 packageName, domainsList) != null) { 717 scheduleWriteSettingsLocked(); 718 } 719 } 720 sendVerificationRequest(userId, verificationId, ivs); 721 } 722 mCurrentIntentFilterVerifications.clear(); 723 } 724 725 private void sendVerificationRequest(int userId, int verificationId, 726 IntentFilterVerificationState ivs) { 727 728 Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 729 verificationIntent.putExtra( 730 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID, 731 verificationId); 732 verificationIntent.putExtra( 733 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME, 734 getDefaultScheme()); 735 verificationIntent.putExtra( 736 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS, 737 ivs.getHostsString()); 738 verificationIntent.putExtra( 739 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME, 740 ivs.getPackageName()); 741 verificationIntent.setComponent(mIntentFilterVerifierComponent); 742 verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 743 744 UserHandle user = new UserHandle(userId); 745 mContext.sendBroadcastAsUser(verificationIntent, user); 746 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 747 "Sending IntentFilter verification broadcast"); 748 } 749 750 public void receiveVerificationResponse(int verificationId) { 751 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 752 753 final boolean verified = ivs.isVerified(); 754 755 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 756 final int count = filters.size(); 757 if (DEBUG_DOMAIN_VERIFICATION) { 758 Slog.i(TAG, "Received verification response " + verificationId 759 + " for " + count + " filters, verified=" + verified); 760 } 761 for (int n=0; n<count; n++) { 762 PackageParser.ActivityIntentInfo filter = filters.get(n); 763 filter.setVerified(verified); 764 765 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString() 766 + " verified with result:" + verified + " and hosts:" 767 + ivs.getHostsString()); 768 } 769 770 mIntentFilterVerificationStates.remove(verificationId); 771 772 final String packageName = ivs.getPackageName(); 773 IntentFilterVerificationInfo ivi = null; 774 775 synchronized (mPackages) { 776 ivi = mSettings.getIntentFilterVerificationLPr(packageName); 777 } 778 if (ivi == null) { 779 Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:" 780 + verificationId + " packageName:" + packageName); 781 return; 782 } 783 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 784 "Updating IntentFilterVerificationInfo for package " + packageName 785 +" verificationId:" + verificationId); 786 787 synchronized (mPackages) { 788 if (verified) { 789 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS); 790 } else { 791 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK); 792 } 793 scheduleWriteSettingsLocked(); 794 795 final int userId = ivs.getUserId(); 796 if (userId != UserHandle.USER_ALL) { 797 final int userStatus = 798 mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 799 800 int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 801 boolean needUpdate = false; 802 803 // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have 804 // already been set by the User thru the Disambiguation dialog 805 switch (userStatus) { 806 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 807 if (verified) { 808 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 809 } else { 810 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 811 } 812 needUpdate = true; 813 break; 814 815 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 816 if (verified) { 817 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 818 needUpdate = true; 819 } 820 break; 821 822 default: 823 // Nothing to do 824 } 825 826 if (needUpdate) { 827 mSettings.updateIntentFilterVerificationStatusLPw( 828 packageName, updatedStatus, userId); 829 scheduleWritePackageRestrictionsLocked(userId); 830 } 831 } 832 } 833 } 834 835 @Override 836 public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId, 837 ActivityIntentInfo filter, String packageName) { 838 if (!hasValidDomains(filter)) { 839 return false; 840 } 841 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 842 if (ivs == null) { 843 ivs = createDomainVerificationState(verifierUid, userId, verificationId, 844 packageName); 845 } 846 if (DEBUG_DOMAIN_VERIFICATION) { 847 Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter); 848 } 849 ivs.addFilter(filter); 850 return true; 851 } 852 853 private IntentFilterVerificationState createDomainVerificationState(int verifierUid, 854 int userId, int verificationId, String packageName) { 855 IntentFilterVerificationState ivs = new IntentFilterVerificationState( 856 verifierUid, userId, packageName); 857 ivs.setPendingState(); 858 synchronized (mPackages) { 859 mIntentFilterVerificationStates.append(verificationId, ivs); 860 mCurrentIntentFilterVerifications.add(verificationId); 861 } 862 return ivs; 863 } 864 } 865 866 private static boolean hasValidDomains(ActivityIntentInfo filter) { 867 return filter.hasCategory(Intent.CATEGORY_BROWSABLE) 868 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 869 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS)); 870 } 871 872 // Set of pending broadcasts for aggregating enable/disable of components. 873 static class PendingPackageBroadcasts { 874 // for each user id, a map of <package name -> components within that package> 875 final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap; 876 877 public PendingPackageBroadcasts() { 878 mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2); 879 } 880 881 public ArrayList<String> get(int userId, String packageName) { 882 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 883 return packages.get(packageName); 884 } 885 886 public void put(int userId, String packageName, ArrayList<String> components) { 887 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 888 packages.put(packageName, components); 889 } 890 891 public void remove(int userId, String packageName) { 892 ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId); 893 if (packages != null) { 894 packages.remove(packageName); 895 } 896 } 897 898 public void remove(int userId) { 899 mUidMap.remove(userId); 900 } 901 902 public int userIdCount() { 903 return mUidMap.size(); 904 } 905 906 public int userIdAt(int n) { 907 return mUidMap.keyAt(n); 908 } 909 910 public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) { 911 return mUidMap.get(userId); 912 } 913 914 public int size() { 915 // total number of pending broadcast entries across all userIds 916 int num = 0; 917 for (int i = 0; i< mUidMap.size(); i++) { 918 num += mUidMap.valueAt(i).size(); 919 } 920 return num; 921 } 922 923 public void clear() { 924 mUidMap.clear(); 925 } 926 927 private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) { 928 ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId); 929 if (map == null) { 930 map = new ArrayMap<String, ArrayList<String>>(); 931 mUidMap.put(userId, map); 932 } 933 return map; 934 } 935 } 936 final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts(); 937 938 // Service Connection to remote media container service to copy 939 // package uri's from external media onto secure containers 940 // or internal storage. 941 private IMediaContainerService mContainerService = null; 942 943 static final int SEND_PENDING_BROADCAST = 1; 944 static final int MCS_BOUND = 3; 945 static final int END_COPY = 4; 946 static final int INIT_COPY = 5; 947 static final int MCS_UNBIND = 6; 948 static final int START_CLEANING_PACKAGE = 7; 949 static final int FIND_INSTALL_LOC = 8; 950 static final int POST_INSTALL = 9; 951 static final int MCS_RECONNECT = 10; 952 static final int MCS_GIVE_UP = 11; 953 static final int UPDATED_MEDIA_STATUS = 12; 954 static final int WRITE_SETTINGS = 13; 955 static final int WRITE_PACKAGE_RESTRICTIONS = 14; 956 static final int PACKAGE_VERIFIED = 15; 957 static final int CHECK_PENDING_VERIFICATION = 16; 958 static final int START_INTENT_FILTER_VERIFICATIONS = 17; 959 static final int INTENT_FILTER_VERIFIED = 18; 960 961 static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds 962 963 // Delay time in millisecs 964 static final int BROADCAST_DELAY = 10 * 1000; 965 966 static UserManagerService sUserManager; 967 968 // Stores a list of users whose package restrictions file needs to be updated 969 private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>(); 970 971 final private DefaultContainerConnection mDefContainerConn = 972 new DefaultContainerConnection(); 973 class DefaultContainerConnection implements ServiceConnection { 974 public void onServiceConnected(ComponentName name, IBinder service) { 975 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected"); 976 IMediaContainerService imcs = 977 IMediaContainerService.Stub.asInterface(service); 978 mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs)); 979 } 980 981 public void onServiceDisconnected(ComponentName name) { 982 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected"); 983 } 984 } 985 986 // Recordkeeping of restore-after-install operations that are currently in flight 987 // between the Package Manager and the Backup Manager 988 static class PostInstallData { 989 public InstallArgs args; 990 public PackageInstalledInfo res; 991 992 PostInstallData(InstallArgs _a, PackageInstalledInfo _r) { 993 args = _a; 994 res = _r; 995 } 996 } 997 998 final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>(); 999 int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows 1000 1001 // XML tags for backup/restore of various bits of state 1002 private static final String TAG_PREFERRED_BACKUP = "pa"; 1003 private static final String TAG_DEFAULT_APPS = "da"; 1004 private static final String TAG_INTENT_FILTER_VERIFICATION = "iv"; 1005 1006 private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup"; 1007 private static final String TAG_ALL_GRANTS = "rt-grants"; 1008 private static final String TAG_GRANT = "grant"; 1009 private static final String ATTR_PACKAGE_NAME = "pkg"; 1010 1011 private static final String TAG_PERMISSION = "perm"; 1012 private static final String ATTR_PERMISSION_NAME = "name"; 1013 private static final String ATTR_IS_GRANTED = "g"; 1014 private static final String ATTR_USER_SET = "set"; 1015 private static final String ATTR_USER_FIXED = "fixed"; 1016 private static final String ATTR_REVOKE_ON_UPGRADE = "rou"; 1017 1018 // System/policy permission grants are not backed up 1019 private static final int SYSTEM_RUNTIME_GRANT_MASK = 1020 FLAG_PERMISSION_POLICY_FIXED 1021 | FLAG_PERMISSION_SYSTEM_FIXED 1022 | FLAG_PERMISSION_GRANTED_BY_DEFAULT; 1023 1024 // And we back up these user-adjusted states 1025 private static final int USER_RUNTIME_GRANT_MASK = 1026 FLAG_PERMISSION_USER_SET 1027 | FLAG_PERMISSION_USER_FIXED 1028 | FLAG_PERMISSION_REVOKE_ON_UPGRADE; 1029 1030 final @Nullable String mRequiredVerifierPackage; 1031 final @Nullable String mRequiredInstallerPackage; 1032 1033 private final PackageUsage mPackageUsage = new PackageUsage(); 1034 1035 private class PackageUsage { 1036 private static final int WRITE_INTERVAL 1037 = (DEBUG_DEXOPT) ? 0 : 30*60*1000; // 30m in ms 1038 1039 private final Object mFileLock = new Object(); 1040 private final AtomicLong mLastWritten = new AtomicLong(0); 1041 private final AtomicBoolean mBackgroundWriteRunning = new AtomicBoolean(false); 1042 1043 private boolean mIsHistoricalPackageUsageAvailable = true; 1044 1045 boolean isHistoricalPackageUsageAvailable() { 1046 return mIsHistoricalPackageUsageAvailable; 1047 } 1048 1049 void write(boolean force) { 1050 if (force) { 1051 writeInternal(); 1052 return; 1053 } 1054 if (SystemClock.elapsedRealtime() - mLastWritten.get() < WRITE_INTERVAL 1055 && !DEBUG_DEXOPT) { 1056 return; 1057 } 1058 if (mBackgroundWriteRunning.compareAndSet(false, true)) { 1059 new Thread("PackageUsage_DiskWriter") { 1060 @Override 1061 public void run() { 1062 try { 1063 writeInternal(); 1064 } finally { 1065 mBackgroundWriteRunning.set(false); 1066 } 1067 } 1068 }.start(); 1069 } 1070 } 1071 1072 private void writeInternal() { 1073 synchronized (mPackages) { 1074 synchronized (mFileLock) { 1075 AtomicFile file = getFile(); 1076 FileOutputStream f = null; 1077 try { 1078 f = file.startWrite(); 1079 BufferedOutputStream out = new BufferedOutputStream(f); 1080 FileUtils.setPermissions(file.getBaseFile().getPath(), 0640, SYSTEM_UID, PACKAGE_INFO_GID); 1081 StringBuilder sb = new StringBuilder(); 1082 for (PackageParser.Package pkg : mPackages.values()) { 1083 if (pkg.mLastPackageUsageTimeInMills == 0) { 1084 continue; 1085 } 1086 sb.setLength(0); 1087 sb.append(pkg.packageName); 1088 sb.append(' '); 1089 sb.append((long)pkg.mLastPackageUsageTimeInMills); 1090 sb.append('\n'); 1091 out.write(sb.toString().getBytes(StandardCharsets.US_ASCII)); 1092 } 1093 out.flush(); 1094 file.finishWrite(f); 1095 } catch (IOException e) { 1096 if (f != null) { 1097 file.failWrite(f); 1098 } 1099 Log.e(TAG, "Failed to write package usage times", e); 1100 } 1101 } 1102 } 1103 mLastWritten.set(SystemClock.elapsedRealtime()); 1104 } 1105 1106 void readLP() { 1107 synchronized (mFileLock) { 1108 AtomicFile file = getFile(); 1109 BufferedInputStream in = null; 1110 try { 1111 in = new BufferedInputStream(file.openRead()); 1112 StringBuffer sb = new StringBuffer(); 1113 while (true) { 1114 String packageName = readToken(in, sb, ' '); 1115 if (packageName == null) { 1116 break; 1117 } 1118 String timeInMillisString = readToken(in, sb, '\n'); 1119 if (timeInMillisString == null) { 1120 throw new IOException("Failed to find last usage time for package " 1121 + packageName); 1122 } 1123 PackageParser.Package pkg = mPackages.get(packageName); 1124 if (pkg == null) { 1125 continue; 1126 } 1127 long timeInMillis; 1128 try { 1129 timeInMillis = Long.parseLong(timeInMillisString); 1130 } catch (NumberFormatException e) { 1131 throw new IOException("Failed to parse " + timeInMillisString 1132 + " as a long.", e); 1133 } 1134 pkg.mLastPackageUsageTimeInMills = timeInMillis; 1135 } 1136 } catch (FileNotFoundException expected) { 1137 mIsHistoricalPackageUsageAvailable = false; 1138 } catch (IOException e) { 1139 Log.w(TAG, "Failed to read package usage times", e); 1140 } finally { 1141 IoUtils.closeQuietly(in); 1142 } 1143 } 1144 mLastWritten.set(SystemClock.elapsedRealtime()); 1145 } 1146 1147 private String readToken(InputStream in, StringBuffer sb, char endOfToken) 1148 throws IOException { 1149 sb.setLength(0); 1150 while (true) { 1151 int ch = in.read(); 1152 if (ch == -1) { 1153 if (sb.length() == 0) { 1154 return null; 1155 } 1156 throw new IOException("Unexpected EOF"); 1157 } 1158 if (ch == endOfToken) { 1159 return sb.toString(); 1160 } 1161 sb.append((char)ch); 1162 } 1163 } 1164 1165 private AtomicFile getFile() { 1166 File dataDir = Environment.getDataDirectory(); 1167 File systemDir = new File(dataDir, "system"); 1168 File fname = new File(systemDir, "package-usage.list"); 1169 return new AtomicFile(fname); 1170 } 1171 } 1172 1173 class PackageHandler extends Handler { 1174 private boolean mBound = false; 1175 final ArrayList<HandlerParams> mPendingInstalls = 1176 new ArrayList<HandlerParams>(); 1177 1178 private boolean connectToService() { 1179 if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" + 1180 " DefaultContainerService"); 1181 Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 1182 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1183 if (mContext.bindServiceAsUser(service, mDefContainerConn, 1184 Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) { 1185 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1186 mBound = true; 1187 return true; 1188 } 1189 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1190 return false; 1191 } 1192 1193 private void disconnectService() { 1194 mContainerService = null; 1195 mBound = false; 1196 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1197 mContext.unbindService(mDefContainerConn); 1198 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1199 } 1200 1201 PackageHandler(Looper looper) { 1202 super(looper); 1203 } 1204 1205 public void handleMessage(Message msg) { 1206 try { 1207 doHandleMessage(msg); 1208 } finally { 1209 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1210 } 1211 } 1212 1213 void doHandleMessage(Message msg) { 1214 switch (msg.what) { 1215 case INIT_COPY: { 1216 HandlerParams params = (HandlerParams) msg.obj; 1217 int idx = mPendingInstalls.size(); 1218 if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params); 1219 // If a bind was already initiated we dont really 1220 // need to do anything. The pending install 1221 // will be processed later on. 1222 if (!mBound) { 1223 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1224 System.identityHashCode(mHandler)); 1225 // If this is the only one pending we might 1226 // have to bind to the service again. 1227 if (!connectToService()) { 1228 Slog.e(TAG, "Failed to bind to media container service"); 1229 params.serviceError(); 1230 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1231 System.identityHashCode(mHandler)); 1232 if (params.traceMethod != null) { 1233 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod, 1234 params.traceCookie); 1235 } 1236 return; 1237 } else { 1238 // Once we bind to the service, the first 1239 // pending request will be processed. 1240 mPendingInstalls.add(idx, params); 1241 } 1242 } else { 1243 mPendingInstalls.add(idx, params); 1244 // Already bound to the service. Just make 1245 // sure we trigger off processing the first request. 1246 if (idx == 0) { 1247 mHandler.sendEmptyMessage(MCS_BOUND); 1248 } 1249 } 1250 break; 1251 } 1252 case MCS_BOUND: { 1253 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound"); 1254 if (msg.obj != null) { 1255 mContainerService = (IMediaContainerService) msg.obj; 1256 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1257 System.identityHashCode(mHandler)); 1258 } 1259 if (mContainerService == null) { 1260 if (!mBound) { 1261 // Something seriously wrong since we are not bound and we are not 1262 // waiting for connection. Bail out. 1263 Slog.e(TAG, "Cannot bind to media container service"); 1264 for (HandlerParams params : mPendingInstalls) { 1265 // Indicate service bind error 1266 params.serviceError(); 1267 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1268 System.identityHashCode(params)); 1269 if (params.traceMethod != null) { 1270 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, 1271 params.traceMethod, params.traceCookie); 1272 } 1273 return; 1274 } 1275 mPendingInstalls.clear(); 1276 } else { 1277 Slog.w(TAG, "Waiting to connect to media container service"); 1278 } 1279 } else if (mPendingInstalls.size() > 0) { 1280 HandlerParams params = mPendingInstalls.get(0); 1281 if (params != null) { 1282 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1283 System.identityHashCode(params)); 1284 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy"); 1285 if (params.startCopy()) { 1286 // We are done... look for more work or to 1287 // go idle. 1288 if (DEBUG_SD_INSTALL) Log.i(TAG, 1289 "Checking for more work or unbind..."); 1290 // Delete pending install 1291 if (mPendingInstalls.size() > 0) { 1292 mPendingInstalls.remove(0); 1293 } 1294 if (mPendingInstalls.size() == 0) { 1295 if (mBound) { 1296 if (DEBUG_SD_INSTALL) Log.i(TAG, 1297 "Posting delayed MCS_UNBIND"); 1298 removeMessages(MCS_UNBIND); 1299 Message ubmsg = obtainMessage(MCS_UNBIND); 1300 // Unbind after a little delay, to avoid 1301 // continual thrashing. 1302 sendMessageDelayed(ubmsg, 10000); 1303 } 1304 } else { 1305 // There are more pending requests in queue. 1306 // Just post MCS_BOUND message to trigger processing 1307 // of next pending install. 1308 if (DEBUG_SD_INSTALL) Log.i(TAG, 1309 "Posting MCS_BOUND for next work"); 1310 mHandler.sendEmptyMessage(MCS_BOUND); 1311 } 1312 } 1313 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 1314 } 1315 } else { 1316 // Should never happen ideally. 1317 Slog.w(TAG, "Empty queue"); 1318 } 1319 break; 1320 } 1321 case MCS_RECONNECT: { 1322 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect"); 1323 if (mPendingInstalls.size() > 0) { 1324 if (mBound) { 1325 disconnectService(); 1326 } 1327 if (!connectToService()) { 1328 Slog.e(TAG, "Failed to bind to media container service"); 1329 for (HandlerParams params : mPendingInstalls) { 1330 // Indicate service bind error 1331 params.serviceError(); 1332 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1333 System.identityHashCode(params)); 1334 } 1335 mPendingInstalls.clear(); 1336 } 1337 } 1338 break; 1339 } 1340 case MCS_UNBIND: { 1341 // If there is no actual work left, then time to unbind. 1342 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind"); 1343 1344 if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) { 1345 if (mBound) { 1346 if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()"); 1347 1348 disconnectService(); 1349 } 1350 } else if (mPendingInstalls.size() > 0) { 1351 // There are more pending requests in queue. 1352 // Just post MCS_BOUND message to trigger processing 1353 // of next pending install. 1354 mHandler.sendEmptyMessage(MCS_BOUND); 1355 } 1356 1357 break; 1358 } 1359 case MCS_GIVE_UP: { 1360 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries"); 1361 HandlerParams params = mPendingInstalls.remove(0); 1362 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1363 System.identityHashCode(params)); 1364 break; 1365 } 1366 case SEND_PENDING_BROADCAST: { 1367 String packages[]; 1368 ArrayList<String> components[]; 1369 int size = 0; 1370 int uids[]; 1371 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1372 synchronized (mPackages) { 1373 if (mPendingBroadcasts == null) { 1374 return; 1375 } 1376 size = mPendingBroadcasts.size(); 1377 if (size <= 0) { 1378 // Nothing to be done. Just return 1379 return; 1380 } 1381 packages = new String[size]; 1382 components = new ArrayList[size]; 1383 uids = new int[size]; 1384 int i = 0; // filling out the above arrays 1385 1386 for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) { 1387 int packageUserId = mPendingBroadcasts.userIdAt(n); 1388 Iterator<Map.Entry<String, ArrayList<String>>> it 1389 = mPendingBroadcasts.packagesForUserId(packageUserId) 1390 .entrySet().iterator(); 1391 while (it.hasNext() && i < size) { 1392 Map.Entry<String, ArrayList<String>> ent = it.next(); 1393 packages[i] = ent.getKey(); 1394 components[i] = ent.getValue(); 1395 PackageSetting ps = mSettings.mPackages.get(ent.getKey()); 1396 uids[i] = (ps != null) 1397 ? UserHandle.getUid(packageUserId, ps.appId) 1398 : -1; 1399 i++; 1400 } 1401 } 1402 size = i; 1403 mPendingBroadcasts.clear(); 1404 } 1405 // Send broadcasts 1406 for (int i = 0; i < size; i++) { 1407 sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]); 1408 } 1409 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1410 break; 1411 } 1412 case START_CLEANING_PACKAGE: { 1413 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1414 final String packageName = (String)msg.obj; 1415 final int userId = msg.arg1; 1416 final boolean andCode = msg.arg2 != 0; 1417 synchronized (mPackages) { 1418 if (userId == UserHandle.USER_ALL) { 1419 int[] users = sUserManager.getUserIds(); 1420 for (int user : users) { 1421 mSettings.addPackageToCleanLPw( 1422 new PackageCleanItem(user, packageName, andCode)); 1423 } 1424 } else { 1425 mSettings.addPackageToCleanLPw( 1426 new PackageCleanItem(userId, packageName, andCode)); 1427 } 1428 } 1429 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1430 startCleaningPackages(); 1431 } break; 1432 case POST_INSTALL: { 1433 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1); 1434 1435 PostInstallData data = mRunningInstalls.get(msg.arg1); 1436 mRunningInstalls.delete(msg.arg1); 1437 1438 if (data != null) { 1439 InstallArgs args = data.args; 1440 PackageInstalledInfo parentRes = data.res; 1441 1442 final boolean grantPermissions = (args.installFlags 1443 & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0; 1444 final boolean killApp = (args.installFlags 1445 & PackageManager.INSTALL_DONT_KILL_APP) == 0; 1446 final String[] grantedPermissions = args.installGrantPermissions; 1447 1448 // Handle the parent package 1449 handlePackagePostInstall(parentRes, grantPermissions, killApp, 1450 grantedPermissions, args.observer); 1451 1452 // Handle the child packages 1453 final int childCount = (parentRes.addedChildPackages != null) 1454 ? parentRes.addedChildPackages.size() : 0; 1455 for (int i = 0; i < childCount; i++) { 1456 PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i); 1457 handlePackagePostInstall(childRes, grantPermissions, killApp, 1458 grantedPermissions, args.observer); 1459 } 1460 1461 // Log tracing if needed 1462 if (args.traceMethod != null) { 1463 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod, 1464 args.traceCookie); 1465 } 1466 } else { 1467 Slog.e(TAG, "Bogus post-install token " + msg.arg1); 1468 } 1469 1470 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1); 1471 } break; 1472 case UPDATED_MEDIA_STATUS: { 1473 if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS"); 1474 boolean reportStatus = msg.arg1 == 1; 1475 boolean doGc = msg.arg2 == 1; 1476 if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc); 1477 if (doGc) { 1478 // Force a gc to clear up stale containers. 1479 Runtime.getRuntime().gc(); 1480 } 1481 if (msg.obj != null) { 1482 @SuppressWarnings("unchecked") 1483 Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj; 1484 if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers"); 1485 // Unload containers 1486 unloadAllContainers(args); 1487 } 1488 if (reportStatus) { 1489 try { 1490 if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back"); 1491 PackageHelper.getMountService().finishMediaUpdate(); 1492 } catch (RemoteException e) { 1493 Log.e(TAG, "MountService not running?"); 1494 } 1495 } 1496 } break; 1497 case WRITE_SETTINGS: { 1498 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1499 synchronized (mPackages) { 1500 removeMessages(WRITE_SETTINGS); 1501 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1502 mSettings.writeLPr(); 1503 mDirtyUsers.clear(); 1504 } 1505 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1506 } break; 1507 case WRITE_PACKAGE_RESTRICTIONS: { 1508 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1509 synchronized (mPackages) { 1510 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1511 for (int userId : mDirtyUsers) { 1512 mSettings.writePackageRestrictionsLPr(userId); 1513 } 1514 mDirtyUsers.clear(); 1515 } 1516 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1517 } break; 1518 case CHECK_PENDING_VERIFICATION: { 1519 final int verificationId = msg.arg1; 1520 final PackageVerificationState state = mPendingVerification.get(verificationId); 1521 1522 if ((state != null) && !state.timeoutExtended()) { 1523 final InstallArgs args = state.getInstallArgs(); 1524 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1525 1526 Slog.i(TAG, "Verification timed out for " + originUri); 1527 mPendingVerification.remove(verificationId); 1528 1529 int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1530 1531 if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) { 1532 Slog.i(TAG, "Continuing with installation of " + originUri); 1533 state.setVerifierResponse(Binder.getCallingUid(), 1534 PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT); 1535 broadcastPackageVerified(verificationId, originUri, 1536 PackageManager.VERIFICATION_ALLOW, 1537 state.getInstallArgs().getUser()); 1538 try { 1539 ret = args.copyApk(mContainerService, true); 1540 } catch (RemoteException e) { 1541 Slog.e(TAG, "Could not contact the ContainerService"); 1542 } 1543 } else { 1544 broadcastPackageVerified(verificationId, originUri, 1545 PackageManager.VERIFICATION_REJECT, 1546 state.getInstallArgs().getUser()); 1547 } 1548 1549 Trace.asyncTraceEnd( 1550 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 1551 1552 processPendingInstall(args, ret); 1553 mHandler.sendEmptyMessage(MCS_UNBIND); 1554 } 1555 break; 1556 } 1557 case PACKAGE_VERIFIED: { 1558 final int verificationId = msg.arg1; 1559 1560 final PackageVerificationState state = mPendingVerification.get(verificationId); 1561 if (state == null) { 1562 Slog.w(TAG, "Invalid verification token " + verificationId + " received"); 1563 break; 1564 } 1565 1566 final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj; 1567 1568 state.setVerifierResponse(response.callerUid, response.code); 1569 1570 if (state.isVerificationComplete()) { 1571 mPendingVerification.remove(verificationId); 1572 1573 final InstallArgs args = state.getInstallArgs(); 1574 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1575 1576 int ret; 1577 if (state.isInstallAllowed()) { 1578 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 1579 broadcastPackageVerified(verificationId, originUri, 1580 response.code, state.getInstallArgs().getUser()); 1581 try { 1582 ret = args.copyApk(mContainerService, true); 1583 } catch (RemoteException e) { 1584 Slog.e(TAG, "Could not contact the ContainerService"); 1585 } 1586 } else { 1587 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1588 } 1589 1590 Trace.asyncTraceEnd( 1591 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 1592 1593 processPendingInstall(args, ret); 1594 mHandler.sendEmptyMessage(MCS_UNBIND); 1595 } 1596 1597 break; 1598 } 1599 case START_INTENT_FILTER_VERIFICATIONS: { 1600 IFVerificationParams params = (IFVerificationParams) msg.obj; 1601 verifyIntentFiltersIfNeeded(params.userId, params.verifierUid, 1602 params.replacing, params.pkg); 1603 break; 1604 } 1605 case INTENT_FILTER_VERIFIED: { 1606 final int verificationId = msg.arg1; 1607 1608 final IntentFilterVerificationState state = mIntentFilterVerificationStates.get( 1609 verificationId); 1610 if (state == null) { 1611 Slog.w(TAG, "Invalid IntentFilter verification token " 1612 + verificationId + " received"); 1613 break; 1614 } 1615 1616 final int userId = state.getUserId(); 1617 1618 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1619 "Processing IntentFilter verification with token:" 1620 + verificationId + " and userId:" + userId); 1621 1622 final IntentFilterVerificationResponse response = 1623 (IntentFilterVerificationResponse) msg.obj; 1624 1625 state.setVerifierResponse(response.callerUid, response.code); 1626 1627 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1628 "IntentFilter verification with token:" + verificationId 1629 + " and userId:" + userId 1630 + " is settings verifier response with response code:" 1631 + response.code); 1632 1633 if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) { 1634 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: " 1635 + response.getFailedDomainsString()); 1636 } 1637 1638 if (state.isVerificationComplete()) { 1639 mIntentFilterVerifier.receiveVerificationResponse(verificationId); 1640 } else { 1641 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1642 "IntentFilter verification with token:" + verificationId 1643 + " was not said to be complete"); 1644 } 1645 1646 break; 1647 } 1648 } 1649 } 1650 } 1651 1652 private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions, 1653 boolean killApp, String[] grantedPermissions, 1654 IPackageInstallObserver2 installObserver) { 1655 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 1656 // Send the removed broadcasts 1657 if (res.removedInfo != null) { 1658 res.removedInfo.sendPackageRemovedBroadcasts(killApp); 1659 } 1660 1661 // Now that we successfully installed the package, grant runtime 1662 // permissions if requested before broadcasting the install. 1663 if (grantPermissions && res.pkg.applicationInfo.targetSdkVersion 1664 >= Build.VERSION_CODES.M) { 1665 grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions); 1666 } 1667 1668 final boolean update = res.removedInfo != null 1669 && res.removedInfo.removedPackage != null; 1670 1671 // If this is the first time we have child packages for a disabled privileged 1672 // app that had no children, we grant requested runtime permissions to the new 1673 // children if the parent on the system image had them already granted. 1674 if (res.pkg.parentPackage != null) { 1675 synchronized (mPackages) { 1676 grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg); 1677 } 1678 } 1679 1680 synchronized (mPackages) { 1681 mEphemeralApplicationRegistry.onPackageInstalledLPw(res.pkg); 1682 } 1683 1684 final String packageName = res.pkg.applicationInfo.packageName; 1685 Bundle extras = new Bundle(1); 1686 extras.putInt(Intent.EXTRA_UID, res.uid); 1687 1688 // Determine the set of users who are adding this package for 1689 // the first time vs. those who are seeing an update. 1690 int[] firstUsers = EMPTY_INT_ARRAY; 1691 int[] updateUsers = EMPTY_INT_ARRAY; 1692 if (res.origUsers == null || res.origUsers.length == 0) { 1693 firstUsers = res.newUsers; 1694 } else { 1695 for (int newUser : res.newUsers) { 1696 boolean isNew = true; 1697 for (int origUser : res.origUsers) { 1698 if (origUser == newUser) { 1699 isNew = false; 1700 break; 1701 } 1702 } 1703 if (isNew) { 1704 firstUsers = ArrayUtils.appendInt(firstUsers, newUser); 1705 } else { 1706 updateUsers = ArrayUtils.appendInt(updateUsers, newUser); 1707 } 1708 } 1709 } 1710 1711 // Send installed broadcasts if the install/update is not ephemeral 1712 if (!isEphemeral(res.pkg)) { 1713 // Send added for users that see the package for the first time 1714 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, 1715 extras, 0 /*flags*/, null /*targetPackage*/, 1716 null /*finishedReceiver*/, firstUsers); 1717 1718 // Send added for users that don't see the package for the first time 1719 if (update) { 1720 extras.putBoolean(Intent.EXTRA_REPLACING, true); 1721 } 1722 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, 1723 extras, 0 /*flags*/, null /*targetPackage*/, 1724 null /*finishedReceiver*/, updateUsers); 1725 1726 // Send replaced for users that don't see the package for the first time 1727 if (update) { 1728 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, 1729 packageName, extras, 0 /*flags*/, 1730 null /*targetPackage*/, null /*finishedReceiver*/, 1731 updateUsers); 1732 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, 1733 null /*package*/, null /*extras*/, 0 /*flags*/, 1734 packageName /*targetPackage*/, 1735 null /*finishedReceiver*/, updateUsers); 1736 } 1737 1738 // Send broadcast package appeared if forward locked/external for all users 1739 // treat asec-hosted packages like removable media on upgrade 1740 if (res.pkg.isForwardLocked() || isExternal(res.pkg)) { 1741 if (DEBUG_INSTALL) { 1742 Slog.i(TAG, "upgrading pkg " + res.pkg 1743 + " is ASEC-hosted -> AVAILABLE"); 1744 } 1745 final int[] uidArray = new int[]{res.pkg.applicationInfo.uid}; 1746 ArrayList<String> pkgList = new ArrayList<>(1); 1747 pkgList.add(packageName); 1748 sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null); 1749 } 1750 } 1751 1752 // Work that needs to happen on first install within each user 1753 if (firstUsers != null && firstUsers.length > 0) { 1754 synchronized (mPackages) { 1755 for (int userId : firstUsers) { 1756 // If this app is a browser and it's newly-installed for some 1757 // users, clear any default-browser state in those users. The 1758 // app's nature doesn't depend on the user, so we can just check 1759 // its browser nature in any user and generalize. 1760 if (packageIsBrowser(packageName, userId)) { 1761 mSettings.setDefaultBrowserPackageNameLPw(null, userId); 1762 } 1763 1764 // We may also need to apply pending (restored) runtime 1765 // permission grants within these users. 1766 mSettings.applyPendingPermissionGrantsLPw(packageName, userId); 1767 } 1768 } 1769 } 1770 1771 // Log current value of "unknown sources" setting 1772 EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED, 1773 getUnknownSourcesSettings()); 1774 1775 // Force a gc to clear up things 1776 Runtime.getRuntime().gc(); 1777 1778 // Remove the replaced package's older resources safely now 1779 // We delete after a gc for applications on sdcard. 1780 if (res.removedInfo != null && res.removedInfo.args != null) { 1781 synchronized (mInstallLock) { 1782 res.removedInfo.args.doPostDeleteLI(true); 1783 } 1784 } 1785 } 1786 1787 // If someone is watching installs - notify them 1788 if (installObserver != null) { 1789 try { 1790 Bundle extras = extrasForInstallResult(res); 1791 installObserver.onPackageInstalled(res.name, res.returnCode, 1792 res.returnMsg, extras); 1793 } catch (RemoteException e) { 1794 Slog.i(TAG, "Observer no longer exists."); 1795 } 1796 } 1797 } 1798 1799 private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw( 1800 PackageParser.Package pkg) { 1801 if (pkg.parentPackage == null) { 1802 return; 1803 } 1804 if (pkg.requestedPermissions == null) { 1805 return; 1806 } 1807 final PackageSetting disabledSysParentPs = mSettings 1808 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName); 1809 if (disabledSysParentPs == null || disabledSysParentPs.pkg == null 1810 || !disabledSysParentPs.isPrivileged() 1811 || (disabledSysParentPs.childPackageNames != null 1812 && !disabledSysParentPs.childPackageNames.isEmpty())) { 1813 return; 1814 } 1815 final int[] allUserIds = sUserManager.getUserIds(); 1816 final int permCount = pkg.requestedPermissions.size(); 1817 for (int i = 0; i < permCount; i++) { 1818 String permission = pkg.requestedPermissions.get(i); 1819 BasePermission bp = mSettings.mPermissions.get(permission); 1820 if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) { 1821 continue; 1822 } 1823 for (int userId : allUserIds) { 1824 if (disabledSysParentPs.getPermissionsState().hasRuntimePermission( 1825 permission, userId)) { 1826 grantRuntimePermission(pkg.packageName, permission, userId); 1827 } 1828 } 1829 } 1830 } 1831 1832 private StorageEventListener mStorageListener = new StorageEventListener() { 1833 @Override 1834 public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) { 1835 if (vol.type == VolumeInfo.TYPE_PRIVATE) { 1836 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1837 final String volumeUuid = vol.getFsUuid(); 1838 1839 // Clean up any users or apps that were removed or recreated 1840 // while this volume was missing 1841 reconcileUsers(volumeUuid); 1842 reconcileApps(volumeUuid); 1843 1844 // Clean up any install sessions that expired or were 1845 // cancelled while this volume was missing 1846 mInstallerService.onPrivateVolumeMounted(volumeUuid); 1847 1848 loadPrivatePackages(vol); 1849 1850 } else if (vol.state == VolumeInfo.STATE_EJECTING) { 1851 unloadPrivatePackages(vol); 1852 } 1853 } 1854 1855 if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) { 1856 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1857 updateExternalMediaStatus(true, false); 1858 } else if (vol.state == VolumeInfo.STATE_EJECTING) { 1859 updateExternalMediaStatus(false, false); 1860 } 1861 } 1862 } 1863 1864 @Override 1865 public void onVolumeForgotten(String fsUuid) { 1866 if (TextUtils.isEmpty(fsUuid)) { 1867 Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring"); 1868 return; 1869 } 1870 1871 // Remove any apps installed on the forgotten volume 1872 synchronized (mPackages) { 1873 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid); 1874 for (PackageSetting ps : packages) { 1875 Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten"); 1876 deletePackage(ps.name, new LegacyPackageDeleteObserver(null).getBinder(), 1877 UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS); 1878 } 1879 1880 mSettings.onVolumeForgotten(fsUuid); 1881 mSettings.writeLPr(); 1882 } 1883 } 1884 }; 1885 1886 private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds, 1887 String[] grantedPermissions) { 1888 for (int userId : userIds) { 1889 grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions); 1890 } 1891 1892 // We could have touched GID membership, so flush out packages.list 1893 synchronized (mPackages) { 1894 mSettings.writePackageListLPr(); 1895 } 1896 } 1897 1898 private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId, 1899 String[] grantedPermissions) { 1900 SettingBase sb = (SettingBase) pkg.mExtras; 1901 if (sb == null) { 1902 return; 1903 } 1904 1905 PermissionsState permissionsState = sb.getPermissionsState(); 1906 1907 final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 1908 | PackageManager.FLAG_PERMISSION_POLICY_FIXED; 1909 1910 synchronized (mPackages) { 1911 for (String permission : pkg.requestedPermissions) { 1912 BasePermission bp = mSettings.mPermissions.get(permission); 1913 if (bp != null && (bp.isRuntime() || bp.isDevelopment()) 1914 && (grantedPermissions == null 1915 || ArrayUtils.contains(grantedPermissions, permission))) { 1916 final int flags = permissionsState.getPermissionFlags(permission, userId); 1917 // Installer cannot change immutable permissions. 1918 if ((flags & immutableFlags) == 0) { 1919 grantRuntimePermission(pkg.packageName, permission, userId); 1920 } 1921 } 1922 } 1923 } 1924 } 1925 1926 Bundle extrasForInstallResult(PackageInstalledInfo res) { 1927 Bundle extras = null; 1928 switch (res.returnCode) { 1929 case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: { 1930 extras = new Bundle(); 1931 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION, 1932 res.origPermission); 1933 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE, 1934 res.origPackage); 1935 break; 1936 } 1937 case PackageManager.INSTALL_SUCCEEDED: { 1938 extras = new Bundle(); 1939 extras.putBoolean(Intent.EXTRA_REPLACING, 1940 res.removedInfo != null && res.removedInfo.removedPackage != null); 1941 break; 1942 } 1943 } 1944 return extras; 1945 } 1946 1947 void scheduleWriteSettingsLocked() { 1948 if (!mHandler.hasMessages(WRITE_SETTINGS)) { 1949 mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY); 1950 } 1951 } 1952 1953 void scheduleWritePackageRestrictionsLocked(UserHandle user) { 1954 final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier(); 1955 scheduleWritePackageRestrictionsLocked(userId); 1956 } 1957 1958 void scheduleWritePackageRestrictionsLocked(int userId) { 1959 final int[] userIds = (userId == UserHandle.USER_ALL) 1960 ? sUserManager.getUserIds() : new int[]{userId}; 1961 for (int nextUserId : userIds) { 1962 if (!sUserManager.exists(nextUserId)) return; 1963 mDirtyUsers.add(nextUserId); 1964 if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) { 1965 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY); 1966 } 1967 } 1968 } 1969 1970 public static PackageManagerService main(Context context, Installer installer, 1971 boolean factoryTest, boolean onlyCore) { 1972 // Self-check for initial settings. 1973 PackageManagerServiceCompilerMapping.checkProperties(); 1974 1975 PackageManagerService m = new PackageManagerService(context, installer, 1976 factoryTest, onlyCore); 1977 m.enableSystemUserPackages(); 1978 ServiceManager.addService("package", m); 1979 return m; 1980 } 1981 1982 private void enableSystemUserPackages() { 1983 if (!UserManager.isSplitSystemUser()) { 1984 return; 1985 } 1986 // For system user, enable apps based on the following conditions: 1987 // - app is whitelisted or belong to one of these groups: 1988 // -- system app which has no launcher icons 1989 // -- system app which has INTERACT_ACROSS_USERS permission 1990 // -- system IME app 1991 // - app is not in the blacklist 1992 AppsQueryHelper queryHelper = new AppsQueryHelper(this); 1993 Set<String> enableApps = new ArraySet<>(); 1994 enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS 1995 | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM 1996 | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM)); 1997 ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps(); 1998 enableApps.addAll(wlApps); 1999 enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER, 2000 /* systemAppsOnly */ false, UserHandle.SYSTEM)); 2001 ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps(); 2002 enableApps.removeAll(blApps); 2003 Log.i(TAG, "Applications installed for system user: " + enableApps); 2004 List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false, 2005 UserHandle.SYSTEM); 2006 final int allAppsSize = allAps.size(); 2007 synchronized (mPackages) { 2008 for (int i = 0; i < allAppsSize; i++) { 2009 String pName = allAps.get(i); 2010 PackageSetting pkgSetting = mSettings.mPackages.get(pName); 2011 // Should not happen, but we shouldn't be failing if it does 2012 if (pkgSetting == null) { 2013 continue; 2014 } 2015 boolean install = enableApps.contains(pName); 2016 if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) { 2017 Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName 2018 + " for system user"); 2019 pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM); 2020 } 2021 } 2022 } 2023 } 2024 2025 private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) { 2026 DisplayManager displayManager = (DisplayManager) context.getSystemService( 2027 Context.DISPLAY_SERVICE); 2028 displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics); 2029 } 2030 2031 public PackageManagerService(Context context, Installer installer, 2032 boolean factoryTest, boolean onlyCore) { 2033 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START, 2034 SystemClock.uptimeMillis()); 2035 2036 if (mSdkVersion <= 0) { 2037 Slog.w(TAG, "**** ro.build.version.sdk not set!"); 2038 } 2039 2040 mContext = context; 2041 mFactoryTest = factoryTest; 2042 mOnlyCore = onlyCore; 2043 mMetrics = new DisplayMetrics(); 2044 mSettings = new Settings(mPackages); 2045 mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID, 2046 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2047 mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, 2048 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2049 mSettings.addSharedUserLPw("android.uid.log", LOG_UID, 2050 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2051 mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, 2052 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2053 mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID, 2054 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2055 mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID, 2056 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2057 2058 String separateProcesses = SystemProperties.get("debug.separate_processes"); 2059 if (separateProcesses != null && separateProcesses.length() > 0) { 2060 if ("*".equals(separateProcesses)) { 2061 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES; 2062 mSeparateProcesses = null; 2063 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)"); 2064 } else { 2065 mDefParseFlags = 0; 2066 mSeparateProcesses = separateProcesses.split(","); 2067 Slog.w(TAG, "Running with debug.separate_processes: " 2068 + separateProcesses); 2069 } 2070 } else { 2071 mDefParseFlags = 0; 2072 mSeparateProcesses = null; 2073 } 2074 2075 mInstaller = installer; 2076 mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context, 2077 "*dexopt*"); 2078 mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper()); 2079 2080 mOnPermissionChangeListeners = new OnPermissionChangeListeners( 2081 FgThread.get().getLooper()); 2082 2083 getDefaultDisplayMetrics(context, mMetrics); 2084 2085 SystemConfig systemConfig = SystemConfig.getInstance(); 2086 mGlobalGids = systemConfig.getGlobalGids(); 2087 mSystemPermissions = systemConfig.getSystemPermissions(); 2088 mAvailableFeatures = systemConfig.getAvailableFeatures(); 2089 2090 synchronized (mInstallLock) { 2091 // writer 2092 synchronized (mPackages) { 2093 mHandlerThread = new ServiceThread(TAG, 2094 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/); 2095 mHandlerThread.start(); 2096 mHandler = new PackageHandler(mHandlerThread.getLooper()); 2097 Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT); 2098 2099 File dataDir = Environment.getDataDirectory(); 2100 mAppInstallDir = new File(dataDir, "app"); 2101 mAppLib32InstallDir = new File(dataDir, "app-lib"); 2102 mEphemeralInstallDir = new File(dataDir, "app-ephemeral"); 2103 mAsecInternalPath = new File(dataDir, "app-asec").getPath(); 2104 mDrmAppPrivateInstallDir = new File(dataDir, "app-private"); 2105 2106 sUserManager = new UserManagerService(context, this, mPackages); 2107 2108 // Propagate permission configuration in to package manager. 2109 ArrayMap<String, SystemConfig.PermissionEntry> permConfig 2110 = systemConfig.getPermissions(); 2111 for (int i=0; i<permConfig.size(); i++) { 2112 SystemConfig.PermissionEntry perm = permConfig.valueAt(i); 2113 BasePermission bp = mSettings.mPermissions.get(perm.name); 2114 if (bp == null) { 2115 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN); 2116 mSettings.mPermissions.put(perm.name, bp); 2117 } 2118 if (perm.gids != null) { 2119 bp.setGids(perm.gids, perm.perUser); 2120 } 2121 } 2122 2123 ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries(); 2124 for (int i=0; i<libConfig.size(); i++) { 2125 mSharedLibraries.put(libConfig.keyAt(i), 2126 new SharedLibraryEntry(libConfig.valueAt(i), null)); 2127 } 2128 2129 mFoundPolicyFile = SELinuxMMAC.readInstallPolicy(); 2130 2131 mRestoredSettings = mSettings.readLPw(sUserManager.getUsers(false)); 2132 2133 String customResolverActivity = Resources.getSystem().getString( 2134 R.string.config_customResolverActivity); 2135 if (TextUtils.isEmpty(customResolverActivity)) { 2136 customResolverActivity = null; 2137 } else { 2138 mCustomResolverComponentName = ComponentName.unflattenFromString( 2139 customResolverActivity); 2140 } 2141 2142 long startTime = SystemClock.uptimeMillis(); 2143 2144 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START, 2145 startTime); 2146 2147 // Set flag to monitor and not change apk file paths when 2148 // scanning install directories. 2149 final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING | SCAN_INITIAL; 2150 2151 final String bootClassPath = System.getenv("BOOTCLASSPATH"); 2152 final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH"); 2153 2154 if (bootClassPath == null) { 2155 Slog.w(TAG, "No BOOTCLASSPATH found!"); 2156 } 2157 2158 if (systemServerClassPath == null) { 2159 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!"); 2160 } 2161 2162 final List<String> allInstructionSets = InstructionSets.getAllInstructionSets(); 2163 final String[] dexCodeInstructionSets = 2164 getDexCodeInstructionSets( 2165 allInstructionSets.toArray(new String[allInstructionSets.size()])); 2166 2167 /** 2168 * Ensure all external libraries have had dexopt run on them. 2169 */ 2170 if (mSharedLibraries.size() > 0) { 2171 // NOTE: For now, we're compiling these system "shared libraries" 2172 // (and framework jars) into all available architectures. It's possible 2173 // to compile them only when we come across an app that uses them (there's 2174 // already logic for that in scanPackageLI) but that adds some complexity. 2175 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 2176 for (SharedLibraryEntry libEntry : mSharedLibraries.values()) { 2177 final String lib = libEntry.path; 2178 if (lib == null) { 2179 continue; 2180 } 2181 2182 try { 2183 // Shared libraries do not have profiles so we perform a full 2184 // AOT compilation (if needed). 2185 int dexoptNeeded = DexFile.getDexOptNeeded( 2186 lib, dexCodeInstructionSet, 2187 getCompilerFilterForReason(REASON_SHARED_APK), 2188 false /* newProfile */); 2189 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { 2190 mInstaller.dexopt(lib, Process.SYSTEM_UID, dexCodeInstructionSet, 2191 dexoptNeeded, DEXOPT_PUBLIC /*dexFlags*/, 2192 getCompilerFilterForReason(REASON_SHARED_APK), 2193 StorageManager.UUID_PRIVATE_INTERNAL); 2194 } 2195 } catch (FileNotFoundException e) { 2196 Slog.w(TAG, "Library not found: " + lib); 2197 } catch (IOException | InstallerException e) { 2198 Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? " 2199 + e.getMessage()); 2200 } 2201 } 2202 } 2203 } 2204 2205 File frameworkDir = new File(Environment.getRootDirectory(), "framework"); 2206 2207 final VersionInfo ver = mSettings.getInternalVersion(); 2208 mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint); 2209 // when upgrading from pre-M, promote system app permissions from install to runtime 2210 mPromoteSystemApps = 2211 mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1; 2212 2213 // save off the names of pre-existing system packages prior to scanning; we don't 2214 // want to automatically grant runtime permissions for new system apps 2215 if (mPromoteSystemApps) { 2216 Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator(); 2217 while (pkgSettingIter.hasNext()) { 2218 PackageSetting ps = pkgSettingIter.next(); 2219 if (isSystemApp(ps)) { 2220 mExistingSystemPackages.add(ps.name); 2221 } 2222 } 2223 } 2224 2225 // Collect vendor overlay packages. 2226 // (Do this before scanning any apps.) 2227 // For security and version matching reason, only consider 2228 // overlay packages if they reside in VENDOR_OVERLAY_DIR. 2229 File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR); 2230 scanDirTracedLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM 2231 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0); 2232 2233 // Find base frameworks (resource packages without code). 2234 scanDirTracedLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM 2235 | PackageParser.PARSE_IS_SYSTEM_DIR 2236 | PackageParser.PARSE_IS_PRIVILEGED, 2237 scanFlags | SCAN_NO_DEX, 0); 2238 2239 // Collected privileged system packages. 2240 final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app"); 2241 scanDirTracedLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM 2242 | PackageParser.PARSE_IS_SYSTEM_DIR 2243 | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0); 2244 2245 // Collect ordinary system packages. 2246 final File systemAppDir = new File(Environment.getRootDirectory(), "app"); 2247 scanDirTracedLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM 2248 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2249 2250 // Collect all vendor packages. 2251 File vendorAppDir = new File("/vendor/app"); 2252 try { 2253 vendorAppDir = vendorAppDir.getCanonicalFile(); 2254 } catch (IOException e) { 2255 // failed to look up canonical path, continue with original one 2256 } 2257 scanDirTracedLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM 2258 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2259 2260 // Collect all OEM packages. 2261 final File oemAppDir = new File(Environment.getOemDirectory(), "app"); 2262 scanDirTracedLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM 2263 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2264 2265 // Prune any system packages that no longer exist. 2266 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>(); 2267 if (!mOnlyCore) { 2268 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 2269 while (psit.hasNext()) { 2270 PackageSetting ps = psit.next(); 2271 2272 /* 2273 * If this is not a system app, it can't be a 2274 * disable system app. 2275 */ 2276 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) { 2277 continue; 2278 } 2279 2280 /* 2281 * If the package is scanned, it's not erased. 2282 */ 2283 final PackageParser.Package scannedPkg = mPackages.get(ps.name); 2284 if (scannedPkg != null) { 2285 /* 2286 * If the system app is both scanned and in the 2287 * disabled packages list, then it must have been 2288 * added via OTA. Remove it from the currently 2289 * scanned package so the previously user-installed 2290 * application can be scanned. 2291 */ 2292 if (mSettings.isDisabledSystemPackageLPr(ps.name)) { 2293 logCriticalInfo(Log.WARN, "Expecting better updated system app for " 2294 + ps.name + "; removing system app. Last known codePath=" 2295 + ps.codePathString + ", installStatus=" + ps.installStatus 2296 + ", versionCode=" + ps.versionCode + "; scanned versionCode=" 2297 + scannedPkg.mVersionCode); 2298 removePackageLI(scannedPkg, true); 2299 mExpectingBetter.put(ps.name, ps.codePath); 2300 } 2301 2302 continue; 2303 } 2304 2305 if (!mSettings.isDisabledSystemPackageLPr(ps.name)) { 2306 psit.remove(); 2307 logCriticalInfo(Log.WARN, "System package " + ps.name 2308 + " no longer exists; wiping its data"); 2309 removeDataDirsLI(null, ps.name); 2310 } else { 2311 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name); 2312 if (disabledPs.codePath == null || !disabledPs.codePath.exists()) { 2313 possiblyDeletedUpdatedSystemApps.add(ps.name); 2314 } 2315 } 2316 } 2317 } 2318 2319 //look for any incomplete package installations 2320 ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr(); 2321 //clean up list 2322 for(int i = 0; i < deletePkgsList.size(); i++) { 2323 //clean up here 2324 cleanupInstallFailedPackage(deletePkgsList.get(i)); 2325 } 2326 //delete tmp files 2327 deleteTempPackageFiles(); 2328 2329 // Remove any shared userIDs that have no associated packages 2330 mSettings.pruneSharedUsersLPw(); 2331 2332 if (!mOnlyCore) { 2333 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START, 2334 SystemClock.uptimeMillis()); 2335 scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0); 2336 2337 scanDirTracedLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK, 2338 scanFlags | SCAN_REQUIRE_KNOWN, 0); 2339 2340 scanDirLI(mEphemeralInstallDir, PackageParser.PARSE_IS_EPHEMERAL, 2341 scanFlags | SCAN_REQUIRE_KNOWN, 0); 2342 2343 /** 2344 * Remove disable package settings for any updated system 2345 * apps that were removed via an OTA. If they're not a 2346 * previously-updated app, remove them completely. 2347 * Otherwise, just revoke their system-level permissions. 2348 */ 2349 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) { 2350 PackageParser.Package deletedPkg = mPackages.get(deletedAppName); 2351 mSettings.removeDisabledSystemPackageLPw(deletedAppName); 2352 2353 String msg; 2354 if (deletedPkg == null) { 2355 msg = "Updated system package " + deletedAppName 2356 + " no longer exists; wiping its data"; 2357 removeDataDirsLI(null, deletedAppName); 2358 } else { 2359 msg = "Updated system app + " + deletedAppName 2360 + " no longer present; removing system privileges for " 2361 + deletedAppName; 2362 2363 deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM; 2364 2365 PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName); 2366 deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM; 2367 } 2368 logCriticalInfo(Log.WARN, msg); 2369 } 2370 2371 /** 2372 * Make sure all system apps that we expected to appear on 2373 * the userdata partition actually showed up. If they never 2374 * appeared, crawl back and revive the system version. 2375 */ 2376 for (int i = 0; i < mExpectingBetter.size(); i++) { 2377 final String packageName = mExpectingBetter.keyAt(i); 2378 if (!mPackages.containsKey(packageName)) { 2379 final File scanFile = mExpectingBetter.valueAt(i); 2380 2381 logCriticalInfo(Log.WARN, "Expected better " + packageName 2382 + " but never showed up; reverting to system"); 2383 2384 final int reparseFlags; 2385 if (FileUtils.contains(privilegedAppDir, scanFile)) { 2386 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2387 | PackageParser.PARSE_IS_SYSTEM_DIR 2388 | PackageParser.PARSE_IS_PRIVILEGED; 2389 } else if (FileUtils.contains(systemAppDir, scanFile)) { 2390 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2391 | PackageParser.PARSE_IS_SYSTEM_DIR; 2392 } else if (FileUtils.contains(vendorAppDir, scanFile)) { 2393 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2394 | PackageParser.PARSE_IS_SYSTEM_DIR; 2395 } else if (FileUtils.contains(oemAppDir, scanFile)) { 2396 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2397 | PackageParser.PARSE_IS_SYSTEM_DIR; 2398 } else { 2399 Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile); 2400 continue; 2401 } 2402 2403 mSettings.enableSystemPackageLPw(packageName); 2404 2405 try { 2406 scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null); 2407 } catch (PackageManagerException e) { 2408 Slog.e(TAG, "Failed to parse original system package: " 2409 + e.getMessage()); 2410 } 2411 } 2412 } 2413 } 2414 mExpectingBetter.clear(); 2415 2416 // Now that we know all of the shared libraries, update all clients to have 2417 // the correct library paths. 2418 updateAllSharedLibrariesLPw(); 2419 2420 for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) { 2421 // NOTE: We ignore potential failures here during a system scan (like 2422 // the rest of the commands above) because there's precious little we 2423 // can do about it. A settings error is reported, though. 2424 adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */, 2425 false /* boot complete */); 2426 } 2427 2428 // Now that we know all the packages we are keeping, 2429 // read and update their last usage times. 2430 mPackageUsage.readLP(); 2431 2432 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END, 2433 SystemClock.uptimeMillis()); 2434 Slog.i(TAG, "Time to scan packages: " 2435 + ((SystemClock.uptimeMillis()-startTime)/1000f) 2436 + " seconds"); 2437 2438 // If the platform SDK has changed since the last time we booted, 2439 // we need to re-grant app permission to catch any new ones that 2440 // appear. This is really a hack, and means that apps can in some 2441 // cases get permissions that the user didn't initially explicitly 2442 // allow... it would be nice to have some better way to handle 2443 // this situation. 2444 int updateFlags = UPDATE_PERMISSIONS_ALL; 2445 if (ver.sdkVersion != mSdkVersion) { 2446 Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to " 2447 + mSdkVersion + "; regranting permissions for internal storage"); 2448 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 2449 } 2450 updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags); 2451 ver.sdkVersion = mSdkVersion; 2452 2453 // If this is the first boot or an update from pre-M, and it is a normal 2454 // boot, then we need to initialize the default preferred apps across 2455 // all defined users. 2456 if (!onlyCore && (mPromoteSystemApps || !mRestoredSettings)) { 2457 for (UserInfo user : sUserManager.getUsers(true)) { 2458 mSettings.applyDefaultPreferredAppsLPw(this, user.id); 2459 applyFactoryDefaultBrowserLPw(user.id); 2460 primeDomainVerificationsLPw(user.id); 2461 } 2462 } 2463 2464 // Prepare storage for system user really early during boot, 2465 // since core system apps like SettingsProvider and SystemUI 2466 // can't wait for user to start 2467 final int storageFlags; 2468 if (StorageManager.isFileEncryptedNativeOrEmulated()) { 2469 storageFlags = StorageManager.FLAG_STORAGE_DE; 2470 } else { 2471 storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 2472 } 2473 reconcileAppsData(StorageManager.UUID_PRIVATE_INTERNAL, UserHandle.USER_SYSTEM, 2474 storageFlags); 2475 2476 // If this is first boot after an OTA, and a normal boot, then 2477 // we need to clear code cache directories. 2478 if (mIsUpgrade && !onlyCore) { 2479 Slog.i(TAG, "Build fingerprint changed; clearing code caches"); 2480 for (int i = 0; i < mSettings.mPackages.size(); i++) { 2481 final PackageSetting ps = mSettings.mPackages.valueAt(i); 2482 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) { 2483 deleteCodeCacheDirsLI(ps.volumeUuid, ps.name); 2484 } 2485 } 2486 ver.fingerprint = Build.FINGERPRINT; 2487 } 2488 2489 checkDefaultBrowser(); 2490 2491 // clear only after permissions and other defaults have been updated 2492 mExistingSystemPackages.clear(); 2493 mPromoteSystemApps = false; 2494 2495 // All the changes are done during package scanning. 2496 ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION; 2497 2498 // can downgrade to reader 2499 mSettings.writeLPr(); 2500 2501 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY, 2502 SystemClock.uptimeMillis()); 2503 2504 if (!mOnlyCore) { 2505 mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr(); 2506 mRequiredInstallerPackage = getRequiredInstallerLPr(); 2507 mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr(); 2508 mIntentFilterVerifier = new IntentVerifierProxy(mContext, 2509 mIntentFilterVerifierComponent); 2510 } else { 2511 mRequiredVerifierPackage = null; 2512 mRequiredInstallerPackage = null; 2513 mIntentFilterVerifierComponent = null; 2514 mIntentFilterVerifier = null; 2515 } 2516 2517 mInstallerService = new PackageInstallerService(context, this); 2518 2519 final ComponentName ephemeralResolverComponent = getEphemeralResolverLPr(); 2520 final ComponentName ephemeralInstallerComponent = getEphemeralInstallerLPr(); 2521 // both the installer and resolver must be present to enable ephemeral 2522 if (ephemeralInstallerComponent != null && ephemeralResolverComponent != null) { 2523 if (DEBUG_EPHEMERAL) { 2524 Slog.i(TAG, "Ephemeral activated; resolver: " + ephemeralResolverComponent 2525 + " installer:" + ephemeralInstallerComponent); 2526 } 2527 mEphemeralResolverComponent = ephemeralResolverComponent; 2528 mEphemeralInstallerComponent = ephemeralInstallerComponent; 2529 setUpEphemeralInstallerActivityLP(mEphemeralInstallerComponent); 2530 mEphemeralResolverConnection = 2531 new EphemeralResolverConnection(mContext, mEphemeralResolverComponent); 2532 } else { 2533 if (DEBUG_EPHEMERAL) { 2534 final String missingComponent = 2535 (ephemeralResolverComponent == null) 2536 ? (ephemeralInstallerComponent == null) 2537 ? "resolver and installer" 2538 : "resolver" 2539 : "installer"; 2540 Slog.i(TAG, "Ephemeral deactivated; missing " + missingComponent); 2541 } 2542 mEphemeralResolverComponent = null; 2543 mEphemeralInstallerComponent = null; 2544 mEphemeralResolverConnection = null; 2545 } 2546 2547 mEphemeralApplicationRegistry = new EphemeralApplicationRegistry(this); 2548 } // synchronized (mPackages) 2549 } // synchronized (mInstallLock) 2550 2551 // Now after opening every single application zip, make sure they 2552 // are all flushed. Not really needed, but keeps things nice and 2553 // tidy. 2554 Runtime.getRuntime().gc(); 2555 2556 // The initial scanning above does many calls into installd while 2557 // holding the mPackages lock, but we're mostly interested in yelling 2558 // once we have a booted system. 2559 mInstaller.setWarnIfHeld(mPackages); 2560 2561 // Expose private service for system components to use. 2562 LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl()); 2563 } 2564 2565 @Override 2566 public boolean isFirstBoot() { 2567 return !mRestoredSettings; 2568 } 2569 2570 @Override 2571 public boolean isOnlyCoreApps() { 2572 return mOnlyCore; 2573 } 2574 2575 @Override 2576 public boolean isUpgrade() { 2577 return mIsUpgrade; 2578 } 2579 2580 private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() { 2581 final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 2582 2583 final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE, 2584 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 2585 UserHandle.USER_SYSTEM); 2586 if (matches.size() == 1) { 2587 return matches.get(0).getComponentInfo().packageName; 2588 } else { 2589 Log.e(TAG, "There should probably be exactly one verifier; found " + matches); 2590 return null; 2591 } 2592 } 2593 2594 private @NonNull String getRequiredInstallerLPr() { 2595 final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE); 2596 intent.addCategory(Intent.CATEGORY_DEFAULT); 2597 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE); 2598 2599 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE, 2600 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 2601 UserHandle.USER_SYSTEM); 2602 if (matches.size() == 1) { 2603 return matches.get(0).getComponentInfo().packageName; 2604 } else { 2605 throw new RuntimeException("There must be exactly one installer; found " + matches); 2606 } 2607 } 2608 2609 private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() { 2610 final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 2611 2612 final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE, 2613 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 2614 UserHandle.USER_SYSTEM); 2615 ResolveInfo best = null; 2616 final int N = matches.size(); 2617 for (int i = 0; i < N; i++) { 2618 final ResolveInfo cur = matches.get(i); 2619 final String packageName = cur.getComponentInfo().packageName; 2620 if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 2621 packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) { 2622 continue; 2623 } 2624 2625 if (best == null || cur.priority > best.priority) { 2626 best = cur; 2627 } 2628 } 2629 2630 if (best != null) { 2631 return best.getComponentInfo().getComponentName(); 2632 } else { 2633 throw new RuntimeException("There must be at least one intent filter verifier"); 2634 } 2635 } 2636 2637 private @Nullable ComponentName getEphemeralResolverLPr() { 2638 final String[] packageArray = 2639 mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage); 2640 if (packageArray.length == 0) { 2641 if (DEBUG_EPHEMERAL) { 2642 Slog.d(TAG, "Ephemeral resolver NOT found; empty package list"); 2643 } 2644 return null; 2645 } 2646 2647 final Intent resolverIntent = new Intent(Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE); 2648 final List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null, 2649 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 2650 UserHandle.USER_SYSTEM); 2651 2652 final int N = resolvers.size(); 2653 if (N == 0) { 2654 if (DEBUG_EPHEMERAL) { 2655 Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters"); 2656 } 2657 return null; 2658 } 2659 2660 final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray)); 2661 for (int i = 0; i < N; i++) { 2662 final ResolveInfo info = resolvers.get(i); 2663 2664 if (info.serviceInfo == null) { 2665 continue; 2666 } 2667 2668 final String packageName = info.serviceInfo.packageName; 2669 if (!possiblePackages.contains(packageName)) { 2670 if (DEBUG_EPHEMERAL) { 2671 Slog.d(TAG, "Ephemeral resolver not in allowed package list;" 2672 + " pkg: " + packageName + ", info:" + info); 2673 } 2674 continue; 2675 } 2676 2677 if (DEBUG_EPHEMERAL) { 2678 Slog.v(TAG, "Ephemeral resolver found;" 2679 + " pkg: " + packageName + ", info:" + info); 2680 } 2681 return new ComponentName(packageName, info.serviceInfo.name); 2682 } 2683 if (DEBUG_EPHEMERAL) { 2684 Slog.v(TAG, "Ephemeral resolver NOT found"); 2685 } 2686 return null; 2687 } 2688 2689 private @Nullable ComponentName getEphemeralInstallerLPr() { 2690 final Intent intent = new Intent(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE); 2691 intent.addCategory(Intent.CATEGORY_DEFAULT); 2692 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE); 2693 2694 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE, 2695 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 2696 UserHandle.USER_SYSTEM); 2697 if (matches.size() == 0) { 2698 return null; 2699 } else if (matches.size() == 1) { 2700 return matches.get(0).getComponentInfo().getComponentName(); 2701 } else { 2702 throw new RuntimeException( 2703 "There must be at most one ephemeral installer; found " + matches); 2704 } 2705 } 2706 2707 private void primeDomainVerificationsLPw(int userId) { 2708 if (DEBUG_DOMAIN_VERIFICATION) { 2709 Slog.d(TAG, "Priming domain verifications in user " + userId); 2710 } 2711 2712 SystemConfig systemConfig = SystemConfig.getInstance(); 2713 ArraySet<String> packages = systemConfig.getLinkedApps(); 2714 ArraySet<String> domains = new ArraySet<String>(); 2715 2716 for (String packageName : packages) { 2717 PackageParser.Package pkg = mPackages.get(packageName); 2718 if (pkg != null) { 2719 if (!pkg.isSystemApp()) { 2720 Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>"); 2721 continue; 2722 } 2723 2724 domains.clear(); 2725 for (PackageParser.Activity a : pkg.activities) { 2726 for (ActivityIntentInfo filter : a.intents) { 2727 if (hasValidDomains(filter)) { 2728 domains.addAll(filter.getHostsList()); 2729 } 2730 } 2731 } 2732 2733 if (domains.size() > 0) { 2734 if (DEBUG_DOMAIN_VERIFICATION) { 2735 Slog.v(TAG, " + " + packageName); 2736 } 2737 // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual 2738 // state w.r.t. the formal app-linkage "no verification attempted" state; 2739 // and then 'always' in the per-user state actually used for intent resolution. 2740 final IntentFilterVerificationInfo ivi; 2741 ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, 2742 new ArrayList<String>(domains)); 2743 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED); 2744 mSettings.updateIntentFilterVerificationStatusLPw(packageName, 2745 INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId); 2746 } else { 2747 Slog.w(TAG, "Sysconfig <app-link> package '" + packageName 2748 + "' does not handle web links"); 2749 } 2750 } else { 2751 Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>"); 2752 } 2753 } 2754 2755 scheduleWritePackageRestrictionsLocked(userId); 2756 scheduleWriteSettingsLocked(); 2757 } 2758 2759 private void applyFactoryDefaultBrowserLPw(int userId) { 2760 // The default browser app's package name is stored in a string resource, 2761 // with a product-specific overlay used for vendor customization. 2762 String browserPkg = mContext.getResources().getString( 2763 com.android.internal.R.string.default_browser); 2764 if (!TextUtils.isEmpty(browserPkg)) { 2765 // non-empty string => required to be a known package 2766 PackageSetting ps = mSettings.mPackages.get(browserPkg); 2767 if (ps == null) { 2768 Slog.e(TAG, "Product default browser app does not exist: " + browserPkg); 2769 browserPkg = null; 2770 } else { 2771 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId); 2772 } 2773 } 2774 2775 // Nothing valid explicitly set? Make the factory-installed browser the explicit 2776 // default. If there's more than one, just leave everything alone. 2777 if (browserPkg == null) { 2778 calculateDefaultBrowserLPw(userId); 2779 } 2780 } 2781 2782 private void calculateDefaultBrowserLPw(int userId) { 2783 List<String> allBrowsers = resolveAllBrowserApps(userId); 2784 final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null; 2785 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId); 2786 } 2787 2788 private List<String> resolveAllBrowserApps(int userId) { 2789 // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set 2790 List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null, 2791 PackageManager.MATCH_ALL, userId); 2792 2793 final int count = list.size(); 2794 List<String> result = new ArrayList<String>(count); 2795 for (int i=0; i<count; i++) { 2796 ResolveInfo info = list.get(i); 2797 if (info.activityInfo == null 2798 || !info.handleAllWebDataURI 2799 || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0 2800 || result.contains(info.activityInfo.packageName)) { 2801 continue; 2802 } 2803 result.add(info.activityInfo.packageName); 2804 } 2805 2806 return result; 2807 } 2808 2809 private boolean packageIsBrowser(String packageName, int userId) { 2810 List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null, 2811 PackageManager.MATCH_ALL, userId); 2812 final int N = list.size(); 2813 for (int i = 0; i < N; i++) { 2814 ResolveInfo info = list.get(i); 2815 if (packageName.equals(info.activityInfo.packageName)) { 2816 return true; 2817 } 2818 } 2819 return false; 2820 } 2821 2822 private void checkDefaultBrowser() { 2823 final int myUserId = UserHandle.myUserId(); 2824 final String packageName = getDefaultBrowserPackageName(myUserId); 2825 if (packageName != null) { 2826 PackageInfo info = getPackageInfo(packageName, 0, myUserId); 2827 if (info == null) { 2828 Slog.w(TAG, "Default browser no longer installed: " + packageName); 2829 synchronized (mPackages) { 2830 applyFactoryDefaultBrowserLPw(myUserId); // leaves ambiguous when > 1 2831 } 2832 } 2833 } 2834 } 2835 2836 @Override 2837 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2838 throws RemoteException { 2839 try { 2840 return super.onTransact(code, data, reply, flags); 2841 } catch (RuntimeException e) { 2842 if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) { 2843 Slog.wtf(TAG, "Package Manager Crash", e); 2844 } 2845 throw e; 2846 } 2847 } 2848 2849 void cleanupInstallFailedPackage(PackageSetting ps) { 2850 logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + ps.name); 2851 2852 removeDataDirsLI(ps.volumeUuid, ps.name); 2853 if (ps.codePath != null) { 2854 removeCodePathLI(ps.codePath); 2855 } 2856 if (ps.resourcePath != null && !ps.resourcePath.equals(ps.codePath)) { 2857 if (ps.resourcePath.isDirectory()) { 2858 FileUtils.deleteContents(ps.resourcePath); 2859 } 2860 ps.resourcePath.delete(); 2861 } 2862 mSettings.removePackageLPw(ps.name); 2863 } 2864 2865 static int[] appendInts(int[] cur, int[] add) { 2866 if (add == null) return cur; 2867 if (cur == null) return add; 2868 final int N = add.length; 2869 for (int i=0; i<N; i++) { 2870 cur = appendInt(cur, add[i]); 2871 } 2872 return cur; 2873 } 2874 2875 PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) { 2876 if (!sUserManager.exists(userId)) return null; 2877 final PackageSetting ps = (PackageSetting) p.mExtras; 2878 if (ps == null) { 2879 return null; 2880 } 2881 2882 final PermissionsState permissionsState = ps.getPermissionsState(); 2883 2884 final int[] gids = permissionsState.computeGids(userId); 2885 final Set<String> permissions = permissionsState.getPermissions(userId); 2886 final PackageUserState state = ps.readUserState(userId); 2887 2888 return PackageParser.generatePackageInfo(p, gids, flags, 2889 ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId); 2890 } 2891 2892 @Override 2893 public void checkPackageStartable(String packageName, int userId) { 2894 final boolean userKeyUnlocked = isUserKeyUnlocked(userId); 2895 2896 synchronized (mPackages) { 2897 final PackageSetting ps = mSettings.mPackages.get(packageName); 2898 if (ps == null) { 2899 throw new SecurityException("Package " + packageName + " was not found!"); 2900 } 2901 2902 if (mSafeMode && !ps.isSystem()) { 2903 throw new SecurityException("Package " + packageName + " not a system app!"); 2904 } 2905 2906 if (ps.frozen) { 2907 throw new SecurityException("Package " + packageName + " is currently frozen!"); 2908 } 2909 2910 if (!userKeyUnlocked && !(ps.pkg.applicationInfo.isDirectBootAware() 2911 || ps.pkg.applicationInfo.isPartiallyDirectBootAware())) { 2912 throw new SecurityException("Package " + packageName + " is not encryption aware!"); 2913 } 2914 } 2915 } 2916 2917 @Override 2918 public boolean isPackageAvailable(String packageName, int userId) { 2919 if (!sUserManager.exists(userId)) return false; 2920 enforceCrossUserPermission(Binder.getCallingUid(), userId, 2921 false /* requireFullPermission */, false /* checkShell */, "is package available"); 2922 synchronized (mPackages) { 2923 PackageParser.Package p = mPackages.get(packageName); 2924 if (p != null) { 2925 final PackageSetting ps = (PackageSetting) p.mExtras; 2926 if (ps != null) { 2927 final PackageUserState state = ps.readUserState(userId); 2928 if (state != null) { 2929 return PackageParser.isAvailable(state); 2930 } 2931 } 2932 } 2933 } 2934 return false; 2935 } 2936 2937 @Override 2938 public PackageInfo getPackageInfo(String packageName, int flags, int userId) { 2939 if (!sUserManager.exists(userId)) return null; 2940 flags = updateFlagsForPackage(flags, userId, packageName); 2941 enforceCrossUserPermission(Binder.getCallingUid(), userId, 2942 false /* requireFullPermission */, false /* checkShell */, "get package info"); 2943 // reader 2944 synchronized (mPackages) { 2945 PackageParser.Package p = mPackages.get(packageName); 2946 if (DEBUG_PACKAGE_INFO) 2947 Log.v(TAG, "getPackageInfo " + packageName + ": " + p); 2948 if (p != null) { 2949 return generatePackageInfo(p, flags, userId); 2950 } 2951 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 2952 return generatePackageInfoFromSettingsLPw(packageName, flags, userId); 2953 } 2954 } 2955 return null; 2956 } 2957 2958 @Override 2959 public String[] currentToCanonicalPackageNames(String[] names) { 2960 String[] out = new String[names.length]; 2961 // reader 2962 synchronized (mPackages) { 2963 for (int i=names.length-1; i>=0; i--) { 2964 PackageSetting ps = mSettings.mPackages.get(names[i]); 2965 out[i] = ps != null && ps.realName != null ? ps.realName : names[i]; 2966 } 2967 } 2968 return out; 2969 } 2970 2971 @Override 2972 public String[] canonicalToCurrentPackageNames(String[] names) { 2973 String[] out = new String[names.length]; 2974 // reader 2975 synchronized (mPackages) { 2976 for (int i=names.length-1; i>=0; i--) { 2977 String cur = mSettings.mRenamedPackages.get(names[i]); 2978 out[i] = cur != null ? cur : names[i]; 2979 } 2980 } 2981 return out; 2982 } 2983 2984 @Override 2985 public int getPackageUid(String packageName, int flags, int userId) { 2986 if (!sUserManager.exists(userId)) return -1; 2987 flags = updateFlagsForPackage(flags, userId, packageName); 2988 enforceCrossUserPermission(Binder.getCallingUid(), userId, 2989 false /* requireFullPermission */, false /* checkShell */, "get package uid"); 2990 2991 // reader 2992 synchronized (mPackages) { 2993 final PackageParser.Package p = mPackages.get(packageName); 2994 if (p != null && p.isMatch(flags)) { 2995 return UserHandle.getUid(userId, p.applicationInfo.uid); 2996 } 2997 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 2998 final PackageSetting ps = mSettings.mPackages.get(packageName); 2999 if (ps != null && ps.isMatch(flags)) { 3000 return UserHandle.getUid(userId, ps.appId); 3001 } 3002 } 3003 } 3004 3005 return -1; 3006 } 3007 3008 @Override 3009 public int[] getPackageGids(String packageName, int flags, int userId) { 3010 if (!sUserManager.exists(userId)) return null; 3011 flags = updateFlagsForPackage(flags, userId, packageName); 3012 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3013 false /* requireFullPermission */, false /* checkShell */, 3014 "getPackageGids"); 3015 3016 // reader 3017 synchronized (mPackages) { 3018 final PackageParser.Package p = mPackages.get(packageName); 3019 if (p != null && p.isMatch(flags)) { 3020 PackageSetting ps = (PackageSetting) p.mExtras; 3021 return ps.getPermissionsState().computeGids(userId); 3022 } 3023 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 3024 final PackageSetting ps = mSettings.mPackages.get(packageName); 3025 if (ps != null && ps.isMatch(flags)) { 3026 return ps.getPermissionsState().computeGids(userId); 3027 } 3028 } 3029 } 3030 3031 return null; 3032 } 3033 3034 static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) { 3035 if (bp.perm != null) { 3036 return PackageParser.generatePermissionInfo(bp.perm, flags); 3037 } 3038 PermissionInfo pi = new PermissionInfo(); 3039 pi.name = bp.name; 3040 pi.packageName = bp.sourcePackage; 3041 pi.nonLocalizedLabel = bp.name; 3042 pi.protectionLevel = bp.protectionLevel; 3043 return pi; 3044 } 3045 3046 @Override 3047 public PermissionInfo getPermissionInfo(String name, int flags) { 3048 // reader 3049 synchronized (mPackages) { 3050 final BasePermission p = mSettings.mPermissions.get(name); 3051 if (p != null) { 3052 return generatePermissionInfo(p, flags); 3053 } 3054 return null; 3055 } 3056 } 3057 3058 @Override 3059 public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group, 3060 int flags) { 3061 // reader 3062 synchronized (mPackages) { 3063 if (group != null && !mPermissionGroups.containsKey(group)) { 3064 // This is thrown as NameNotFoundException 3065 return null; 3066 } 3067 3068 ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10); 3069 for (BasePermission p : mSettings.mPermissions.values()) { 3070 if (group == null) { 3071 if (p.perm == null || p.perm.info.group == null) { 3072 out.add(generatePermissionInfo(p, flags)); 3073 } 3074 } else { 3075 if (p.perm != null && group.equals(p.perm.info.group)) { 3076 out.add(PackageParser.generatePermissionInfo(p.perm, flags)); 3077 } 3078 } 3079 } 3080 return new ParceledListSlice<>(out); 3081 } 3082 } 3083 3084 @Override 3085 public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) { 3086 // reader 3087 synchronized (mPackages) { 3088 return PackageParser.generatePermissionGroupInfo( 3089 mPermissionGroups.get(name), flags); 3090 } 3091 } 3092 3093 @Override 3094 public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) { 3095 // reader 3096 synchronized (mPackages) { 3097 final int N = mPermissionGroups.size(); 3098 ArrayList<PermissionGroupInfo> out 3099 = new ArrayList<PermissionGroupInfo>(N); 3100 for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) { 3101 out.add(PackageParser.generatePermissionGroupInfo(pg, flags)); 3102 } 3103 return new ParceledListSlice<>(out); 3104 } 3105 } 3106 3107 private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags, 3108 int userId) { 3109 if (!sUserManager.exists(userId)) return null; 3110 PackageSetting ps = mSettings.mPackages.get(packageName); 3111 if (ps != null) { 3112 if (ps.pkg == null) { 3113 PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName, 3114 flags, userId); 3115 if (pInfo != null) { 3116 return pInfo.applicationInfo; 3117 } 3118 return null; 3119 } 3120 return PackageParser.generateApplicationInfo(ps.pkg, flags, 3121 ps.readUserState(userId), userId); 3122 } 3123 return null; 3124 } 3125 3126 private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags, 3127 int userId) { 3128 if (!sUserManager.exists(userId)) return null; 3129 PackageSetting ps = mSettings.mPackages.get(packageName); 3130 if (ps != null) { 3131 PackageParser.Package pkg = ps.pkg; 3132 if (pkg == null) { 3133 if ((flags & MATCH_UNINSTALLED_PACKAGES) == 0) { 3134 return null; 3135 } 3136 // Only data remains, so we aren't worried about code paths 3137 pkg = new PackageParser.Package(packageName); 3138 pkg.applicationInfo.packageName = packageName; 3139 pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY; 3140 pkg.applicationInfo.privateFlags = ps.pkgPrivateFlags; 3141 pkg.applicationInfo.uid = ps.appId; 3142 pkg.applicationInfo.initForUser(userId); 3143 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString; 3144 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString; 3145 } 3146 return generatePackageInfo(pkg, flags, userId); 3147 } 3148 return null; 3149 } 3150 3151 @Override 3152 public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) { 3153 if (!sUserManager.exists(userId)) return null; 3154 flags = updateFlagsForApplication(flags, userId, packageName); 3155 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3156 false /* requireFullPermission */, false /* checkShell */, "get application info"); 3157 // writer 3158 synchronized (mPackages) { 3159 PackageParser.Package p = mPackages.get(packageName); 3160 if (DEBUG_PACKAGE_INFO) Log.v( 3161 TAG, "getApplicationInfo " + packageName 3162 + ": " + p); 3163 if (p != null) { 3164 PackageSetting ps = mSettings.mPackages.get(packageName); 3165 if (ps == null) return null; 3166 // Note: isEnabledLP() does not apply here - always return info 3167 return PackageParser.generateApplicationInfo( 3168 p, flags, ps.readUserState(userId), userId); 3169 } 3170 if ("android".equals(packageName)||"system".equals(packageName)) { 3171 return mAndroidApplication; 3172 } 3173 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 3174 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId); 3175 } 3176 } 3177 return null; 3178 } 3179 3180 @Override 3181 public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize, 3182 final IPackageDataObserver observer) { 3183 mContext.enforceCallingOrSelfPermission( 3184 android.Manifest.permission.CLEAR_APP_CACHE, null); 3185 // Queue up an async operation since clearing cache may take a little while. 3186 mHandler.post(new Runnable() { 3187 public void run() { 3188 mHandler.removeCallbacks(this); 3189 boolean success = true; 3190 synchronized (mInstallLock) { 3191 try { 3192 mInstaller.freeCache(volumeUuid, freeStorageSize); 3193 } catch (InstallerException e) { 3194 Slog.w(TAG, "Couldn't clear application caches: " + e); 3195 success = false; 3196 } 3197 } 3198 if (observer != null) { 3199 try { 3200 observer.onRemoveCompleted(null, success); 3201 } catch (RemoteException e) { 3202 Slog.w(TAG, "RemoveException when invoking call back"); 3203 } 3204 } 3205 } 3206 }); 3207 } 3208 3209 @Override 3210 public void freeStorage(final String volumeUuid, final long freeStorageSize, 3211 final IntentSender pi) { 3212 mContext.enforceCallingOrSelfPermission( 3213 android.Manifest.permission.CLEAR_APP_CACHE, null); 3214 // Queue up an async operation since clearing cache may take a little while. 3215 mHandler.post(new Runnable() { 3216 public void run() { 3217 mHandler.removeCallbacks(this); 3218 boolean success = true; 3219 synchronized (mInstallLock) { 3220 try { 3221 mInstaller.freeCache(volumeUuid, freeStorageSize); 3222 } catch (InstallerException e) { 3223 Slog.w(TAG, "Couldn't clear application caches: " + e); 3224 success = false; 3225 } 3226 } 3227 if(pi != null) { 3228 try { 3229 // Callback via pending intent 3230 int code = success ? 1 : 0; 3231 pi.sendIntent(null, code, null, 3232 null, null); 3233 } catch (SendIntentException e1) { 3234 Slog.i(TAG, "Failed to send pending intent"); 3235 } 3236 } 3237 } 3238 }); 3239 } 3240 3241 void freeStorage(String volumeUuid, long freeStorageSize) throws IOException { 3242 synchronized (mInstallLock) { 3243 try { 3244 mInstaller.freeCache(volumeUuid, freeStorageSize); 3245 } catch (InstallerException e) { 3246 throw new IOException("Failed to free enough space", e); 3247 } 3248 } 3249 } 3250 3251 /** 3252 * Return if the user key is currently unlocked. 3253 */ 3254 private boolean isUserKeyUnlocked(int userId) { 3255 if (StorageManager.isFileEncryptedNativeOrEmulated()) { 3256 final IMountService mount = IMountService.Stub 3257 .asInterface(ServiceManager.getService("mount")); 3258 if (mount == null) { 3259 Slog.w(TAG, "Early during boot, assuming locked"); 3260 return false; 3261 } 3262 final long token = Binder.clearCallingIdentity(); 3263 try { 3264 return mount.isUserKeyUnlocked(userId); 3265 } catch (RemoteException e) { 3266 throw e.rethrowAsRuntimeException(); 3267 } finally { 3268 Binder.restoreCallingIdentity(token); 3269 } 3270 } else { 3271 return true; 3272 } 3273 } 3274 3275 /** 3276 * Update given flags based on encryption status of current user. 3277 */ 3278 private int updateFlags(int flags, int userId) { 3279 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE 3280 | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) { 3281 // Caller expressed an explicit opinion about what encryption 3282 // aware/unaware components they want to see, so fall through and 3283 // give them what they want 3284 } else { 3285 // Caller expressed no opinion, so match based on user state 3286 if (isUserKeyUnlocked(userId)) { 3287 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE; 3288 } else { 3289 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE; 3290 } 3291 } 3292 return flags; 3293 } 3294 3295 /** 3296 * Update given flags when being used to request {@link PackageInfo}. 3297 */ 3298 private int updateFlagsForPackage(int flags, int userId, Object cookie) { 3299 boolean triaged = true; 3300 if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS 3301 | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) { 3302 // Caller is asking for component details, so they'd better be 3303 // asking for specific encryption matching behavior, or be triaged 3304 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE 3305 | PackageManager.MATCH_DIRECT_BOOT_AWARE 3306 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3307 triaged = false; 3308 } 3309 } 3310 if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES 3311 | PackageManager.MATCH_SYSTEM_ONLY 3312 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3313 triaged = false; 3314 } 3315 if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) { 3316 Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie 3317 + " with flags 0x" + Integer.toHexString(flags), new Throwable()); 3318 } 3319 return updateFlags(flags, userId); 3320 } 3321 3322 /** 3323 * Update given flags when being used to request {@link ApplicationInfo}. 3324 */ 3325 private int updateFlagsForApplication(int flags, int userId, Object cookie) { 3326 return updateFlagsForPackage(flags, userId, cookie); 3327 } 3328 3329 /** 3330 * Update given flags when being used to request {@link ComponentInfo}. 3331 */ 3332 private int updateFlagsForComponent(int flags, int userId, Object cookie) { 3333 if (cookie instanceof Intent) { 3334 if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) { 3335 flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING; 3336 } 3337 } 3338 3339 boolean triaged = true; 3340 // Caller is asking for component details, so they'd better be 3341 // asking for specific encryption matching behavior, or be triaged 3342 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE 3343 | PackageManager.MATCH_DIRECT_BOOT_AWARE 3344 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3345 triaged = false; 3346 } 3347 if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) { 3348 Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie 3349 + " with flags 0x" + Integer.toHexString(flags), new Throwable()); 3350 } 3351 3352 return updateFlags(flags, userId); 3353 } 3354 3355 /** 3356 * Update given flags when being used to request {@link ResolveInfo}. 3357 */ 3358 int updateFlagsForResolve(int flags, int userId, Object cookie) { 3359 // Safe mode means we shouldn't match any third-party components 3360 if (mSafeMode) { 3361 flags |= PackageManager.MATCH_SYSTEM_ONLY; 3362 } 3363 3364 return updateFlagsForComponent(flags, userId, cookie); 3365 } 3366 3367 @Override 3368 public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) { 3369 if (!sUserManager.exists(userId)) return null; 3370 flags = updateFlagsForComponent(flags, userId, component); 3371 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3372 false /* requireFullPermission */, false /* checkShell */, "get activity info"); 3373 synchronized (mPackages) { 3374 PackageParser.Activity a = mActivities.mActivities.get(component); 3375 3376 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a); 3377 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) { 3378 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3379 if (ps == null) return null; 3380 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 3381 userId); 3382 } 3383 if (mResolveComponentName.equals(component)) { 3384 return PackageParser.generateActivityInfo(mResolveActivity, flags, 3385 new PackageUserState(), userId); 3386 } 3387 } 3388 return null; 3389 } 3390 3391 @Override 3392 public boolean activitySupportsIntent(ComponentName component, Intent intent, 3393 String resolvedType) { 3394 synchronized (mPackages) { 3395 if (component.equals(mResolveComponentName)) { 3396 // The resolver supports EVERYTHING! 3397 return true; 3398 } 3399 PackageParser.Activity a = mActivities.mActivities.get(component); 3400 if (a == null) { 3401 return false; 3402 } 3403 for (int i=0; i<a.intents.size(); i++) { 3404 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(), 3405 intent.getData(), intent.getCategories(), TAG) >= 0) { 3406 return true; 3407 } 3408 } 3409 return false; 3410 } 3411 } 3412 3413 @Override 3414 public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) { 3415 if (!sUserManager.exists(userId)) return null; 3416 flags = updateFlagsForComponent(flags, userId, component); 3417 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3418 false /* requireFullPermission */, false /* checkShell */, "get receiver info"); 3419 synchronized (mPackages) { 3420 PackageParser.Activity a = mReceivers.mActivities.get(component); 3421 if (DEBUG_PACKAGE_INFO) Log.v( 3422 TAG, "getReceiverInfo " + component + ": " + a); 3423 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) { 3424 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3425 if (ps == null) return null; 3426 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 3427 userId); 3428 } 3429 } 3430 return null; 3431 } 3432 3433 @Override 3434 public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) { 3435 if (!sUserManager.exists(userId)) return null; 3436 flags = updateFlagsForComponent(flags, userId, component); 3437 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3438 false /* requireFullPermission */, false /* checkShell */, "get service info"); 3439 synchronized (mPackages) { 3440 PackageParser.Service s = mServices.mServices.get(component); 3441 if (DEBUG_PACKAGE_INFO) Log.v( 3442 TAG, "getServiceInfo " + component + ": " + s); 3443 if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) { 3444 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3445 if (ps == null) return null; 3446 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId), 3447 userId); 3448 } 3449 } 3450 return null; 3451 } 3452 3453 @Override 3454 public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) { 3455 if (!sUserManager.exists(userId)) return null; 3456 flags = updateFlagsForComponent(flags, userId, component); 3457 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3458 false /* requireFullPermission */, false /* checkShell */, "get provider info"); 3459 synchronized (mPackages) { 3460 PackageParser.Provider p = mProviders.mProviders.get(component); 3461 if (DEBUG_PACKAGE_INFO) Log.v( 3462 TAG, "getProviderInfo " + component + ": " + p); 3463 if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) { 3464 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3465 if (ps == null) return null; 3466 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId), 3467 userId); 3468 } 3469 } 3470 return null; 3471 } 3472 3473 @Override 3474 public String[] getSystemSharedLibraryNames() { 3475 Set<String> libSet; 3476 synchronized (mPackages) { 3477 libSet = mSharedLibraries.keySet(); 3478 int size = libSet.size(); 3479 if (size > 0) { 3480 String[] libs = new String[size]; 3481 libSet.toArray(libs); 3482 return libs; 3483 } 3484 } 3485 return null; 3486 } 3487 3488 @Override 3489 public @Nullable String getServicesSystemSharedLibraryPackageName() { 3490 synchronized (mPackages) { 3491 SharedLibraryEntry libraryEntry = mSharedLibraries.get( 3492 PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES); 3493 if (libraryEntry != null) { 3494 return libraryEntry.apk; 3495 } 3496 } 3497 return null; 3498 } 3499 3500 @Override 3501 public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() { 3502 synchronized (mPackages) { 3503 final ArrayList<FeatureInfo> res = new ArrayList<>(mAvailableFeatures.values()); 3504 3505 final FeatureInfo fi = new FeatureInfo(); 3506 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version", 3507 FeatureInfo.GL_ES_VERSION_UNDEFINED); 3508 res.add(fi); 3509 3510 return new ParceledListSlice<>(res); 3511 } 3512 } 3513 3514 @Override 3515 public boolean hasSystemFeature(String name, int version) { 3516 synchronized (mPackages) { 3517 final FeatureInfo feat = mAvailableFeatures.get(name); 3518 if (feat == null) { 3519 return false; 3520 } else { 3521 return feat.version >= version; 3522 } 3523 } 3524 } 3525 3526 @Override 3527 public int checkPermission(String permName, String pkgName, int userId) { 3528 if (!sUserManager.exists(userId)) { 3529 return PackageManager.PERMISSION_DENIED; 3530 } 3531 3532 synchronized (mPackages) { 3533 final PackageParser.Package p = mPackages.get(pkgName); 3534 if (p != null && p.mExtras != null) { 3535 final PackageSetting ps = (PackageSetting) p.mExtras; 3536 final PermissionsState permissionsState = ps.getPermissionsState(); 3537 if (permissionsState.hasPermission(permName, userId)) { 3538 return PackageManager.PERMISSION_GRANTED; 3539 } 3540 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION 3541 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState 3542 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { 3543 return PackageManager.PERMISSION_GRANTED; 3544 } 3545 } 3546 } 3547 3548 return PackageManager.PERMISSION_DENIED; 3549 } 3550 3551 @Override 3552 public int checkUidPermission(String permName, int uid) { 3553 final int userId = UserHandle.getUserId(uid); 3554 3555 if (!sUserManager.exists(userId)) { 3556 return PackageManager.PERMISSION_DENIED; 3557 } 3558 3559 synchronized (mPackages) { 3560 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 3561 if (obj != null) { 3562 final SettingBase ps = (SettingBase) obj; 3563 final PermissionsState permissionsState = ps.getPermissionsState(); 3564 if (permissionsState.hasPermission(permName, userId)) { 3565 return PackageManager.PERMISSION_GRANTED; 3566 } 3567 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION 3568 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState 3569 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { 3570 return PackageManager.PERMISSION_GRANTED; 3571 } 3572 } else { 3573 ArraySet<String> perms = mSystemPermissions.get(uid); 3574 if (perms != null) { 3575 if (perms.contains(permName)) { 3576 return PackageManager.PERMISSION_GRANTED; 3577 } 3578 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms 3579 .contains(Manifest.permission.ACCESS_FINE_LOCATION)) { 3580 return PackageManager.PERMISSION_GRANTED; 3581 } 3582 } 3583 } 3584 } 3585 3586 return PackageManager.PERMISSION_DENIED; 3587 } 3588 3589 @Override 3590 public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) { 3591 if (UserHandle.getCallingUserId() != userId) { 3592 mContext.enforceCallingPermission( 3593 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 3594 "isPermissionRevokedByPolicy for user " + userId); 3595 } 3596 3597 if (checkPermission(permission, packageName, userId) 3598 == PackageManager.PERMISSION_GRANTED) { 3599 return false; 3600 } 3601 3602 final long identity = Binder.clearCallingIdentity(); 3603 try { 3604 final int flags = getPermissionFlags(permission, packageName, userId); 3605 return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0; 3606 } finally { 3607 Binder.restoreCallingIdentity(identity); 3608 } 3609 } 3610 3611 @Override 3612 public String getPermissionControllerPackageName() { 3613 synchronized (mPackages) { 3614 return mRequiredInstallerPackage; 3615 } 3616 } 3617 3618 /** 3619 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS 3620 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller. 3621 * @param checkShell whether to prevent shell from access if there's a debugging restriction 3622 * @param message the message to log on security exception 3623 */ 3624 void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, 3625 boolean checkShell, String message) { 3626 if (userId < 0) { 3627 throw new IllegalArgumentException("Invalid userId " + userId); 3628 } 3629 if (checkShell) { 3630 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); 3631 } 3632 if (userId == UserHandle.getUserId(callingUid)) return; 3633 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 3634 if (requireFullPermission) { 3635 mContext.enforceCallingOrSelfPermission( 3636 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 3637 } else { 3638 try { 3639 mContext.enforceCallingOrSelfPermission( 3640 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 3641 } catch (SecurityException se) { 3642 mContext.enforceCallingOrSelfPermission( 3643 android.Manifest.permission.INTERACT_ACROSS_USERS, message); 3644 } 3645 } 3646 } 3647 } 3648 3649 void enforceShellRestriction(String restriction, int callingUid, int userHandle) { 3650 if (callingUid == Process.SHELL_UID) { 3651 if (userHandle >= 0 3652 && sUserManager.hasUserRestriction(restriction, userHandle)) { 3653 throw new SecurityException("Shell does not have permission to access user " 3654 + userHandle); 3655 } else if (userHandle < 0) { 3656 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t" 3657 + Debug.getCallers(3)); 3658 } 3659 } 3660 } 3661 3662 private BasePermission findPermissionTreeLP(String permName) { 3663 for(BasePermission bp : mSettings.mPermissionTrees.values()) { 3664 if (permName.startsWith(bp.name) && 3665 permName.length() > bp.name.length() && 3666 permName.charAt(bp.name.length()) == '.') { 3667 return bp; 3668 } 3669 } 3670 return null; 3671 } 3672 3673 private BasePermission checkPermissionTreeLP(String permName) { 3674 if (permName != null) { 3675 BasePermission bp = findPermissionTreeLP(permName); 3676 if (bp != null) { 3677 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) { 3678 return bp; 3679 } 3680 throw new SecurityException("Calling uid " 3681 + Binder.getCallingUid() 3682 + " is not allowed to add to permission tree " 3683 + bp.name + " owned by uid " + bp.uid); 3684 } 3685 } 3686 throw new SecurityException("No permission tree found for " + permName); 3687 } 3688 3689 static boolean compareStrings(CharSequence s1, CharSequence s2) { 3690 if (s1 == null) { 3691 return s2 == null; 3692 } 3693 if (s2 == null) { 3694 return false; 3695 } 3696 if (s1.getClass() != s2.getClass()) { 3697 return false; 3698 } 3699 return s1.equals(s2); 3700 } 3701 3702 static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) { 3703 if (pi1.icon != pi2.icon) return false; 3704 if (pi1.logo != pi2.logo) return false; 3705 if (pi1.protectionLevel != pi2.protectionLevel) return false; 3706 if (!compareStrings(pi1.name, pi2.name)) return false; 3707 if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false; 3708 // We'll take care of setting this one. 3709 if (!compareStrings(pi1.packageName, pi2.packageName)) return false; 3710 // These are not currently stored in settings. 3711 //if (!compareStrings(pi1.group, pi2.group)) return false; 3712 //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false; 3713 //if (pi1.labelRes != pi2.labelRes) return false; 3714 //if (pi1.descriptionRes != pi2.descriptionRes) return false; 3715 return true; 3716 } 3717 3718 int permissionInfoFootprint(PermissionInfo info) { 3719 int size = info.name.length(); 3720 if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length(); 3721 if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length(); 3722 return size; 3723 } 3724 3725 int calculateCurrentPermissionFootprintLocked(BasePermission tree) { 3726 int size = 0; 3727 for (BasePermission perm : mSettings.mPermissions.values()) { 3728 if (perm.uid == tree.uid) { 3729 size += perm.name.length() + permissionInfoFootprint(perm.perm.info); 3730 } 3731 } 3732 return size; 3733 } 3734 3735 void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) { 3736 // We calculate the max size of permissions defined by this uid and throw 3737 // if that plus the size of 'info' would exceed our stated maximum. 3738 if (tree.uid != Process.SYSTEM_UID) { 3739 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree); 3740 if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) { 3741 throw new SecurityException("Permission tree size cap exceeded"); 3742 } 3743 } 3744 } 3745 3746 boolean addPermissionLocked(PermissionInfo info, boolean async) { 3747 if (info.labelRes == 0 && info.nonLocalizedLabel == null) { 3748 throw new SecurityException("Label must be specified in permission"); 3749 } 3750 BasePermission tree = checkPermissionTreeLP(info.name); 3751 BasePermission bp = mSettings.mPermissions.get(info.name); 3752 boolean added = bp == null; 3753 boolean changed = true; 3754 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel); 3755 if (added) { 3756 enforcePermissionCapLocked(info, tree); 3757 bp = new BasePermission(info.name, tree.sourcePackage, 3758 BasePermission.TYPE_DYNAMIC); 3759 } else if (bp.type != BasePermission.TYPE_DYNAMIC) { 3760 throw new SecurityException( 3761 "Not allowed to modify non-dynamic permission " 3762 + info.name); 3763 } else { 3764 if (bp.protectionLevel == fixedLevel 3765 && bp.perm.owner.equals(tree.perm.owner) 3766 && bp.uid == tree.uid 3767 && comparePermissionInfos(bp.perm.info, info)) { 3768 changed = false; 3769 } 3770 } 3771 bp.protectionLevel = fixedLevel; 3772 info = new PermissionInfo(info); 3773 info.protectionLevel = fixedLevel; 3774 bp.perm = new PackageParser.Permission(tree.perm.owner, info); 3775 bp.perm.info.packageName = tree.perm.info.packageName; 3776 bp.uid = tree.uid; 3777 if (added) { 3778 mSettings.mPermissions.put(info.name, bp); 3779 } 3780 if (changed) { 3781 if (!async) { 3782 mSettings.writeLPr(); 3783 } else { 3784 scheduleWriteSettingsLocked(); 3785 } 3786 } 3787 return added; 3788 } 3789 3790 @Override 3791 public boolean addPermission(PermissionInfo info) { 3792 synchronized (mPackages) { 3793 return addPermissionLocked(info, false); 3794 } 3795 } 3796 3797 @Override 3798 public boolean addPermissionAsync(PermissionInfo info) { 3799 synchronized (mPackages) { 3800 return addPermissionLocked(info, true); 3801 } 3802 } 3803 3804 @Override 3805 public void removePermission(String name) { 3806 synchronized (mPackages) { 3807 checkPermissionTreeLP(name); 3808 BasePermission bp = mSettings.mPermissions.get(name); 3809 if (bp != null) { 3810 if (bp.type != BasePermission.TYPE_DYNAMIC) { 3811 throw new SecurityException( 3812 "Not allowed to modify non-dynamic permission " 3813 + name); 3814 } 3815 mSettings.mPermissions.remove(name); 3816 mSettings.writeLPr(); 3817 } 3818 } 3819 } 3820 3821 private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg, 3822 BasePermission bp) { 3823 int index = pkg.requestedPermissions.indexOf(bp.name); 3824 if (index == -1) { 3825 throw new SecurityException("Package " + pkg.packageName 3826 + " has not requested permission " + bp.name); 3827 } 3828 if (!bp.isRuntime() && !bp.isDevelopment()) { 3829 throw new SecurityException("Permission " + bp.name 3830 + " is not a changeable permission type"); 3831 } 3832 } 3833 3834 @Override 3835 public void grantRuntimePermission(String packageName, String name, final int userId) { 3836 if (!sUserManager.exists(userId)) { 3837 Log.e(TAG, "No such user:" + userId); 3838 return; 3839 } 3840 3841 mContext.enforceCallingOrSelfPermission( 3842 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 3843 "grantRuntimePermission"); 3844 3845 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3846 true /* requireFullPermission */, true /* checkShell */, 3847 "grantRuntimePermission"); 3848 3849 final int uid; 3850 final SettingBase sb; 3851 3852 synchronized (mPackages) { 3853 final PackageParser.Package pkg = mPackages.get(packageName); 3854 if (pkg == null) { 3855 throw new IllegalArgumentException("Unknown package: " + packageName); 3856 } 3857 3858 final BasePermission bp = mSettings.mPermissions.get(name); 3859 if (bp == null) { 3860 throw new IllegalArgumentException("Unknown permission: " + name); 3861 } 3862 3863 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp); 3864 3865 // If a permission review is required for legacy apps we represent 3866 // their permissions as always granted runtime ones since we need 3867 // to keep the review required permission flag per user while an 3868 // install permission's state is shared across all users. 3869 if (Build.PERMISSIONS_REVIEW_REQUIRED 3870 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M 3871 && bp.isRuntime()) { 3872 return; 3873 } 3874 3875 uid = UserHandle.getUid(userId, pkg.applicationInfo.uid); 3876 sb = (SettingBase) pkg.mExtras; 3877 if (sb == null) { 3878 throw new IllegalArgumentException("Unknown package: " + packageName); 3879 } 3880 3881 final PermissionsState permissionsState = sb.getPermissionsState(); 3882 3883 final int flags = permissionsState.getPermissionFlags(name, userId); 3884 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 3885 throw new SecurityException("Cannot grant system fixed permission " 3886 + name + " for package " + packageName); 3887 } 3888 3889 if (bp.isDevelopment()) { 3890 // Development permissions must be handled specially, since they are not 3891 // normal runtime permissions. For now they apply to all users. 3892 if (permissionsState.grantInstallPermission(bp) != 3893 PermissionsState.PERMISSION_OPERATION_FAILURE) { 3894 scheduleWriteSettingsLocked(); 3895 } 3896 return; 3897 } 3898 3899 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 3900 Slog.w(TAG, "Cannot grant runtime permission to a legacy app"); 3901 return; 3902 } 3903 3904 final int result = permissionsState.grantRuntimePermission(bp, userId); 3905 switch (result) { 3906 case PermissionsState.PERMISSION_OPERATION_FAILURE: { 3907 return; 3908 } 3909 3910 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 3911 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); 3912 mHandler.post(new Runnable() { 3913 @Override 3914 public void run() { 3915 killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED); 3916 } 3917 }); 3918 } 3919 break; 3920 } 3921 3922 mOnPermissionChangeListeners.onPermissionsChanged(uid); 3923 3924 // Not critical if that is lost - app has to request again. 3925 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 3926 } 3927 3928 // Only need to do this if user is initialized. Otherwise it's a new user 3929 // and there are no processes running as the user yet and there's no need 3930 // to make an expensive call to remount processes for the changed permissions. 3931 if (READ_EXTERNAL_STORAGE.equals(name) 3932 || WRITE_EXTERNAL_STORAGE.equals(name)) { 3933 final long token = Binder.clearCallingIdentity(); 3934 try { 3935 if (sUserManager.isInitialized(userId)) { 3936 MountServiceInternal mountServiceInternal = LocalServices.getService( 3937 MountServiceInternal.class); 3938 mountServiceInternal.onExternalStoragePolicyChanged(uid, packageName); 3939 } 3940 } finally { 3941 Binder.restoreCallingIdentity(token); 3942 } 3943 } 3944 } 3945 3946 @Override 3947 public void revokeRuntimePermission(String packageName, String name, int userId) { 3948 if (!sUserManager.exists(userId)) { 3949 Log.e(TAG, "No such user:" + userId); 3950 return; 3951 } 3952 3953 mContext.enforceCallingOrSelfPermission( 3954 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 3955 "revokeRuntimePermission"); 3956 3957 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3958 true /* requireFullPermission */, true /* checkShell */, 3959 "revokeRuntimePermission"); 3960 3961 final int appId; 3962 3963 synchronized (mPackages) { 3964 final PackageParser.Package pkg = mPackages.get(packageName); 3965 if (pkg == null) { 3966 throw new IllegalArgumentException("Unknown package: " + packageName); 3967 } 3968 3969 final BasePermission bp = mSettings.mPermissions.get(name); 3970 if (bp == null) { 3971 throw new IllegalArgumentException("Unknown permission: " + name); 3972 } 3973 3974 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp); 3975 3976 // If a permission review is required for legacy apps we represent 3977 // their permissions as always granted runtime ones since we need 3978 // to keep the review required permission flag per user while an 3979 // install permission's state is shared across all users. 3980 if (Build.PERMISSIONS_REVIEW_REQUIRED 3981 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M 3982 && bp.isRuntime()) { 3983 return; 3984 } 3985 3986 SettingBase sb = (SettingBase) pkg.mExtras; 3987 if (sb == null) { 3988 throw new IllegalArgumentException("Unknown package: " + packageName); 3989 } 3990 3991 final PermissionsState permissionsState = sb.getPermissionsState(); 3992 3993 final int flags = permissionsState.getPermissionFlags(name, userId); 3994 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 3995 throw new SecurityException("Cannot revoke system fixed permission " 3996 + name + " for package " + packageName); 3997 } 3998 3999 if (bp.isDevelopment()) { 4000 // Development permissions must be handled specially, since they are not 4001 // normal runtime permissions. For now they apply to all users. 4002 if (permissionsState.revokeInstallPermission(bp) != 4003 PermissionsState.PERMISSION_OPERATION_FAILURE) { 4004 scheduleWriteSettingsLocked(); 4005 } 4006 return; 4007 } 4008 4009 if (permissionsState.revokeRuntimePermission(bp, userId) == 4010 PermissionsState.PERMISSION_OPERATION_FAILURE) { 4011 return; 4012 } 4013 4014 mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid); 4015 4016 // Critical, after this call app should never have the permission. 4017 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 4018 4019 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 4020 } 4021 4022 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED); 4023 } 4024 4025 @Override 4026 public void resetRuntimePermissions() { 4027 mContext.enforceCallingOrSelfPermission( 4028 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 4029 "revokeRuntimePermission"); 4030 4031 int callingUid = Binder.getCallingUid(); 4032 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 4033 mContext.enforceCallingOrSelfPermission( 4034 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 4035 "resetRuntimePermissions"); 4036 } 4037 4038 synchronized (mPackages) { 4039 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL); 4040 for (int userId : UserManagerService.getInstance().getUserIds()) { 4041 final int packageCount = mPackages.size(); 4042 for (int i = 0; i < packageCount; i++) { 4043 PackageParser.Package pkg = mPackages.valueAt(i); 4044 if (!(pkg.mExtras instanceof PackageSetting)) { 4045 continue; 4046 } 4047 PackageSetting ps = (PackageSetting) pkg.mExtras; 4048 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 4049 } 4050 } 4051 } 4052 } 4053 4054 @Override 4055 public int getPermissionFlags(String name, String packageName, int userId) { 4056 if (!sUserManager.exists(userId)) { 4057 return 0; 4058 } 4059 4060 enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags"); 4061 4062 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4063 true /* requireFullPermission */, false /* checkShell */, 4064 "getPermissionFlags"); 4065 4066 synchronized (mPackages) { 4067 final PackageParser.Package pkg = mPackages.get(packageName); 4068 if (pkg == null) { 4069 throw new IllegalArgumentException("Unknown package: " + packageName); 4070 } 4071 4072 final BasePermission bp = mSettings.mPermissions.get(name); 4073 if (bp == null) { 4074 throw new IllegalArgumentException("Unknown permission: " + name); 4075 } 4076 4077 SettingBase sb = (SettingBase) pkg.mExtras; 4078 if (sb == null) { 4079 throw new IllegalArgumentException("Unknown package: " + packageName); 4080 } 4081 4082 PermissionsState permissionsState = sb.getPermissionsState(); 4083 return permissionsState.getPermissionFlags(name, userId); 4084 } 4085 } 4086 4087 @Override 4088 public void updatePermissionFlags(String name, String packageName, int flagMask, 4089 int flagValues, int userId) { 4090 if (!sUserManager.exists(userId)) { 4091 return; 4092 } 4093 4094 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags"); 4095 4096 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4097 true /* requireFullPermission */, true /* checkShell */, 4098 "updatePermissionFlags"); 4099 4100 // Only the system can change these flags and nothing else. 4101 if (getCallingUid() != Process.SYSTEM_UID) { 4102 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4103 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4104 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 4105 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 4106 flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 4107 } 4108 4109 synchronized (mPackages) { 4110 final PackageParser.Package pkg = mPackages.get(packageName); 4111 if (pkg == null) { 4112 throw new IllegalArgumentException("Unknown package: " + packageName); 4113 } 4114 4115 final BasePermission bp = mSettings.mPermissions.get(name); 4116 if (bp == null) { 4117 throw new IllegalArgumentException("Unknown permission: " + name); 4118 } 4119 4120 SettingBase sb = (SettingBase) pkg.mExtras; 4121 if (sb == null) { 4122 throw new IllegalArgumentException("Unknown package: " + packageName); 4123 } 4124 4125 PermissionsState permissionsState = sb.getPermissionsState(); 4126 4127 boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null; 4128 4129 if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) { 4130 // Install and runtime permissions are stored in different places, 4131 // so figure out what permission changed and persist the change. 4132 if (permissionsState.getInstallPermissionState(name) != null) { 4133 scheduleWriteSettingsLocked(); 4134 } else if (permissionsState.getRuntimePermissionState(name, userId) != null 4135 || hadState) { 4136 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 4137 } 4138 } 4139 } 4140 } 4141 4142 /** 4143 * Update the permission flags for all packages and runtime permissions of a user in order 4144 * to allow device or profile owner to remove POLICY_FIXED. 4145 */ 4146 @Override 4147 public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) { 4148 if (!sUserManager.exists(userId)) { 4149 return; 4150 } 4151 4152 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps"); 4153 4154 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4155 true /* requireFullPermission */, true /* checkShell */, 4156 "updatePermissionFlagsForAllApps"); 4157 4158 // Only the system can change system fixed flags. 4159 if (getCallingUid() != Process.SYSTEM_UID) { 4160 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4161 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4162 } 4163 4164 synchronized (mPackages) { 4165 boolean changed = false; 4166 final int packageCount = mPackages.size(); 4167 for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) { 4168 final PackageParser.Package pkg = mPackages.valueAt(pkgIndex); 4169 SettingBase sb = (SettingBase) pkg.mExtras; 4170 if (sb == null) { 4171 continue; 4172 } 4173 PermissionsState permissionsState = sb.getPermissionsState(); 4174 changed |= permissionsState.updatePermissionFlagsForAllPermissions( 4175 userId, flagMask, flagValues); 4176 } 4177 if (changed) { 4178 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 4179 } 4180 } 4181 } 4182 4183 private void enforceGrantRevokeRuntimePermissionPermissions(String message) { 4184 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS) 4185 != PackageManager.PERMISSION_GRANTED 4186 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) 4187 != PackageManager.PERMISSION_GRANTED) { 4188 throw new SecurityException(message + " requires " 4189 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or " 4190 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS); 4191 } 4192 } 4193 4194 @Override 4195 public boolean shouldShowRequestPermissionRationale(String permissionName, 4196 String packageName, int userId) { 4197 if (UserHandle.getCallingUserId() != userId) { 4198 mContext.enforceCallingPermission( 4199 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 4200 "canShowRequestPermissionRationale for user " + userId); 4201 } 4202 4203 final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId); 4204 if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) { 4205 return false; 4206 } 4207 4208 if (checkPermission(permissionName, packageName, userId) 4209 == PackageManager.PERMISSION_GRANTED) { 4210 return false; 4211 } 4212 4213 final int flags; 4214 4215 final long identity = Binder.clearCallingIdentity(); 4216 try { 4217 flags = getPermissionFlags(permissionName, 4218 packageName, userId); 4219 } finally { 4220 Binder.restoreCallingIdentity(identity); 4221 } 4222 4223 final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 4224 | PackageManager.FLAG_PERMISSION_POLICY_FIXED 4225 | PackageManager.FLAG_PERMISSION_USER_FIXED; 4226 4227 if ((flags & fixedFlags) != 0) { 4228 return false; 4229 } 4230 4231 return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0; 4232 } 4233 4234 @Override 4235 public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 4236 mContext.enforceCallingOrSelfPermission( 4237 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS, 4238 "addOnPermissionsChangeListener"); 4239 4240 synchronized (mPackages) { 4241 mOnPermissionChangeListeners.addListenerLocked(listener); 4242 } 4243 } 4244 4245 @Override 4246 public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 4247 synchronized (mPackages) { 4248 mOnPermissionChangeListeners.removeListenerLocked(listener); 4249 } 4250 } 4251 4252 @Override 4253 public boolean isProtectedBroadcast(String actionName) { 4254 synchronized (mPackages) { 4255 if (mProtectedBroadcasts.contains(actionName)) { 4256 return true; 4257 } else if (actionName != null) { 4258 // TODO: remove these terrible hacks 4259 if (actionName.startsWith("android.net.netmon.lingerExpired") 4260 || actionName.startsWith("com.android.server.sip.SipWakeupTimer") 4261 || actionName.startsWith("com.android.internal.telephony.data-reconnect") 4262 || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) { 4263 return true; 4264 } 4265 } 4266 } 4267 return false; 4268 } 4269 4270 @Override 4271 public int checkSignatures(String pkg1, String pkg2) { 4272 synchronized (mPackages) { 4273 final PackageParser.Package p1 = mPackages.get(pkg1); 4274 final PackageParser.Package p2 = mPackages.get(pkg2); 4275 if (p1 == null || p1.mExtras == null 4276 || p2 == null || p2.mExtras == null) { 4277 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4278 } 4279 return compareSignatures(p1.mSignatures, p2.mSignatures); 4280 } 4281 } 4282 4283 @Override 4284 public int checkUidSignatures(int uid1, int uid2) { 4285 // Map to base uids. 4286 uid1 = UserHandle.getAppId(uid1); 4287 uid2 = UserHandle.getAppId(uid2); 4288 // reader 4289 synchronized (mPackages) { 4290 Signature[] s1; 4291 Signature[] s2; 4292 Object obj = mSettings.getUserIdLPr(uid1); 4293 if (obj != null) { 4294 if (obj instanceof SharedUserSetting) { 4295 s1 = ((SharedUserSetting)obj).signatures.mSignatures; 4296 } else if (obj instanceof PackageSetting) { 4297 s1 = ((PackageSetting)obj).signatures.mSignatures; 4298 } else { 4299 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4300 } 4301 } else { 4302 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4303 } 4304 obj = mSettings.getUserIdLPr(uid2); 4305 if (obj != null) { 4306 if (obj instanceof SharedUserSetting) { 4307 s2 = ((SharedUserSetting)obj).signatures.mSignatures; 4308 } else if (obj instanceof PackageSetting) { 4309 s2 = ((PackageSetting)obj).signatures.mSignatures; 4310 } else { 4311 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4312 } 4313 } else { 4314 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4315 } 4316 return compareSignatures(s1, s2); 4317 } 4318 } 4319 4320 private void killUid(int appId, int userId, String reason) { 4321 final long identity = Binder.clearCallingIdentity(); 4322 try { 4323 IActivityManager am = ActivityManagerNative.getDefault(); 4324 if (am != null) { 4325 try { 4326 am.killUid(appId, userId, reason); 4327 } catch (RemoteException e) { 4328 /* ignore - same process */ 4329 } 4330 } 4331 } finally { 4332 Binder.restoreCallingIdentity(identity); 4333 } 4334 } 4335 4336 /** 4337 * Compares two sets of signatures. Returns: 4338 * <br /> 4339 * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null, 4340 * <br /> 4341 * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null, 4342 * <br /> 4343 * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null, 4344 * <br /> 4345 * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical, 4346 * <br /> 4347 * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ. 4348 */ 4349 static int compareSignatures(Signature[] s1, Signature[] s2) { 4350 if (s1 == null) { 4351 return s2 == null 4352 ? PackageManager.SIGNATURE_NEITHER_SIGNED 4353 : PackageManager.SIGNATURE_FIRST_NOT_SIGNED; 4354 } 4355 4356 if (s2 == null) { 4357 return PackageManager.SIGNATURE_SECOND_NOT_SIGNED; 4358 } 4359 4360 if (s1.length != s2.length) { 4361 return PackageManager.SIGNATURE_NO_MATCH; 4362 } 4363 4364 // Since both signature sets are of size 1, we can compare without HashSets. 4365 if (s1.length == 1) { 4366 return s1[0].equals(s2[0]) ? 4367 PackageManager.SIGNATURE_MATCH : 4368 PackageManager.SIGNATURE_NO_MATCH; 4369 } 4370 4371 ArraySet<Signature> set1 = new ArraySet<Signature>(); 4372 for (Signature sig : s1) { 4373 set1.add(sig); 4374 } 4375 ArraySet<Signature> set2 = new ArraySet<Signature>(); 4376 for (Signature sig : s2) { 4377 set2.add(sig); 4378 } 4379 // Make sure s2 contains all signatures in s1. 4380 if (set1.equals(set2)) { 4381 return PackageManager.SIGNATURE_MATCH; 4382 } 4383 return PackageManager.SIGNATURE_NO_MATCH; 4384 } 4385 4386 /** 4387 * If the database version for this type of package (internal storage or 4388 * external storage) is less than the version where package signatures 4389 * were updated, return true. 4390 */ 4391 private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 4392 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); 4393 return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY; 4394 } 4395 4396 /** 4397 * Used for backward compatibility to make sure any packages with 4398 * certificate chains get upgraded to the new style. {@code existingSigs} 4399 * will be in the old format (since they were stored on disk from before the 4400 * system upgrade) and {@code scannedSigs} will be in the newer format. 4401 */ 4402 private int compareSignaturesCompat(PackageSignatures existingSigs, 4403 PackageParser.Package scannedPkg) { 4404 if (!isCompatSignatureUpdateNeeded(scannedPkg)) { 4405 return PackageManager.SIGNATURE_NO_MATCH; 4406 } 4407 4408 ArraySet<Signature> existingSet = new ArraySet<Signature>(); 4409 for (Signature sig : existingSigs.mSignatures) { 4410 existingSet.add(sig); 4411 } 4412 ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>(); 4413 for (Signature sig : scannedPkg.mSignatures) { 4414 try { 4415 Signature[] chainSignatures = sig.getChainSignatures(); 4416 for (Signature chainSig : chainSignatures) { 4417 scannedCompatSet.add(chainSig); 4418 } 4419 } catch (CertificateEncodingException e) { 4420 scannedCompatSet.add(sig); 4421 } 4422 } 4423 /* 4424 * Make sure the expanded scanned set contains all signatures in the 4425 * existing one. 4426 */ 4427 if (scannedCompatSet.equals(existingSet)) { 4428 // Migrate the old signatures to the new scheme. 4429 existingSigs.assignSignatures(scannedPkg.mSignatures); 4430 // The new KeySets will be re-added later in the scanning process. 4431 synchronized (mPackages) { 4432 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName); 4433 } 4434 return PackageManager.SIGNATURE_MATCH; 4435 } 4436 return PackageManager.SIGNATURE_NO_MATCH; 4437 } 4438 4439 private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 4440 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); 4441 return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER; 4442 } 4443 4444 private int compareSignaturesRecover(PackageSignatures existingSigs, 4445 PackageParser.Package scannedPkg) { 4446 if (!isRecoverSignatureUpdateNeeded(scannedPkg)) { 4447 return PackageManager.SIGNATURE_NO_MATCH; 4448 } 4449 4450 String msg = null; 4451 try { 4452 if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) { 4453 logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for " 4454 + scannedPkg.packageName); 4455 return PackageManager.SIGNATURE_MATCH; 4456 } 4457 } catch (CertificateException e) { 4458 msg = e.getMessage(); 4459 } 4460 4461 logCriticalInfo(Log.INFO, 4462 "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg); 4463 return PackageManager.SIGNATURE_NO_MATCH; 4464 } 4465 4466 @Override 4467 public List<String> getAllPackages() { 4468 synchronized (mPackages) { 4469 return new ArrayList<String>(mPackages.keySet()); 4470 } 4471 } 4472 4473 @Override 4474 public String[] getPackagesForUid(int uid) { 4475 uid = UserHandle.getAppId(uid); 4476 // reader 4477 synchronized (mPackages) { 4478 Object obj = mSettings.getUserIdLPr(uid); 4479 if (obj instanceof SharedUserSetting) { 4480 final SharedUserSetting sus = (SharedUserSetting) obj; 4481 final int N = sus.packages.size(); 4482 final String[] res = new String[N]; 4483 final Iterator<PackageSetting> it = sus.packages.iterator(); 4484 int i = 0; 4485 while (it.hasNext()) { 4486 res[i++] = it.next().name; 4487 } 4488 return res; 4489 } else if (obj instanceof PackageSetting) { 4490 final PackageSetting ps = (PackageSetting) obj; 4491 return new String[] { ps.name }; 4492 } 4493 } 4494 return null; 4495 } 4496 4497 @Override 4498 public String getNameForUid(int uid) { 4499 // reader 4500 synchronized (mPackages) { 4501 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4502 if (obj instanceof SharedUserSetting) { 4503 final SharedUserSetting sus = (SharedUserSetting) obj; 4504 return sus.name + ":" + sus.userId; 4505 } else if (obj instanceof PackageSetting) { 4506 final PackageSetting ps = (PackageSetting) obj; 4507 return ps.name; 4508 } 4509 } 4510 return null; 4511 } 4512 4513 @Override 4514 public int getUidForSharedUser(String sharedUserName) { 4515 if(sharedUserName == null) { 4516 return -1; 4517 } 4518 // reader 4519 synchronized (mPackages) { 4520 final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false); 4521 if (suid == null) { 4522 return -1; 4523 } 4524 return suid.userId; 4525 } 4526 } 4527 4528 @Override 4529 public int getFlagsForUid(int uid) { 4530 synchronized (mPackages) { 4531 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4532 if (obj instanceof SharedUserSetting) { 4533 final SharedUserSetting sus = (SharedUserSetting) obj; 4534 return sus.pkgFlags; 4535 } else if (obj instanceof PackageSetting) { 4536 final PackageSetting ps = (PackageSetting) obj; 4537 return ps.pkgFlags; 4538 } 4539 } 4540 return 0; 4541 } 4542 4543 @Override 4544 public int getPrivateFlagsForUid(int uid) { 4545 synchronized (mPackages) { 4546 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4547 if (obj instanceof SharedUserSetting) { 4548 final SharedUserSetting sus = (SharedUserSetting) obj; 4549 return sus.pkgPrivateFlags; 4550 } else if (obj instanceof PackageSetting) { 4551 final PackageSetting ps = (PackageSetting) obj; 4552 return ps.pkgPrivateFlags; 4553 } 4554 } 4555 return 0; 4556 } 4557 4558 @Override 4559 public boolean isUidPrivileged(int uid) { 4560 uid = UserHandle.getAppId(uid); 4561 // reader 4562 synchronized (mPackages) { 4563 Object obj = mSettings.getUserIdLPr(uid); 4564 if (obj instanceof SharedUserSetting) { 4565 final SharedUserSetting sus = (SharedUserSetting) obj; 4566 final Iterator<PackageSetting> it = sus.packages.iterator(); 4567 while (it.hasNext()) { 4568 if (it.next().isPrivileged()) { 4569 return true; 4570 } 4571 } 4572 } else if (obj instanceof PackageSetting) { 4573 final PackageSetting ps = (PackageSetting) obj; 4574 return ps.isPrivileged(); 4575 } 4576 } 4577 return false; 4578 } 4579 4580 @Override 4581 public String[] getAppOpPermissionPackages(String permissionName) { 4582 synchronized (mPackages) { 4583 ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName); 4584 if (pkgs == null) { 4585 return null; 4586 } 4587 return pkgs.toArray(new String[pkgs.size()]); 4588 } 4589 } 4590 4591 @Override 4592 public ResolveInfo resolveIntent(Intent intent, String resolvedType, 4593 int flags, int userId) { 4594 if (!sUserManager.exists(userId)) return null; 4595 flags = updateFlagsForResolve(flags, userId, intent); 4596 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4597 false /* requireFullPermission */, false /* checkShell */, "resolve intent"); 4598 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags, 4599 userId); 4600 final ResolveInfo bestChoice = 4601 chooseBestActivity(intent, resolvedType, flags, query, userId); 4602 4603 if (isEphemeralAllowed(intent, query, userId)) { 4604 final EphemeralResolveInfo ai = 4605 getEphemeralResolveInfo(intent, resolvedType, userId); 4606 if (ai != null) { 4607 if (DEBUG_EPHEMERAL) { 4608 Slog.v(TAG, "Returning an EphemeralResolveInfo"); 4609 } 4610 bestChoice.ephemeralInstaller = mEphemeralInstallerInfo; 4611 bestChoice.ephemeralResolveInfo = ai; 4612 } 4613 } 4614 return bestChoice; 4615 } 4616 4617 @Override 4618 public void setLastChosenActivity(Intent intent, String resolvedType, int flags, 4619 IntentFilter filter, int match, ComponentName activity) { 4620 final int userId = UserHandle.getCallingUserId(); 4621 if (DEBUG_PREFERRED) { 4622 Log.v(TAG, "setLastChosenActivity intent=" + intent 4623 + " resolvedType=" + resolvedType 4624 + " flags=" + flags 4625 + " filter=" + filter 4626 + " match=" + match 4627 + " activity=" + activity); 4628 filter.dump(new PrintStreamPrinter(System.out), " "); 4629 } 4630 intent.setComponent(null); 4631 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags, 4632 userId); 4633 // Find any earlier preferred or last chosen entries and nuke them 4634 findPreferredActivity(intent, resolvedType, 4635 flags, query, 0, false, true, false, userId); 4636 // Add the new activity as the last chosen for this filter 4637 addPreferredActivityInternal(filter, match, null, activity, false, userId, 4638 "Setting last chosen"); 4639 } 4640 4641 @Override 4642 public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) { 4643 final int userId = UserHandle.getCallingUserId(); 4644 if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent); 4645 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags, 4646 userId); 4647 return findPreferredActivity(intent, resolvedType, flags, query, 0, 4648 false, false, false, userId); 4649 } 4650 4651 4652 private boolean isEphemeralAllowed( 4653 Intent intent, List<ResolveInfo> resolvedActivites, int userId) { 4654 // Short circuit and return early if possible. 4655 if (DISABLE_EPHEMERAL_APPS) { 4656 return false; 4657 } 4658 final int callingUser = UserHandle.getCallingUserId(); 4659 if (callingUser != UserHandle.USER_SYSTEM) { 4660 return false; 4661 } 4662 if (mEphemeralResolverConnection == null) { 4663 return false; 4664 } 4665 if (intent.getComponent() != null) { 4666 return false; 4667 } 4668 if (intent.getPackage() != null) { 4669 return false; 4670 } 4671 final boolean isWebUri = hasWebURI(intent); 4672 if (!isWebUri) { 4673 return false; 4674 } 4675 // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution. 4676 synchronized (mPackages) { 4677 final int count = resolvedActivites.size(); 4678 for (int n = 0; n < count; n++) { 4679 ResolveInfo info = resolvedActivites.get(n); 4680 String packageName = info.activityInfo.packageName; 4681 PackageSetting ps = mSettings.mPackages.get(packageName); 4682 if (ps != null) { 4683 // Try to get the status from User settings first 4684 long packedStatus = getDomainVerificationStatusLPr(ps, userId); 4685 int status = (int) (packedStatus >> 32); 4686 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS 4687 || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) { 4688 if (DEBUG_EPHEMERAL) { 4689 Slog.v(TAG, "DENY ephemeral apps;" 4690 + " pkg: " + packageName + ", status: " + status); 4691 } 4692 return false; 4693 } 4694 } 4695 } 4696 } 4697 // We've exhausted all ways to deny ephemeral application; let the system look for them. 4698 return true; 4699 } 4700 4701 private EphemeralResolveInfo getEphemeralResolveInfo(Intent intent, String resolvedType, 4702 int userId) { 4703 MessageDigest digest = null; 4704 try { 4705 digest = MessageDigest.getInstance(EphemeralResolveInfo.SHA_ALGORITHM); 4706 } catch (NoSuchAlgorithmException e) { 4707 // If we can't create a digest, ignore ephemeral apps. 4708 return null; 4709 } 4710 4711 final byte[] hostBytes = intent.getData().getHost().getBytes(); 4712 final byte[] digestBytes = digest.digest(hostBytes); 4713 int shaPrefix = 4714 digestBytes[0] << 24 4715 | digestBytes[1] << 16 4716 | digestBytes[2] << 8 4717 | digestBytes[3] << 0; 4718 final List<EphemeralResolveInfo> ephemeralResolveInfoList = 4719 mEphemeralResolverConnection.getEphemeralResolveInfoList(shaPrefix); 4720 if (ephemeralResolveInfoList == null || ephemeralResolveInfoList.size() == 0) { 4721 // No hash prefix match; there are no ephemeral apps for this domain. 4722 return null; 4723 } 4724 for (int i = ephemeralResolveInfoList.size() - 1; i >= 0; --i) { 4725 EphemeralResolveInfo ephemeralApplication = ephemeralResolveInfoList.get(i); 4726 if (!Arrays.equals(digestBytes, ephemeralApplication.getDigestBytes())) { 4727 continue; 4728 } 4729 final List<IntentFilter> filters = ephemeralApplication.getFilters(); 4730 // No filters; this should never happen. 4731 if (filters.isEmpty()) { 4732 continue; 4733 } 4734 // We have a domain match; resolve the filters to see if anything matches. 4735 final EphemeralIntentResolver ephemeralResolver = new EphemeralIntentResolver(); 4736 for (int j = filters.size() - 1; j >= 0; --j) { 4737 final EphemeralResolveIntentInfo intentInfo = 4738 new EphemeralResolveIntentInfo(filters.get(j), ephemeralApplication); 4739 ephemeralResolver.addFilter(intentInfo); 4740 } 4741 List<EphemeralResolveInfo> matchedResolveInfoList = ephemeralResolver.queryIntent( 4742 intent, resolvedType, false /*defaultOnly*/, userId); 4743 if (!matchedResolveInfoList.isEmpty()) { 4744 return matchedResolveInfoList.get(0); 4745 } 4746 } 4747 // Hash or filter mis-match; no ephemeral apps for this domain. 4748 return null; 4749 } 4750 4751 private ResolveInfo chooseBestActivity(Intent intent, String resolvedType, 4752 int flags, List<ResolveInfo> query, int userId) { 4753 if (query != null) { 4754 final int N = query.size(); 4755 if (N == 1) { 4756 return query.get(0); 4757 } else if (N > 1) { 4758 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 4759 // If there is more than one activity with the same priority, 4760 // then let the user decide between them. 4761 ResolveInfo r0 = query.get(0); 4762 ResolveInfo r1 = query.get(1); 4763 if (DEBUG_INTENT_MATCHING || debug) { 4764 Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs " 4765 + r1.activityInfo.name + "=" + r1.priority); 4766 } 4767 // If the first activity has a higher priority, or a different 4768 // default, then it is always desirable to pick it. 4769 if (r0.priority != r1.priority 4770 || r0.preferredOrder != r1.preferredOrder 4771 || r0.isDefault != r1.isDefault) { 4772 return query.get(0); 4773 } 4774 // If we have saved a preference for a preferred activity for 4775 // this Intent, use that. 4776 ResolveInfo ri = findPreferredActivity(intent, resolvedType, 4777 flags, query, r0.priority, true, false, debug, userId); 4778 if (ri != null) { 4779 return ri; 4780 } 4781 ri = new ResolveInfo(mResolveInfo); 4782 ri.activityInfo = new ActivityInfo(ri.activityInfo); 4783 ri.activityInfo.applicationInfo = new ApplicationInfo( 4784 ri.activityInfo.applicationInfo); 4785 if (userId != 0) { 4786 ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId, 4787 UserHandle.getAppId(ri.activityInfo.applicationInfo.uid)); 4788 } 4789 // Make sure that the resolver is displayable in car mode 4790 if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle(); 4791 ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true); 4792 return ri; 4793 } 4794 } 4795 return null; 4796 } 4797 4798 private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType, 4799 int flags, List<ResolveInfo> query, boolean debug, int userId) { 4800 final int N = query.size(); 4801 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 4802 .get(userId); 4803 // Get the list of persistent preferred activities that handle the intent 4804 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities..."); 4805 List<PersistentPreferredActivity> pprefs = ppir != null 4806 ? ppir.queryIntent(intent, resolvedType, 4807 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 4808 : null; 4809 if (pprefs != null && pprefs.size() > 0) { 4810 final int M = pprefs.size(); 4811 for (int i=0; i<M; i++) { 4812 final PersistentPreferredActivity ppa = pprefs.get(i); 4813 if (DEBUG_PREFERRED || debug) { 4814 Slog.v(TAG, "Checking PersistentPreferredActivity ds=" 4815 + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>") 4816 + "\n component=" + ppa.mComponent); 4817 ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4818 } 4819 final ActivityInfo ai = getActivityInfo(ppa.mComponent, 4820 flags | MATCH_DISABLED_COMPONENTS, userId); 4821 if (DEBUG_PREFERRED || debug) { 4822 Slog.v(TAG, "Found persistent preferred activity:"); 4823 if (ai != null) { 4824 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4825 } else { 4826 Slog.v(TAG, " null"); 4827 } 4828 } 4829 if (ai == null) { 4830 // This previously registered persistent preferred activity 4831 // component is no longer known. Ignore it and do NOT remove it. 4832 continue; 4833 } 4834 for (int j=0; j<N; j++) { 4835 final ResolveInfo ri = query.get(j); 4836 if (!ri.activityInfo.applicationInfo.packageName 4837 .equals(ai.applicationInfo.packageName)) { 4838 continue; 4839 } 4840 if (!ri.activityInfo.name.equals(ai.name)) { 4841 continue; 4842 } 4843 // Found a persistent preference that can handle the intent. 4844 if (DEBUG_PREFERRED || debug) { 4845 Slog.v(TAG, "Returning persistent preferred activity: " + 4846 ri.activityInfo.packageName + "/" + ri.activityInfo.name); 4847 } 4848 return ri; 4849 } 4850 } 4851 } 4852 return null; 4853 } 4854 4855 // TODO: handle preferred activities missing while user has amnesia 4856 ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags, 4857 List<ResolveInfo> query, int priority, boolean always, 4858 boolean removeMatches, boolean debug, int userId) { 4859 if (!sUserManager.exists(userId)) return null; 4860 flags = updateFlagsForResolve(flags, userId, intent); 4861 // writer 4862 synchronized (mPackages) { 4863 if (intent.getSelector() != null) { 4864 intent = intent.getSelector(); 4865 } 4866 if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION); 4867 4868 // Try to find a matching persistent preferred activity. 4869 ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query, 4870 debug, userId); 4871 4872 // If a persistent preferred activity matched, use it. 4873 if (pri != null) { 4874 return pri; 4875 } 4876 4877 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 4878 // Get the list of preferred activities that handle the intent 4879 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities..."); 4880 List<PreferredActivity> prefs = pir != null 4881 ? pir.queryIntent(intent, resolvedType, 4882 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 4883 : null; 4884 if (prefs != null && prefs.size() > 0) { 4885 boolean changed = false; 4886 try { 4887 // First figure out how good the original match set is. 4888 // We will only allow preferred activities that came 4889 // from the same match quality. 4890 int match = 0; 4891 4892 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match..."); 4893 4894 final int N = query.size(); 4895 for (int j=0; j<N; j++) { 4896 final ResolveInfo ri = query.get(j); 4897 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo 4898 + ": 0x" + Integer.toHexString(match)); 4899 if (ri.match > match) { 4900 match = ri.match; 4901 } 4902 } 4903 4904 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x" 4905 + Integer.toHexString(match)); 4906 4907 match &= IntentFilter.MATCH_CATEGORY_MASK; 4908 final int M = prefs.size(); 4909 for (int i=0; i<M; i++) { 4910 final PreferredActivity pa = prefs.get(i); 4911 if (DEBUG_PREFERRED || debug) { 4912 Slog.v(TAG, "Checking PreferredActivity ds=" 4913 + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>") 4914 + "\n component=" + pa.mPref.mComponent); 4915 pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4916 } 4917 if (pa.mPref.mMatch != match) { 4918 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match " 4919 + Integer.toHexString(pa.mPref.mMatch)); 4920 continue; 4921 } 4922 // If it's not an "always" type preferred activity and that's what we're 4923 // looking for, skip it. 4924 if (always && !pa.mPref.mAlways) { 4925 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry"); 4926 continue; 4927 } 4928 final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent, 4929 flags | MATCH_DISABLED_COMPONENTS, userId); 4930 if (DEBUG_PREFERRED || debug) { 4931 Slog.v(TAG, "Found preferred activity:"); 4932 if (ai != null) { 4933 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4934 } else { 4935 Slog.v(TAG, " null"); 4936 } 4937 } 4938 if (ai == null) { 4939 // This previously registered preferred activity 4940 // component is no longer known. Most likely an update 4941 // to the app was installed and in the new version this 4942 // component no longer exists. Clean it up by removing 4943 // it from the preferred activities list, and skip it. 4944 Slog.w(TAG, "Removing dangling preferred activity: " 4945 + pa.mPref.mComponent); 4946 pir.removeFilter(pa); 4947 changed = true; 4948 continue; 4949 } 4950 for (int j=0; j<N; j++) { 4951 final ResolveInfo ri = query.get(j); 4952 if (!ri.activityInfo.applicationInfo.packageName 4953 .equals(ai.applicationInfo.packageName)) { 4954 continue; 4955 } 4956 if (!ri.activityInfo.name.equals(ai.name)) { 4957 continue; 4958 } 4959 4960 if (removeMatches) { 4961 pir.removeFilter(pa); 4962 changed = true; 4963 if (DEBUG_PREFERRED) { 4964 Slog.v(TAG, "Removing match " + pa.mPref.mComponent); 4965 } 4966 break; 4967 } 4968 4969 // Okay we found a previously set preferred or last chosen app. 4970 // If the result set is different from when this 4971 // was created, we need to clear it and re-ask the 4972 // user their preference, if we're looking for an "always" type entry. 4973 if (always && !pa.mPref.sameSet(query)) { 4974 Slog.i(TAG, "Result set changed, dropping preferred activity for " 4975 + intent + " type " + resolvedType); 4976 if (DEBUG_PREFERRED) { 4977 Slog.v(TAG, "Removing preferred activity since set changed " 4978 + pa.mPref.mComponent); 4979 } 4980 pir.removeFilter(pa); 4981 // Re-add the filter as a "last chosen" entry (!always) 4982 PreferredActivity lastChosen = new PreferredActivity( 4983 pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false); 4984 pir.addFilter(lastChosen); 4985 changed = true; 4986 return null; 4987 } 4988 4989 // Yay! Either the set matched or we're looking for the last chosen 4990 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: " 4991 + ri.activityInfo.packageName + "/" + ri.activityInfo.name); 4992 return ri; 4993 } 4994 } 4995 } finally { 4996 if (changed) { 4997 if (DEBUG_PREFERRED) { 4998 Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions"); 4999 } 5000 scheduleWritePackageRestrictionsLocked(userId); 5001 } 5002 } 5003 } 5004 } 5005 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return"); 5006 return null; 5007 } 5008 5009 /* 5010 * Returns if intent can be forwarded from the sourceUserId to the targetUserId 5011 */ 5012 @Override 5013 public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId, 5014 int targetUserId) { 5015 mContext.enforceCallingOrSelfPermission( 5016 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 5017 List<CrossProfileIntentFilter> matches = 5018 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId); 5019 if (matches != null) { 5020 int size = matches.size(); 5021 for (int i = 0; i < size; i++) { 5022 if (matches.get(i).getTargetUserId() == targetUserId) return true; 5023 } 5024 } 5025 if (hasWebURI(intent)) { 5026 // cross-profile app linking works only towards the parent. 5027 final UserInfo parent = getProfileParent(sourceUserId); 5028 synchronized(mPackages) { 5029 int flags = updateFlagsForResolve(0, parent.id, intent); 5030 CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr( 5031 intent, resolvedType, flags, sourceUserId, parent.id); 5032 return xpDomainInfo != null; 5033 } 5034 } 5035 return false; 5036 } 5037 5038 private UserInfo getProfileParent(int userId) { 5039 final long identity = Binder.clearCallingIdentity(); 5040 try { 5041 return sUserManager.getProfileParent(userId); 5042 } finally { 5043 Binder.restoreCallingIdentity(identity); 5044 } 5045 } 5046 5047 private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent, 5048 String resolvedType, int userId) { 5049 CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId); 5050 if (resolver != null) { 5051 return resolver.queryIntent(intent, resolvedType, false, userId); 5052 } 5053 return null; 5054 } 5055 5056 @Override 5057 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent, 5058 String resolvedType, int flags, int userId) { 5059 return new ParceledListSlice<>( 5060 queryIntentActivitiesInternal(intent, resolvedType, flags, userId)); 5061 } 5062 5063 private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, 5064 String resolvedType, int flags, int userId) { 5065 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5066 flags = updateFlagsForResolve(flags, userId, intent); 5067 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5068 false /* requireFullPermission */, false /* checkShell */, 5069 "query intent activities"); 5070 ComponentName comp = intent.getComponent(); 5071 if (comp == null) { 5072 if (intent.getSelector() != null) { 5073 intent = intent.getSelector(); 5074 comp = intent.getComponent(); 5075 } 5076 } 5077 5078 if (comp != null) { 5079 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5080 final ActivityInfo ai = getActivityInfo(comp, flags, userId); 5081 if (ai != null) { 5082 final ResolveInfo ri = new ResolveInfo(); 5083 ri.activityInfo = ai; 5084 list.add(ri); 5085 } 5086 return list; 5087 } 5088 5089 // reader 5090 synchronized (mPackages) { 5091 final String pkgName = intent.getPackage(); 5092 if (pkgName == null) { 5093 List<CrossProfileIntentFilter> matchingFilters = 5094 getMatchingCrossProfileIntentFilters(intent, resolvedType, userId); 5095 // Check for results that need to skip the current profile. 5096 ResolveInfo xpResolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent, 5097 resolvedType, flags, userId); 5098 if (xpResolveInfo != null) { 5099 List<ResolveInfo> result = new ArrayList<ResolveInfo>(1); 5100 result.add(xpResolveInfo); 5101 return filterIfNotSystemUser(result, userId); 5102 } 5103 5104 // Check for results in the current profile. 5105 List<ResolveInfo> result = mActivities.queryIntent( 5106 intent, resolvedType, flags, userId); 5107 result = filterIfNotSystemUser(result, userId); 5108 5109 // Check for cross profile results. 5110 boolean hasNonNegativePriorityResult = hasNonNegativePriority(result); 5111 xpResolveInfo = queryCrossProfileIntents( 5112 matchingFilters, intent, resolvedType, flags, userId, 5113 hasNonNegativePriorityResult); 5114 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) { 5115 boolean isVisibleToUser = filterIfNotSystemUser( 5116 Collections.singletonList(xpResolveInfo), userId).size() > 0; 5117 if (isVisibleToUser) { 5118 result.add(xpResolveInfo); 5119 Collections.sort(result, mResolvePrioritySorter); 5120 } 5121 } 5122 if (hasWebURI(intent)) { 5123 CrossProfileDomainInfo xpDomainInfo = null; 5124 final UserInfo parent = getProfileParent(userId); 5125 if (parent != null) { 5126 xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType, 5127 flags, userId, parent.id); 5128 } 5129 if (xpDomainInfo != null) { 5130 if (xpResolveInfo != null) { 5131 // If we didn't remove it, the cross-profile ResolveInfo would be twice 5132 // in the result. 5133 result.remove(xpResolveInfo); 5134 } 5135 if (result.size() == 0) { 5136 result.add(xpDomainInfo.resolveInfo); 5137 return result; 5138 } 5139 } else if (result.size() <= 1) { 5140 return result; 5141 } 5142 result = filterCandidatesWithDomainPreferredActivitiesLPr(intent, flags, result, 5143 xpDomainInfo, userId); 5144 Collections.sort(result, mResolvePrioritySorter); 5145 } 5146 return result; 5147 } 5148 final PackageParser.Package pkg = mPackages.get(pkgName); 5149 if (pkg != null) { 5150 return filterIfNotSystemUser( 5151 mActivities.queryIntentForPackage( 5152 intent, resolvedType, flags, pkg.activities, userId), 5153 userId); 5154 } 5155 return new ArrayList<ResolveInfo>(); 5156 } 5157 } 5158 5159 private static class CrossProfileDomainInfo { 5160 /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */ 5161 ResolveInfo resolveInfo; 5162 /* Best domain verification status of the activities found in the other profile */ 5163 int bestDomainVerificationStatus; 5164 } 5165 5166 private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent, 5167 String resolvedType, int flags, int sourceUserId, int parentUserId) { 5168 if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING, 5169 sourceUserId)) { 5170 return null; 5171 } 5172 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 5173 resolvedType, flags, parentUserId); 5174 5175 if (resultTargetUser == null || resultTargetUser.isEmpty()) { 5176 return null; 5177 } 5178 CrossProfileDomainInfo result = null; 5179 int size = resultTargetUser.size(); 5180 for (int i = 0; i < size; i++) { 5181 ResolveInfo riTargetUser = resultTargetUser.get(i); 5182 // Intent filter verification is only for filters that specify a host. So don't return 5183 // those that handle all web uris. 5184 if (riTargetUser.handleAllWebDataURI) { 5185 continue; 5186 } 5187 String packageName = riTargetUser.activityInfo.packageName; 5188 PackageSetting ps = mSettings.mPackages.get(packageName); 5189 if (ps == null) { 5190 continue; 5191 } 5192 long verificationState = getDomainVerificationStatusLPr(ps, parentUserId); 5193 int status = (int)(verificationState >> 32); 5194 if (result == null) { 5195 result = new CrossProfileDomainInfo(); 5196 result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(), 5197 sourceUserId, parentUserId); 5198 result.bestDomainVerificationStatus = status; 5199 } else { 5200 result.bestDomainVerificationStatus = bestDomainVerificationStatus(status, 5201 result.bestDomainVerificationStatus); 5202 } 5203 } 5204 // Don't consider matches with status NEVER across profiles. 5205 if (result != null && result.bestDomainVerificationStatus 5206 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5207 return null; 5208 } 5209 return result; 5210 } 5211 5212 /** 5213 * Verification statuses are ordered from the worse to the best, except for 5214 * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse. 5215 */ 5216 private int bestDomainVerificationStatus(int status1, int status2) { 5217 if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5218 return status2; 5219 } 5220 if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5221 return status1; 5222 } 5223 return (int) MathUtils.max(status1, status2); 5224 } 5225 5226 private boolean isUserEnabled(int userId) { 5227 long callingId = Binder.clearCallingIdentity(); 5228 try { 5229 UserInfo userInfo = sUserManager.getUserInfo(userId); 5230 return userInfo != null && userInfo.isEnabled(); 5231 } finally { 5232 Binder.restoreCallingIdentity(callingId); 5233 } 5234 } 5235 5236 /** 5237 * Filter out activities with systemUserOnly flag set, when current user is not System. 5238 * 5239 * @return filtered list 5240 */ 5241 private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) { 5242 if (userId == UserHandle.USER_SYSTEM) { 5243 return resolveInfos; 5244 } 5245 for (int i = resolveInfos.size() - 1; i >= 0; i--) { 5246 ResolveInfo info = resolveInfos.get(i); 5247 if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) { 5248 resolveInfos.remove(i); 5249 } 5250 } 5251 return resolveInfos; 5252 } 5253 5254 /** 5255 * @param resolveInfos list of resolve infos in descending priority order 5256 * @return if the list contains a resolve info with non-negative priority 5257 */ 5258 private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) { 5259 return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0; 5260 } 5261 5262 private static boolean hasWebURI(Intent intent) { 5263 if (intent.getData() == null) { 5264 return false; 5265 } 5266 final String scheme = intent.getScheme(); 5267 if (TextUtils.isEmpty(scheme)) { 5268 return false; 5269 } 5270 return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS); 5271 } 5272 5273 private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent, 5274 int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo, 5275 int userId) { 5276 final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0; 5277 5278 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) { 5279 Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " + 5280 candidates.size()); 5281 } 5282 5283 ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>(); 5284 ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>(); 5285 ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>(); 5286 ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>(); 5287 ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>(); 5288 ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>(); 5289 5290 synchronized (mPackages) { 5291 final int count = candidates.size(); 5292 // First, try to use linked apps. Partition the candidates into four lists: 5293 // one for the final results, one for the "do not use ever", one for "undefined status" 5294 // and finally one for "browser app type". 5295 for (int n=0; n<count; n++) { 5296 ResolveInfo info = candidates.get(n); 5297 String packageName = info.activityInfo.packageName; 5298 PackageSetting ps = mSettings.mPackages.get(packageName); 5299 if (ps != null) { 5300 // Add to the special match all list (Browser use case) 5301 if (info.handleAllWebDataURI) { 5302 matchAllList.add(info); 5303 continue; 5304 } 5305 // Try to get the status from User settings first 5306 long packedStatus = getDomainVerificationStatusLPr(ps, userId); 5307 int status = (int)(packedStatus >> 32); 5308 int linkGeneration = (int)(packedStatus & 0xFFFFFFFF); 5309 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) { 5310 if (DEBUG_DOMAIN_VERIFICATION) { 5311 Slog.i(TAG, " + always: " + info.activityInfo.packageName 5312 + " : linkgen=" + linkGeneration); 5313 } 5314 // Use link-enabled generation as preferredOrder, i.e. 5315 // prefer newly-enabled over earlier-enabled. 5316 info.preferredOrder = linkGeneration; 5317 alwaysList.add(info); 5318 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5319 if (DEBUG_DOMAIN_VERIFICATION) { 5320 Slog.i(TAG, " + never: " + info.activityInfo.packageName); 5321 } 5322 neverList.add(info); 5323 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) { 5324 if (DEBUG_DOMAIN_VERIFICATION) { 5325 Slog.i(TAG, " + always-ask: " + info.activityInfo.packageName); 5326 } 5327 alwaysAskList.add(info); 5328 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED || 5329 status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) { 5330 if (DEBUG_DOMAIN_VERIFICATION) { 5331 Slog.i(TAG, " + ask: " + info.activityInfo.packageName); 5332 } 5333 undefinedList.add(info); 5334 } 5335 } 5336 } 5337 5338 // We'll want to include browser possibilities in a few cases 5339 boolean includeBrowser = false; 5340 5341 // First try to add the "always" resolution(s) for the current user, if any 5342 if (alwaysList.size() > 0) { 5343 result.addAll(alwaysList); 5344 } else { 5345 // Add all undefined apps as we want them to appear in the disambiguation dialog. 5346 result.addAll(undefinedList); 5347 // Maybe add one for the other profile. 5348 if (xpDomainInfo != null && ( 5349 xpDomainInfo.bestDomainVerificationStatus 5350 != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) { 5351 result.add(xpDomainInfo.resolveInfo); 5352 } 5353 includeBrowser = true; 5354 } 5355 5356 // The presence of any 'always ask' alternatives means we'll also offer browsers. 5357 // If there were 'always' entries their preferred order has been set, so we also 5358 // back that off to make the alternatives equivalent 5359 if (alwaysAskList.size() > 0) { 5360 for (ResolveInfo i : result) { 5361 i.preferredOrder = 0; 5362 } 5363 result.addAll(alwaysAskList); 5364 includeBrowser = true; 5365 } 5366 5367 if (includeBrowser) { 5368 // Also add browsers (all of them or only the default one) 5369 if (DEBUG_DOMAIN_VERIFICATION) { 5370 Slog.v(TAG, " ...including browsers in candidate set"); 5371 } 5372 if ((matchFlags & MATCH_ALL) != 0) { 5373 result.addAll(matchAllList); 5374 } else { 5375 // Browser/generic handling case. If there's a default browser, go straight 5376 // to that (but only if there is no other higher-priority match). 5377 final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId); 5378 int maxMatchPrio = 0; 5379 ResolveInfo defaultBrowserMatch = null; 5380 final int numCandidates = matchAllList.size(); 5381 for (int n = 0; n < numCandidates; n++) { 5382 ResolveInfo info = matchAllList.get(n); 5383 // track the highest overall match priority... 5384 if (info.priority > maxMatchPrio) { 5385 maxMatchPrio = info.priority; 5386 } 5387 // ...and the highest-priority default browser match 5388 if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) { 5389 if (defaultBrowserMatch == null 5390 || (defaultBrowserMatch.priority < info.priority)) { 5391 if (debug) { 5392 Slog.v(TAG, "Considering default browser match " + info); 5393 } 5394 defaultBrowserMatch = info; 5395 } 5396 } 5397 } 5398 if (defaultBrowserMatch != null 5399 && defaultBrowserMatch.priority >= maxMatchPrio 5400 && !TextUtils.isEmpty(defaultBrowserPackageName)) 5401 { 5402 if (debug) { 5403 Slog.v(TAG, "Default browser match " + defaultBrowserMatch); 5404 } 5405 result.add(defaultBrowserMatch); 5406 } else { 5407 result.addAll(matchAllList); 5408 } 5409 } 5410 5411 // If there is nothing selected, add all candidates and remove the ones that the user 5412 // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state 5413 if (result.size() == 0) { 5414 result.addAll(candidates); 5415 result.removeAll(neverList); 5416 } 5417 } 5418 } 5419 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) { 5420 Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " + 5421 result.size()); 5422 for (ResolveInfo info : result) { 5423 Slog.v(TAG, " + " + info.activityInfo); 5424 } 5425 } 5426 return result; 5427 } 5428 5429 // Returns a packed value as a long: 5430 // 5431 // high 'int'-sized word: link status: undefined/ask/never/always. 5432 // low 'int'-sized word: relative priority among 'always' results. 5433 private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) { 5434 long result = ps.getDomainVerificationStatusForUser(userId); 5435 // if none available, get the master status 5436 if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 5437 if (ps.getIntentFilterVerificationInfo() != null) { 5438 result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32; 5439 } 5440 } 5441 return result; 5442 } 5443 5444 private ResolveInfo querySkipCurrentProfileIntents( 5445 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 5446 int flags, int sourceUserId) { 5447 if (matchingFilters != null) { 5448 int size = matchingFilters.size(); 5449 for (int i = 0; i < size; i ++) { 5450 CrossProfileIntentFilter filter = matchingFilters.get(i); 5451 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) { 5452 // Checking if there are activities in the target user that can handle the 5453 // intent. 5454 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent, 5455 resolvedType, flags, sourceUserId); 5456 if (resolveInfo != null) { 5457 return resolveInfo; 5458 } 5459 } 5460 } 5461 } 5462 return null; 5463 } 5464 5465 // Return matching ResolveInfo in target user if any. 5466 private ResolveInfo queryCrossProfileIntents( 5467 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 5468 int flags, int sourceUserId, boolean matchInCurrentProfile) { 5469 if (matchingFilters != null) { 5470 // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and 5471 // match the same intent. For performance reasons, it is better not to 5472 // run queryIntent twice for the same userId 5473 SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray(); 5474 int size = matchingFilters.size(); 5475 for (int i = 0; i < size; i++) { 5476 CrossProfileIntentFilter filter = matchingFilters.get(i); 5477 int targetUserId = filter.getTargetUserId(); 5478 boolean skipCurrentProfile = 5479 (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0; 5480 boolean skipCurrentProfileIfNoMatchFound = 5481 (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0; 5482 if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId) 5483 && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) { 5484 // Checking if there are activities in the target user that can handle the 5485 // intent. 5486 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent, 5487 resolvedType, flags, sourceUserId); 5488 if (resolveInfo != null) return resolveInfo; 5489 alreadyTriedUserIds.put(targetUserId, true); 5490 } 5491 } 5492 } 5493 return null; 5494 } 5495 5496 /** 5497 * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that 5498 * will forward the intent to the filter's target user. 5499 * Otherwise, returns null. 5500 */ 5501 private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent, 5502 String resolvedType, int flags, int sourceUserId) { 5503 int targetUserId = filter.getTargetUserId(); 5504 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 5505 resolvedType, flags, targetUserId); 5506 if (resultTargetUser != null && isUserEnabled(targetUserId)) { 5507 // If all the matches in the target profile are suspended, return null. 5508 for (int i = resultTargetUser.size() - 1; i >= 0; i--) { 5509 if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags 5510 & ApplicationInfo.FLAG_SUSPENDED) == 0) { 5511 return createForwardingResolveInfoUnchecked(filter, sourceUserId, 5512 targetUserId); 5513 } 5514 } 5515 } 5516 return null; 5517 } 5518 5519 private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter, 5520 int sourceUserId, int targetUserId) { 5521 ResolveInfo forwardingResolveInfo = new ResolveInfo(); 5522 long ident = Binder.clearCallingIdentity(); 5523 boolean targetIsProfile; 5524 try { 5525 targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile(); 5526 } finally { 5527 Binder.restoreCallingIdentity(ident); 5528 } 5529 String className; 5530 if (targetIsProfile) { 5531 className = FORWARD_INTENT_TO_MANAGED_PROFILE; 5532 } else { 5533 className = FORWARD_INTENT_TO_PARENT; 5534 } 5535 ComponentName forwardingActivityComponentName = new ComponentName( 5536 mAndroidApplication.packageName, className); 5537 ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0, 5538 sourceUserId); 5539 if (!targetIsProfile) { 5540 forwardingActivityInfo.showUserIcon = targetUserId; 5541 forwardingResolveInfo.noResourceId = true; 5542 } 5543 forwardingResolveInfo.activityInfo = forwardingActivityInfo; 5544 forwardingResolveInfo.priority = 0; 5545 forwardingResolveInfo.preferredOrder = 0; 5546 forwardingResolveInfo.match = 0; 5547 forwardingResolveInfo.isDefault = true; 5548 forwardingResolveInfo.filter = filter; 5549 forwardingResolveInfo.targetUserId = targetUserId; 5550 return forwardingResolveInfo; 5551 } 5552 5553 @Override 5554 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller, 5555 Intent[] specifics, String[] specificTypes, Intent intent, 5556 String resolvedType, int flags, int userId) { 5557 return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics, 5558 specificTypes, intent, resolvedType, flags, userId)); 5559 } 5560 5561 private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller, 5562 Intent[] specifics, String[] specificTypes, Intent intent, 5563 String resolvedType, int flags, int userId) { 5564 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5565 flags = updateFlagsForResolve(flags, userId, intent); 5566 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5567 false /* requireFullPermission */, false /* checkShell */, 5568 "query intent activity options"); 5569 final String resultsAction = intent.getAction(); 5570 5571 final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags 5572 | PackageManager.GET_RESOLVED_FILTER, userId); 5573 5574 if (DEBUG_INTENT_MATCHING) { 5575 Log.v(TAG, "Query " + intent + ": " + results); 5576 } 5577 5578 int specificsPos = 0; 5579 int N; 5580 5581 // todo: note that the algorithm used here is O(N^2). This 5582 // isn't a problem in our current environment, but if we start running 5583 // into situations where we have more than 5 or 10 matches then this 5584 // should probably be changed to something smarter... 5585 5586 // First we go through and resolve each of the specific items 5587 // that were supplied, taking care of removing any corresponding 5588 // duplicate items in the generic resolve list. 5589 if (specifics != null) { 5590 for (int i=0; i<specifics.length; i++) { 5591 final Intent sintent = specifics[i]; 5592 if (sintent == null) { 5593 continue; 5594 } 5595 5596 if (DEBUG_INTENT_MATCHING) { 5597 Log.v(TAG, "Specific #" + i + ": " + sintent); 5598 } 5599 5600 String action = sintent.getAction(); 5601 if (resultsAction != null && resultsAction.equals(action)) { 5602 // If this action was explicitly requested, then don't 5603 // remove things that have it. 5604 action = null; 5605 } 5606 5607 ResolveInfo ri = null; 5608 ActivityInfo ai = null; 5609 5610 ComponentName comp = sintent.getComponent(); 5611 if (comp == null) { 5612 ri = resolveIntent( 5613 sintent, 5614 specificTypes != null ? specificTypes[i] : null, 5615 flags, userId); 5616 if (ri == null) { 5617 continue; 5618 } 5619 if (ri == mResolveInfo) { 5620 // ACK! Must do something better with this. 5621 } 5622 ai = ri.activityInfo; 5623 comp = new ComponentName(ai.applicationInfo.packageName, 5624 ai.name); 5625 } else { 5626 ai = getActivityInfo(comp, flags, userId); 5627 if (ai == null) { 5628 continue; 5629 } 5630 } 5631 5632 // Look for any generic query activities that are duplicates 5633 // of this specific one, and remove them from the results. 5634 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai); 5635 N = results.size(); 5636 int j; 5637 for (j=specificsPos; j<N; j++) { 5638 ResolveInfo sri = results.get(j); 5639 if ((sri.activityInfo.name.equals(comp.getClassName()) 5640 && sri.activityInfo.applicationInfo.packageName.equals( 5641 comp.getPackageName())) 5642 || (action != null && sri.filter.matchAction(action))) { 5643 results.remove(j); 5644 if (DEBUG_INTENT_MATCHING) Log.v( 5645 TAG, "Removing duplicate item from " + j 5646 + " due to specific " + specificsPos); 5647 if (ri == null) { 5648 ri = sri; 5649 } 5650 j--; 5651 N--; 5652 } 5653 } 5654 5655 // Add this specific item to its proper place. 5656 if (ri == null) { 5657 ri = new ResolveInfo(); 5658 ri.activityInfo = ai; 5659 } 5660 results.add(specificsPos, ri); 5661 ri.specificIndex = i; 5662 specificsPos++; 5663 } 5664 } 5665 5666 // Now we go through the remaining generic results and remove any 5667 // duplicate actions that are found here. 5668 N = results.size(); 5669 for (int i=specificsPos; i<N-1; i++) { 5670 final ResolveInfo rii = results.get(i); 5671 if (rii.filter == null) { 5672 continue; 5673 } 5674 5675 // Iterate over all of the actions of this result's intent 5676 // filter... typically this should be just one. 5677 final Iterator<String> it = rii.filter.actionsIterator(); 5678 if (it == null) { 5679 continue; 5680 } 5681 while (it.hasNext()) { 5682 final String action = it.next(); 5683 if (resultsAction != null && resultsAction.equals(action)) { 5684 // If this action was explicitly requested, then don't 5685 // remove things that have it. 5686 continue; 5687 } 5688 for (int j=i+1; j<N; j++) { 5689 final ResolveInfo rij = results.get(j); 5690 if (rij.filter != null && rij.filter.hasAction(action)) { 5691 results.remove(j); 5692 if (DEBUG_INTENT_MATCHING) Log.v( 5693 TAG, "Removing duplicate item from " + j 5694 + " due to action " + action + " at " + i); 5695 j--; 5696 N--; 5697 } 5698 } 5699 } 5700 5701 // If the caller didn't request filter information, drop it now 5702 // so we don't have to marshall/unmarshall it. 5703 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 5704 rii.filter = null; 5705 } 5706 } 5707 5708 // Filter out the caller activity if so requested. 5709 if (caller != null) { 5710 N = results.size(); 5711 for (int i=0; i<N; i++) { 5712 ActivityInfo ainfo = results.get(i).activityInfo; 5713 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName) 5714 && caller.getClassName().equals(ainfo.name)) { 5715 results.remove(i); 5716 break; 5717 } 5718 } 5719 } 5720 5721 // If the caller didn't request filter information, 5722 // drop them now so we don't have to 5723 // marshall/unmarshall it. 5724 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 5725 N = results.size(); 5726 for (int i=0; i<N; i++) { 5727 results.get(i).filter = null; 5728 } 5729 } 5730 5731 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results); 5732 return results; 5733 } 5734 5735 @Override 5736 public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent, 5737 String resolvedType, int flags, int userId) { 5738 return new ParceledListSlice<>( 5739 queryIntentReceiversInternal(intent, resolvedType, flags, userId)); 5740 } 5741 5742 private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent, 5743 String resolvedType, int flags, int userId) { 5744 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5745 flags = updateFlagsForResolve(flags, userId, intent); 5746 ComponentName comp = intent.getComponent(); 5747 if (comp == null) { 5748 if (intent.getSelector() != null) { 5749 intent = intent.getSelector(); 5750 comp = intent.getComponent(); 5751 } 5752 } 5753 if (comp != null) { 5754 List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5755 ActivityInfo ai = getReceiverInfo(comp, flags, userId); 5756 if (ai != null) { 5757 ResolveInfo ri = new ResolveInfo(); 5758 ri.activityInfo = ai; 5759 list.add(ri); 5760 } 5761 return list; 5762 } 5763 5764 // reader 5765 synchronized (mPackages) { 5766 String pkgName = intent.getPackage(); 5767 if (pkgName == null) { 5768 return mReceivers.queryIntent(intent, resolvedType, flags, userId); 5769 } 5770 final PackageParser.Package pkg = mPackages.get(pkgName); 5771 if (pkg != null) { 5772 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers, 5773 userId); 5774 } 5775 return Collections.emptyList(); 5776 } 5777 } 5778 5779 @Override 5780 public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) { 5781 if (!sUserManager.exists(userId)) return null; 5782 flags = updateFlagsForResolve(flags, userId, intent); 5783 List<ResolveInfo> query = queryIntentServicesInternal(intent, resolvedType, flags, userId); 5784 if (query != null) { 5785 if (query.size() >= 1) { 5786 // If there is more than one service with the same priority, 5787 // just arbitrarily pick the first one. 5788 return query.get(0); 5789 } 5790 } 5791 return null; 5792 } 5793 5794 @Override 5795 public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent, 5796 String resolvedType, int flags, int userId) { 5797 return new ParceledListSlice<>( 5798 queryIntentServicesInternal(intent, resolvedType, flags, userId)); 5799 } 5800 5801 private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent, 5802 String resolvedType, int flags, int userId) { 5803 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5804 flags = updateFlagsForResolve(flags, userId, intent); 5805 ComponentName comp = intent.getComponent(); 5806 if (comp == null) { 5807 if (intent.getSelector() != null) { 5808 intent = intent.getSelector(); 5809 comp = intent.getComponent(); 5810 } 5811 } 5812 if (comp != null) { 5813 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5814 final ServiceInfo si = getServiceInfo(comp, flags, userId); 5815 if (si != null) { 5816 final ResolveInfo ri = new ResolveInfo(); 5817 ri.serviceInfo = si; 5818 list.add(ri); 5819 } 5820 return list; 5821 } 5822 5823 // reader 5824 synchronized (mPackages) { 5825 String pkgName = intent.getPackage(); 5826 if (pkgName == null) { 5827 return mServices.queryIntent(intent, resolvedType, flags, userId); 5828 } 5829 final PackageParser.Package pkg = mPackages.get(pkgName); 5830 if (pkg != null) { 5831 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services, 5832 userId); 5833 } 5834 return Collections.emptyList(); 5835 } 5836 } 5837 5838 @Override 5839 public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent, 5840 String resolvedType, int flags, int userId) { 5841 return new ParceledListSlice<>( 5842 queryIntentContentProvidersInternal(intent, resolvedType, flags, userId)); 5843 } 5844 5845 private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal( 5846 Intent intent, String resolvedType, int flags, int userId) { 5847 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5848 flags = updateFlagsForResolve(flags, userId, intent); 5849 ComponentName comp = intent.getComponent(); 5850 if (comp == null) { 5851 if (intent.getSelector() != null) { 5852 intent = intent.getSelector(); 5853 comp = intent.getComponent(); 5854 } 5855 } 5856 if (comp != null) { 5857 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5858 final ProviderInfo pi = getProviderInfo(comp, flags, userId); 5859 if (pi != null) { 5860 final ResolveInfo ri = new ResolveInfo(); 5861 ri.providerInfo = pi; 5862 list.add(ri); 5863 } 5864 return list; 5865 } 5866 5867 // reader 5868 synchronized (mPackages) { 5869 String pkgName = intent.getPackage(); 5870 if (pkgName == null) { 5871 return mProviders.queryIntent(intent, resolvedType, flags, userId); 5872 } 5873 final PackageParser.Package pkg = mPackages.get(pkgName); 5874 if (pkg != null) { 5875 return mProviders.queryIntentForPackage( 5876 intent, resolvedType, flags, pkg.providers, userId); 5877 } 5878 return Collections.emptyList(); 5879 } 5880 } 5881 5882 @Override 5883 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) { 5884 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 5885 flags = updateFlagsForPackage(flags, userId, null); 5886 final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0; 5887 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5888 true /* requireFullPermission */, false /* checkShell */, 5889 "get installed packages"); 5890 5891 // writer 5892 synchronized (mPackages) { 5893 ArrayList<PackageInfo> list; 5894 if (listUninstalled) { 5895 list = new ArrayList<PackageInfo>(mSettings.mPackages.size()); 5896 for (PackageSetting ps : mSettings.mPackages.values()) { 5897 PackageInfo pi; 5898 if (ps.pkg != null) { 5899 pi = generatePackageInfo(ps.pkg, flags, userId); 5900 } else { 5901 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId); 5902 } 5903 if (pi != null) { 5904 list.add(pi); 5905 } 5906 } 5907 } else { 5908 list = new ArrayList<PackageInfo>(mPackages.size()); 5909 for (PackageParser.Package p : mPackages.values()) { 5910 PackageInfo pi = generatePackageInfo(p, flags, userId); 5911 if (pi != null) { 5912 list.add(pi); 5913 } 5914 } 5915 } 5916 5917 return new ParceledListSlice<PackageInfo>(list); 5918 } 5919 } 5920 5921 private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps, 5922 String[] permissions, boolean[] tmp, int flags, int userId) { 5923 int numMatch = 0; 5924 final PermissionsState permissionsState = ps.getPermissionsState(); 5925 for (int i=0; i<permissions.length; i++) { 5926 final String permission = permissions[i]; 5927 if (permissionsState.hasPermission(permission, userId)) { 5928 tmp[i] = true; 5929 numMatch++; 5930 } else { 5931 tmp[i] = false; 5932 } 5933 } 5934 if (numMatch == 0) { 5935 return; 5936 } 5937 PackageInfo pi; 5938 if (ps.pkg != null) { 5939 pi = generatePackageInfo(ps.pkg, flags, userId); 5940 } else { 5941 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId); 5942 } 5943 // The above might return null in cases of uninstalled apps or install-state 5944 // skew across users/profiles. 5945 if (pi != null) { 5946 if ((flags&PackageManager.GET_PERMISSIONS) == 0) { 5947 if (numMatch == permissions.length) { 5948 pi.requestedPermissions = permissions; 5949 } else { 5950 pi.requestedPermissions = new String[numMatch]; 5951 numMatch = 0; 5952 for (int i=0; i<permissions.length; i++) { 5953 if (tmp[i]) { 5954 pi.requestedPermissions[numMatch] = permissions[i]; 5955 numMatch++; 5956 } 5957 } 5958 } 5959 } 5960 list.add(pi); 5961 } 5962 } 5963 5964 @Override 5965 public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions( 5966 String[] permissions, int flags, int userId) { 5967 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 5968 flags = updateFlagsForPackage(flags, userId, permissions); 5969 final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0; 5970 5971 // writer 5972 synchronized (mPackages) { 5973 ArrayList<PackageInfo> list = new ArrayList<PackageInfo>(); 5974 boolean[] tmpBools = new boolean[permissions.length]; 5975 if (listUninstalled) { 5976 for (PackageSetting ps : mSettings.mPackages.values()) { 5977 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId); 5978 } 5979 } else { 5980 for (PackageParser.Package pkg : mPackages.values()) { 5981 PackageSetting ps = (PackageSetting)pkg.mExtras; 5982 if (ps != null) { 5983 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, 5984 userId); 5985 } 5986 } 5987 } 5988 5989 return new ParceledListSlice<PackageInfo>(list); 5990 } 5991 } 5992 5993 @Override 5994 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) { 5995 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 5996 flags = updateFlagsForApplication(flags, userId, null); 5997 final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0; 5998 5999 // writer 6000 synchronized (mPackages) { 6001 ArrayList<ApplicationInfo> list; 6002 if (listUninstalled) { 6003 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size()); 6004 for (PackageSetting ps : mSettings.mPackages.values()) { 6005 ApplicationInfo ai; 6006 if (ps.pkg != null) { 6007 ai = PackageParser.generateApplicationInfo(ps.pkg, flags, 6008 ps.readUserState(userId), userId); 6009 } else { 6010 ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId); 6011 } 6012 if (ai != null) { 6013 list.add(ai); 6014 } 6015 } 6016 } else { 6017 list = new ArrayList<ApplicationInfo>(mPackages.size()); 6018 for (PackageParser.Package p : mPackages.values()) { 6019 if (p.mExtras != null) { 6020 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 6021 ((PackageSetting)p.mExtras).readUserState(userId), userId); 6022 if (ai != null) { 6023 list.add(ai); 6024 } 6025 } 6026 } 6027 } 6028 6029 return new ParceledListSlice<ApplicationInfo>(list); 6030 } 6031 } 6032 6033 @Override 6034 public ParceledListSlice<EphemeralApplicationInfo> getEphemeralApplications(int userId) { 6035 if (DISABLE_EPHEMERAL_APPS) { 6036 return null; 6037 } 6038 6039 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS, 6040 "getEphemeralApplications"); 6041 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6042 true /* requireFullPermission */, false /* checkShell */, 6043 "getEphemeralApplications"); 6044 synchronized (mPackages) { 6045 List<EphemeralApplicationInfo> ephemeralApps = mEphemeralApplicationRegistry 6046 .getEphemeralApplicationsLPw(userId); 6047 if (ephemeralApps != null) { 6048 return new ParceledListSlice<>(ephemeralApps); 6049 } 6050 } 6051 return null; 6052 } 6053 6054 @Override 6055 public boolean isEphemeralApplication(String packageName, int userId) { 6056 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6057 true /* requireFullPermission */, false /* checkShell */, 6058 "isEphemeral"); 6059 if (DISABLE_EPHEMERAL_APPS) { 6060 return false; 6061 } 6062 6063 if (!isCallerSameApp(packageName)) { 6064 return false; 6065 } 6066 synchronized (mPackages) { 6067 PackageParser.Package pkg = mPackages.get(packageName); 6068 if (pkg != null) { 6069 return pkg.applicationInfo.isEphemeralApp(); 6070 } 6071 } 6072 return false; 6073 } 6074 6075 @Override 6076 public byte[] getEphemeralApplicationCookie(String packageName, int userId) { 6077 if (DISABLE_EPHEMERAL_APPS) { 6078 return null; 6079 } 6080 6081 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6082 true /* requireFullPermission */, false /* checkShell */, 6083 "getCookie"); 6084 if (!isCallerSameApp(packageName)) { 6085 return null; 6086 } 6087 synchronized (mPackages) { 6088 return mEphemeralApplicationRegistry.getEphemeralApplicationCookieLPw( 6089 packageName, userId); 6090 } 6091 } 6092 6093 @Override 6094 public boolean setEphemeralApplicationCookie(String packageName, byte[] cookie, int userId) { 6095 if (DISABLE_EPHEMERAL_APPS) { 6096 return true; 6097 } 6098 6099 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6100 true /* requireFullPermission */, true /* checkShell */, 6101 "setCookie"); 6102 if (!isCallerSameApp(packageName)) { 6103 return false; 6104 } 6105 synchronized (mPackages) { 6106 return mEphemeralApplicationRegistry.setEphemeralApplicationCookieLPw( 6107 packageName, cookie, userId); 6108 } 6109 } 6110 6111 @Override 6112 public Bitmap getEphemeralApplicationIcon(String packageName, int userId) { 6113 if (DISABLE_EPHEMERAL_APPS) { 6114 return null; 6115 } 6116 6117 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS, 6118 "getEphemeralApplicationIcon"); 6119 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6120 true /* requireFullPermission */, false /* checkShell */, 6121 "getEphemeralApplicationIcon"); 6122 synchronized (mPackages) { 6123 return mEphemeralApplicationRegistry.getEphemeralApplicationIconLPw( 6124 packageName, userId); 6125 } 6126 } 6127 6128 private boolean isCallerSameApp(String packageName) { 6129 PackageParser.Package pkg = mPackages.get(packageName); 6130 return pkg != null 6131 && UserHandle.getAppId(Binder.getCallingUid()) == pkg.applicationInfo.uid; 6132 } 6133 6134 @Override 6135 public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) { 6136 return new ParceledListSlice<>(getPersistentApplicationsInternal(flags)); 6137 } 6138 6139 private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) { 6140 final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>(); 6141 6142 // reader 6143 synchronized (mPackages) { 6144 final Iterator<PackageParser.Package> i = mPackages.values().iterator(); 6145 final int userId = UserHandle.getCallingUserId(); 6146 while (i.hasNext()) { 6147 final PackageParser.Package p = i.next(); 6148 if (p.applicationInfo == null) continue; 6149 6150 final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0) 6151 && !p.applicationInfo.isDirectBootAware(); 6152 final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0) 6153 && p.applicationInfo.isDirectBootAware(); 6154 6155 if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0 6156 && (!mSafeMode || isSystemApp(p)) 6157 && (matchesUnaware || matchesAware)) { 6158 PackageSetting ps = mSettings.mPackages.get(p.packageName); 6159 if (ps != null) { 6160 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 6161 ps.readUserState(userId), userId); 6162 if (ai != null) { 6163 finalList.add(ai); 6164 } 6165 } 6166 } 6167 } 6168 } 6169 6170 return finalList; 6171 } 6172 6173 @Override 6174 public ProviderInfo resolveContentProvider(String name, int flags, int userId) { 6175 if (!sUserManager.exists(userId)) return null; 6176 flags = updateFlagsForComponent(flags, userId, name); 6177 // reader 6178 synchronized (mPackages) { 6179 final PackageParser.Provider provider = mProvidersByAuthority.get(name); 6180 PackageSetting ps = provider != null 6181 ? mSettings.mPackages.get(provider.owner.packageName) 6182 : null; 6183 return ps != null 6184 && mSettings.isEnabledAndMatchLPr(provider.info, flags, userId) 6185 ? PackageParser.generateProviderInfo(provider, flags, 6186 ps.readUserState(userId), userId) 6187 : null; 6188 } 6189 } 6190 6191 /** 6192 * @deprecated 6193 */ 6194 @Deprecated 6195 public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) { 6196 // reader 6197 synchronized (mPackages) { 6198 final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority 6199 .entrySet().iterator(); 6200 final int userId = UserHandle.getCallingUserId(); 6201 while (i.hasNext()) { 6202 Map.Entry<String, PackageParser.Provider> entry = i.next(); 6203 PackageParser.Provider p = entry.getValue(); 6204 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 6205 6206 if (ps != null && p.syncable 6207 && (!mSafeMode || (p.info.applicationInfo.flags 6208 &ApplicationInfo.FLAG_SYSTEM) != 0)) { 6209 ProviderInfo info = PackageParser.generateProviderInfo(p, 0, 6210 ps.readUserState(userId), userId); 6211 if (info != null) { 6212 outNames.add(entry.getKey()); 6213 outInfo.add(info); 6214 } 6215 } 6216 } 6217 } 6218 } 6219 6220 @Override 6221 public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName, 6222 int uid, int flags) { 6223 final int userId = processName != null ? UserHandle.getUserId(uid) 6224 : UserHandle.getCallingUserId(); 6225 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 6226 flags = updateFlagsForComponent(flags, userId, processName); 6227 6228 ArrayList<ProviderInfo> finalList = null; 6229 // reader 6230 synchronized (mPackages) { 6231 final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator(); 6232 while (i.hasNext()) { 6233 final PackageParser.Provider p = i.next(); 6234 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 6235 if (ps != null && p.info.authority != null 6236 && (processName == null 6237 || (p.info.processName.equals(processName) 6238 && UserHandle.isSameApp(p.info.applicationInfo.uid, uid))) 6239 && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) { 6240 if (finalList == null) { 6241 finalList = new ArrayList<ProviderInfo>(3); 6242 } 6243 ProviderInfo info = PackageParser.generateProviderInfo(p, flags, 6244 ps.readUserState(userId), userId); 6245 if (info != null) { 6246 finalList.add(info); 6247 } 6248 } 6249 } 6250 } 6251 6252 if (finalList != null) { 6253 Collections.sort(finalList, mProviderInitOrderSorter); 6254 return new ParceledListSlice<ProviderInfo>(finalList); 6255 } 6256 6257 return ParceledListSlice.emptyList(); 6258 } 6259 6260 @Override 6261 public InstrumentationInfo getInstrumentationInfo(ComponentName name, int flags) { 6262 // reader 6263 synchronized (mPackages) { 6264 final PackageParser.Instrumentation i = mInstrumentation.get(name); 6265 return PackageParser.generateInstrumentationInfo(i, flags); 6266 } 6267 } 6268 6269 @Override 6270 public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation( 6271 String targetPackage, int flags) { 6272 return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags)); 6273 } 6274 6275 private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage, 6276 int flags) { 6277 ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>(); 6278 6279 // reader 6280 synchronized (mPackages) { 6281 final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator(); 6282 while (i.hasNext()) { 6283 final PackageParser.Instrumentation p = i.next(); 6284 if (targetPackage == null 6285 || targetPackage.equals(p.info.targetPackage)) { 6286 InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p, 6287 flags); 6288 if (ii != null) { 6289 finalList.add(ii); 6290 } 6291 } 6292 } 6293 } 6294 6295 return finalList; 6296 } 6297 6298 private void createIdmapsForPackageLI(PackageParser.Package pkg) { 6299 ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName); 6300 if (overlays == null) { 6301 Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages"); 6302 return; 6303 } 6304 for (PackageParser.Package opkg : overlays.values()) { 6305 // Not much to do if idmap fails: we already logged the error 6306 // and we certainly don't want to abort installation of pkg simply 6307 // because an overlay didn't fit properly. For these reasons, 6308 // ignore the return value of createIdmapForPackagePairLI. 6309 createIdmapForPackagePairLI(pkg, opkg); 6310 } 6311 } 6312 6313 private boolean createIdmapForPackagePairLI(PackageParser.Package pkg, 6314 PackageParser.Package opkg) { 6315 if (!opkg.mTrustedOverlay) { 6316 Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " + 6317 opkg.baseCodePath + ": overlay not trusted"); 6318 return false; 6319 } 6320 ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName); 6321 if (overlaySet == null) { 6322 Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " + 6323 opkg.baseCodePath + " but target package has no known overlays"); 6324 return false; 6325 } 6326 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 6327 // TODO: generate idmap for split APKs 6328 try { 6329 mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid); 6330 } catch (InstallerException e) { 6331 Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and " 6332 + opkg.baseCodePath); 6333 return false; 6334 } 6335 PackageParser.Package[] overlayArray = 6336 overlaySet.values().toArray(new PackageParser.Package[0]); 6337 Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() { 6338 public int compare(PackageParser.Package p1, PackageParser.Package p2) { 6339 return p1.mOverlayPriority - p2.mOverlayPriority; 6340 } 6341 }; 6342 Arrays.sort(overlayArray, cmp); 6343 6344 pkg.applicationInfo.resourceDirs = new String[overlayArray.length]; 6345 int i = 0; 6346 for (PackageParser.Package p : overlayArray) { 6347 pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath; 6348 } 6349 return true; 6350 } 6351 6352 private void scanDirTracedLI(File dir, int parseFlags, int scanFlags, long currentTime) { 6353 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir"); 6354 try { 6355 scanDirLI(dir, parseFlags, scanFlags, currentTime); 6356 } finally { 6357 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6358 } 6359 } 6360 6361 private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) { 6362 final File[] files = dir.listFiles(); 6363 if (ArrayUtils.isEmpty(files)) { 6364 Log.d(TAG, "No files in app dir " + dir); 6365 return; 6366 } 6367 6368 if (DEBUG_PACKAGE_SCANNING) { 6369 Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags 6370 + " flags=0x" + Integer.toHexString(parseFlags)); 6371 } 6372 6373 for (File file : files) { 6374 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 6375 && !PackageInstallerService.isStageName(file.getName()); 6376 if (!isPackage) { 6377 // Ignore entries which are not packages 6378 continue; 6379 } 6380 try { 6381 scanPackageTracedLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK, 6382 scanFlags, currentTime, null); 6383 } catch (PackageManagerException e) { 6384 Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage()); 6385 6386 // Delete invalid userdata apps 6387 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 && 6388 e.error == PackageManager.INSTALL_FAILED_INVALID_APK) { 6389 logCriticalInfo(Log.WARN, "Deleting invalid package at " + file); 6390 removeCodePathLI(file); 6391 } 6392 } 6393 } 6394 } 6395 6396 private static File getSettingsProblemFile() { 6397 File dataDir = Environment.getDataDirectory(); 6398 File systemDir = new File(dataDir, "system"); 6399 File fname = new File(systemDir, "uiderrors.txt"); 6400 return fname; 6401 } 6402 6403 static void reportSettingsProblem(int priority, String msg) { 6404 logCriticalInfo(priority, msg); 6405 } 6406 6407 static void logCriticalInfo(int priority, String msg) { 6408 Slog.println(priority, TAG, msg); 6409 EventLogTags.writePmCriticalInfo(msg); 6410 try { 6411 File fname = getSettingsProblemFile(); 6412 FileOutputStream out = new FileOutputStream(fname, true); 6413 PrintWriter pw = new FastPrintWriter(out); 6414 SimpleDateFormat formatter = new SimpleDateFormat(); 6415 String dateString = formatter.format(new Date(System.currentTimeMillis())); 6416 pw.println(dateString + ": " + msg); 6417 pw.close(); 6418 FileUtils.setPermissions( 6419 fname.toString(), 6420 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH, 6421 -1, -1); 6422 } catch (java.io.IOException e) { 6423 } 6424 } 6425 6426 private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile, 6427 int parseFlags) throws PackageManagerException { 6428 if (ps != null 6429 && ps.codePath.equals(srcFile) 6430 && ps.timeStamp == srcFile.lastModified() 6431 && !isCompatSignatureUpdateNeeded(pkg) 6432 && !isRecoverSignatureUpdateNeeded(pkg)) { 6433 long mSigningKeySetId = ps.keySetData.getProperSigningKeySet(); 6434 KeySetManagerService ksms = mSettings.mKeySetManagerService; 6435 ArraySet<PublicKey> signingKs; 6436 synchronized (mPackages) { 6437 signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId); 6438 } 6439 if (ps.signatures.mSignatures != null 6440 && ps.signatures.mSignatures.length != 0 6441 && signingKs != null) { 6442 // Optimization: reuse the existing cached certificates 6443 // if the package appears to be unchanged. 6444 pkg.mSignatures = ps.signatures.mSignatures; 6445 pkg.mSigningKeys = signingKs; 6446 return; 6447 } 6448 6449 Slog.w(TAG, "PackageSetting for " + ps.name 6450 + " is missing signatures. Collecting certs again to recover them."); 6451 } else { 6452 Log.i(TAG, srcFile.toString() + " changed; collecting certs"); 6453 } 6454 6455 try { 6456 PackageParser.collectCertificates(pkg, parseFlags); 6457 } catch (PackageParserException e) { 6458 throw PackageManagerException.from(e); 6459 } 6460 } 6461 6462 /** 6463 * Traces a package scan. 6464 * @see #scanPackageLI(File, int, int, long, UserHandle) 6465 */ 6466 private PackageParser.Package scanPackageTracedLI(File scanFile, int parseFlags, int scanFlags, 6467 long currentTime, UserHandle user) throws PackageManagerException { 6468 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage"); 6469 try { 6470 return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user); 6471 } finally { 6472 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6473 } 6474 } 6475 6476 /** 6477 * Scans a package and returns the newly parsed package. 6478 * Returns {@code null} in case of errors and the error code is stored in mLastScanError 6479 */ 6480 private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags, 6481 long currentTime, UserHandle user) throws PackageManagerException { 6482 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile); 6483 parseFlags |= mDefParseFlags; 6484 PackageParser pp = new PackageParser(); 6485 pp.setSeparateProcesses(mSeparateProcesses); 6486 pp.setOnlyCoreApps(mOnlyCore); 6487 pp.setDisplayMetrics(mMetrics); 6488 6489 if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) { 6490 parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY; 6491 } 6492 6493 final PackageParser.Package pkg; 6494 try { 6495 pkg = pp.parsePackage(scanFile, parseFlags); 6496 } catch (PackageParserException e) { 6497 throw PackageManagerException.from(e); 6498 } 6499 6500 return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user); 6501 } 6502 6503 /** 6504 * Scans a package and returns the newly parsed package. 6505 * @throws PackageManagerException on a parse error. 6506 */ 6507 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile, 6508 int parseFlags, int scanFlags, long currentTime, UserHandle user) 6509 throws PackageManagerException { 6510 // If the package has children and this is the first dive in the function 6511 // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all 6512 // packages (parent and children) would be successfully scanned before the 6513 // actual scan since scanning mutates internal state and we want to atomically 6514 // install the package and its children. 6515 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 6516 if (pkg.childPackages != null && pkg.childPackages.size() > 0) { 6517 scanFlags |= SCAN_CHECK_ONLY; 6518 } 6519 } else { 6520 scanFlags &= ~SCAN_CHECK_ONLY; 6521 } 6522 6523 // Scan the parent 6524 PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, parseFlags, 6525 scanFlags, currentTime, user); 6526 6527 // Scan the children 6528 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 6529 for (int i = 0; i < childCount; i++) { 6530 PackageParser.Package childPackage = pkg.childPackages.get(i); 6531 scanPackageInternalLI(childPackage, scanFile, parseFlags, scanFlags, 6532 currentTime, user); 6533 } 6534 6535 6536 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 6537 return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user); 6538 } 6539 6540 return scannedPkg; 6541 } 6542 6543 /** 6544 * Scans a package and returns the newly parsed package. 6545 * @throws PackageManagerException on a parse error. 6546 */ 6547 private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile, 6548 int parseFlags, int scanFlags, long currentTime, UserHandle user) 6549 throws PackageManagerException { 6550 PackageSetting ps = null; 6551 PackageSetting updatedPkg; 6552 // reader 6553 synchronized (mPackages) { 6554 // Look to see if we already know about this package. 6555 String oldName = mSettings.mRenamedPackages.get(pkg.packageName); 6556 if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) { 6557 // This package has been renamed to its original name. Let's 6558 // use that. 6559 ps = mSettings.peekPackageLPr(oldName); 6560 } 6561 // If there was no original package, see one for the real package name. 6562 if (ps == null) { 6563 ps = mSettings.peekPackageLPr(pkg.packageName); 6564 } 6565 // Check to see if this package could be hiding/updating a system 6566 // package. Must look for it either under the original or real 6567 // package name depending on our state. 6568 updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName); 6569 if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg); 6570 6571 // If this is a package we don't know about on the system partition, we 6572 // may need to remove disabled child packages on the system partition 6573 // or may need to not add child packages if the parent apk is updated 6574 // on the data partition and no longer defines this child package. 6575 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) != 0) { 6576 // If this is a parent package for an updated system app and this system 6577 // app got an OTA update which no longer defines some of the child packages 6578 // we have to prune them from the disabled system packages. 6579 PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName); 6580 if (disabledPs != null) { 6581 final int scannedChildCount = (pkg.childPackages != null) 6582 ? pkg.childPackages.size() : 0; 6583 final int disabledChildCount = disabledPs.childPackageNames != null 6584 ? disabledPs.childPackageNames.size() : 0; 6585 for (int i = 0; i < disabledChildCount; i++) { 6586 String disabledChildPackageName = disabledPs.childPackageNames.get(i); 6587 boolean disabledPackageAvailable = false; 6588 for (int j = 0; j < scannedChildCount; j++) { 6589 PackageParser.Package childPkg = pkg.childPackages.get(j); 6590 if (childPkg.packageName.equals(disabledChildPackageName)) { 6591 disabledPackageAvailable = true; 6592 break; 6593 } 6594 } 6595 if (!disabledPackageAvailable) { 6596 mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName); 6597 } 6598 } 6599 } 6600 } 6601 } 6602 6603 boolean updatedPkgBetter = false; 6604 // First check if this is a system package that may involve an update 6605 if (updatedPkg != null && (parseFlags & PackageParser.PARSE_IS_SYSTEM) != 0) { 6606 // If new package is not located in "/system/priv-app" (e.g. due to an OTA), 6607 // it needs to drop FLAG_PRIVILEGED. 6608 if (locationIsPrivileged(scanFile)) { 6609 updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 6610 } else { 6611 updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 6612 } 6613 6614 if (ps != null && !ps.codePath.equals(scanFile)) { 6615 // The path has changed from what was last scanned... check the 6616 // version of the new path against what we have stored to determine 6617 // what to do. 6618 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath); 6619 if (pkg.mVersionCode <= ps.versionCode) { 6620 // The system package has been updated and the code path does not match 6621 // Ignore entry. Skip it. 6622 if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile 6623 + " ignored: updated version " + ps.versionCode 6624 + " better than this " + pkg.mVersionCode); 6625 if (!updatedPkg.codePath.equals(scanFile)) { 6626 Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg " 6627 + ps.name + " changing from " + updatedPkg.codePathString 6628 + " to " + scanFile); 6629 updatedPkg.codePath = scanFile; 6630 updatedPkg.codePathString = scanFile.toString(); 6631 updatedPkg.resourcePath = scanFile; 6632 updatedPkg.resourcePathString = scanFile.toString(); 6633 } 6634 updatedPkg.pkg = pkg; 6635 updatedPkg.versionCode = pkg.mVersionCode; 6636 6637 // Update the disabled system child packages to point to the package too. 6638 final int childCount = updatedPkg.childPackageNames != null 6639 ? updatedPkg.childPackageNames.size() : 0; 6640 for (int i = 0; i < childCount; i++) { 6641 String childPackageName = updatedPkg.childPackageNames.get(i); 6642 PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr( 6643 childPackageName); 6644 if (updatedChildPkg != null) { 6645 updatedChildPkg.pkg = pkg; 6646 updatedChildPkg.versionCode = pkg.mVersionCode; 6647 } 6648 } 6649 6650 throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at " 6651 + scanFile + " ignored: updated version " + ps.versionCode 6652 + " better than this " + pkg.mVersionCode); 6653 } else { 6654 // The current app on the system partition is better than 6655 // what we have updated to on the data partition; switch 6656 // back to the system partition version. 6657 // At this point, its safely assumed that package installation for 6658 // apps in system partition will go through. If not there won't be a working 6659 // version of the app 6660 // writer 6661 synchronized (mPackages) { 6662 // Just remove the loaded entries from package lists. 6663 mPackages.remove(ps.name); 6664 } 6665 6666 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 6667 + " reverting from " + ps.codePathString 6668 + ": new version " + pkg.mVersionCode 6669 + " better than installed " + ps.versionCode); 6670 6671 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 6672 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 6673 synchronized (mInstallLock) { 6674 args.cleanUpResourcesLI(); 6675 } 6676 synchronized (mPackages) { 6677 mSettings.enableSystemPackageLPw(ps.name); 6678 } 6679 updatedPkgBetter = true; 6680 } 6681 } 6682 } 6683 6684 if (updatedPkg != null) { 6685 // An updated system app will not have the PARSE_IS_SYSTEM flag set 6686 // initially 6687 parseFlags |= PackageParser.PARSE_IS_SYSTEM; 6688 6689 // An updated privileged app will not have the PARSE_IS_PRIVILEGED 6690 // flag set initially 6691 if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) { 6692 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 6693 } 6694 } 6695 6696 // Verify certificates against what was last scanned 6697 collectCertificatesLI(ps, pkg, scanFile, parseFlags); 6698 6699 /* 6700 * A new system app appeared, but we already had a non-system one of the 6701 * same name installed earlier. 6702 */ 6703 boolean shouldHideSystemApp = false; 6704 if (updatedPkg == null && ps != null 6705 && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) { 6706 /* 6707 * Check to make sure the signatures match first. If they don't, 6708 * wipe the installed application and its data. 6709 */ 6710 if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures) 6711 != PackageManager.SIGNATURE_MATCH) { 6712 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but" 6713 + " signatures don't match existing userdata copy; removing"); 6714 deletePackageLI(pkg.packageName, null, true, null, 0, null, false, null); 6715 ps = null; 6716 } else { 6717 /* 6718 * If the newly-added system app is an older version than the 6719 * already installed version, hide it. It will be scanned later 6720 * and re-added like an update. 6721 */ 6722 if (pkg.mVersionCode <= ps.versionCode) { 6723 shouldHideSystemApp = true; 6724 logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile 6725 + " but new version " + pkg.mVersionCode + " better than installed " 6726 + ps.versionCode + "; hiding system"); 6727 } else { 6728 /* 6729 * The newly found system app is a newer version that the 6730 * one previously installed. Simply remove the 6731 * already-installed application and replace it with our own 6732 * while keeping the application data. 6733 */ 6734 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 6735 + " reverting from " + ps.codePathString + ": new version " 6736 + pkg.mVersionCode + " better than installed " + ps.versionCode); 6737 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 6738 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 6739 synchronized (mInstallLock) { 6740 args.cleanUpResourcesLI(); 6741 } 6742 } 6743 } 6744 } 6745 6746 // The apk is forward locked (not public) if its code and resources 6747 // are kept in different files. (except for app in either system or 6748 // vendor path). 6749 // TODO grab this value from PackageSettings 6750 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 6751 if (ps != null && !ps.codePath.equals(ps.resourcePath)) { 6752 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 6753 } 6754 } 6755 6756 // TODO: extend to support forward-locked splits 6757 String resourcePath = null; 6758 String baseResourcePath = null; 6759 if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) { 6760 if (ps != null && ps.resourcePathString != null) { 6761 resourcePath = ps.resourcePathString; 6762 baseResourcePath = ps.resourcePathString; 6763 } else { 6764 // Should not happen at all. Just log an error. 6765 Slog.e(TAG, "Resource path not set for package " + pkg.packageName); 6766 } 6767 } else { 6768 resourcePath = pkg.codePath; 6769 baseResourcePath = pkg.baseCodePath; 6770 } 6771 6772 // Set application objects path explicitly. 6773 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 6774 pkg.setApplicationInfoCodePath(pkg.codePath); 6775 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 6776 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 6777 pkg.setApplicationInfoResourcePath(resourcePath); 6778 pkg.setApplicationInfoBaseResourcePath(baseResourcePath); 6779 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 6780 6781 // Note that we invoke the following method only if we are about to unpack an application 6782 PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags 6783 | SCAN_UPDATE_SIGNATURE, currentTime, user); 6784 6785 /* 6786 * If the system app should be overridden by a previously installed 6787 * data, hide the system app now and let the /data/app scan pick it up 6788 * again. 6789 */ 6790 if (shouldHideSystemApp) { 6791 synchronized (mPackages) { 6792 mSettings.disableSystemPackageLPw(pkg.packageName, true); 6793 } 6794 } 6795 6796 return scannedPkg; 6797 } 6798 6799 private static String fixProcessName(String defProcessName, 6800 String processName, int uid) { 6801 if (processName == null) { 6802 return defProcessName; 6803 } 6804 return processName; 6805 } 6806 6807 private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg) 6808 throws PackageManagerException { 6809 if (pkgSetting.signatures.mSignatures != null) { 6810 // Already existing package. Make sure signatures match 6811 boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures) 6812 == PackageManager.SIGNATURE_MATCH; 6813 if (!match) { 6814 match = compareSignaturesCompat(pkgSetting.signatures, pkg) 6815 == PackageManager.SIGNATURE_MATCH; 6816 } 6817 if (!match) { 6818 match = compareSignaturesRecover(pkgSetting.signatures, pkg) 6819 == PackageManager.SIGNATURE_MATCH; 6820 } 6821 if (!match) { 6822 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 6823 + pkg.packageName + " signatures do not match the " 6824 + "previously installed version; ignoring!"); 6825 } 6826 } 6827 6828 // Check for shared user signatures 6829 if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) { 6830 // Already existing package. Make sure signatures match 6831 boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 6832 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 6833 if (!match) { 6834 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg) 6835 == PackageManager.SIGNATURE_MATCH; 6836 } 6837 if (!match) { 6838 match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg) 6839 == PackageManager.SIGNATURE_MATCH; 6840 } 6841 if (!match) { 6842 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 6843 "Package " + pkg.packageName 6844 + " has no signatures that match those in shared user " 6845 + pkgSetting.sharedUser.name + "; ignoring!"); 6846 } 6847 } 6848 } 6849 6850 /** 6851 * Enforces that only the system UID or root's UID can call a method exposed 6852 * via Binder. 6853 * 6854 * @param message used as message if SecurityException is thrown 6855 * @throws SecurityException if the caller is not system or root 6856 */ 6857 private static final void enforceSystemOrRoot(String message) { 6858 final int uid = Binder.getCallingUid(); 6859 if (uid != Process.SYSTEM_UID && uid != 0) { 6860 throw new SecurityException(message); 6861 } 6862 } 6863 6864 @Override 6865 public void performFstrimIfNeeded() { 6866 enforceSystemOrRoot("Only the system can request fstrim"); 6867 6868 // Before everything else, see whether we need to fstrim. 6869 try { 6870 IMountService ms = PackageHelper.getMountService(); 6871 if (ms != null) { 6872 final boolean isUpgrade = isUpgrade(); 6873 boolean doTrim = isUpgrade; 6874 if (doTrim) { 6875 Slog.w(TAG, "Running disk maintenance immediately due to system update"); 6876 } else { 6877 final long interval = android.provider.Settings.Global.getLong( 6878 mContext.getContentResolver(), 6879 android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL, 6880 DEFAULT_MANDATORY_FSTRIM_INTERVAL); 6881 if (interval > 0) { 6882 final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance(); 6883 if (timeSinceLast > interval) { 6884 doTrim = true; 6885 Slog.w(TAG, "No disk maintenance in " + timeSinceLast 6886 + "; running immediately"); 6887 } 6888 } 6889 } 6890 if (doTrim) { 6891 if (!isFirstBoot()) { 6892 try { 6893 ActivityManagerNative.getDefault().showBootMessage( 6894 mContext.getResources().getString( 6895 R.string.android_upgrading_fstrim), true); 6896 } catch (RemoteException e) { 6897 } 6898 } 6899 ms.runMaintenance(); 6900 } 6901 } else { 6902 Slog.e(TAG, "Mount service unavailable!"); 6903 } 6904 } catch (RemoteException e) { 6905 // Can't happen; MountService is local 6906 } 6907 } 6908 6909 @Override 6910 public void extractPackagesIfNeeded() { 6911 enforceSystemOrRoot("Only the system can request package extraction"); 6912 6913 // Extract pacakges only if profile-guided compilation is enabled because 6914 // otherwise BackgroundDexOptService will not dexopt them later. 6915 boolean prunedCache = VMRuntime.didPruneDalvikCache(); 6916 if (!isUpgrade() && !prunedCache) { 6917 return; 6918 } 6919 6920 List<PackageParser.Package> pkgs; 6921 synchronized (mPackages) { 6922 pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this); 6923 } 6924 6925 int curr = 0; 6926 int total = pkgs.size(); 6927 for (PackageParser.Package pkg : pkgs) { 6928 curr++; 6929 6930 if (DEBUG_DEXOPT) { 6931 Log.i(TAG, "Extracting app " + curr + " of " + total + ": " + pkg.packageName); 6932 } 6933 6934 if (!isFirstBoot()) { 6935 try { 6936 ActivityManagerNative.getDefault().showBootMessage( 6937 mContext.getResources().getString(R.string.android_upgrading_apk, 6938 curr, total), true); 6939 } catch (RemoteException e) { 6940 } 6941 } 6942 6943 if (PackageDexOptimizer.canOptimizePackage(pkg)) { 6944 // If the cache was pruned, any compiled odex files will likely be out of date 6945 // and would have to be patched (would be SELF_PATCHOAT, which is deprecated). 6946 // Instead, force the extraction in this case. 6947 performDexOpt(pkg.packageName, null /* instructionSet */, 6948 false /* checkProfiles */, REASON_BOOT, prunedCache); 6949 } 6950 } 6951 } 6952 6953 @Override 6954 public void notifyPackageUse(String packageName) { 6955 synchronized (mPackages) { 6956 PackageParser.Package p = mPackages.get(packageName); 6957 if (p == null) { 6958 return; 6959 } 6960 p.mLastPackageUsageTimeInMills = System.currentTimeMillis(); 6961 } 6962 } 6963 6964 // TODO: this is not used nor needed. Delete it. 6965 @Override 6966 public boolean performDexOptIfNeeded(String packageName, String instructionSet) { 6967 return performDexOptTraced(packageName, instructionSet, false /* checkProfiles */, 6968 getFullCompilerFilter(), false /* force */); 6969 } 6970 6971 @Override 6972 public boolean performDexOpt(String packageName, String instructionSet, 6973 boolean checkProfiles, int compileReason, boolean force) { 6974 return performDexOptTraced(packageName, instructionSet, checkProfiles, 6975 getCompilerFilterForReason(compileReason), force); 6976 } 6977 6978 @Override 6979 public boolean performDexOptMode(String packageName, String instructionSet, 6980 boolean checkProfiles, String targetCompilerFilter, boolean force) { 6981 return performDexOptTraced(packageName, instructionSet, checkProfiles, 6982 targetCompilerFilter, force); 6983 } 6984 6985 private boolean performDexOptTraced(String packageName, String instructionSet, 6986 boolean checkProfiles, String targetCompilerFilter, boolean force) { 6987 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 6988 try { 6989 return performDexOptInternal(packageName, instructionSet, checkProfiles, 6990 targetCompilerFilter, force); 6991 } finally { 6992 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6993 } 6994 } 6995 6996 private boolean performDexOptInternal(String packageName, String instructionSet, 6997 boolean checkProfiles, String targetCompilerFilter, boolean force) { 6998 PackageParser.Package p; 6999 final String targetInstructionSet; 7000 synchronized (mPackages) { 7001 p = mPackages.get(packageName); 7002 if (p == null) { 7003 return false; 7004 } 7005 mPackageUsage.write(false); 7006 7007 targetInstructionSet = instructionSet != null ? instructionSet : 7008 getPrimaryInstructionSet(p.applicationInfo); 7009 } 7010 long callingId = Binder.clearCallingIdentity(); 7011 try { 7012 synchronized (mInstallLock) { 7013 final String[] instructionSets = new String[] { targetInstructionSet }; 7014 int result = performDexOptInternalWithDependenciesLI(p, instructionSets, 7015 checkProfiles, targetCompilerFilter, force); 7016 return result == PackageDexOptimizer.DEX_OPT_PERFORMED; 7017 } 7018 } finally { 7019 Binder.restoreCallingIdentity(callingId); 7020 } 7021 } 7022 7023 public ArraySet<String> getOptimizablePackages() { 7024 ArraySet<String> pkgs = new ArraySet<String>(); 7025 synchronized (mPackages) { 7026 for (PackageParser.Package p : mPackages.values()) { 7027 if (PackageDexOptimizer.canOptimizePackage(p)) { 7028 pkgs.add(p.packageName); 7029 } 7030 } 7031 } 7032 return pkgs; 7033 } 7034 7035 private int performDexOptInternalWithDependenciesLI(PackageParser.Package p, 7036 String instructionSets[], boolean checkProfiles, String targetCompilerFilter, 7037 boolean force) { 7038 // Select the dex optimizer based on the force parameter. 7039 // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to 7040 // allocate an object here. 7041 PackageDexOptimizer pdo = force 7042 ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer) 7043 : mPackageDexOptimizer; 7044 7045 // Optimize all dependencies first. Note: we ignore the return value and march on 7046 // on errors. 7047 Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p); 7048 if (!deps.isEmpty()) { 7049 for (PackageParser.Package depPackage : deps) { 7050 // TODO: Analyze and investigate if we (should) profile libraries. 7051 // Currently this will do a full compilation of the library by default. 7052 pdo.performDexOpt(depPackage, instructionSets, false /* checkProfiles */, 7053 getCompilerFilterForReason(REASON_NON_SYSTEM_LIBRARY)); 7054 } 7055 } 7056 7057 return pdo.performDexOpt(p, instructionSets, checkProfiles, targetCompilerFilter); 7058 } 7059 7060 Collection<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) { 7061 if (p.usesLibraries != null || p.usesOptionalLibraries != null) { 7062 ArrayList<PackageParser.Package> retValue = new ArrayList<>(); 7063 Set<String> collectedNames = new HashSet<>(); 7064 findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames); 7065 7066 retValue.remove(p); 7067 7068 return retValue; 7069 } else { 7070 return Collections.emptyList(); 7071 } 7072 } 7073 7074 private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p, 7075 Collection<PackageParser.Package> collected, Set<String> collectedNames) { 7076 if (!collectedNames.contains(p.packageName)) { 7077 collectedNames.add(p.packageName); 7078 collected.add(p); 7079 7080 if (p.usesLibraries != null) { 7081 findSharedNonSystemLibrariesRecursive(p.usesLibraries, collected, collectedNames); 7082 } 7083 if (p.usesOptionalLibraries != null) { 7084 findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries, collected, 7085 collectedNames); 7086 } 7087 } 7088 } 7089 7090 private void findSharedNonSystemLibrariesRecursive(Collection<String> libs, 7091 Collection<PackageParser.Package> collected, Set<String> collectedNames) { 7092 for (String libName : libs) { 7093 PackageParser.Package libPkg = findSharedNonSystemLibrary(libName); 7094 if (libPkg != null) { 7095 findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames); 7096 } 7097 } 7098 } 7099 7100 private PackageParser.Package findSharedNonSystemLibrary(String libName) { 7101 synchronized (mPackages) { 7102 PackageManagerService.SharedLibraryEntry lib = mSharedLibraries.get(libName); 7103 if (lib != null && lib.apk != null) { 7104 return mPackages.get(lib.apk); 7105 } 7106 } 7107 return null; 7108 } 7109 7110 public void shutdown() { 7111 mPackageUsage.write(true); 7112 } 7113 7114 @Override 7115 public void forceDexOpt(String packageName) { 7116 enforceSystemOrRoot("forceDexOpt"); 7117 7118 PackageParser.Package pkg; 7119 synchronized (mPackages) { 7120 pkg = mPackages.get(packageName); 7121 if (pkg == null) { 7122 throw new IllegalArgumentException("Unknown package: " + packageName); 7123 } 7124 } 7125 7126 synchronized (mInstallLock) { 7127 final String[] instructionSets = new String[] { 7128 getPrimaryInstructionSet(pkg.applicationInfo) }; 7129 7130 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 7131 7132 // Whoever is calling forceDexOpt wants a fully compiled package. 7133 // Don't use profiles since that may cause compilation to be skipped. 7134 final int res = performDexOptInternalWithDependenciesLI(pkg, instructionSets, 7135 false /* checkProfiles */, getCompilerFilterForReason(REASON_FORCED_DEXOPT), 7136 true /* force */); 7137 7138 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7139 if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) { 7140 throw new IllegalStateException("Failed to dexopt: " + res); 7141 } 7142 } 7143 } 7144 7145 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) { 7146 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) { 7147 Slog.w(TAG, "Unable to update from " + oldPkg.name 7148 + " to " + newPkg.packageName 7149 + ": old package not in system partition"); 7150 return false; 7151 } else if (mPackages.get(oldPkg.name) != null) { 7152 Slog.w(TAG, "Unable to update from " + oldPkg.name 7153 + " to " + newPkg.packageName 7154 + ": old package still exists"); 7155 return false; 7156 } 7157 return true; 7158 } 7159 7160 private boolean removeDataDirsLI(String volumeUuid, String packageName) { 7161 // TODO: triage flags as part of 26466827 7162 final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE; 7163 7164 boolean res = true; 7165 final int[] users = sUserManager.getUserIds(); 7166 for (int user : users) { 7167 try { 7168 mInstaller.destroyAppData(volumeUuid, packageName, user, flags); 7169 } catch (InstallerException e) { 7170 Slog.w(TAG, "Failed to delete data directory", e); 7171 res = false; 7172 } 7173 } 7174 return res; 7175 } 7176 7177 void removeCodePathLI(File codePath) { 7178 if (codePath.isDirectory()) { 7179 try { 7180 mInstaller.rmPackageDir(codePath.getAbsolutePath()); 7181 } catch (InstallerException e) { 7182 Slog.w(TAG, "Failed to remove code path", e); 7183 } 7184 } else { 7185 codePath.delete(); 7186 } 7187 } 7188 7189 void destroyAppDataLI(String volumeUuid, String packageName, int userId, int flags) { 7190 try { 7191 mInstaller.destroyAppData(volumeUuid, packageName, userId, flags); 7192 } catch (InstallerException e) { 7193 Slog.w(TAG, "Failed to destroy app data", e); 7194 } 7195 } 7196 7197 void restoreconAppDataLI(String volumeUuid, String packageName, int userId, int flags, 7198 int appId, String seinfo) { 7199 try { 7200 mInstaller.restoreconAppData(volumeUuid, packageName, userId, flags, appId, seinfo); 7201 } catch (InstallerException e) { 7202 Slog.e(TAG, "Failed to restorecon for " + packageName + ": " + e); 7203 } 7204 } 7205 7206 private void deleteCodeCacheDirsLI(String volumeUuid, String packageName) { 7207 final PackageParser.Package pkg; 7208 synchronized (mPackages) { 7209 pkg = mPackages.get(packageName); 7210 } 7211 if (pkg == null) { 7212 Slog.w(TAG, "Failed to delete code cache directory. No package: " + packageName); 7213 return; 7214 } 7215 deleteCodeCacheDirsLI(pkg); 7216 } 7217 7218 private void deleteCodeCacheDirsLI(PackageParser.Package pkg) { 7219 // TODO: triage flags as part of 26466827 7220 final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE; 7221 7222 int[] users = sUserManager.getUserIds(); 7223 int res = 0; 7224 for (int user : users) { 7225 // Remove the parent code cache 7226 try { 7227 mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, user, 7228 flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 7229 } catch (InstallerException e) { 7230 Slog.w(TAG, "Failed to delete code cache directory", e); 7231 } 7232 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7233 for (int i = 0; i < childCount; i++) { 7234 PackageParser.Package childPkg = pkg.childPackages.get(i); 7235 // Remove the child code cache 7236 try { 7237 mInstaller.clearAppData(childPkg.volumeUuid, childPkg.packageName, 7238 user, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 7239 } catch (InstallerException e) { 7240 Slog.w(TAG, "Failed to delete code cache directory", e); 7241 } 7242 } 7243 } 7244 } 7245 7246 private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime, 7247 long lastUpdateTime) { 7248 // Set parent install/update time 7249 PackageSetting ps = (PackageSetting) pkg.mExtras; 7250 if (ps != null) { 7251 ps.firstInstallTime = firstInstallTime; 7252 ps.lastUpdateTime = lastUpdateTime; 7253 } 7254 // Set children install/update time 7255 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7256 for (int i = 0; i < childCount; i++) { 7257 PackageParser.Package childPkg = pkg.childPackages.get(i); 7258 ps = (PackageSetting) childPkg.mExtras; 7259 if (ps != null) { 7260 ps.firstInstallTime = firstInstallTime; 7261 ps.lastUpdateTime = lastUpdateTime; 7262 } 7263 } 7264 } 7265 7266 private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file, 7267 PackageParser.Package changingLib) { 7268 if (file.path != null) { 7269 usesLibraryFiles.add(file.path); 7270 return; 7271 } 7272 PackageParser.Package p = mPackages.get(file.apk); 7273 if (changingLib != null && changingLib.packageName.equals(file.apk)) { 7274 // If we are doing this while in the middle of updating a library apk, 7275 // then we need to make sure to use that new apk for determining the 7276 // dependencies here. (We haven't yet finished committing the new apk 7277 // to the package manager state.) 7278 if (p == null || p.packageName.equals(changingLib.packageName)) { 7279 p = changingLib; 7280 } 7281 } 7282 if (p != null) { 7283 usesLibraryFiles.addAll(p.getAllCodePaths()); 7284 } 7285 } 7286 7287 private void updateSharedLibrariesLPw(PackageParser.Package pkg, 7288 PackageParser.Package changingLib) throws PackageManagerException { 7289 if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) { 7290 final ArraySet<String> usesLibraryFiles = new ArraySet<>(); 7291 int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0; 7292 for (int i=0; i<N; i++) { 7293 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i)); 7294 if (file == null) { 7295 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, 7296 "Package " + pkg.packageName + " requires unavailable shared library " 7297 + pkg.usesLibraries.get(i) + "; failing!"); 7298 } 7299 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 7300 } 7301 N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0; 7302 for (int i=0; i<N; i++) { 7303 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i)); 7304 if (file == null) { 7305 Slog.w(TAG, "Package " + pkg.packageName 7306 + " desires unavailable shared library " 7307 + pkg.usesOptionalLibraries.get(i) + "; ignoring!"); 7308 } else { 7309 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 7310 } 7311 } 7312 N = usesLibraryFiles.size(); 7313 if (N > 0) { 7314 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]); 7315 } else { 7316 pkg.usesLibraryFiles = null; 7317 } 7318 } 7319 } 7320 7321 private static boolean hasString(List<String> list, List<String> which) { 7322 if (list == null) { 7323 return false; 7324 } 7325 for (int i=list.size()-1; i>=0; i--) { 7326 for (int j=which.size()-1; j>=0; j--) { 7327 if (which.get(j).equals(list.get(i))) { 7328 return true; 7329 } 7330 } 7331 } 7332 return false; 7333 } 7334 7335 private void updateAllSharedLibrariesLPw() { 7336 for (PackageParser.Package pkg : mPackages.values()) { 7337 try { 7338 updateSharedLibrariesLPw(pkg, null); 7339 } catch (PackageManagerException e) { 7340 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 7341 } 7342 } 7343 } 7344 7345 private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw( 7346 PackageParser.Package changingPkg) { 7347 ArrayList<PackageParser.Package> res = null; 7348 for (PackageParser.Package pkg : mPackages.values()) { 7349 if (hasString(pkg.usesLibraries, changingPkg.libraryNames) 7350 || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) { 7351 if (res == null) { 7352 res = new ArrayList<PackageParser.Package>(); 7353 } 7354 res.add(pkg); 7355 try { 7356 updateSharedLibrariesLPw(pkg, changingPkg); 7357 } catch (PackageManagerException e) { 7358 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 7359 } 7360 } 7361 } 7362 return res; 7363 } 7364 7365 /** 7366 * Derive the value of the {@code cpuAbiOverride} based on the provided 7367 * value and an optional stored value from the package settings. 7368 */ 7369 private static String deriveAbiOverride(String abiOverride, PackageSetting settings) { 7370 String cpuAbiOverride = null; 7371 7372 if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) { 7373 cpuAbiOverride = null; 7374 } else if (abiOverride != null) { 7375 cpuAbiOverride = abiOverride; 7376 } else if (settings != null) { 7377 cpuAbiOverride = settings.cpuAbiOverrideString; 7378 } 7379 7380 return cpuAbiOverride; 7381 } 7382 7383 private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg, int parseFlags, 7384 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 7385 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage"); 7386 // If the package has children and this is the first dive in the function 7387 // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see 7388 // whether all packages (parent and children) would be successfully scanned 7389 // before the actual scan since scanning mutates internal state and we want 7390 // to atomically install the package and its children. 7391 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 7392 if (pkg.childPackages != null && pkg.childPackages.size() > 0) { 7393 scanFlags |= SCAN_CHECK_ONLY; 7394 } 7395 } else { 7396 scanFlags &= ~SCAN_CHECK_ONLY; 7397 } 7398 7399 final PackageParser.Package scannedPkg; 7400 try { 7401 // Scan the parent 7402 scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags, currentTime, user); 7403 // Scan the children 7404 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7405 for (int i = 0; i < childCount; i++) { 7406 PackageParser.Package childPkg = pkg.childPackages.get(i); 7407 scanPackageLI(childPkg, parseFlags, 7408 scanFlags, currentTime, user); 7409 } 7410 } finally { 7411 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7412 } 7413 7414 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 7415 return scanPackageTracedLI(pkg, parseFlags, scanFlags, currentTime, user); 7416 } 7417 7418 return scannedPkg; 7419 } 7420 7421 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags, 7422 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 7423 boolean success = false; 7424 try { 7425 final PackageParser.Package res = scanPackageDirtyLI(pkg, parseFlags, scanFlags, 7426 currentTime, user); 7427 success = true; 7428 return res; 7429 } finally { 7430 if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) { 7431 removeDataDirsLI(pkg.volumeUuid, pkg.packageName); 7432 } 7433 } 7434 } 7435 7436 private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags, 7437 int scanFlags, long currentTime, UserHandle user) 7438 throws PackageManagerException { 7439 final File scanFile = new File(pkg.codePath); 7440 if (pkg.applicationInfo.getCodePath() == null || 7441 pkg.applicationInfo.getResourcePath() == null) { 7442 // Bail out. The resource and code paths haven't been set. 7443 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 7444 "Code and resource paths haven't been set correctly"); 7445 } 7446 7447 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 7448 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; 7449 } else { 7450 // Only allow system apps to be flagged as core apps. 7451 pkg.coreApp = false; 7452 } 7453 7454 if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) { 7455 pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 7456 } 7457 7458 if (mCustomResolverComponentName != null && 7459 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) { 7460 setUpCustomResolverActivity(pkg); 7461 } 7462 7463 if (pkg.packageName.equals("android")) { 7464 synchronized (mPackages) { 7465 if (mAndroidApplication != null) { 7466 Slog.w(TAG, "*************************************************"); 7467 Slog.w(TAG, "Core android package being redefined. Skipping."); 7468 Slog.w(TAG, " file=" + scanFile); 7469 Slog.w(TAG, "*************************************************"); 7470 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 7471 "Core android package being redefined. Skipping."); 7472 } 7473 7474 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 7475 // Set up information for our fall-back user intent resolution activity. 7476 mPlatformPackage = pkg; 7477 pkg.mVersionCode = mSdkVersion; 7478 mAndroidApplication = pkg.applicationInfo; 7479 7480 if (!mResolverReplaced) { 7481 mResolveActivity.applicationInfo = mAndroidApplication; 7482 mResolveActivity.name = ResolverActivity.class.getName(); 7483 mResolveActivity.packageName = mAndroidApplication.packageName; 7484 mResolveActivity.processName = "system:ui"; 7485 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 7486 mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER; 7487 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS; 7488 mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert; 7489 mResolveActivity.exported = true; 7490 mResolveActivity.enabled = true; 7491 mResolveInfo.activityInfo = mResolveActivity; 7492 mResolveInfo.priority = 0; 7493 mResolveInfo.preferredOrder = 0; 7494 mResolveInfo.match = 0; 7495 mResolveComponentName = new ComponentName( 7496 mAndroidApplication.packageName, mResolveActivity.name); 7497 } 7498 } 7499 } 7500 } 7501 7502 if (DEBUG_PACKAGE_SCANNING) { 7503 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 7504 Log.d(TAG, "Scanning package " + pkg.packageName); 7505 } 7506 7507 synchronized (mPackages) { 7508 if (mPackages.containsKey(pkg.packageName) 7509 || mSharedLibraries.containsKey(pkg.packageName)) { 7510 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 7511 "Application package " + pkg.packageName 7512 + " already installed. Skipping duplicate."); 7513 } 7514 7515 // If we're only installing presumed-existing packages, require that the 7516 // scanned APK is both already known and at the path previously established 7517 // for it. Previously unknown packages we pick up normally, but if we have an 7518 // a priori expectation about this package's install presence, enforce it. 7519 // With a singular exception for new system packages. When an OTA contains 7520 // a new system package, we allow the codepath to change from a system location 7521 // to the user-installed location. If we don't allow this change, any newer, 7522 // user-installed version of the application will be ignored. 7523 if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) { 7524 if (mExpectingBetter.containsKey(pkg.packageName)) { 7525 logCriticalInfo(Log.WARN, 7526 "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName); 7527 } else { 7528 PackageSetting known = mSettings.peekPackageLPr(pkg.packageName); 7529 if (known != null) { 7530 if (DEBUG_PACKAGE_SCANNING) { 7531 Log.d(TAG, "Examining " + pkg.codePath 7532 + " and requiring known paths " + known.codePathString 7533 + " & " + known.resourcePathString); 7534 } 7535 if (!pkg.applicationInfo.getCodePath().equals(known.codePathString) 7536 || !pkg.applicationInfo.getResourcePath().equals( 7537 known.resourcePathString)) { 7538 throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED, 7539 "Application package " + pkg.packageName 7540 + " found at " + pkg.applicationInfo.getCodePath() 7541 + " but expected at " + known.codePathString 7542 + "; ignoring."); 7543 } 7544 } 7545 } 7546 } 7547 } 7548 7549 // Initialize package source and resource directories 7550 File destCodeFile = new File(pkg.applicationInfo.getCodePath()); 7551 File destResourceFile = new File(pkg.applicationInfo.getResourcePath()); 7552 7553 SharedUserSetting suid = null; 7554 PackageSetting pkgSetting = null; 7555 7556 if (!isSystemApp(pkg)) { 7557 // Only system apps can use these features. 7558 pkg.mOriginalPackages = null; 7559 pkg.mRealPackage = null; 7560 pkg.mAdoptPermissions = null; 7561 } 7562 7563 // Getting the package setting may have a side-effect, so if we 7564 // are only checking if scan would succeed, stash a copy of the 7565 // old setting to restore at the end. 7566 PackageSetting nonMutatedPs = null; 7567 7568 // writer 7569 synchronized (mPackages) { 7570 if (pkg.mSharedUserId != null) { 7571 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, true); 7572 if (suid == null) { 7573 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 7574 "Creating application package " + pkg.packageName 7575 + " for shared user failed"); 7576 } 7577 if (DEBUG_PACKAGE_SCANNING) { 7578 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 7579 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId 7580 + "): packages=" + suid.packages); 7581 } 7582 } 7583 7584 // Check if we are renaming from an original package name. 7585 PackageSetting origPackage = null; 7586 String realName = null; 7587 if (pkg.mOriginalPackages != null) { 7588 // This package may need to be renamed to a previously 7589 // installed name. Let's check on that... 7590 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage); 7591 if (pkg.mOriginalPackages.contains(renamed)) { 7592 // This package had originally been installed as the 7593 // original name, and we have already taken care of 7594 // transitioning to the new one. Just update the new 7595 // one to continue using the old name. 7596 realName = pkg.mRealPackage; 7597 if (!pkg.packageName.equals(renamed)) { 7598 // Callers into this function may have already taken 7599 // care of renaming the package; only do it here if 7600 // it is not already done. 7601 pkg.setPackageName(renamed); 7602 } 7603 7604 } else { 7605 for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) { 7606 if ((origPackage = mSettings.peekPackageLPr( 7607 pkg.mOriginalPackages.get(i))) != null) { 7608 // We do have the package already installed under its 7609 // original name... should we use it? 7610 if (!verifyPackageUpdateLPr(origPackage, pkg)) { 7611 // New package is not compatible with original. 7612 origPackage = null; 7613 continue; 7614 } else if (origPackage.sharedUser != null) { 7615 // Make sure uid is compatible between packages. 7616 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) { 7617 Slog.w(TAG, "Unable to migrate data from " + origPackage.name 7618 + " to " + pkg.packageName + ": old uid " 7619 + origPackage.sharedUser.name 7620 + " differs from " + pkg.mSharedUserId); 7621 origPackage = null; 7622 continue; 7623 } 7624 } else { 7625 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package " 7626 + pkg.packageName + " to old name " + origPackage.name); 7627 } 7628 break; 7629 } 7630 } 7631 } 7632 } 7633 7634 if (mTransferedPackages.contains(pkg.packageName)) { 7635 Slog.w(TAG, "Package " + pkg.packageName 7636 + " was transferred to another, but its .apk remains"); 7637 } 7638 7639 // See comments in nonMutatedPs declaration 7640 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 7641 PackageSetting foundPs = mSettings.peekPackageLPr(pkg.packageName); 7642 if (foundPs != null) { 7643 nonMutatedPs = new PackageSetting(foundPs); 7644 } 7645 } 7646 7647 // Just create the setting, don't add it yet. For already existing packages 7648 // the PkgSetting exists already and doesn't have to be created. 7649 pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile, 7650 destResourceFile, pkg.applicationInfo.nativeLibraryRootDir, 7651 pkg.applicationInfo.primaryCpuAbi, 7652 pkg.applicationInfo.secondaryCpuAbi, 7653 pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, 7654 user, false); 7655 if (pkgSetting == null) { 7656 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 7657 "Creating application package " + pkg.packageName + " failed"); 7658 } 7659 7660 if (pkgSetting.origPackage != null) { 7661 // If we are first transitioning from an original package, 7662 // fix up the new package's name now. We need to do this after 7663 // looking up the package under its new name, so getPackageLP 7664 // can take care of fiddling things correctly. 7665 pkg.setPackageName(origPackage.name); 7666 7667 // File a report about this. 7668 String msg = "New package " + pkgSetting.realName 7669 + " renamed to replace old package " + pkgSetting.name; 7670 reportSettingsProblem(Log.WARN, msg); 7671 7672 // Make a note of it. 7673 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 7674 mTransferedPackages.add(origPackage.name); 7675 } 7676 7677 // No longer need to retain this. 7678 pkgSetting.origPackage = null; 7679 } 7680 7681 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) { 7682 // Make a note of it. 7683 mTransferedPackages.add(pkg.packageName); 7684 } 7685 7686 if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) { 7687 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 7688 } 7689 7690 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 7691 // Check all shared libraries and map to their actual file path. 7692 // We only do this here for apps not on a system dir, because those 7693 // are the only ones that can fail an install due to this. We 7694 // will take care of the system apps by updating all of their 7695 // library paths after the scan is done. 7696 updateSharedLibrariesLPw(pkg, null); 7697 } 7698 7699 if (mFoundPolicyFile) { 7700 SELinuxMMAC.assignSeinfoValue(pkg); 7701 } 7702 7703 pkg.applicationInfo.uid = pkgSetting.appId; 7704 pkg.mExtras = pkgSetting; 7705 if (shouldCheckUpgradeKeySetLP(pkgSetting, scanFlags)) { 7706 if (checkUpgradeKeySetLP(pkgSetting, pkg)) { 7707 // We just determined the app is signed correctly, so bring 7708 // over the latest parsed certs. 7709 pkgSetting.signatures.mSignatures = pkg.mSignatures; 7710 } else { 7711 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 7712 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 7713 "Package " + pkg.packageName + " upgrade keys do not match the " 7714 + "previously installed version"); 7715 } else { 7716 pkgSetting.signatures.mSignatures = pkg.mSignatures; 7717 String msg = "System package " + pkg.packageName 7718 + " signature changed; retaining data."; 7719 reportSettingsProblem(Log.WARN, msg); 7720 } 7721 } 7722 } else { 7723 try { 7724 verifySignaturesLP(pkgSetting, pkg); 7725 // We just determined the app is signed correctly, so bring 7726 // over the latest parsed certs. 7727 pkgSetting.signatures.mSignatures = pkg.mSignatures; 7728 } catch (PackageManagerException e) { 7729 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 7730 throw e; 7731 } 7732 // The signature has changed, but this package is in the system 7733 // image... let's recover! 7734 pkgSetting.signatures.mSignatures = pkg.mSignatures; 7735 // However... if this package is part of a shared user, but it 7736 // doesn't match the signature of the shared user, let's fail. 7737 // What this means is that you can't change the signatures 7738 // associated with an overall shared user, which doesn't seem all 7739 // that unreasonable. 7740 if (pkgSetting.sharedUser != null) { 7741 if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 7742 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { 7743 throw new PackageManagerException( 7744 INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES, 7745 "Signature mismatch for shared user: " 7746 + pkgSetting.sharedUser); 7747 } 7748 } 7749 // File a report about this. 7750 String msg = "System package " + pkg.packageName 7751 + " signature changed; retaining data."; 7752 reportSettingsProblem(Log.WARN, msg); 7753 } 7754 } 7755 // Verify that this new package doesn't have any content providers 7756 // that conflict with existing packages. Only do this if the 7757 // package isn't already installed, since we don't want to break 7758 // things that are installed. 7759 if ((scanFlags & SCAN_NEW_INSTALL) != 0) { 7760 final int N = pkg.providers.size(); 7761 int i; 7762 for (i=0; i<N; i++) { 7763 PackageParser.Provider p = pkg.providers.get(i); 7764 if (p.info.authority != null) { 7765 String names[] = p.info.authority.split(";"); 7766 for (int j = 0; j < names.length; j++) { 7767 if (mProvidersByAuthority.containsKey(names[j])) { 7768 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 7769 final String otherPackageName = 7770 ((other != null && other.getComponentName() != null) ? 7771 other.getComponentName().getPackageName() : "?"); 7772 throw new PackageManagerException( 7773 INSTALL_FAILED_CONFLICTING_PROVIDER, 7774 "Can't install because provider name " + names[j] 7775 + " (in package " + pkg.applicationInfo.packageName 7776 + ") is already used by " + otherPackageName); 7777 } 7778 } 7779 } 7780 } 7781 } 7782 7783 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) { 7784 // This package wants to adopt ownership of permissions from 7785 // another package. 7786 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) { 7787 final String origName = pkg.mAdoptPermissions.get(i); 7788 final PackageSetting orig = mSettings.peekPackageLPr(origName); 7789 if (orig != null) { 7790 if (verifyPackageUpdateLPr(orig, pkg)) { 7791 Slog.i(TAG, "Adopting permissions from " + origName + " to " 7792 + pkg.packageName); 7793 mSettings.transferPermissionsLPw(origName, pkg.packageName); 7794 } 7795 } 7796 } 7797 } 7798 } 7799 7800 final String pkgName = pkg.packageName; 7801 7802 final long scanFileTime = scanFile.lastModified(); 7803 final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0; 7804 pkg.applicationInfo.processName = fixProcessName( 7805 pkg.applicationInfo.packageName, 7806 pkg.applicationInfo.processName, 7807 pkg.applicationInfo.uid); 7808 7809 if (pkg != mPlatformPackage) { 7810 // Get all of our default paths setup 7811 pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM); 7812 } 7813 7814 final String path = scanFile.getPath(); 7815 final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting); 7816 7817 if ((scanFlags & SCAN_NEW_INSTALL) == 0) { 7818 derivePackageAbi(pkg, scanFile, cpuAbiOverride, true /* extract libs */); 7819 7820 // Some system apps still use directory structure for native libraries 7821 // in which case we might end up not detecting abi solely based on apk 7822 // structure. Try to detect abi based on directory structure. 7823 if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() && 7824 pkg.applicationInfo.primaryCpuAbi == null) { 7825 setBundledAppAbisAndRoots(pkg, pkgSetting); 7826 setNativeLibraryPaths(pkg); 7827 } 7828 7829 } else { 7830 if ((scanFlags & SCAN_MOVE) != 0) { 7831 // We haven't run dex-opt for this move (since we've moved the compiled output too) 7832 // but we already have this packages package info in the PackageSetting. We just 7833 // use that and derive the native library path based on the new codepath. 7834 pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString; 7835 pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString; 7836 } 7837 7838 // Set native library paths again. For moves, the path will be updated based on the 7839 // ABIs we've determined above. For non-moves, the path will be updated based on the 7840 // ABIs we determined during compilation, but the path will depend on the final 7841 // package path (after the rename away from the stage path). 7842 setNativeLibraryPaths(pkg); 7843 } 7844 7845 // This is a special case for the "system" package, where the ABI is 7846 // dictated by the zygote configuration (and init.rc). We should keep track 7847 // of this ABI so that we can deal with "normal" applications that run under 7848 // the same UID correctly. 7849 if (mPlatformPackage == pkg) { 7850 pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ? 7851 Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]; 7852 } 7853 7854 // If there's a mismatch between the abi-override in the package setting 7855 // and the abiOverride specified for the install. Warn about this because we 7856 // would've already compiled the app without taking the package setting into 7857 // account. 7858 if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) { 7859 if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) { 7860 Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride + 7861 " for package " + pkg.packageName); 7862 } 7863 } 7864 7865 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 7866 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 7867 pkgSetting.cpuAbiOverrideString = cpuAbiOverride; 7868 7869 // Copy the derived override back to the parsed package, so that we can 7870 // update the package settings accordingly. 7871 pkg.cpuAbiOverride = cpuAbiOverride; 7872 7873 if (DEBUG_ABI_SELECTION) { 7874 Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName 7875 + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa=" 7876 + pkg.applicationInfo.nativeLibraryRootRequiresIsa); 7877 } 7878 7879 // Push the derived path down into PackageSettings so we know what to 7880 // clean up at uninstall time. 7881 pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir; 7882 7883 if (DEBUG_ABI_SELECTION) { 7884 Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" + 7885 " primary=" + pkg.applicationInfo.primaryCpuAbi + 7886 " secondary=" + pkg.applicationInfo.secondaryCpuAbi); 7887 } 7888 7889 if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) { 7890 // We don't do this here during boot because we can do it all 7891 // at once after scanning all existing packages. 7892 // 7893 // We also do this *before* we perform dexopt on this package, so that 7894 // we can avoid redundant dexopts, and also to make sure we've got the 7895 // code and package path correct. 7896 adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, 7897 pkg, true /* boot complete */); 7898 } 7899 7900 if (mFactoryTest && pkg.requestedPermissions.contains( 7901 android.Manifest.permission.FACTORY_TEST)) { 7902 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST; 7903 } 7904 7905 ArrayList<PackageParser.Package> clientLibPkgs = null; 7906 7907 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 7908 if (nonMutatedPs != null) { 7909 synchronized (mPackages) { 7910 mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs); 7911 } 7912 } 7913 return pkg; 7914 } 7915 7916 // Only privileged apps and updated privileged apps can add child packages. 7917 if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) { 7918 if ((parseFlags & PARSE_IS_PRIVILEGED) == 0) { 7919 throw new PackageManagerException("Only privileged apps and updated " 7920 + "privileged apps can add child packages. Ignoring package " 7921 + pkg.packageName); 7922 } 7923 final int childCount = pkg.childPackages.size(); 7924 for (int i = 0; i < childCount; i++) { 7925 PackageParser.Package childPkg = pkg.childPackages.get(i); 7926 if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName, 7927 childPkg.packageName)) { 7928 throw new PackageManagerException("Cannot override a child package of " 7929 + "another disabled system app. Ignoring package " + pkg.packageName); 7930 } 7931 } 7932 } 7933 7934 // writer 7935 synchronized (mPackages) { 7936 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7937 // Only system apps can add new shared libraries. 7938 if (pkg.libraryNames != null) { 7939 for (int i=0; i<pkg.libraryNames.size(); i++) { 7940 String name = pkg.libraryNames.get(i); 7941 boolean allowed = false; 7942 if (pkg.isUpdatedSystemApp()) { 7943 // New library entries can only be added through the 7944 // system image. This is important to get rid of a lot 7945 // of nasty edge cases: for example if we allowed a non- 7946 // system update of the app to add a library, then uninstalling 7947 // the update would make the library go away, and assumptions 7948 // we made such as through app install filtering would now 7949 // have allowed apps on the device which aren't compatible 7950 // with it. Better to just have the restriction here, be 7951 // conservative, and create many fewer cases that can negatively 7952 // impact the user experience. 7953 final PackageSetting sysPs = mSettings 7954 .getDisabledSystemPkgLPr(pkg.packageName); 7955 if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) { 7956 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) { 7957 if (name.equals(sysPs.pkg.libraryNames.get(j))) { 7958 allowed = true; 7959 break; 7960 } 7961 } 7962 } 7963 } else { 7964 allowed = true; 7965 } 7966 if (allowed) { 7967 if (!mSharedLibraries.containsKey(name)) { 7968 mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName)); 7969 } else if (!name.equals(pkg.packageName)) { 7970 Slog.w(TAG, "Package " + pkg.packageName + " library " 7971 + name + " already exists; skipping"); 7972 } 7973 } else { 7974 Slog.w(TAG, "Package " + pkg.packageName + " declares lib " 7975 + name + " that is not declared on system image; skipping"); 7976 } 7977 } 7978 if ((scanFlags & SCAN_BOOTING) == 0) { 7979 // If we are not booting, we need to update any applications 7980 // that are clients of our shared library. If we are booting, 7981 // this will all be done once the scan is complete. 7982 clientLibPkgs = updateAllSharedLibrariesLPw(pkg); 7983 } 7984 } 7985 } 7986 } 7987 7988 // Request the ActivityManager to kill the process(only for existing packages) 7989 // so that we do not end up in a confused state while the user is still using the older 7990 // version of the application while the new one gets installed. 7991 final boolean isReplacing = (scanFlags & SCAN_REPLACING) != 0; 7992 final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0; 7993 if (killApp) { 7994 if (isReplacing) { 7995 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "killApplication"); 7996 7997 killApplication(pkg.applicationInfo.packageName, 7998 pkg.applicationInfo.uid, "replace pkg"); 7999 8000 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 8001 } 8002 } 8003 8004 // Also need to kill any apps that are dependent on the library. 8005 if (clientLibPkgs != null) { 8006 for (int i=0; i<clientLibPkgs.size(); i++) { 8007 PackageParser.Package clientPkg = clientLibPkgs.get(i); 8008 killApplication(clientPkg.applicationInfo.packageName, 8009 clientPkg.applicationInfo.uid, "update lib"); 8010 } 8011 } 8012 8013 // Make sure we're not adding any bogus keyset info 8014 KeySetManagerService ksms = mSettings.mKeySetManagerService; 8015 ksms.assertScannedPackageValid(pkg); 8016 8017 // writer 8018 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 8019 8020 boolean createIdmapFailed = false; 8021 synchronized (mPackages) { 8022 // We don't expect installation to fail beyond this point 8023 8024 // Add the new setting to mSettings 8025 mSettings.insertPackageSettingLPw(pkgSetting, pkg); 8026 // Add the new setting to mPackages 8027 mPackages.put(pkg.applicationInfo.packageName, pkg); 8028 // Make sure we don't accidentally delete its data. 8029 final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator(); 8030 while (iter.hasNext()) { 8031 PackageCleanItem item = iter.next(); 8032 if (pkgName.equals(item.packageName)) { 8033 iter.remove(); 8034 } 8035 } 8036 8037 // Take care of first install / last update times. 8038 if (currentTime != 0) { 8039 if (pkgSetting.firstInstallTime == 0) { 8040 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime; 8041 } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) { 8042 pkgSetting.lastUpdateTime = currentTime; 8043 } 8044 } else if (pkgSetting.firstInstallTime == 0) { 8045 // We need *something*. Take time time stamp of the file. 8046 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime; 8047 } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) { 8048 if (scanFileTime != pkgSetting.timeStamp) { 8049 // A package on the system image has changed; consider this 8050 // to be an update. 8051 pkgSetting.lastUpdateTime = scanFileTime; 8052 } 8053 } 8054 8055 // Add the package's KeySets to the global KeySetManagerService 8056 ksms.addScannedPackageLPw(pkg); 8057 8058 int N = pkg.providers.size(); 8059 StringBuilder r = null; 8060 int i; 8061 for (i=0; i<N; i++) { 8062 PackageParser.Provider p = pkg.providers.get(i); 8063 p.info.processName = fixProcessName(pkg.applicationInfo.processName, 8064 p.info.processName, pkg.applicationInfo.uid); 8065 mProviders.addProvider(p); 8066 p.syncable = p.info.isSyncable; 8067 if (p.info.authority != null) { 8068 String names[] = p.info.authority.split(";"); 8069 p.info.authority = null; 8070 for (int j = 0; j < names.length; j++) { 8071 if (j == 1 && p.syncable) { 8072 // We only want the first authority for a provider to possibly be 8073 // syncable, so if we already added this provider using a different 8074 // authority clear the syncable flag. We copy the provider before 8075 // changing it because the mProviders object contains a reference 8076 // to a provider that we don't want to change. 8077 // Only do this for the second authority since the resulting provider 8078 // object can be the same for all future authorities for this provider. 8079 p = new PackageParser.Provider(p); 8080 p.syncable = false; 8081 } 8082 if (!mProvidersByAuthority.containsKey(names[j])) { 8083 mProvidersByAuthority.put(names[j], p); 8084 if (p.info.authority == null) { 8085 p.info.authority = names[j]; 8086 } else { 8087 p.info.authority = p.info.authority + ";" + names[j]; 8088 } 8089 if (DEBUG_PACKAGE_SCANNING) { 8090 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 8091 Log.d(TAG, "Registered content provider: " + names[j] 8092 + ", className = " + p.info.name + ", isSyncable = " 8093 + p.info.isSyncable); 8094 } 8095 } else { 8096 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 8097 Slog.w(TAG, "Skipping provider name " + names[j] + 8098 " (in package " + pkg.applicationInfo.packageName + 8099 "): name already used by " 8100 + ((other != null && other.getComponentName() != null) 8101 ? other.getComponentName().getPackageName() : "?")); 8102 } 8103 } 8104 } 8105 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8106 if (r == null) { 8107 r = new StringBuilder(256); 8108 } else { 8109 r.append(' '); 8110 } 8111 r.append(p.info.name); 8112 } 8113 } 8114 if (r != null) { 8115 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r); 8116 } 8117 8118 N = pkg.services.size(); 8119 r = null; 8120 for (i=0; i<N; i++) { 8121 PackageParser.Service s = pkg.services.get(i); 8122 s.info.processName = fixProcessName(pkg.applicationInfo.processName, 8123 s.info.processName, pkg.applicationInfo.uid); 8124 mServices.addService(s); 8125 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8126 if (r == null) { 8127 r = new StringBuilder(256); 8128 } else { 8129 r.append(' '); 8130 } 8131 r.append(s.info.name); 8132 } 8133 } 8134 if (r != null) { 8135 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r); 8136 } 8137 8138 N = pkg.receivers.size(); 8139 r = null; 8140 for (i=0; i<N; i++) { 8141 PackageParser.Activity a = pkg.receivers.get(i); 8142 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 8143 a.info.processName, pkg.applicationInfo.uid); 8144 mReceivers.addActivity(a, "receiver"); 8145 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8146 if (r == null) { 8147 r = new StringBuilder(256); 8148 } else { 8149 r.append(' '); 8150 } 8151 r.append(a.info.name); 8152 } 8153 } 8154 if (r != null) { 8155 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r); 8156 } 8157 8158 N = pkg.activities.size(); 8159 r = null; 8160 for (i=0; i<N; i++) { 8161 PackageParser.Activity a = pkg.activities.get(i); 8162 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 8163 a.info.processName, pkg.applicationInfo.uid); 8164 mActivities.addActivity(a, "activity"); 8165 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8166 if (r == null) { 8167 r = new StringBuilder(256); 8168 } else { 8169 r.append(' '); 8170 } 8171 r.append(a.info.name); 8172 } 8173 } 8174 if (r != null) { 8175 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r); 8176 } 8177 8178 N = pkg.permissionGroups.size(); 8179 r = null; 8180 for (i=0; i<N; i++) { 8181 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i); 8182 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name); 8183 if (cur == null) { 8184 mPermissionGroups.put(pg.info.name, pg); 8185 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8186 if (r == null) { 8187 r = new StringBuilder(256); 8188 } else { 8189 r.append(' '); 8190 } 8191 r.append(pg.info.name); 8192 } 8193 } else { 8194 Slog.w(TAG, "Permission group " + pg.info.name + " from package " 8195 + pg.info.packageName + " ignored: original from " 8196 + cur.info.packageName); 8197 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8198 if (r == null) { 8199 r = new StringBuilder(256); 8200 } else { 8201 r.append(' '); 8202 } 8203 r.append("DUP:"); 8204 r.append(pg.info.name); 8205 } 8206 } 8207 } 8208 if (r != null) { 8209 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permission Groups: " + r); 8210 } 8211 8212 N = pkg.permissions.size(); 8213 r = null; 8214 for (i=0; i<N; i++) { 8215 PackageParser.Permission p = pkg.permissions.get(i); 8216 8217 // Assume by default that we did not install this permission into the system. 8218 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED; 8219 8220 // Now that permission groups have a special meaning, we ignore permission 8221 // groups for legacy apps to prevent unexpected behavior. In particular, 8222 // permissions for one app being granted to someone just becase they happen 8223 // to be in a group defined by another app (before this had no implications). 8224 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) { 8225 p.group = mPermissionGroups.get(p.info.group); 8226 // Warn for a permission in an unknown group. 8227 if (p.info.group != null && p.group == null) { 8228 Slog.w(TAG, "Permission " + p.info.name + " from package " 8229 + p.info.packageName + " in an unknown group " + p.info.group); 8230 } 8231 } 8232 8233 ArrayMap<String, BasePermission> permissionMap = 8234 p.tree ? mSettings.mPermissionTrees 8235 : mSettings.mPermissions; 8236 BasePermission bp = permissionMap.get(p.info.name); 8237 8238 // Allow system apps to redefine non-system permissions 8239 if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) { 8240 final boolean currentOwnerIsSystem = (bp.perm != null 8241 && isSystemApp(bp.perm.owner)); 8242 if (isSystemApp(p.owner)) { 8243 if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) { 8244 // It's a built-in permission and no owner, take ownership now 8245 bp.packageSetting = pkgSetting; 8246 bp.perm = p; 8247 bp.uid = pkg.applicationInfo.uid; 8248 bp.sourcePackage = p.info.packageName; 8249 p.info.flags |= PermissionInfo.FLAG_INSTALLED; 8250 } else if (!currentOwnerIsSystem) { 8251 String msg = "New decl " + p.owner + " of permission " 8252 + p.info.name + " is system; overriding " + bp.sourcePackage; 8253 reportSettingsProblem(Log.WARN, msg); 8254 bp = null; 8255 } 8256 } 8257 } 8258 8259 if (bp == null) { 8260 bp = new BasePermission(p.info.name, p.info.packageName, 8261 BasePermission.TYPE_NORMAL); 8262 permissionMap.put(p.info.name, bp); 8263 } 8264 8265 if (bp.perm == null) { 8266 if (bp.sourcePackage == null 8267 || bp.sourcePackage.equals(p.info.packageName)) { 8268 BasePermission tree = findPermissionTreeLP(p.info.name); 8269 if (tree == null 8270 || tree.sourcePackage.equals(p.info.packageName)) { 8271 bp.packageSetting = pkgSetting; 8272 bp.perm = p; 8273 bp.uid = pkg.applicationInfo.uid; 8274 bp.sourcePackage = p.info.packageName; 8275 p.info.flags |= PermissionInfo.FLAG_INSTALLED; 8276 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8277 if (r == null) { 8278 r = new StringBuilder(256); 8279 } else { 8280 r.append(' '); 8281 } 8282 r.append(p.info.name); 8283 } 8284 } else { 8285 Slog.w(TAG, "Permission " + p.info.name + " from package " 8286 + p.info.packageName + " ignored: base tree " 8287 + tree.name + " is from package " 8288 + tree.sourcePackage); 8289 } 8290 } else { 8291 Slog.w(TAG, "Permission " + p.info.name + " from package " 8292 + p.info.packageName + " ignored: original from " 8293 + bp.sourcePackage); 8294 } 8295 } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8296 if (r == null) { 8297 r = new StringBuilder(256); 8298 } else { 8299 r.append(' '); 8300 } 8301 r.append("DUP:"); 8302 r.append(p.info.name); 8303 } 8304 if (bp.perm == p) { 8305 bp.protectionLevel = p.info.protectionLevel; 8306 } 8307 } 8308 8309 if (r != null) { 8310 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permissions: " + r); 8311 } 8312 8313 N = pkg.instrumentation.size(); 8314 r = null; 8315 for (i=0; i<N; i++) { 8316 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 8317 a.info.packageName = pkg.applicationInfo.packageName; 8318 a.info.sourceDir = pkg.applicationInfo.sourceDir; 8319 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir; 8320 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs; 8321 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs; 8322 a.info.dataDir = pkg.applicationInfo.dataDir; 8323 a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir; 8324 a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir; 8325 8326 // TODO: Update instrumentation.nativeLibraryDir as well ? Does it 8327 // need other information about the application, like the ABI and what not ? 8328 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir; 8329 mInstrumentation.put(a.getComponentName(), a); 8330 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8331 if (r == null) { 8332 r = new StringBuilder(256); 8333 } else { 8334 r.append(' '); 8335 } 8336 r.append(a.info.name); 8337 } 8338 } 8339 if (r != null) { 8340 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r); 8341 } 8342 8343 if (pkg.protectedBroadcasts != null) { 8344 N = pkg.protectedBroadcasts.size(); 8345 for (i=0; i<N; i++) { 8346 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i)); 8347 } 8348 } 8349 8350 pkgSetting.setTimeStamp(scanFileTime); 8351 8352 // Create idmap files for pairs of (packages, overlay packages). 8353 // Note: "android", ie framework-res.apk, is handled by native layers. 8354 if (pkg.mOverlayTarget != null) { 8355 // This is an overlay package. 8356 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) { 8357 if (!mOverlays.containsKey(pkg.mOverlayTarget)) { 8358 mOverlays.put(pkg.mOverlayTarget, 8359 new ArrayMap<String, PackageParser.Package>()); 8360 } 8361 ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget); 8362 map.put(pkg.packageName, pkg); 8363 PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget); 8364 if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) { 8365 createIdmapFailed = true; 8366 } 8367 } 8368 } else if (mOverlays.containsKey(pkg.packageName) && 8369 !pkg.packageName.equals("android")) { 8370 // This is a regular package, with one or more known overlay packages. 8371 createIdmapsForPackageLI(pkg); 8372 } 8373 } 8374 8375 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 8376 8377 if (createIdmapFailed) { 8378 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 8379 "scanPackageLI failed to createIdmap"); 8380 } 8381 return pkg; 8382 } 8383 8384 /** 8385 * Derive the ABI of a non-system package located at {@code scanFile}. This information 8386 * is derived purely on the basis of the contents of {@code scanFile} and 8387 * {@code cpuAbiOverride}. 8388 * 8389 * If {@code extractLibs} is true, native libraries are extracted from the app if required. 8390 */ 8391 private void derivePackageAbi(PackageParser.Package pkg, File scanFile, 8392 String cpuAbiOverride, boolean extractLibs) 8393 throws PackageManagerException { 8394 // TODO: We can probably be smarter about this stuff. For installed apps, 8395 // we can calculate this information at install time once and for all. For 8396 // system apps, we can probably assume that this information doesn't change 8397 // after the first boot scan. As things stand, we do lots of unnecessary work. 8398 8399 // Give ourselves some initial paths; we'll come back for another 8400 // pass once we've determined ABI below. 8401 setNativeLibraryPaths(pkg); 8402 8403 // We would never need to extract libs for forward-locked and external packages, 8404 // since the container service will do it for us. We shouldn't attempt to 8405 // extract libs from system app when it was not updated. 8406 if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() || 8407 (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) { 8408 extractLibs = false; 8409 } 8410 8411 final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir; 8412 final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa; 8413 8414 NativeLibraryHelper.Handle handle = null; 8415 try { 8416 handle = NativeLibraryHelper.Handle.create(pkg); 8417 // TODO(multiArch): This can be null for apps that didn't go through the 8418 // usual installation process. We can calculate it again, like we 8419 // do during install time. 8420 // 8421 // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally 8422 // unnecessary. 8423 final File nativeLibraryRoot = new File(nativeLibraryRootStr); 8424 8425 // Null out the abis so that they can be recalculated. 8426 pkg.applicationInfo.primaryCpuAbi = null; 8427 pkg.applicationInfo.secondaryCpuAbi = null; 8428 if (isMultiArch(pkg.applicationInfo)) { 8429 // Warn if we've set an abiOverride for multi-lib packages.. 8430 // By definition, we need to copy both 32 and 64 bit libraries for 8431 // such packages. 8432 if (pkg.cpuAbiOverride != null 8433 && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) { 8434 Slog.w(TAG, "Ignoring abiOverride for multi arch application."); 8435 } 8436 8437 int abi32 = PackageManager.NO_NATIVE_LIBRARIES; 8438 int abi64 = PackageManager.NO_NATIVE_LIBRARIES; 8439 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) { 8440 if (extractLibs) { 8441 abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 8442 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS, 8443 useIsaSpecificSubdirs); 8444 } else { 8445 abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS); 8446 } 8447 } 8448 8449 maybeThrowExceptionForMultiArchCopy( 8450 "Error unpackaging 32 bit native libs for multiarch app.", abi32); 8451 8452 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) { 8453 if (extractLibs) { 8454 abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 8455 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS, 8456 useIsaSpecificSubdirs); 8457 } else { 8458 abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS); 8459 } 8460 } 8461 8462 maybeThrowExceptionForMultiArchCopy( 8463 "Error unpackaging 64 bit native libs for multiarch app.", abi64); 8464 8465 if (abi64 >= 0) { 8466 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64]; 8467 } 8468 8469 if (abi32 >= 0) { 8470 final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32]; 8471 if (abi64 >= 0) { 8472 if (cpuAbiOverride == null && pkg.use32bitAbi) { 8473 pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi; 8474 pkg.applicationInfo.primaryCpuAbi = abi; 8475 } else { 8476 pkg.applicationInfo.secondaryCpuAbi = abi; 8477 } 8478 } else { 8479 pkg.applicationInfo.primaryCpuAbi = abi; 8480 } 8481 } 8482 8483 } else { 8484 String[] abiList = (cpuAbiOverride != null) ? 8485 new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS; 8486 8487 // Enable gross and lame hacks for apps that are built with old 8488 // SDK tools. We must scan their APKs for renderscript bitcode and 8489 // not launch them if it's present. Don't bother checking on devices 8490 // that don't have 64 bit support. 8491 boolean needsRenderScriptOverride = false; 8492 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null && 8493 NativeLibraryHelper.hasRenderscriptBitcode(handle)) { 8494 abiList = Build.SUPPORTED_32_BIT_ABIS; 8495 needsRenderScriptOverride = true; 8496 } 8497 8498 final int copyRet; 8499 if (extractLibs) { 8500 copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 8501 nativeLibraryRoot, abiList, useIsaSpecificSubdirs); 8502 } else { 8503 copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList); 8504 } 8505 8506 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { 8507 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, 8508 "Error unpackaging native libs for app, errorCode=" + copyRet); 8509 } 8510 8511 if (copyRet >= 0) { 8512 pkg.applicationInfo.primaryCpuAbi = abiList[copyRet]; 8513 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) { 8514 pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride; 8515 } else if (needsRenderScriptOverride) { 8516 pkg.applicationInfo.primaryCpuAbi = abiList[0]; 8517 } 8518 } 8519 } catch (IOException ioe) { 8520 Slog.e(TAG, "Unable to get canonical file " + ioe.toString()); 8521 } finally { 8522 IoUtils.closeQuietly(handle); 8523 } 8524 8525 // Now that we've calculated the ABIs and determined if it's an internal app, 8526 // we will go ahead and populate the nativeLibraryPath. 8527 setNativeLibraryPaths(pkg); 8528 } 8529 8530 /** 8531 * Adjusts ABIs for a set of packages belonging to a shared user so that they all match. 8532 * i.e, so that all packages can be run inside a single process if required. 8533 * 8534 * Optionally, callers can pass in a parsed package via {@code newPackage} in which case 8535 * this function will either try and make the ABI for all packages in {@code packagesForUser} 8536 * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match 8537 * the ABI selected for {@code packagesForUser}. This variant is used when installing or 8538 * updating a package that belongs to a shared user. 8539 * 8540 * NOTE: We currently only match for the primary CPU abi string. Matching the secondary 8541 * adds unnecessary complexity. 8542 */ 8543 private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser, 8544 PackageParser.Package scannedPackage, boolean bootComplete) { 8545 String requiredInstructionSet = null; 8546 if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) { 8547 requiredInstructionSet = VMRuntime.getInstructionSet( 8548 scannedPackage.applicationInfo.primaryCpuAbi); 8549 } 8550 8551 PackageSetting requirer = null; 8552 for (PackageSetting ps : packagesForUser) { 8553 // If packagesForUser contains scannedPackage, we skip it. This will happen 8554 // when scannedPackage is an update of an existing package. Without this check, 8555 // we will never be able to change the ABI of any package belonging to a shared 8556 // user, even if it's compatible with other packages. 8557 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 8558 if (ps.primaryCpuAbiString == null) { 8559 continue; 8560 } 8561 8562 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString); 8563 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) { 8564 // We have a mismatch between instruction sets (say arm vs arm64) warn about 8565 // this but there's not much we can do. 8566 String errorMessage = "Instruction set mismatch, " 8567 + ((requirer == null) ? "[caller]" : requirer) 8568 + " requires " + requiredInstructionSet + " whereas " + ps 8569 + " requires " + instructionSet; 8570 Slog.w(TAG, errorMessage); 8571 } 8572 8573 if (requiredInstructionSet == null) { 8574 requiredInstructionSet = instructionSet; 8575 requirer = ps; 8576 } 8577 } 8578 } 8579 8580 if (requiredInstructionSet != null) { 8581 String adjustedAbi; 8582 if (requirer != null) { 8583 // requirer != null implies that either scannedPackage was null or that scannedPackage 8584 // did not require an ABI, in which case we have to adjust scannedPackage to match 8585 // the ABI of the set (which is the same as requirer's ABI) 8586 adjustedAbi = requirer.primaryCpuAbiString; 8587 if (scannedPackage != null) { 8588 scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi; 8589 } 8590 } else { 8591 // requirer == null implies that we're updating all ABIs in the set to 8592 // match scannedPackage. 8593 adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi; 8594 } 8595 8596 for (PackageSetting ps : packagesForUser) { 8597 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 8598 if (ps.primaryCpuAbiString != null) { 8599 continue; 8600 } 8601 8602 ps.primaryCpuAbiString = adjustedAbi; 8603 if (ps.pkg != null && ps.pkg.applicationInfo != null && 8604 !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) { 8605 ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi; 8606 Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi 8607 + " (requirer=" 8608 + (requirer == null ? "null" : requirer.pkg.packageName) 8609 + ", scannedPackage=" 8610 + (scannedPackage != null ? scannedPackage.packageName : "null") 8611 + ")"); 8612 try { 8613 mInstaller.rmdex(ps.codePathString, 8614 getDexCodeInstructionSet(getPreferredInstructionSet())); 8615 } catch (InstallerException ignored) { 8616 } 8617 } 8618 } 8619 } 8620 } 8621 } 8622 8623 private void setUpCustomResolverActivity(PackageParser.Package pkg) { 8624 synchronized (mPackages) { 8625 mResolverReplaced = true; 8626 // Set up information for custom user intent resolution activity. 8627 mResolveActivity.applicationInfo = pkg.applicationInfo; 8628 mResolveActivity.name = mCustomResolverComponentName.getClassName(); 8629 mResolveActivity.packageName = pkg.applicationInfo.packageName; 8630 mResolveActivity.processName = pkg.applicationInfo.packageName; 8631 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 8632 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS | 8633 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 8634 mResolveActivity.theme = 0; 8635 mResolveActivity.exported = true; 8636 mResolveActivity.enabled = true; 8637 mResolveInfo.activityInfo = mResolveActivity; 8638 mResolveInfo.priority = 0; 8639 mResolveInfo.preferredOrder = 0; 8640 mResolveInfo.match = 0; 8641 mResolveComponentName = mCustomResolverComponentName; 8642 Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " + 8643 mResolveComponentName); 8644 } 8645 } 8646 8647 private void setUpEphemeralInstallerActivityLP(ComponentName installerComponent) { 8648 final PackageParser.Package pkg = mPackages.get(installerComponent.getPackageName()); 8649 8650 // Set up information for ephemeral installer activity 8651 mEphemeralInstallerActivity.applicationInfo = pkg.applicationInfo; 8652 mEphemeralInstallerActivity.name = mEphemeralInstallerComponent.getClassName(); 8653 mEphemeralInstallerActivity.packageName = pkg.applicationInfo.packageName; 8654 mEphemeralInstallerActivity.processName = pkg.applicationInfo.packageName; 8655 mEphemeralInstallerActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 8656 mEphemeralInstallerActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS | 8657 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 8658 mEphemeralInstallerActivity.theme = 0; 8659 mEphemeralInstallerActivity.exported = true; 8660 mEphemeralInstallerActivity.enabled = true; 8661 mEphemeralInstallerInfo.activityInfo = mEphemeralInstallerActivity; 8662 mEphemeralInstallerInfo.priority = 0; 8663 mEphemeralInstallerInfo.preferredOrder = 0; 8664 mEphemeralInstallerInfo.match = 0; 8665 8666 if (DEBUG_EPHEMERAL) { 8667 Slog.d(TAG, "Set ephemeral installer activity: " + mEphemeralInstallerComponent); 8668 } 8669 } 8670 8671 private static String calculateBundledApkRoot(final String codePathString) { 8672 final File codePath = new File(codePathString); 8673 final File codeRoot; 8674 if (FileUtils.contains(Environment.getRootDirectory(), codePath)) { 8675 codeRoot = Environment.getRootDirectory(); 8676 } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) { 8677 codeRoot = Environment.getOemDirectory(); 8678 } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) { 8679 codeRoot = Environment.getVendorDirectory(); 8680 } else { 8681 // Unrecognized code path; take its top real segment as the apk root: 8682 // e.g. /something/app/blah.apk => /something 8683 try { 8684 File f = codePath.getCanonicalFile(); 8685 File parent = f.getParentFile(); // non-null because codePath is a file 8686 File tmp; 8687 while ((tmp = parent.getParentFile()) != null) { 8688 f = parent; 8689 parent = tmp; 8690 } 8691 codeRoot = f; 8692 Slog.w(TAG, "Unrecognized code path " 8693 + codePath + " - using " + codeRoot); 8694 } catch (IOException e) { 8695 // Can't canonicalize the code path -- shenanigans? 8696 Slog.w(TAG, "Can't canonicalize code path " + codePath); 8697 return Environment.getRootDirectory().getPath(); 8698 } 8699 } 8700 return codeRoot.getPath(); 8701 } 8702 8703 /** 8704 * Derive and set the location of native libraries for the given package, 8705 * which varies depending on where and how the package was installed. 8706 */ 8707 private void setNativeLibraryPaths(PackageParser.Package pkg) { 8708 final ApplicationInfo info = pkg.applicationInfo; 8709 final String codePath = pkg.codePath; 8710 final File codeFile = new File(codePath); 8711 final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp(); 8712 final boolean asecApp = info.isForwardLocked() || info.isExternalAsec(); 8713 8714 info.nativeLibraryRootDir = null; 8715 info.nativeLibraryRootRequiresIsa = false; 8716 info.nativeLibraryDir = null; 8717 info.secondaryNativeLibraryDir = null; 8718 8719 if (isApkFile(codeFile)) { 8720 // Monolithic install 8721 if (bundledApp) { 8722 // If "/system/lib64/apkname" exists, assume that is the per-package 8723 // native library directory to use; otherwise use "/system/lib/apkname". 8724 final String apkRoot = calculateBundledApkRoot(info.sourceDir); 8725 final boolean is64Bit = VMRuntime.is64BitInstructionSet( 8726 getPrimaryInstructionSet(info)); 8727 8728 // This is a bundled system app so choose the path based on the ABI. 8729 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this 8730 // is just the default path. 8731 final String apkName = deriveCodePathName(codePath); 8732 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME; 8733 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir, 8734 apkName).getAbsolutePath(); 8735 8736 if (info.secondaryCpuAbi != null) { 8737 final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME; 8738 info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot), 8739 secondaryLibDir, apkName).getAbsolutePath(); 8740 } 8741 } else if (asecApp) { 8742 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME) 8743 .getAbsolutePath(); 8744 } else { 8745 final String apkName = deriveCodePathName(codePath); 8746 info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName) 8747 .getAbsolutePath(); 8748 } 8749 8750 info.nativeLibraryRootRequiresIsa = false; 8751 info.nativeLibraryDir = info.nativeLibraryRootDir; 8752 } else { 8753 // Cluster install 8754 info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath(); 8755 info.nativeLibraryRootRequiresIsa = true; 8756 8757 info.nativeLibraryDir = new File(info.nativeLibraryRootDir, 8758 getPrimaryInstructionSet(info)).getAbsolutePath(); 8759 8760 if (info.secondaryCpuAbi != null) { 8761 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir, 8762 VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath(); 8763 } 8764 } 8765 } 8766 8767 /** 8768 * Calculate the abis and roots for a bundled app. These can uniquely 8769 * be determined from the contents of the system partition, i.e whether 8770 * it contains 64 or 32 bit shared libraries etc. We do not validate any 8771 * of this information, and instead assume that the system was built 8772 * sensibly. 8773 */ 8774 private void setBundledAppAbisAndRoots(PackageParser.Package pkg, 8775 PackageSetting pkgSetting) { 8776 final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath()); 8777 8778 // If "/system/lib64/apkname" exists, assume that is the per-package 8779 // native library directory to use; otherwise use "/system/lib/apkname". 8780 final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir); 8781 setBundledAppAbi(pkg, apkRoot, apkName); 8782 // pkgSetting might be null during rescan following uninstall of updates 8783 // to a bundled app, so accommodate that possibility. The settings in 8784 // that case will be established later from the parsed package. 8785 // 8786 // If the settings aren't null, sync them up with what we've just derived. 8787 // note that apkRoot isn't stored in the package settings. 8788 if (pkgSetting != null) { 8789 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 8790 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 8791 } 8792 } 8793 8794 /** 8795 * Deduces the ABI of a bundled app and sets the relevant fields on the 8796 * parsed pkg object. 8797 * 8798 * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem} 8799 * under which system libraries are installed. 8800 * @param apkName the name of the installed package. 8801 */ 8802 private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) { 8803 final File codeFile = new File(pkg.codePath); 8804 8805 final boolean has64BitLibs; 8806 final boolean has32BitLibs; 8807 if (isApkFile(codeFile)) { 8808 // Monolithic install 8809 has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists(); 8810 has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists(); 8811 } else { 8812 // Cluster install 8813 final File rootDir = new File(codeFile, LIB_DIR_NAME); 8814 if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS) 8815 && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) { 8816 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]); 8817 has64BitLibs = (new File(rootDir, isa)).exists(); 8818 } else { 8819 has64BitLibs = false; 8820 } 8821 if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS) 8822 && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) { 8823 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]); 8824 has32BitLibs = (new File(rootDir, isa)).exists(); 8825 } else { 8826 has32BitLibs = false; 8827 } 8828 } 8829 8830 if (has64BitLibs && !has32BitLibs) { 8831 // The package has 64 bit libs, but not 32 bit libs. Its primary 8832 // ABI should be 64 bit. We can safely assume here that the bundled 8833 // native libraries correspond to the most preferred ABI in the list. 8834 8835 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 8836 pkg.applicationInfo.secondaryCpuAbi = null; 8837 } else if (has32BitLibs && !has64BitLibs) { 8838 // The package has 32 bit libs but not 64 bit libs. Its primary 8839 // ABI should be 32 bit. 8840 8841 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 8842 pkg.applicationInfo.secondaryCpuAbi = null; 8843 } else if (has32BitLibs && has64BitLibs) { 8844 // The application has both 64 and 32 bit bundled libraries. We check 8845 // here that the app declares multiArch support, and warn if it doesn't. 8846 // 8847 // We will be lenient here and record both ABIs. The primary will be the 8848 // ABI that's higher on the list, i.e, a device that's configured to prefer 8849 // 64 bit apps will see a 64 bit primary ABI, 8850 8851 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) { 8852 Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch."); 8853 } 8854 8855 if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) { 8856 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 8857 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 8858 } else { 8859 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 8860 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 8861 } 8862 } else { 8863 pkg.applicationInfo.primaryCpuAbi = null; 8864 pkg.applicationInfo.secondaryCpuAbi = null; 8865 } 8866 } 8867 8868 private void killPackage(PackageParser.Package pkg, String reason) { 8869 // Kill the parent package 8870 killApplication(pkg.packageName, pkg.applicationInfo.uid, reason); 8871 // Kill the child packages 8872 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8873 for (int i = 0; i < childCount; i++) { 8874 PackageParser.Package childPkg = pkg.childPackages.get(i); 8875 killApplication(childPkg.packageName, childPkg.applicationInfo.uid, reason); 8876 } 8877 } 8878 8879 private void killApplication(String pkgName, int appId, String reason) { 8880 // Request the ActivityManager to kill the process(only for existing packages) 8881 // so that we do not end up in a confused state while the user is still using the older 8882 // version of the application while the new one gets installed. 8883 IActivityManager am = ActivityManagerNative.getDefault(); 8884 if (am != null) { 8885 try { 8886 am.killApplicationWithAppId(pkgName, appId, reason); 8887 } catch (RemoteException e) { 8888 } 8889 } 8890 } 8891 8892 private void removePackageLI(PackageParser.Package pkg, boolean chatty) { 8893 // Remove the parent package setting 8894 PackageSetting ps = (PackageSetting) pkg.mExtras; 8895 if (ps != null) { 8896 removePackageLI(ps, chatty); 8897 } 8898 // Remove the child package setting 8899 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8900 for (int i = 0; i < childCount; i++) { 8901 PackageParser.Package childPkg = pkg.childPackages.get(i); 8902 ps = (PackageSetting) childPkg.mExtras; 8903 if (ps != null) { 8904 removePackageLI(ps, chatty); 8905 } 8906 } 8907 } 8908 8909 void removePackageLI(PackageSetting ps, boolean chatty) { 8910 if (DEBUG_INSTALL) { 8911 if (chatty) 8912 Log.d(TAG, "Removing package " + ps.name); 8913 } 8914 8915 // writer 8916 synchronized (mPackages) { 8917 mPackages.remove(ps.name); 8918 final PackageParser.Package pkg = ps.pkg; 8919 if (pkg != null) { 8920 cleanPackageDataStructuresLILPw(pkg, chatty); 8921 } 8922 } 8923 } 8924 8925 void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) { 8926 if (DEBUG_INSTALL) { 8927 if (chatty) 8928 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName); 8929 } 8930 8931 // writer 8932 synchronized (mPackages) { 8933 // Remove the parent package 8934 mPackages.remove(pkg.applicationInfo.packageName); 8935 cleanPackageDataStructuresLILPw(pkg, chatty); 8936 8937 // Remove the child packages 8938 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8939 for (int i = 0; i < childCount; i++) { 8940 PackageParser.Package childPkg = pkg.childPackages.get(i); 8941 mPackages.remove(childPkg.applicationInfo.packageName); 8942 cleanPackageDataStructuresLILPw(childPkg, chatty); 8943 } 8944 } 8945 } 8946 8947 void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) { 8948 int N = pkg.providers.size(); 8949 StringBuilder r = null; 8950 int i; 8951 for (i=0; i<N; i++) { 8952 PackageParser.Provider p = pkg.providers.get(i); 8953 mProviders.removeProvider(p); 8954 if (p.info.authority == null) { 8955 8956 /* There was another ContentProvider with this authority when 8957 * this app was installed so this authority is null, 8958 * Ignore it as we don't have to unregister the provider. 8959 */ 8960 continue; 8961 } 8962 String names[] = p.info.authority.split(";"); 8963 for (int j = 0; j < names.length; j++) { 8964 if (mProvidersByAuthority.get(names[j]) == p) { 8965 mProvidersByAuthority.remove(names[j]); 8966 if (DEBUG_REMOVE) { 8967 if (chatty) 8968 Log.d(TAG, "Unregistered content provider: " + names[j] 8969 + ", className = " + p.info.name + ", isSyncable = " 8970 + p.info.isSyncable); 8971 } 8972 } 8973 } 8974 if (DEBUG_REMOVE && chatty) { 8975 if (r == null) { 8976 r = new StringBuilder(256); 8977 } else { 8978 r.append(' '); 8979 } 8980 r.append(p.info.name); 8981 } 8982 } 8983 if (r != null) { 8984 if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r); 8985 } 8986 8987 N = pkg.services.size(); 8988 r = null; 8989 for (i=0; i<N; i++) { 8990 PackageParser.Service s = pkg.services.get(i); 8991 mServices.removeService(s); 8992 if (chatty) { 8993 if (r == null) { 8994 r = new StringBuilder(256); 8995 } else { 8996 r.append(' '); 8997 } 8998 r.append(s.info.name); 8999 } 9000 } 9001 if (r != null) { 9002 if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r); 9003 } 9004 9005 N = pkg.receivers.size(); 9006 r = null; 9007 for (i=0; i<N; i++) { 9008 PackageParser.Activity a = pkg.receivers.get(i); 9009 mReceivers.removeActivity(a, "receiver"); 9010 if (DEBUG_REMOVE && chatty) { 9011 if (r == null) { 9012 r = new StringBuilder(256); 9013 } else { 9014 r.append(' '); 9015 } 9016 r.append(a.info.name); 9017 } 9018 } 9019 if (r != null) { 9020 if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r); 9021 } 9022 9023 N = pkg.activities.size(); 9024 r = null; 9025 for (i=0; i<N; i++) { 9026 PackageParser.Activity a = pkg.activities.get(i); 9027 mActivities.removeActivity(a, "activity"); 9028 if (DEBUG_REMOVE && chatty) { 9029 if (r == null) { 9030 r = new StringBuilder(256); 9031 } else { 9032 r.append(' '); 9033 } 9034 r.append(a.info.name); 9035 } 9036 } 9037 if (r != null) { 9038 if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r); 9039 } 9040 9041 N = pkg.permissions.size(); 9042 r = null; 9043 for (i=0; i<N; i++) { 9044 PackageParser.Permission p = pkg.permissions.get(i); 9045 BasePermission bp = mSettings.mPermissions.get(p.info.name); 9046 if (bp == null) { 9047 bp = mSettings.mPermissionTrees.get(p.info.name); 9048 } 9049 if (bp != null && bp.perm == p) { 9050 bp.perm = null; 9051 if (DEBUG_REMOVE && chatty) { 9052 if (r == null) { 9053 r = new StringBuilder(256); 9054 } else { 9055 r.append(' '); 9056 } 9057 r.append(p.info.name); 9058 } 9059 } 9060 if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 9061 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name); 9062 if (appOpPkgs != null) { 9063 appOpPkgs.remove(pkg.packageName); 9064 } 9065 } 9066 } 9067 if (r != null) { 9068 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 9069 } 9070 9071 N = pkg.requestedPermissions.size(); 9072 r = null; 9073 for (i=0; i<N; i++) { 9074 String perm = pkg.requestedPermissions.get(i); 9075 BasePermission bp = mSettings.mPermissions.get(perm); 9076 if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 9077 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm); 9078 if (appOpPkgs != null) { 9079 appOpPkgs.remove(pkg.packageName); 9080 if (appOpPkgs.isEmpty()) { 9081 mAppOpPermissionPackages.remove(perm); 9082 } 9083 } 9084 } 9085 } 9086 if (r != null) { 9087 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 9088 } 9089 9090 N = pkg.instrumentation.size(); 9091 r = null; 9092 for (i=0; i<N; i++) { 9093 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 9094 mInstrumentation.remove(a.getComponentName()); 9095 if (DEBUG_REMOVE && chatty) { 9096 if (r == null) { 9097 r = new StringBuilder(256); 9098 } else { 9099 r.append(' '); 9100 } 9101 r.append(a.info.name); 9102 } 9103 } 9104 if (r != null) { 9105 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r); 9106 } 9107 9108 r = null; 9109 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9110 // Only system apps can hold shared libraries. 9111 if (pkg.libraryNames != null) { 9112 for (i=0; i<pkg.libraryNames.size(); i++) { 9113 String name = pkg.libraryNames.get(i); 9114 SharedLibraryEntry cur = mSharedLibraries.get(name); 9115 if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) { 9116 mSharedLibraries.remove(name); 9117 if (DEBUG_REMOVE && chatty) { 9118 if (r == null) { 9119 r = new StringBuilder(256); 9120 } else { 9121 r.append(' '); 9122 } 9123 r.append(name); 9124 } 9125 } 9126 } 9127 } 9128 } 9129 if (r != null) { 9130 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r); 9131 } 9132 } 9133 9134 private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) { 9135 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) { 9136 if (pkgInfo.permissions.get(i).info.name.equals(perm)) { 9137 return true; 9138 } 9139 } 9140 return false; 9141 } 9142 9143 static final int UPDATE_PERMISSIONS_ALL = 1<<0; 9144 static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1; 9145 static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2; 9146 9147 private void updatePermissionsLPw(PackageParser.Package pkg, int flags) { 9148 // Update the parent permissions 9149 updatePermissionsLPw(pkg.packageName, pkg, flags); 9150 // Update the child permissions 9151 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 9152 for (int i = 0; i < childCount; i++) { 9153 PackageParser.Package childPkg = pkg.childPackages.get(i); 9154 updatePermissionsLPw(childPkg.packageName, childPkg, flags); 9155 } 9156 } 9157 9158 private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo, 9159 int flags) { 9160 final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null; 9161 updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags); 9162 } 9163 9164 private void updatePermissionsLPw(String changingPkg, 9165 PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) { 9166 // Make sure there are no dangling permission trees. 9167 Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator(); 9168 while (it.hasNext()) { 9169 final BasePermission bp = it.next(); 9170 if (bp.packageSetting == null) { 9171 // We may not yet have parsed the package, so just see if 9172 // we still know about its settings. 9173 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 9174 } 9175 if (bp.packageSetting == null) { 9176 Slog.w(TAG, "Removing dangling permission tree: " + bp.name 9177 + " from package " + bp.sourcePackage); 9178 it.remove(); 9179 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 9180 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 9181 Slog.i(TAG, "Removing old permission tree: " + bp.name 9182 + " from package " + bp.sourcePackage); 9183 flags |= UPDATE_PERMISSIONS_ALL; 9184 it.remove(); 9185 } 9186 } 9187 } 9188 9189 // Make sure all dynamic permissions have been assigned to a package, 9190 // and make sure there are no dangling permissions. 9191 it = mSettings.mPermissions.values().iterator(); 9192 while (it.hasNext()) { 9193 final BasePermission bp = it.next(); 9194 if (bp.type == BasePermission.TYPE_DYNAMIC) { 9195 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name=" 9196 + bp.name + " pkg=" + bp.sourcePackage 9197 + " info=" + bp.pendingInfo); 9198 if (bp.packageSetting == null && bp.pendingInfo != null) { 9199 final BasePermission tree = findPermissionTreeLP(bp.name); 9200 if (tree != null && tree.perm != null) { 9201 bp.packageSetting = tree.packageSetting; 9202 bp.perm = new PackageParser.Permission(tree.perm.owner, 9203 new PermissionInfo(bp.pendingInfo)); 9204 bp.perm.info.packageName = tree.perm.info.packageName; 9205 bp.perm.info.name = bp.name; 9206 bp.uid = tree.uid; 9207 } 9208 } 9209 } 9210 if (bp.packageSetting == null) { 9211 // We may not yet have parsed the package, so just see if 9212 // we still know about its settings. 9213 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 9214 } 9215 if (bp.packageSetting == null) { 9216 Slog.w(TAG, "Removing dangling permission: " + bp.name 9217 + " from package " + bp.sourcePackage); 9218 it.remove(); 9219 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 9220 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 9221 Slog.i(TAG, "Removing old permission: " + bp.name 9222 + " from package " + bp.sourcePackage); 9223 flags |= UPDATE_PERMISSIONS_ALL; 9224 it.remove(); 9225 } 9226 } 9227 } 9228 9229 // Now update the permissions for all packages, in particular 9230 // replace the granted permissions of the system packages. 9231 if ((flags&UPDATE_PERMISSIONS_ALL) != 0) { 9232 for (PackageParser.Package pkg : mPackages.values()) { 9233 if (pkg != pkgInfo) { 9234 // Only replace for packages on requested volume 9235 final String volumeUuid = getVolumeUuidForPackage(pkg); 9236 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0) 9237 && Objects.equals(replaceVolumeUuid, volumeUuid); 9238 grantPermissionsLPw(pkg, replace, changingPkg); 9239 } 9240 } 9241 } 9242 9243 if (pkgInfo != null) { 9244 // Only replace for packages on requested volume 9245 final String volumeUuid = getVolumeUuidForPackage(pkgInfo); 9246 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0) 9247 && Objects.equals(replaceVolumeUuid, volumeUuid); 9248 grantPermissionsLPw(pkgInfo, replace, changingPkg); 9249 } 9250 } 9251 9252 private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace, 9253 String packageOfInterest) { 9254 // IMPORTANT: There are two types of permissions: install and runtime. 9255 // Install time permissions are granted when the app is installed to 9256 // all device users and users added in the future. Runtime permissions 9257 // are granted at runtime explicitly to specific users. Normal and signature 9258 // protected permissions are install time permissions. Dangerous permissions 9259 // are install permissions if the app's target SDK is Lollipop MR1 or older, 9260 // otherwise they are runtime permissions. This function does not manage 9261 // runtime permissions except for the case an app targeting Lollipop MR1 9262 // being upgraded to target a newer SDK, in which case dangerous permissions 9263 // are transformed from install time to runtime ones. 9264 9265 final PackageSetting ps = (PackageSetting) pkg.mExtras; 9266 if (ps == null) { 9267 return; 9268 } 9269 9270 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions"); 9271 9272 PermissionsState permissionsState = ps.getPermissionsState(); 9273 PermissionsState origPermissions = permissionsState; 9274 9275 final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); 9276 9277 boolean runtimePermissionsRevoked = false; 9278 int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY; 9279 9280 boolean changedInstallPermission = false; 9281 9282 if (replace) { 9283 ps.installPermissionsFixed = false; 9284 if (!ps.isSharedUser()) { 9285 origPermissions = new PermissionsState(permissionsState); 9286 permissionsState.reset(); 9287 } else { 9288 // We need to know only about runtime permission changes since the 9289 // calling code always writes the install permissions state but 9290 // the runtime ones are written only if changed. The only cases of 9291 // changed runtime permissions here are promotion of an install to 9292 // runtime and revocation of a runtime from a shared user. 9293 changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw( 9294 ps.sharedUser, UserManagerService.getInstance().getUserIds()); 9295 if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) { 9296 runtimePermissionsRevoked = true; 9297 } 9298 } 9299 } 9300 9301 permissionsState.setGlobalGids(mGlobalGids); 9302 9303 final int N = pkg.requestedPermissions.size(); 9304 for (int i=0; i<N; i++) { 9305 final String name = pkg.requestedPermissions.get(i); 9306 final BasePermission bp = mSettings.mPermissions.get(name); 9307 9308 if (DEBUG_INSTALL) { 9309 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp); 9310 } 9311 9312 if (bp == null || bp.packageSetting == null) { 9313 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 9314 Slog.w(TAG, "Unknown permission " + name 9315 + " in package " + pkg.packageName); 9316 } 9317 continue; 9318 } 9319 9320 final String perm = bp.name; 9321 boolean allowedSig = false; 9322 int grant = GRANT_DENIED; 9323 9324 // Keep track of app op permissions. 9325 if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 9326 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name); 9327 if (pkgs == null) { 9328 pkgs = new ArraySet<>(); 9329 mAppOpPermissionPackages.put(bp.name, pkgs); 9330 } 9331 pkgs.add(pkg.packageName); 9332 } 9333 9334 final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; 9335 final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion 9336 >= Build.VERSION_CODES.M; 9337 switch (level) { 9338 case PermissionInfo.PROTECTION_NORMAL: { 9339 // For all apps normal permissions are install time ones. 9340 grant = GRANT_INSTALL; 9341 } break; 9342 9343 case PermissionInfo.PROTECTION_DANGEROUS: { 9344 // If a permission review is required for legacy apps we represent 9345 // their permissions as always granted runtime ones since we need 9346 // to keep the review required permission flag per user while an 9347 // install permission's state is shared across all users. 9348 if (!appSupportsRuntimePermissions && !Build.PERMISSIONS_REVIEW_REQUIRED) { 9349 // For legacy apps dangerous permissions are install time ones. 9350 grant = GRANT_INSTALL; 9351 } else if (origPermissions.hasInstallPermission(bp.name)) { 9352 // For legacy apps that became modern, install becomes runtime. 9353 grant = GRANT_UPGRADE; 9354 } else if (mPromoteSystemApps 9355 && isSystemApp(ps) 9356 && mExistingSystemPackages.contains(ps.name)) { 9357 // For legacy system apps, install becomes runtime. 9358 // We cannot check hasInstallPermission() for system apps since those 9359 // permissions were granted implicitly and not persisted pre-M. 9360 grant = GRANT_UPGRADE; 9361 } else { 9362 // For modern apps keep runtime permissions unchanged. 9363 grant = GRANT_RUNTIME; 9364 } 9365 } break; 9366 9367 case PermissionInfo.PROTECTION_SIGNATURE: { 9368 // For all apps signature permissions are install time ones. 9369 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions); 9370 if (allowedSig) { 9371 grant = GRANT_INSTALL; 9372 } 9373 } break; 9374 } 9375 9376 if (DEBUG_INSTALL) { 9377 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm); 9378 } 9379 9380 if (grant != GRANT_DENIED) { 9381 if (!isSystemApp(ps) && ps.installPermissionsFixed) { 9382 // If this is an existing, non-system package, then 9383 // we can't add any new permissions to it. 9384 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) { 9385 // Except... if this is a permission that was added 9386 // to the platform (note: need to only do this when 9387 // updating the platform). 9388 if (!isNewPlatformPermissionForPackage(perm, pkg)) { 9389 grant = GRANT_DENIED; 9390 } 9391 } 9392 } 9393 9394 switch (grant) { 9395 case GRANT_INSTALL: { 9396 // Revoke this as runtime permission to handle the case of 9397 // a runtime permission being downgraded to an install one. Also in permission review mode we keep dangerous permissions for legacy apps 9398 for (int userId : UserManagerService.getInstance().getUserIds()) { 9399 if (origPermissions.getRuntimePermissionState( 9400 bp.name, userId) != null) { 9401 // Revoke the runtime permission and clear the flags. 9402 origPermissions.revokeRuntimePermission(bp, userId); 9403 origPermissions.updatePermissionFlags(bp, userId, 9404 PackageManager.MASK_PERMISSION_FLAGS, 0); 9405 // If we revoked a permission permission, we have to write. 9406 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 9407 changedRuntimePermissionUserIds, userId); 9408 } 9409 } 9410 // Grant an install permission. 9411 if (permissionsState.grantInstallPermission(bp) != 9412 PermissionsState.PERMISSION_OPERATION_FAILURE) { 9413 changedInstallPermission = true; 9414 } 9415 } break; 9416 9417 case GRANT_RUNTIME: { 9418 // Grant previously granted runtime permissions. 9419 for (int userId : UserManagerService.getInstance().getUserIds()) { 9420 PermissionState permissionState = origPermissions 9421 .getRuntimePermissionState(bp.name, userId); 9422 int flags = permissionState != null 9423 ? permissionState.getFlags() : 0; 9424 if (origPermissions.hasRuntimePermission(bp.name, userId)) { 9425 if (permissionsState.grantRuntimePermission(bp, userId) == 9426 PermissionsState.PERMISSION_OPERATION_FAILURE) { 9427 // If we cannot put the permission as it was, we have to write. 9428 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 9429 changedRuntimePermissionUserIds, userId); 9430 } 9431 // If the app supports runtime permissions no need for a review. 9432 if (Build.PERMISSIONS_REVIEW_REQUIRED 9433 && appSupportsRuntimePermissions 9434 && (flags & PackageManager 9435 .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) { 9436 flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 9437 // Since we changed the flags, we have to write. 9438 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 9439 changedRuntimePermissionUserIds, userId); 9440 } 9441 } else if (Build.PERMISSIONS_REVIEW_REQUIRED 9442 && !appSupportsRuntimePermissions) { 9443 // For legacy apps that need a permission review, every new 9444 // runtime permission is granted but it is pending a review. 9445 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) { 9446 permissionsState.grantRuntimePermission(bp, userId); 9447 flags |= FLAG_PERMISSION_REVIEW_REQUIRED; 9448 // We changed the permission and flags, hence have to write. 9449 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 9450 changedRuntimePermissionUserIds, userId); 9451 } 9452 } 9453 // Propagate the permission flags. 9454 permissionsState.updatePermissionFlags(bp, userId, flags, flags); 9455 } 9456 } break; 9457 9458 case GRANT_UPGRADE: { 9459 // Grant runtime permissions for a previously held install permission. 9460 PermissionState permissionState = origPermissions 9461 .getInstallPermissionState(bp.name); 9462 final int flags = permissionState != null ? permissionState.getFlags() : 0; 9463 9464 if (origPermissions.revokeInstallPermission(bp) 9465 != PermissionsState.PERMISSION_OPERATION_FAILURE) { 9466 // We will be transferring the permission flags, so clear them. 9467 origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL, 9468 PackageManager.MASK_PERMISSION_FLAGS, 0); 9469 changedInstallPermission = true; 9470 } 9471 9472 // If the permission is not to be promoted to runtime we ignore it and 9473 // also its other flags as they are not applicable to install permissions. 9474 if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) { 9475 for (int userId : currentUserIds) { 9476 if (permissionsState.grantRuntimePermission(bp, userId) != 9477 PermissionsState.PERMISSION_OPERATION_FAILURE) { 9478 // Transfer the permission flags. 9479 permissionsState.updatePermissionFlags(bp, userId, 9480 flags, flags); 9481 // If we granted the permission, we have to write. 9482 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 9483 changedRuntimePermissionUserIds, userId); 9484 } 9485 } 9486 } 9487 } break; 9488 9489 default: { 9490 if (packageOfInterest == null 9491 || packageOfInterest.equals(pkg.packageName)) { 9492 Slog.w(TAG, "Not granting permission " + perm 9493 + " to package " + pkg.packageName 9494 + " because it was previously installed without"); 9495 } 9496 } break; 9497 } 9498 } else { 9499 if (permissionsState.revokeInstallPermission(bp) != 9500 PermissionsState.PERMISSION_OPERATION_FAILURE) { 9501 // Also drop the permission flags. 9502 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 9503 PackageManager.MASK_PERMISSION_FLAGS, 0); 9504 changedInstallPermission = true; 9505 Slog.i(TAG, "Un-granting permission " + perm 9506 + " from package " + pkg.packageName 9507 + " (protectionLevel=" + bp.protectionLevel 9508 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 9509 + ")"); 9510 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) { 9511 // Don't print warning for app op permissions, since it is fine for them 9512 // not to be granted, there is a UI for the user to decide. 9513 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 9514 Slog.w(TAG, "Not granting permission " + perm 9515 + " to package " + pkg.packageName 9516 + " (protectionLevel=" + bp.protectionLevel 9517 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 9518 + ")"); 9519 } 9520 } 9521 } 9522 } 9523 9524 if ((changedInstallPermission || replace) && !ps.installPermissionsFixed && 9525 !isSystemApp(ps) || isUpdatedSystemApp(ps)){ 9526 // This is the first that we have heard about this package, so the 9527 // permissions we have now selected are fixed until explicitly 9528 // changed. 9529 ps.installPermissionsFixed = true; 9530 } 9531 9532 // Persist the runtime permissions state for users with changes. If permissions 9533 // were revoked because no app in the shared user declares them we have to 9534 // write synchronously to avoid losing runtime permissions state. 9535 for (int userId : changedRuntimePermissionUserIds) { 9536 mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked); 9537 } 9538 9539 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 9540 } 9541 9542 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) { 9543 boolean allowed = false; 9544 final int NP = PackageParser.NEW_PERMISSIONS.length; 9545 for (int ip=0; ip<NP; ip++) { 9546 final PackageParser.NewPermissionInfo npi 9547 = PackageParser.NEW_PERMISSIONS[ip]; 9548 if (npi.name.equals(perm) 9549 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) { 9550 allowed = true; 9551 Log.i(TAG, "Auto-granting " + perm + " to old pkg " 9552 + pkg.packageName); 9553 break; 9554 } 9555 } 9556 return allowed; 9557 } 9558 9559 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg, 9560 BasePermission bp, PermissionsState origPermissions) { 9561 boolean allowed; 9562 allowed = (compareSignatures( 9563 bp.packageSetting.signatures.mSignatures, pkg.mSignatures) 9564 == PackageManager.SIGNATURE_MATCH) 9565 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures) 9566 == PackageManager.SIGNATURE_MATCH); 9567 if (!allowed && (bp.protectionLevel 9568 & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) { 9569 if (isSystemApp(pkg)) { 9570 // For updated system applications, a system permission 9571 // is granted only if it had been defined by the original application. 9572 if (pkg.isUpdatedSystemApp()) { 9573 final PackageSetting sysPs = mSettings 9574 .getDisabledSystemPkgLPr(pkg.packageName); 9575 if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) { 9576 // If the original was granted this permission, we take 9577 // that grant decision as read and propagate it to the 9578 // update. 9579 if (sysPs.isPrivileged()) { 9580 allowed = true; 9581 } 9582 } else { 9583 // The system apk may have been updated with an older 9584 // version of the one on the data partition, but which 9585 // granted a new system permission that it didn't have 9586 // before. In this case we do want to allow the app to 9587 // now get the new permission if the ancestral apk is 9588 // privileged to get it. 9589 if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) { 9590 for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) { 9591 if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) { 9592 allowed = true; 9593 break; 9594 } 9595 } 9596 } 9597 // Also if a privileged parent package on the system image or any of 9598 // its children requested a privileged permission, the updated child 9599 // packages can also get the permission. 9600 if (pkg.parentPackage != null) { 9601 final PackageSetting disabledSysParentPs = mSettings 9602 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName); 9603 if (disabledSysParentPs != null && disabledSysParentPs.pkg != null 9604 && disabledSysParentPs.isPrivileged()) { 9605 if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) { 9606 allowed = true; 9607 } else if (disabledSysParentPs.pkg.childPackages != null) { 9608 final int count = disabledSysParentPs.pkg.childPackages.size(); 9609 for (int i = 0; i < count; i++) { 9610 PackageParser.Package disabledSysChildPkg = 9611 disabledSysParentPs.pkg.childPackages.get(i); 9612 if (isPackageRequestingPermission(disabledSysChildPkg, 9613 perm)) { 9614 allowed = true; 9615 break; 9616 } 9617 } 9618 } 9619 } 9620 } 9621 } 9622 } else { 9623 allowed = isPrivilegedApp(pkg); 9624 } 9625 } 9626 } 9627 if (!allowed) { 9628 if (!allowed && (bp.protectionLevel 9629 & PermissionInfo.PROTECTION_FLAG_PRE23) != 0 9630 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 9631 // If this was a previously normal/dangerous permission that got moved 9632 // to a system permission as part of the runtime permission redesign, then 9633 // we still want to blindly grant it to old apps. 9634 allowed = true; 9635 } 9636 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0 9637 && pkg.packageName.equals(mRequiredInstallerPackage)) { 9638 // If this permission is to be granted to the system installer and 9639 // this app is an installer, then it gets the permission. 9640 allowed = true; 9641 } 9642 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0 9643 && pkg.packageName.equals(mRequiredVerifierPackage)) { 9644 // If this permission is to be granted to the system verifier and 9645 // this app is a verifier, then it gets the permission. 9646 allowed = true; 9647 } 9648 if (!allowed && (bp.protectionLevel 9649 & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0 9650 && isSystemApp(pkg)) { 9651 // Any pre-installed system app is allowed to get this permission. 9652 allowed = true; 9653 } 9654 if (!allowed && (bp.protectionLevel 9655 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) { 9656 // For development permissions, a development permission 9657 // is granted only if it was already granted. 9658 allowed = origPermissions.hasInstallPermission(perm); 9659 } 9660 } 9661 return allowed; 9662 } 9663 9664 private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) { 9665 final int permCount = pkg.requestedPermissions.size(); 9666 for (int j = 0; j < permCount; j++) { 9667 String requestedPermission = pkg.requestedPermissions.get(j); 9668 if (permission.equals(requestedPermission)) { 9669 return true; 9670 } 9671 } 9672 return false; 9673 } 9674 9675 final class ActivityIntentResolver 9676 extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> { 9677 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 9678 boolean defaultOnly, int userId) { 9679 if (!sUserManager.exists(userId)) return null; 9680 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 9681 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 9682 } 9683 9684 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 9685 int userId) { 9686 if (!sUserManager.exists(userId)) return null; 9687 mFlags = flags; 9688 return super.queryIntent(intent, resolvedType, 9689 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 9690 } 9691 9692 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 9693 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) { 9694 if (!sUserManager.exists(userId)) return null; 9695 if (packageActivities == null) { 9696 return null; 9697 } 9698 mFlags = flags; 9699 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 9700 final int N = packageActivities.size(); 9701 ArrayList<PackageParser.ActivityIntentInfo[]> listCut = 9702 new ArrayList<PackageParser.ActivityIntentInfo[]>(N); 9703 9704 ArrayList<PackageParser.ActivityIntentInfo> intentFilters; 9705 for (int i = 0; i < N; ++i) { 9706 intentFilters = packageActivities.get(i).intents; 9707 if (intentFilters != null && intentFilters.size() > 0) { 9708 PackageParser.ActivityIntentInfo[] array = 9709 new PackageParser.ActivityIntentInfo[intentFilters.size()]; 9710 intentFilters.toArray(array); 9711 listCut.add(array); 9712 } 9713 } 9714 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 9715 } 9716 9717 public final void addActivity(PackageParser.Activity a, String type) { 9718 final boolean systemApp = a.info.applicationInfo.isSystemApp(); 9719 mActivities.put(a.getComponentName(), a); 9720 if (DEBUG_SHOW_INFO) 9721 Log.v( 9722 TAG, " " + type + " " + 9723 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":"); 9724 if (DEBUG_SHOW_INFO) 9725 Log.v(TAG, " Class=" + a.info.name); 9726 final int NI = a.intents.size(); 9727 for (int j=0; j<NI; j++) { 9728 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 9729 if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) { 9730 intent.setPriority(0); 9731 Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity " 9732 + a.className + " with priority > 0, forcing to 0"); 9733 } 9734 if (DEBUG_SHOW_INFO) { 9735 Log.v(TAG, " IntentFilter:"); 9736 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 9737 } 9738 if (!intent.debugCheck()) { 9739 Log.w(TAG, "==> For Activity " + a.info.name); 9740 } 9741 addFilter(intent); 9742 } 9743 } 9744 9745 public final void removeActivity(PackageParser.Activity a, String type) { 9746 mActivities.remove(a.getComponentName()); 9747 if (DEBUG_SHOW_INFO) { 9748 Log.v(TAG, " " + type + " " 9749 + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel 9750 : a.info.name) + ":"); 9751 Log.v(TAG, " Class=" + a.info.name); 9752 } 9753 final int NI = a.intents.size(); 9754 for (int j=0; j<NI; j++) { 9755 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 9756 if (DEBUG_SHOW_INFO) { 9757 Log.v(TAG, " IntentFilter:"); 9758 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 9759 } 9760 removeFilter(intent); 9761 } 9762 } 9763 9764 @Override 9765 protected boolean allowFilterResult( 9766 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) { 9767 ActivityInfo filterAi = filter.activity.info; 9768 for (int i=dest.size()-1; i>=0; i--) { 9769 ActivityInfo destAi = dest.get(i).activityInfo; 9770 if (destAi.name == filterAi.name 9771 && destAi.packageName == filterAi.packageName) { 9772 return false; 9773 } 9774 } 9775 return true; 9776 } 9777 9778 @Override 9779 protected ActivityIntentInfo[] newArray(int size) { 9780 return new ActivityIntentInfo[size]; 9781 } 9782 9783 @Override 9784 protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) { 9785 if (!sUserManager.exists(userId)) return true; 9786 PackageParser.Package p = filter.activity.owner; 9787 if (p != null) { 9788 PackageSetting ps = (PackageSetting)p.mExtras; 9789 if (ps != null) { 9790 // System apps are never considered stopped for purposes of 9791 // filtering, because there may be no way for the user to 9792 // actually re-launch them. 9793 return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0 9794 && ps.getStopped(userId); 9795 } 9796 } 9797 return false; 9798 } 9799 9800 @Override 9801 protected boolean isPackageForFilter(String packageName, 9802 PackageParser.ActivityIntentInfo info) { 9803 return packageName.equals(info.activity.owner.packageName); 9804 } 9805 9806 @Override 9807 protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info, 9808 int match, int userId) { 9809 if (!sUserManager.exists(userId)) return null; 9810 if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) { 9811 return null; 9812 } 9813 final PackageParser.Activity activity = info.activity; 9814 PackageSetting ps = (PackageSetting) activity.owner.mExtras; 9815 if (ps == null) { 9816 return null; 9817 } 9818 ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags, 9819 ps.readUserState(userId), userId); 9820 if (ai == null) { 9821 return null; 9822 } 9823 final ResolveInfo res = new ResolveInfo(); 9824 res.activityInfo = ai; 9825 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 9826 res.filter = info; 9827 } 9828 if (info != null) { 9829 res.handleAllWebDataURI = info.handleAllWebDataURI(); 9830 } 9831 res.priority = info.getPriority(); 9832 res.preferredOrder = activity.owner.mPreferredOrder; 9833 //System.out.println("Result: " + res.activityInfo.className + 9834 // " = " + res.priority); 9835 res.match = match; 9836 res.isDefault = info.hasDefault; 9837 res.labelRes = info.labelRes; 9838 res.nonLocalizedLabel = info.nonLocalizedLabel; 9839 if (userNeedsBadging(userId)) { 9840 res.noResourceId = true; 9841 } else { 9842 res.icon = info.icon; 9843 } 9844 res.iconResourceId = info.icon; 9845 res.system = res.activityInfo.applicationInfo.isSystemApp(); 9846 return res; 9847 } 9848 9849 @Override 9850 protected void sortResults(List<ResolveInfo> results) { 9851 Collections.sort(results, mResolvePrioritySorter); 9852 } 9853 9854 @Override 9855 protected void dumpFilter(PrintWriter out, String prefix, 9856 PackageParser.ActivityIntentInfo filter) { 9857 out.print(prefix); out.print( 9858 Integer.toHexString(System.identityHashCode(filter.activity))); 9859 out.print(' '); 9860 filter.activity.printComponentShortName(out); 9861 out.print(" filter "); 9862 out.println(Integer.toHexString(System.identityHashCode(filter))); 9863 } 9864 9865 @Override 9866 protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) { 9867 return filter.activity; 9868 } 9869 9870 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 9871 PackageParser.Activity activity = (PackageParser.Activity)label; 9872 out.print(prefix); out.print( 9873 Integer.toHexString(System.identityHashCode(activity))); 9874 out.print(' '); 9875 activity.printComponentShortName(out); 9876 if (count > 1) { 9877 out.print(" ("); out.print(count); out.print(" filters)"); 9878 } 9879 out.println(); 9880 } 9881 9882// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 9883// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 9884// final List<ResolveInfo> retList = Lists.newArrayList(); 9885// while (i.hasNext()) { 9886// final ResolveInfo resolveInfo = i.next(); 9887// if (isEnabledLP(resolveInfo.activityInfo)) { 9888// retList.add(resolveInfo); 9889// } 9890// } 9891// return retList; 9892// } 9893 9894 // Keys are String (activity class name), values are Activity. 9895 private final ArrayMap<ComponentName, PackageParser.Activity> mActivities 9896 = new ArrayMap<ComponentName, PackageParser.Activity>(); 9897 private int mFlags; 9898 } 9899 9900 private final class ServiceIntentResolver 9901 extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> { 9902 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 9903 boolean defaultOnly, int userId) { 9904 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 9905 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 9906 } 9907 9908 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 9909 int userId) { 9910 if (!sUserManager.exists(userId)) return null; 9911 mFlags = flags; 9912 return super.queryIntent(intent, resolvedType, 9913 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 9914 } 9915 9916 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 9917 int flags, ArrayList<PackageParser.Service> packageServices, int userId) { 9918 if (!sUserManager.exists(userId)) return null; 9919 if (packageServices == null) { 9920 return null; 9921 } 9922 mFlags = flags; 9923 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 9924 final int N = packageServices.size(); 9925 ArrayList<PackageParser.ServiceIntentInfo[]> listCut = 9926 new ArrayList<PackageParser.ServiceIntentInfo[]>(N); 9927 9928 ArrayList<PackageParser.ServiceIntentInfo> intentFilters; 9929 for (int i = 0; i < N; ++i) { 9930 intentFilters = packageServices.get(i).intents; 9931 if (intentFilters != null && intentFilters.size() > 0) { 9932 PackageParser.ServiceIntentInfo[] array = 9933 new PackageParser.ServiceIntentInfo[intentFilters.size()]; 9934 intentFilters.toArray(array); 9935 listCut.add(array); 9936 } 9937 } 9938 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 9939 } 9940 9941 public final void addService(PackageParser.Service s) { 9942 mServices.put(s.getComponentName(), s); 9943 if (DEBUG_SHOW_INFO) { 9944 Log.v(TAG, " " 9945 + (s.info.nonLocalizedLabel != null 9946 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 9947 Log.v(TAG, " Class=" + s.info.name); 9948 } 9949 final int NI = s.intents.size(); 9950 int j; 9951 for (j=0; j<NI; j++) { 9952 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 9953 if (DEBUG_SHOW_INFO) { 9954 Log.v(TAG, " IntentFilter:"); 9955 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 9956 } 9957 if (!intent.debugCheck()) { 9958 Log.w(TAG, "==> For Service " + s.info.name); 9959 } 9960 addFilter(intent); 9961 } 9962 } 9963 9964 public final void removeService(PackageParser.Service s) { 9965 mServices.remove(s.getComponentName()); 9966 if (DEBUG_SHOW_INFO) { 9967 Log.v(TAG, " " + (s.info.nonLocalizedLabel != null 9968 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 9969 Log.v(TAG, " Class=" + s.info.name); 9970 } 9971 final int NI = s.intents.size(); 9972 int j; 9973 for (j=0; j<NI; j++) { 9974 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 9975 if (DEBUG_SHOW_INFO) { 9976 Log.v(TAG, " IntentFilter:"); 9977 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 9978 } 9979 removeFilter(intent); 9980 } 9981 } 9982 9983 @Override 9984 protected boolean allowFilterResult( 9985 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) { 9986 ServiceInfo filterSi = filter.service.info; 9987 for (int i=dest.size()-1; i>=0; i--) { 9988 ServiceInfo destAi = dest.get(i).serviceInfo; 9989 if (destAi.name == filterSi.name 9990 && destAi.packageName == filterSi.packageName) { 9991 return false; 9992 } 9993 } 9994 return true; 9995 } 9996 9997 @Override 9998 protected PackageParser.ServiceIntentInfo[] newArray(int size) { 9999 return new PackageParser.ServiceIntentInfo[size]; 10000 } 10001 10002 @Override 10003 protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) { 10004 if (!sUserManager.exists(userId)) return true; 10005 PackageParser.Package p = filter.service.owner; 10006 if (p != null) { 10007 PackageSetting ps = (PackageSetting)p.mExtras; 10008 if (ps != null) { 10009 // System apps are never considered stopped for purposes of 10010 // filtering, because there may be no way for the user to 10011 // actually re-launch them. 10012 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 10013 && ps.getStopped(userId); 10014 } 10015 } 10016 return false; 10017 } 10018 10019 @Override 10020 protected boolean isPackageForFilter(String packageName, 10021 PackageParser.ServiceIntentInfo info) { 10022 return packageName.equals(info.service.owner.packageName); 10023 } 10024 10025 @Override 10026 protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter, 10027 int match, int userId) { 10028 if (!sUserManager.exists(userId)) return null; 10029 final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter; 10030 if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) { 10031 return null; 10032 } 10033 final PackageParser.Service service = info.service; 10034 PackageSetting ps = (PackageSetting) service.owner.mExtras; 10035 if (ps == null) { 10036 return null; 10037 } 10038 ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags, 10039 ps.readUserState(userId), userId); 10040 if (si == null) { 10041 return null; 10042 } 10043 final ResolveInfo res = new ResolveInfo(); 10044 res.serviceInfo = si; 10045 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 10046 res.filter = filter; 10047 } 10048 res.priority = info.getPriority(); 10049 res.preferredOrder = service.owner.mPreferredOrder; 10050 res.match = match; 10051 res.isDefault = info.hasDefault; 10052 res.labelRes = info.labelRes; 10053 res.nonLocalizedLabel = info.nonLocalizedLabel; 10054 res.icon = info.icon; 10055 res.system = res.serviceInfo.applicationInfo.isSystemApp(); 10056 return res; 10057 } 10058 10059 @Override 10060 protected void sortResults(List<ResolveInfo> results) { 10061 Collections.sort(results, mResolvePrioritySorter); 10062 } 10063 10064 @Override 10065 protected void dumpFilter(PrintWriter out, String prefix, 10066 PackageParser.ServiceIntentInfo filter) { 10067 out.print(prefix); out.print( 10068 Integer.toHexString(System.identityHashCode(filter.service))); 10069 out.print(' '); 10070 filter.service.printComponentShortName(out); 10071 out.print(" filter "); 10072 out.println(Integer.toHexString(System.identityHashCode(filter))); 10073 } 10074 10075 @Override 10076 protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) { 10077 return filter.service; 10078 } 10079 10080 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 10081 PackageParser.Service service = (PackageParser.Service)label; 10082 out.print(prefix); out.print( 10083 Integer.toHexString(System.identityHashCode(service))); 10084 out.print(' '); 10085 service.printComponentShortName(out); 10086 if (count > 1) { 10087 out.print(" ("); out.print(count); out.print(" filters)"); 10088 } 10089 out.println(); 10090 } 10091 10092// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 10093// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 10094// final List<ResolveInfo> retList = Lists.newArrayList(); 10095// while (i.hasNext()) { 10096// final ResolveInfo resolveInfo = (ResolveInfo) i; 10097// if (isEnabledLP(resolveInfo.serviceInfo)) { 10098// retList.add(resolveInfo); 10099// } 10100// } 10101// return retList; 10102// } 10103 10104 // Keys are String (activity class name), values are Activity. 10105 private final ArrayMap<ComponentName, PackageParser.Service> mServices 10106 = new ArrayMap<ComponentName, PackageParser.Service>(); 10107 private int mFlags; 10108 }; 10109 10110 private final class ProviderIntentResolver 10111 extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> { 10112 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 10113 boolean defaultOnly, int userId) { 10114 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 10115 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 10116 } 10117 10118 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 10119 int userId) { 10120 if (!sUserManager.exists(userId)) 10121 return null; 10122 mFlags = flags; 10123 return super.queryIntent(intent, resolvedType, 10124 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 10125 } 10126 10127 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 10128 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) { 10129 if (!sUserManager.exists(userId)) 10130 return null; 10131 if (packageProviders == null) { 10132 return null; 10133 } 10134 mFlags = flags; 10135 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; 10136 final int N = packageProviders.size(); 10137 ArrayList<PackageParser.ProviderIntentInfo[]> listCut = 10138 new ArrayList<PackageParser.ProviderIntentInfo[]>(N); 10139 10140 ArrayList<PackageParser.ProviderIntentInfo> intentFilters; 10141 for (int i = 0; i < N; ++i) { 10142 intentFilters = packageProviders.get(i).intents; 10143 if (intentFilters != null && intentFilters.size() > 0) { 10144 PackageParser.ProviderIntentInfo[] array = 10145 new PackageParser.ProviderIntentInfo[intentFilters.size()]; 10146 intentFilters.toArray(array); 10147 listCut.add(array); 10148 } 10149 } 10150 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 10151 } 10152 10153 public final void addProvider(PackageParser.Provider p) { 10154 if (mProviders.containsKey(p.getComponentName())) { 10155 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring"); 10156 return; 10157 } 10158 10159 mProviders.put(p.getComponentName(), p); 10160 if (DEBUG_SHOW_INFO) { 10161 Log.v(TAG, " " 10162 + (p.info.nonLocalizedLabel != null 10163 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 10164 Log.v(TAG, " Class=" + p.info.name); 10165 } 10166 final int NI = p.intents.size(); 10167 int j; 10168 for (j = 0; j < NI; j++) { 10169 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 10170 if (DEBUG_SHOW_INFO) { 10171 Log.v(TAG, " IntentFilter:"); 10172 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10173 } 10174 if (!intent.debugCheck()) { 10175 Log.w(TAG, "==> For Provider " + p.info.name); 10176 } 10177 addFilter(intent); 10178 } 10179 } 10180 10181 public final void removeProvider(PackageParser.Provider p) { 10182 mProviders.remove(p.getComponentName()); 10183 if (DEBUG_SHOW_INFO) { 10184 Log.v(TAG, " " + (p.info.nonLocalizedLabel != null 10185 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 10186 Log.v(TAG, " Class=" + p.info.name); 10187 } 10188 final int NI = p.intents.size(); 10189 int j; 10190 for (j = 0; j < NI; j++) { 10191 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 10192 if (DEBUG_SHOW_INFO) { 10193 Log.v(TAG, " IntentFilter:"); 10194 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10195 } 10196 removeFilter(intent); 10197 } 10198 } 10199 10200 @Override 10201 protected boolean allowFilterResult( 10202 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) { 10203 ProviderInfo filterPi = filter.provider.info; 10204 for (int i = dest.size() - 1; i >= 0; i--) { 10205 ProviderInfo destPi = dest.get(i).providerInfo; 10206 if (destPi.name == filterPi.name 10207 && destPi.packageName == filterPi.packageName) { 10208 return false; 10209 } 10210 } 10211 return true; 10212 } 10213 10214 @Override 10215 protected PackageParser.ProviderIntentInfo[] newArray(int size) { 10216 return new PackageParser.ProviderIntentInfo[size]; 10217 } 10218 10219 @Override 10220 protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) { 10221 if (!sUserManager.exists(userId)) 10222 return true; 10223 PackageParser.Package p = filter.provider.owner; 10224 if (p != null) { 10225 PackageSetting ps = (PackageSetting) p.mExtras; 10226 if (ps != null) { 10227 // System apps are never considered stopped for purposes of 10228 // filtering, because there may be no way for the user to 10229 // actually re-launch them. 10230 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 10231 && ps.getStopped(userId); 10232 } 10233 } 10234 return false; 10235 } 10236 10237 @Override 10238 protected boolean isPackageForFilter(String packageName, 10239 PackageParser.ProviderIntentInfo info) { 10240 return packageName.equals(info.provider.owner.packageName); 10241 } 10242 10243 @Override 10244 protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter, 10245 int match, int userId) { 10246 if (!sUserManager.exists(userId)) 10247 return null; 10248 final PackageParser.ProviderIntentInfo info = filter; 10249 if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) { 10250 return null; 10251 } 10252 final PackageParser.Provider provider = info.provider; 10253 PackageSetting ps = (PackageSetting) provider.owner.mExtras; 10254 if (ps == null) { 10255 return null; 10256 } 10257 ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags, 10258 ps.readUserState(userId), userId); 10259 if (pi == null) { 10260 return null; 10261 } 10262 final ResolveInfo res = new ResolveInfo(); 10263 res.providerInfo = pi; 10264 if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) { 10265 res.filter = filter; 10266 } 10267 res.priority = info.getPriority(); 10268 res.preferredOrder = provider.owner.mPreferredOrder; 10269 res.match = match; 10270 res.isDefault = info.hasDefault; 10271 res.labelRes = info.labelRes; 10272 res.nonLocalizedLabel = info.nonLocalizedLabel; 10273 res.icon = info.icon; 10274 res.system = res.providerInfo.applicationInfo.isSystemApp(); 10275 return res; 10276 } 10277 10278 @Override 10279 protected void sortResults(List<ResolveInfo> results) { 10280 Collections.sort(results, mResolvePrioritySorter); 10281 } 10282 10283 @Override 10284 protected void dumpFilter(PrintWriter out, String prefix, 10285 PackageParser.ProviderIntentInfo filter) { 10286 out.print(prefix); 10287 out.print( 10288 Integer.toHexString(System.identityHashCode(filter.provider))); 10289 out.print(' '); 10290 filter.provider.printComponentShortName(out); 10291 out.print(" filter "); 10292 out.println(Integer.toHexString(System.identityHashCode(filter))); 10293 } 10294 10295 @Override 10296 protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) { 10297 return filter.provider; 10298 } 10299 10300 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 10301 PackageParser.Provider provider = (PackageParser.Provider)label; 10302 out.print(prefix); out.print( 10303 Integer.toHexString(System.identityHashCode(provider))); 10304 out.print(' '); 10305 provider.printComponentShortName(out); 10306 if (count > 1) { 10307 out.print(" ("); out.print(count); out.print(" filters)"); 10308 } 10309 out.println(); 10310 } 10311 10312 private final ArrayMap<ComponentName, PackageParser.Provider> mProviders 10313 = new ArrayMap<ComponentName, PackageParser.Provider>(); 10314 private int mFlags; 10315 } 10316 10317 private static final class EphemeralIntentResolver 10318 extends IntentResolver<EphemeralResolveIntentInfo, EphemeralResolveInfo> { 10319 @Override 10320 protected EphemeralResolveIntentInfo[] newArray(int size) { 10321 return new EphemeralResolveIntentInfo[size]; 10322 } 10323 10324 @Override 10325 protected boolean isPackageForFilter(String packageName, EphemeralResolveIntentInfo info) { 10326 return true; 10327 } 10328 10329 @Override 10330 protected EphemeralResolveInfo newResult(EphemeralResolveIntentInfo info, int match, 10331 int userId) { 10332 if (!sUserManager.exists(userId)) { 10333 return null; 10334 } 10335 return info.getEphemeralResolveInfo(); 10336 } 10337 } 10338 10339 private static final Comparator<ResolveInfo> mResolvePrioritySorter = 10340 new Comparator<ResolveInfo>() { 10341 public int compare(ResolveInfo r1, ResolveInfo r2) { 10342 int v1 = r1.priority; 10343 int v2 = r2.priority; 10344 //System.out.println("Comparing: q1=" + q1 + " q2=" + q2); 10345 if (v1 != v2) { 10346 return (v1 > v2) ? -1 : 1; 10347 } 10348 v1 = r1.preferredOrder; 10349 v2 = r2.preferredOrder; 10350 if (v1 != v2) { 10351 return (v1 > v2) ? -1 : 1; 10352 } 10353 if (r1.isDefault != r2.isDefault) { 10354 return r1.isDefault ? -1 : 1; 10355 } 10356 v1 = r1.match; 10357 v2 = r2.match; 10358 //System.out.println("Comparing: m1=" + m1 + " m2=" + m2); 10359 if (v1 != v2) { 10360 return (v1 > v2) ? -1 : 1; 10361 } 10362 if (r1.system != r2.system) { 10363 return r1.system ? -1 : 1; 10364 } 10365 if (r1.activityInfo != null) { 10366 return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName); 10367 } 10368 if (r1.serviceInfo != null) { 10369 return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName); 10370 } 10371 if (r1.providerInfo != null) { 10372 return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName); 10373 } 10374 return 0; 10375 } 10376 }; 10377 10378 private static final Comparator<ProviderInfo> mProviderInitOrderSorter = 10379 new Comparator<ProviderInfo>() { 10380 public int compare(ProviderInfo p1, ProviderInfo p2) { 10381 final int v1 = p1.initOrder; 10382 final int v2 = p2.initOrder; 10383 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0); 10384 } 10385 }; 10386 10387 final void sendPackageBroadcast(final String action, final String pkg, final Bundle extras, 10388 final int flags, final String targetPkg, final IIntentReceiver finishedReceiver, 10389 final int[] userIds) { 10390 mHandler.post(new Runnable() { 10391 @Override 10392 public void run() { 10393 try { 10394 final IActivityManager am = ActivityManagerNative.getDefault(); 10395 if (am == null) return; 10396 final int[] resolvedUserIds; 10397 if (userIds == null) { 10398 resolvedUserIds = am.getRunningUserIds(); 10399 } else { 10400 resolvedUserIds = userIds; 10401 } 10402 for (int id : resolvedUserIds) { 10403 final Intent intent = new Intent(action, 10404 pkg != null ? Uri.fromParts("package", pkg, null) : null); 10405 if (extras != null) { 10406 intent.putExtras(extras); 10407 } 10408 if (targetPkg != null) { 10409 intent.setPackage(targetPkg); 10410 } 10411 // Modify the UID when posting to other users 10412 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); 10413 if (uid > 0 && UserHandle.getUserId(uid) != id) { 10414 uid = UserHandle.getUid(id, UserHandle.getAppId(uid)); 10415 intent.putExtra(Intent.EXTRA_UID, uid); 10416 } 10417 intent.putExtra(Intent.EXTRA_USER_HANDLE, id); 10418 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags); 10419 if (DEBUG_BROADCASTS) { 10420 RuntimeException here = new RuntimeException("here"); 10421 here.fillInStackTrace(); 10422 Slog.d(TAG, "Sending to user " + id + ": " 10423 + intent.toShortString(false, true, false, false) 10424 + " " + intent.getExtras(), here); 10425 } 10426 am.broadcastIntent(null, intent, null, finishedReceiver, 10427 0, null, null, null, android.app.AppOpsManager.OP_NONE, 10428 null, finishedReceiver != null, false, id); 10429 } 10430 } catch (RemoteException ex) { 10431 } 10432 } 10433 }); 10434 } 10435 10436 /** 10437 * Check if the external storage media is available. This is true if there 10438 * is a mounted external storage medium or if the external storage is 10439 * emulated. 10440 */ 10441 private boolean isExternalMediaAvailable() { 10442 return mMediaMounted || Environment.isExternalStorageEmulated(); 10443 } 10444 10445 @Override 10446 public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) { 10447 // writer 10448 synchronized (mPackages) { 10449 if (!isExternalMediaAvailable()) { 10450 // If the external storage is no longer mounted at this point, 10451 // the caller may not have been able to delete all of this 10452 // packages files and can not delete any more. Bail. 10453 return null; 10454 } 10455 final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned; 10456 if (lastPackage != null) { 10457 pkgs.remove(lastPackage); 10458 } 10459 if (pkgs.size() > 0) { 10460 return pkgs.get(0); 10461 } 10462 } 10463 return null; 10464 } 10465 10466 void schedulePackageCleaning(String packageName, int userId, boolean andCode) { 10467 final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE, 10468 userId, andCode ? 1 : 0, packageName); 10469 if (mSystemReady) { 10470 msg.sendToTarget(); 10471 } else { 10472 if (mPostSystemReadyMessages == null) { 10473 mPostSystemReadyMessages = new ArrayList<>(); 10474 } 10475 mPostSystemReadyMessages.add(msg); 10476 } 10477 } 10478 10479 void startCleaningPackages() { 10480 // reader 10481 if (!isExternalMediaAvailable()) { 10482 return; 10483 } 10484 synchronized (mPackages) { 10485 if (mSettings.mPackagesToBeCleaned.isEmpty()) { 10486 return; 10487 } 10488 } 10489 Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE); 10490 intent.setComponent(DEFAULT_CONTAINER_COMPONENT); 10491 IActivityManager am = ActivityManagerNative.getDefault(); 10492 if (am != null) { 10493 try { 10494 am.startService(null, intent, null, mContext.getOpPackageName(), 10495 UserHandle.USER_SYSTEM); 10496 } catch (RemoteException e) { 10497 } 10498 } 10499 } 10500 10501 @Override 10502 public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer, 10503 int installFlags, String installerPackageName, int userId) { 10504 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null); 10505 10506 final int callingUid = Binder.getCallingUid(); 10507 enforceCrossUserPermission(callingUid, userId, 10508 true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser"); 10509 10510 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 10511 try { 10512 if (observer != null) { 10513 observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null); 10514 } 10515 } catch (RemoteException re) { 10516 } 10517 return; 10518 } 10519 10520 if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) { 10521 installFlags |= PackageManager.INSTALL_FROM_ADB; 10522 10523 } else { 10524 // Caller holds INSTALL_PACKAGES permission, so we're less strict 10525 // about installerPackageName. 10526 10527 installFlags &= ~PackageManager.INSTALL_FROM_ADB; 10528 installFlags &= ~PackageManager.INSTALL_ALL_USERS; 10529 } 10530 10531 UserHandle user; 10532 if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) { 10533 user = UserHandle.ALL; 10534 } else { 10535 user = new UserHandle(userId); 10536 } 10537 10538 // Only system components can circumvent runtime permissions when installing. 10539 if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0 10540 && mContext.checkCallingOrSelfPermission(Manifest.permission 10541 .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) { 10542 throw new SecurityException("You need the " 10543 + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission " 10544 + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag"); 10545 } 10546 10547 final File originFile = new File(originPath); 10548 final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile); 10549 10550 final Message msg = mHandler.obtainMessage(INIT_COPY); 10551 final VerificationInfo verificationInfo = new VerificationInfo( 10552 null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid); 10553 final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer, 10554 installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user, 10555 null /*packageAbiOverride*/, null /*grantedPermissions*/); 10556 params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params)); 10557 msg.obj = params; 10558 10559 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser", 10560 System.identityHashCode(msg.obj)); 10561 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 10562 System.identityHashCode(msg.obj)); 10563 10564 mHandler.sendMessage(msg); 10565 } 10566 10567 void installStage(String packageName, File stagedDir, String stagedCid, 10568 IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams, 10569 String installerPackageName, int installerUid, UserHandle user) { 10570 if (DEBUG_EPHEMERAL) { 10571 if ((sessionParams.installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) { 10572 Slog.d(TAG, "Ephemeral install of " + packageName); 10573 } 10574 } 10575 final VerificationInfo verificationInfo = new VerificationInfo( 10576 sessionParams.originatingUri, sessionParams.referrerUri, 10577 sessionParams.originatingUid, installerUid); 10578 10579 final OriginInfo origin; 10580 if (stagedDir != null) { 10581 origin = OriginInfo.fromStagedFile(stagedDir); 10582 } else { 10583 origin = OriginInfo.fromStagedContainer(stagedCid); 10584 } 10585 10586 final Message msg = mHandler.obtainMessage(INIT_COPY); 10587 final InstallParams params = new InstallParams(origin, null, observer, 10588 sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid, 10589 verificationInfo, user, sessionParams.abiOverride, 10590 sessionParams.grantedRuntimePermissions); 10591 params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params)); 10592 msg.obj = params; 10593 10594 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage", 10595 System.identityHashCode(msg.obj)); 10596 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 10597 System.identityHashCode(msg.obj)); 10598 10599 mHandler.sendMessage(msg); 10600 } 10601 10602 private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, 10603 int userId) { 10604 final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting); 10605 sendPackageAddedForUser(packageName, isSystem, pkgSetting.appId, userId); 10606 } 10607 10608 private void sendPackageAddedForUser(String packageName, boolean isSystem, 10609 int appId, int userId) { 10610 Bundle extras = new Bundle(1); 10611 extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, appId)); 10612 10613 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 10614 packageName, extras, 0, null, null, new int[] {userId}); 10615 try { 10616 IActivityManager am = ActivityManagerNative.getDefault(); 10617 if (isSystem && am.isUserRunning(userId, 0)) { 10618 // The just-installed/enabled app is bundled on the system, so presumed 10619 // to be able to run automatically without needing an explicit launch. 10620 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one. 10621 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED) 10622 .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES) 10623 .setPackage(packageName); 10624 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null, 10625 android.app.AppOpsManager.OP_NONE, null, false, false, userId); 10626 } 10627 } catch (RemoteException e) { 10628 // shouldn't happen 10629 Slog.w(TAG, "Unable to bootstrap installed package", e); 10630 } 10631 } 10632 10633 @Override 10634 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, 10635 int userId) { 10636 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 10637 PackageSetting pkgSetting; 10638 final int uid = Binder.getCallingUid(); 10639 enforceCrossUserPermission(uid, userId, 10640 true /* requireFullPermission */, true /* checkShell */, 10641 "setApplicationHiddenSetting for user " + userId); 10642 10643 if (hidden && isPackageDeviceAdmin(packageName, userId)) { 10644 Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin"); 10645 return false; 10646 } 10647 10648 long callingId = Binder.clearCallingIdentity(); 10649 try { 10650 boolean sendAdded = false; 10651 boolean sendRemoved = false; 10652 // writer 10653 synchronized (mPackages) { 10654 pkgSetting = mSettings.mPackages.get(packageName); 10655 if (pkgSetting == null) { 10656 return false; 10657 } 10658 if (pkgSetting.getHidden(userId) != hidden) { 10659 pkgSetting.setHidden(hidden, userId); 10660 mSettings.writePackageRestrictionsLPr(userId); 10661 if (hidden) { 10662 sendRemoved = true; 10663 } else { 10664 sendAdded = true; 10665 } 10666 } 10667 } 10668 if (sendAdded) { 10669 sendPackageAddedForUser(packageName, pkgSetting, userId); 10670 return true; 10671 } 10672 if (sendRemoved) { 10673 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId), 10674 "hiding pkg"); 10675 sendApplicationHiddenForUser(packageName, pkgSetting, userId); 10676 return true; 10677 } 10678 } finally { 10679 Binder.restoreCallingIdentity(callingId); 10680 } 10681 return false; 10682 } 10683 10684 private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting, 10685 int userId) { 10686 final PackageRemovedInfo info = new PackageRemovedInfo(); 10687 info.removedPackage = packageName; 10688 info.removedUsers = new int[] {userId}; 10689 info.uid = UserHandle.getUid(userId, pkgSetting.appId); 10690 info.sendPackageRemovedBroadcasts(true /*killApp*/); 10691 } 10692 10693 private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) { 10694 if (pkgList.length > 0) { 10695 Bundle extras = new Bundle(1); 10696 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 10697 10698 sendPackageBroadcast( 10699 suspended ? Intent.ACTION_PACKAGES_SUSPENDED 10700 : Intent.ACTION_PACKAGES_UNSUSPENDED, 10701 null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null, 10702 new int[] {userId}); 10703 } 10704 } 10705 10706 /** 10707 * Returns true if application is not found or there was an error. Otherwise it returns 10708 * the hidden state of the package for the given user. 10709 */ 10710 @Override 10711 public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) { 10712 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 10713 enforceCrossUserPermission(Binder.getCallingUid(), userId, 10714 true /* requireFullPermission */, false /* checkShell */, 10715 "getApplicationHidden for user " + userId); 10716 PackageSetting pkgSetting; 10717 long callingId = Binder.clearCallingIdentity(); 10718 try { 10719 // writer 10720 synchronized (mPackages) { 10721 pkgSetting = mSettings.mPackages.get(packageName); 10722 if (pkgSetting == null) { 10723 return true; 10724 } 10725 return pkgSetting.getHidden(userId); 10726 } 10727 } finally { 10728 Binder.restoreCallingIdentity(callingId); 10729 } 10730 } 10731 10732 /** 10733 * @hide 10734 */ 10735 @Override 10736 public int installExistingPackageAsUser(String packageName, int userId) { 10737 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, 10738 null); 10739 PackageSetting pkgSetting; 10740 final int uid = Binder.getCallingUid(); 10741 enforceCrossUserPermission(uid, userId, 10742 true /* requireFullPermission */, true /* checkShell */, 10743 "installExistingPackage for user " + userId); 10744 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 10745 return PackageManager.INSTALL_FAILED_USER_RESTRICTED; 10746 } 10747 10748 long callingId = Binder.clearCallingIdentity(); 10749 try { 10750 boolean installed = false; 10751 10752 // writer 10753 synchronized (mPackages) { 10754 pkgSetting = mSettings.mPackages.get(packageName); 10755 if (pkgSetting == null) { 10756 return PackageManager.INSTALL_FAILED_INVALID_URI; 10757 } 10758 if (!pkgSetting.getInstalled(userId)) { 10759 pkgSetting.setInstalled(true, userId); 10760 pkgSetting.setHidden(false, userId); 10761 mSettings.writePackageRestrictionsLPr(userId); 10762 installed = true; 10763 } 10764 } 10765 10766 if (installed) { 10767 if (pkgSetting.pkg != null) { 10768 prepareAppDataAfterInstall(pkgSetting.pkg); 10769 } 10770 sendPackageAddedForUser(packageName, pkgSetting, userId); 10771 } 10772 } finally { 10773 Binder.restoreCallingIdentity(callingId); 10774 } 10775 10776 return PackageManager.INSTALL_SUCCEEDED; 10777 } 10778 10779 boolean isUserRestricted(int userId, String restrictionKey) { 10780 Bundle restrictions = sUserManager.getUserRestrictions(userId); 10781 if (restrictions.getBoolean(restrictionKey, false)) { 10782 Log.w(TAG, "User is restricted: " + restrictionKey); 10783 return true; 10784 } 10785 return false; 10786 } 10787 10788 @Override 10789 public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended, 10790 int userId) { 10791 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 10792 enforceCrossUserPermission(Binder.getCallingUid(), userId, 10793 true /* requireFullPermission */, true /* checkShell */, 10794 "setPackagesSuspended for user " + userId); 10795 10796 if (ArrayUtils.isEmpty(packageNames)) { 10797 return packageNames; 10798 } 10799 10800 // List of package names for whom the suspended state has changed. 10801 List<String> changedPackages = new ArrayList<>(packageNames.length); 10802 // List of package names for whom the suspended state is not set as requested in this 10803 // method. 10804 List<String> unactionedPackages = new ArrayList<>(packageNames.length); 10805 for (int i = 0; i < packageNames.length; i++) { 10806 String packageName = packageNames[i]; 10807 long callingId = Binder.clearCallingIdentity(); 10808 try { 10809 boolean changed = false; 10810 final int appId; 10811 synchronized (mPackages) { 10812 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName); 10813 if (pkgSetting == null) { 10814 Slog.w(TAG, "Could not find package setting for package \"" + packageName 10815 + "\". Skipping suspending/un-suspending."); 10816 unactionedPackages.add(packageName); 10817 continue; 10818 } 10819 appId = pkgSetting.appId; 10820 if (pkgSetting.getSuspended(userId) != suspended) { 10821 if (!canSuspendPackageForUserLocked(packageName, userId)) { 10822 unactionedPackages.add(packageName); 10823 continue; 10824 } 10825 pkgSetting.setSuspended(suspended, userId); 10826 mSettings.writePackageRestrictionsLPr(userId); 10827 changed = true; 10828 changedPackages.add(packageName); 10829 } 10830 } 10831 10832 if (changed && suspended) { 10833 killApplication(packageName, UserHandle.getUid(userId, appId), 10834 "suspending package"); 10835 } 10836 } finally { 10837 Binder.restoreCallingIdentity(callingId); 10838 } 10839 } 10840 10841 if (!changedPackages.isEmpty()) { 10842 sendPackagesSuspendedForUser(changedPackages.toArray( 10843 new String[changedPackages.size()]), userId, suspended); 10844 } 10845 10846 return unactionedPackages.toArray(new String[unactionedPackages.size()]); 10847 } 10848 10849 @Override 10850 public boolean isPackageSuspendedForUser(String packageName, int userId) { 10851 enforceCrossUserPermission(Binder.getCallingUid(), userId, 10852 true /* requireFullPermission */, false /* checkShell */, 10853 "isPackageSuspendedForUser for user " + userId); 10854 synchronized (mPackages) { 10855 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName); 10856 return pkgSetting != null && pkgSetting.getSuspended(userId); 10857 } 10858 } 10859 10860 /** 10861 * TODO: cache and disallow blocking the active dialer. 10862 * 10863 * @see also DefaultPermissionGrantPolicy#grantDefaultSystemHandlerPermissions 10864 */ 10865 private boolean canSuspendPackageForUserLocked(String packageName, int userId) { 10866 if (isPackageDeviceAdmin(packageName, userId)) { 10867 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 10868 + "\": has an active device admin"); 10869 return false; 10870 } 10871 10872 String activeLauncherPackageName = getActiveLauncherPackageName(userId); 10873 if (packageName.equals(activeLauncherPackageName)) { 10874 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 10875 + "\": contains the active launcher"); 10876 return false; 10877 } 10878 10879 if (packageName.equals(mRequiredInstallerPackage)) { 10880 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 10881 + "\": required for package installation"); 10882 return false; 10883 } 10884 10885 if (packageName.equals(mRequiredVerifierPackage)) { 10886 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 10887 + "\": required for package verification"); 10888 return false; 10889 } 10890 10891 final PackageParser.Package pkg = mPackages.get(packageName); 10892 if (pkg != null && isPrivilegedApp(pkg)) { 10893 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 10894 + "\": is a privileged app"); 10895 return false; 10896 } 10897 10898 return true; 10899 } 10900 10901 private String getActiveLauncherPackageName(int userId) { 10902 Intent intent = new Intent(Intent.ACTION_MAIN); 10903 intent.addCategory(Intent.CATEGORY_HOME); 10904 ResolveInfo resolveInfo = resolveIntent( 10905 intent, 10906 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 10907 PackageManager.MATCH_DEFAULT_ONLY, 10908 userId); 10909 10910 return resolveInfo == null ? null : resolveInfo.activityInfo.packageName; 10911 } 10912 10913 @Override 10914 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException { 10915 mContext.enforceCallingOrSelfPermission( 10916 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 10917 "Only package verification agents can verify applications"); 10918 10919 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 10920 final PackageVerificationResponse response = new PackageVerificationResponse( 10921 verificationCode, Binder.getCallingUid()); 10922 msg.arg1 = id; 10923 msg.obj = response; 10924 mHandler.sendMessage(msg); 10925 } 10926 10927 @Override 10928 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, 10929 long millisecondsToDelay) { 10930 mContext.enforceCallingOrSelfPermission( 10931 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 10932 "Only package verification agents can extend verification timeouts"); 10933 10934 final PackageVerificationState state = mPendingVerification.get(id); 10935 final PackageVerificationResponse response = new PackageVerificationResponse( 10936 verificationCodeAtTimeout, Binder.getCallingUid()); 10937 10938 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) { 10939 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT; 10940 } 10941 if (millisecondsToDelay < 0) { 10942 millisecondsToDelay = 0; 10943 } 10944 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW) 10945 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) { 10946 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT; 10947 } 10948 10949 if ((state != null) && !state.timeoutExtended()) { 10950 state.extendTimeout(); 10951 10952 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 10953 msg.arg1 = id; 10954 msg.obj = response; 10955 mHandler.sendMessageDelayed(msg, millisecondsToDelay); 10956 } 10957 } 10958 10959 private void broadcastPackageVerified(int verificationId, Uri packageUri, 10960 int verificationCode, UserHandle user) { 10961 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED); 10962 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE); 10963 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 10964 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 10965 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode); 10966 10967 mContext.sendBroadcastAsUser(intent, user, 10968 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT); 10969 } 10970 10971 private ComponentName matchComponentForVerifier(String packageName, 10972 List<ResolveInfo> receivers) { 10973 ActivityInfo targetReceiver = null; 10974 10975 final int NR = receivers.size(); 10976 for (int i = 0; i < NR; i++) { 10977 final ResolveInfo info = receivers.get(i); 10978 if (info.activityInfo == null) { 10979 continue; 10980 } 10981 10982 if (packageName.equals(info.activityInfo.packageName)) { 10983 targetReceiver = info.activityInfo; 10984 break; 10985 } 10986 } 10987 10988 if (targetReceiver == null) { 10989 return null; 10990 } 10991 10992 return new ComponentName(targetReceiver.packageName, targetReceiver.name); 10993 } 10994 10995 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo, 10996 List<ResolveInfo> receivers, final PackageVerificationState verificationState) { 10997 if (pkgInfo.verifiers.length == 0) { 10998 return null; 10999 } 11000 11001 final int N = pkgInfo.verifiers.length; 11002 final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1); 11003 for (int i = 0; i < N; i++) { 11004 final VerifierInfo verifierInfo = pkgInfo.verifiers[i]; 11005 11006 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName, 11007 receivers); 11008 if (comp == null) { 11009 continue; 11010 } 11011 11012 final int verifierUid = getUidForVerifier(verifierInfo); 11013 if (verifierUid == -1) { 11014 continue; 11015 } 11016 11017 if (DEBUG_VERIFY) { 11018 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName 11019 + " with the correct signature"); 11020 } 11021 sufficientVerifiers.add(comp); 11022 verificationState.addSufficientVerifier(verifierUid); 11023 } 11024 11025 return sufficientVerifiers; 11026 } 11027 11028 private int getUidForVerifier(VerifierInfo verifierInfo) { 11029 synchronized (mPackages) { 11030 final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName); 11031 if (pkg == null) { 11032 return -1; 11033 } else if (pkg.mSignatures.length != 1) { 11034 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 11035 + " has more than one signature; ignoring"); 11036 return -1; 11037 } 11038 11039 /* 11040 * If the public key of the package's signature does not match 11041 * our expected public key, then this is a different package and 11042 * we should skip. 11043 */ 11044 11045 final byte[] expectedPublicKey; 11046 try { 11047 final Signature verifierSig = pkg.mSignatures[0]; 11048 final PublicKey publicKey = verifierSig.getPublicKey(); 11049 expectedPublicKey = publicKey.getEncoded(); 11050 } catch (CertificateException e) { 11051 return -1; 11052 } 11053 11054 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded(); 11055 11056 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) { 11057 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 11058 + " does not have the expected public key; ignoring"); 11059 return -1; 11060 } 11061 11062 return pkg.applicationInfo.uid; 11063 } 11064 } 11065 11066 @Override 11067 public void finishPackageInstall(int token) { 11068 enforceSystemOrRoot("Only the system is allowed to finish installs"); 11069 11070 if (DEBUG_INSTALL) { 11071 Slog.v(TAG, "BM finishing package install for " + token); 11072 } 11073 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token); 11074 11075 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 11076 mHandler.sendMessage(msg); 11077 } 11078 11079 /** 11080 * Get the verification agent timeout. 11081 * 11082 * @return verification timeout in milliseconds 11083 */ 11084 private long getVerificationTimeout() { 11085 return android.provider.Settings.Global.getLong(mContext.getContentResolver(), 11086 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT, 11087 DEFAULT_VERIFICATION_TIMEOUT); 11088 } 11089 11090 /** 11091 * Get the default verification agent response code. 11092 * 11093 * @return default verification response code 11094 */ 11095 private int getDefaultVerificationResponse() { 11096 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 11097 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE, 11098 DEFAULT_VERIFICATION_RESPONSE); 11099 } 11100 11101 /** 11102 * Check whether or not package verification has been enabled. 11103 * 11104 * @return true if verification should be performed 11105 */ 11106 private boolean isVerificationEnabled(int userId, int installFlags) { 11107 if (!DEFAULT_VERIFY_ENABLE) { 11108 return false; 11109 } 11110 // Ephemeral apps don't get the full verification treatment 11111 if ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) { 11112 if (DEBUG_EPHEMERAL) { 11113 Slog.d(TAG, "INSTALL_EPHEMERAL so skipping verification"); 11114 } 11115 return false; 11116 } 11117 11118 boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS); 11119 11120 // Check if installing from ADB 11121 if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) { 11122 // Do not run verification in a test harness environment 11123 if (ActivityManager.isRunningInTestHarness()) { 11124 return false; 11125 } 11126 if (ensureVerifyAppsEnabled) { 11127 return true; 11128 } 11129 // Check if the developer does not want package verification for ADB installs 11130 if (android.provider.Settings.Global.getInt(mContext.getContentResolver(), 11131 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) { 11132 return false; 11133 } 11134 } 11135 11136 if (ensureVerifyAppsEnabled) { 11137 return true; 11138 } 11139 11140 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 11141 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1; 11142 } 11143 11144 @Override 11145 public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains) 11146 throws RemoteException { 11147 mContext.enforceCallingOrSelfPermission( 11148 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 11149 "Only intentfilter verification agents can verify applications"); 11150 11151 final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED); 11152 final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse( 11153 Binder.getCallingUid(), verificationCode, failedDomains); 11154 msg.arg1 = id; 11155 msg.obj = response; 11156 mHandler.sendMessage(msg); 11157 } 11158 11159 @Override 11160 public int getIntentVerificationStatus(String packageName, int userId) { 11161 synchronized (mPackages) { 11162 return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 11163 } 11164 } 11165 11166 @Override 11167 public boolean updateIntentVerificationStatus(String packageName, int status, int userId) { 11168 mContext.enforceCallingOrSelfPermission( 11169 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 11170 11171 boolean result = false; 11172 synchronized (mPackages) { 11173 result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId); 11174 } 11175 if (result) { 11176 scheduleWritePackageRestrictionsLocked(userId); 11177 } 11178 return result; 11179 } 11180 11181 @Override 11182 public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications( 11183 String packageName) { 11184 synchronized (mPackages) { 11185 return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName)); 11186 } 11187 } 11188 11189 @Override 11190 public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) { 11191 if (TextUtils.isEmpty(packageName)) { 11192 return ParceledListSlice.emptyList(); 11193 } 11194 synchronized (mPackages) { 11195 PackageParser.Package pkg = mPackages.get(packageName); 11196 if (pkg == null || pkg.activities == null) { 11197 return ParceledListSlice.emptyList(); 11198 } 11199 final int count = pkg.activities.size(); 11200 ArrayList<IntentFilter> result = new ArrayList<>(); 11201 for (int n=0; n<count; n++) { 11202 PackageParser.Activity activity = pkg.activities.get(n); 11203 if (activity.intents != null && activity.intents.size() > 0) { 11204 result.addAll(activity.intents); 11205 } 11206 } 11207 return new ParceledListSlice<>(result); 11208 } 11209 } 11210 11211 @Override 11212 public boolean setDefaultBrowserPackageName(String packageName, int userId) { 11213 mContext.enforceCallingOrSelfPermission( 11214 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 11215 11216 synchronized (mPackages) { 11217 boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId); 11218 if (packageName != null) { 11219 result |= updateIntentVerificationStatus(packageName, 11220 PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, 11221 userId); 11222 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr( 11223 packageName, userId); 11224 } 11225 return result; 11226 } 11227 } 11228 11229 @Override 11230 public String getDefaultBrowserPackageName(int userId) { 11231 synchronized (mPackages) { 11232 return mSettings.getDefaultBrowserPackageNameLPw(userId); 11233 } 11234 } 11235 11236 /** 11237 * Get the "allow unknown sources" setting. 11238 * 11239 * @return the current "allow unknown sources" setting 11240 */ 11241 private int getUnknownSourcesSettings() { 11242 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 11243 android.provider.Settings.Global.INSTALL_NON_MARKET_APPS, 11244 -1); 11245 } 11246 11247 @Override 11248 public void setInstallerPackageName(String targetPackage, String installerPackageName) { 11249 final int uid = Binder.getCallingUid(); 11250 // writer 11251 synchronized (mPackages) { 11252 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage); 11253 if (targetPackageSetting == null) { 11254 throw new IllegalArgumentException("Unknown target package: " + targetPackage); 11255 } 11256 11257 PackageSetting installerPackageSetting; 11258 if (installerPackageName != null) { 11259 installerPackageSetting = mSettings.mPackages.get(installerPackageName); 11260 if (installerPackageSetting == null) { 11261 throw new IllegalArgumentException("Unknown installer package: " 11262 + installerPackageName); 11263 } 11264 } else { 11265 installerPackageSetting = null; 11266 } 11267 11268 Signature[] callerSignature; 11269 Object obj = mSettings.getUserIdLPr(uid); 11270 if (obj != null) { 11271 if (obj instanceof SharedUserSetting) { 11272 callerSignature = ((SharedUserSetting)obj).signatures.mSignatures; 11273 } else if (obj instanceof PackageSetting) { 11274 callerSignature = ((PackageSetting)obj).signatures.mSignatures; 11275 } else { 11276 throw new SecurityException("Bad object " + obj + " for uid " + uid); 11277 } 11278 } else { 11279 throw new SecurityException("Unknown calling UID: " + uid); 11280 } 11281 11282 // Verify: can't set installerPackageName to a package that is 11283 // not signed with the same cert as the caller. 11284 if (installerPackageSetting != null) { 11285 if (compareSignatures(callerSignature, 11286 installerPackageSetting.signatures.mSignatures) 11287 != PackageManager.SIGNATURE_MATCH) { 11288 throw new SecurityException( 11289 "Caller does not have same cert as new installer package " 11290 + installerPackageName); 11291 } 11292 } 11293 11294 // Verify: if target already has an installer package, it must 11295 // be signed with the same cert as the caller. 11296 if (targetPackageSetting.installerPackageName != null) { 11297 PackageSetting setting = mSettings.mPackages.get( 11298 targetPackageSetting.installerPackageName); 11299 // If the currently set package isn't valid, then it's always 11300 // okay to change it. 11301 if (setting != null) { 11302 if (compareSignatures(callerSignature, 11303 setting.signatures.mSignatures) 11304 != PackageManager.SIGNATURE_MATCH) { 11305 throw new SecurityException( 11306 "Caller does not have same cert as old installer package " 11307 + targetPackageSetting.installerPackageName); 11308 } 11309 } 11310 } 11311 11312 // Okay! 11313 targetPackageSetting.installerPackageName = installerPackageName; 11314 scheduleWriteSettingsLocked(); 11315 } 11316 } 11317 11318 private void processPendingInstall(final InstallArgs args, final int currentStatus) { 11319 // Queue up an async operation since the package installation may take a little while. 11320 mHandler.post(new Runnable() { 11321 public void run() { 11322 mHandler.removeCallbacks(this); 11323 // Result object to be returned 11324 PackageInstalledInfo res = new PackageInstalledInfo(); 11325 res.setReturnCode(currentStatus); 11326 res.uid = -1; 11327 res.pkg = null; 11328 res.removedInfo = null; 11329 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 11330 args.doPreInstall(res.returnCode); 11331 synchronized (mInstallLock) { 11332 installPackageTracedLI(args, res); 11333 } 11334 args.doPostInstall(res.returnCode, res.uid); 11335 } 11336 11337 // A restore should be performed at this point if (a) the install 11338 // succeeded, (b) the operation is not an update, and (c) the new 11339 // package has not opted out of backup participation. 11340 final boolean update = res.removedInfo != null 11341 && res.removedInfo.removedPackage != null; 11342 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags; 11343 boolean doRestore = !update 11344 && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0); 11345 11346 // Set up the post-install work request bookkeeping. This will be used 11347 // and cleaned up by the post-install event handling regardless of whether 11348 // there's a restore pass performed. Token values are >= 1. 11349 int token; 11350 if (mNextInstallToken < 0) mNextInstallToken = 1; 11351 token = mNextInstallToken++; 11352 11353 PostInstallData data = new PostInstallData(args, res); 11354 mRunningInstalls.put(token, data); 11355 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token); 11356 11357 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) { 11358 // Pass responsibility to the Backup Manager. It will perform a 11359 // restore if appropriate, then pass responsibility back to the 11360 // Package Manager to run the post-install observer callbacks 11361 // and broadcasts. 11362 IBackupManager bm = IBackupManager.Stub.asInterface( 11363 ServiceManager.getService(Context.BACKUP_SERVICE)); 11364 if (bm != null) { 11365 if (DEBUG_INSTALL) Log.v(TAG, "token " + token 11366 + " to BM for possible restore"); 11367 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token); 11368 try { 11369 // TODO: http://b/22388012 11370 if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) { 11371 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token); 11372 } else { 11373 doRestore = false; 11374 } 11375 } catch (RemoteException e) { 11376 // can't happen; the backup manager is local 11377 } catch (Exception e) { 11378 Slog.e(TAG, "Exception trying to enqueue restore", e); 11379 doRestore = false; 11380 } 11381 } else { 11382 Slog.e(TAG, "Backup Manager not found!"); 11383 doRestore = false; 11384 } 11385 } 11386 11387 if (!doRestore) { 11388 // No restore possible, or the Backup Manager was mysteriously not 11389 // available -- just fire the post-install work request directly. 11390 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token); 11391 11392 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token); 11393 11394 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 11395 mHandler.sendMessage(msg); 11396 } 11397 } 11398 }); 11399 } 11400 11401 private abstract class HandlerParams { 11402 private static final int MAX_RETRIES = 4; 11403 11404 /** 11405 * Number of times startCopy() has been attempted and had a non-fatal 11406 * error. 11407 */ 11408 private int mRetries = 0; 11409 11410 /** User handle for the user requesting the information or installation. */ 11411 private final UserHandle mUser; 11412 String traceMethod; 11413 int traceCookie; 11414 11415 HandlerParams(UserHandle user) { 11416 mUser = user; 11417 } 11418 11419 UserHandle getUser() { 11420 return mUser; 11421 } 11422 11423 HandlerParams setTraceMethod(String traceMethod) { 11424 this.traceMethod = traceMethod; 11425 return this; 11426 } 11427 11428 HandlerParams setTraceCookie(int traceCookie) { 11429 this.traceCookie = traceCookie; 11430 return this; 11431 } 11432 11433 final boolean startCopy() { 11434 boolean res; 11435 try { 11436 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this); 11437 11438 if (++mRetries > MAX_RETRIES) { 11439 Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up"); 11440 mHandler.sendEmptyMessage(MCS_GIVE_UP); 11441 handleServiceError(); 11442 return false; 11443 } else { 11444 handleStartCopy(); 11445 res = true; 11446 } 11447 } catch (RemoteException e) { 11448 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT"); 11449 mHandler.sendEmptyMessage(MCS_RECONNECT); 11450 res = false; 11451 } 11452 handleReturnCode(); 11453 return res; 11454 } 11455 11456 final void serviceError() { 11457 if (DEBUG_INSTALL) Slog.i(TAG, "serviceError"); 11458 handleServiceError(); 11459 handleReturnCode(); 11460 } 11461 11462 abstract void handleStartCopy() throws RemoteException; 11463 abstract void handleServiceError(); 11464 abstract void handleReturnCode(); 11465 } 11466 11467 class MeasureParams extends HandlerParams { 11468 private final PackageStats mStats; 11469 private boolean mSuccess; 11470 11471 private final IPackageStatsObserver mObserver; 11472 11473 public MeasureParams(PackageStats stats, IPackageStatsObserver observer) { 11474 super(new UserHandle(stats.userHandle)); 11475 mObserver = observer; 11476 mStats = stats; 11477 } 11478 11479 @Override 11480 public String toString() { 11481 return "MeasureParams{" 11482 + Integer.toHexString(System.identityHashCode(this)) 11483 + " " + mStats.packageName + "}"; 11484 } 11485 11486 @Override 11487 void handleStartCopy() throws RemoteException { 11488 synchronized (mInstallLock) { 11489 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats); 11490 } 11491 11492 if (mSuccess) { 11493 final boolean mounted; 11494 if (Environment.isExternalStorageEmulated()) { 11495 mounted = true; 11496 } else { 11497 final String status = Environment.getExternalStorageState(); 11498 mounted = (Environment.MEDIA_MOUNTED.equals(status) 11499 || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status)); 11500 } 11501 11502 if (mounted) { 11503 final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle); 11504 11505 mStats.externalCacheSize = calculateDirectorySize(mContainerService, 11506 userEnv.buildExternalStorageAppCacheDirs(mStats.packageName)); 11507 11508 mStats.externalDataSize = calculateDirectorySize(mContainerService, 11509 userEnv.buildExternalStorageAppDataDirs(mStats.packageName)); 11510 11511 // Always subtract cache size, since it's a subdirectory 11512 mStats.externalDataSize -= mStats.externalCacheSize; 11513 11514 mStats.externalMediaSize = calculateDirectorySize(mContainerService, 11515 userEnv.buildExternalStorageAppMediaDirs(mStats.packageName)); 11516 11517 mStats.externalObbSize = calculateDirectorySize(mContainerService, 11518 userEnv.buildExternalStorageAppObbDirs(mStats.packageName)); 11519 } 11520 } 11521 } 11522 11523 @Override 11524 void handleReturnCode() { 11525 if (mObserver != null) { 11526 try { 11527 mObserver.onGetStatsCompleted(mStats, mSuccess); 11528 } catch (RemoteException e) { 11529 Slog.i(TAG, "Observer no longer exists."); 11530 } 11531 } 11532 } 11533 11534 @Override 11535 void handleServiceError() { 11536 Slog.e(TAG, "Could not measure application " + mStats.packageName 11537 + " external storage"); 11538 } 11539 } 11540 11541 private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths) 11542 throws RemoteException { 11543 long result = 0; 11544 for (File path : paths) { 11545 result += mcs.calculateDirectorySize(path.getAbsolutePath()); 11546 } 11547 return result; 11548 } 11549 11550 private static void clearDirectory(IMediaContainerService mcs, File[] paths) { 11551 for (File path : paths) { 11552 try { 11553 mcs.clearDirectory(path.getAbsolutePath()); 11554 } catch (RemoteException e) { 11555 } 11556 } 11557 } 11558 11559 static class OriginInfo { 11560 /** 11561 * Location where install is coming from, before it has been 11562 * copied/renamed into place. This could be a single monolithic APK 11563 * file, or a cluster directory. This location may be untrusted. 11564 */ 11565 final File file; 11566 final String cid; 11567 11568 /** 11569 * Flag indicating that {@link #file} or {@link #cid} has already been 11570 * staged, meaning downstream users don't need to defensively copy the 11571 * contents. 11572 */ 11573 final boolean staged; 11574 11575 /** 11576 * Flag indicating that {@link #file} or {@link #cid} is an already 11577 * installed app that is being moved. 11578 */ 11579 final boolean existing; 11580 11581 final String resolvedPath; 11582 final File resolvedFile; 11583 11584 static OriginInfo fromNothing() { 11585 return new OriginInfo(null, null, false, false); 11586 } 11587 11588 static OriginInfo fromUntrustedFile(File file) { 11589 return new OriginInfo(file, null, false, false); 11590 } 11591 11592 static OriginInfo fromExistingFile(File file) { 11593 return new OriginInfo(file, null, false, true); 11594 } 11595 11596 static OriginInfo fromStagedFile(File file) { 11597 return new OriginInfo(file, null, true, false); 11598 } 11599 11600 static OriginInfo fromStagedContainer(String cid) { 11601 return new OriginInfo(null, cid, true, false); 11602 } 11603 11604 private OriginInfo(File file, String cid, boolean staged, boolean existing) { 11605 this.file = file; 11606 this.cid = cid; 11607 this.staged = staged; 11608 this.existing = existing; 11609 11610 if (cid != null) { 11611 resolvedPath = PackageHelper.getSdDir(cid); 11612 resolvedFile = new File(resolvedPath); 11613 } else if (file != null) { 11614 resolvedPath = file.getAbsolutePath(); 11615 resolvedFile = file; 11616 } else { 11617 resolvedPath = null; 11618 resolvedFile = null; 11619 } 11620 } 11621 } 11622 11623 static class MoveInfo { 11624 final int moveId; 11625 final String fromUuid; 11626 final String toUuid; 11627 final String packageName; 11628 final String dataAppName; 11629 final int appId; 11630 final String seinfo; 11631 final int targetSdkVersion; 11632 11633 public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName, 11634 String dataAppName, int appId, String seinfo, int targetSdkVersion) { 11635 this.moveId = moveId; 11636 this.fromUuid = fromUuid; 11637 this.toUuid = toUuid; 11638 this.packageName = packageName; 11639 this.dataAppName = dataAppName; 11640 this.appId = appId; 11641 this.seinfo = seinfo; 11642 this.targetSdkVersion = targetSdkVersion; 11643 } 11644 } 11645 11646 static class VerificationInfo { 11647 /** A constant used to indicate that a uid value is not present. */ 11648 public static final int NO_UID = -1; 11649 11650 /** URI referencing where the package was downloaded from. */ 11651 final Uri originatingUri; 11652 11653 /** HTTP referrer URI associated with the originatingURI. */ 11654 final Uri referrer; 11655 11656 /** UID of the application that the install request originated from. */ 11657 final int originatingUid; 11658 11659 /** UID of application requesting the install */ 11660 final int installerUid; 11661 11662 VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) { 11663 this.originatingUri = originatingUri; 11664 this.referrer = referrer; 11665 this.originatingUid = originatingUid; 11666 this.installerUid = installerUid; 11667 } 11668 } 11669 11670 class InstallParams extends HandlerParams { 11671 final OriginInfo origin; 11672 final MoveInfo move; 11673 final IPackageInstallObserver2 observer; 11674 int installFlags; 11675 final String installerPackageName; 11676 final String volumeUuid; 11677 private InstallArgs mArgs; 11678 private int mRet; 11679 final String packageAbiOverride; 11680 final String[] grantedRuntimePermissions; 11681 final VerificationInfo verificationInfo; 11682 11683 InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 11684 int installFlags, String installerPackageName, String volumeUuid, 11685 VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride, 11686 String[] grantedPermissions) { 11687 super(user); 11688 this.origin = origin; 11689 this.move = move; 11690 this.observer = observer; 11691 this.installFlags = installFlags; 11692 this.installerPackageName = installerPackageName; 11693 this.volumeUuid = volumeUuid; 11694 this.verificationInfo = verificationInfo; 11695 this.packageAbiOverride = packageAbiOverride; 11696 this.grantedRuntimePermissions = grantedPermissions; 11697 } 11698 11699 @Override 11700 public String toString() { 11701 return "InstallParams{" + Integer.toHexString(System.identityHashCode(this)) 11702 + " file=" + origin.file + " cid=" + origin.cid + "}"; 11703 } 11704 11705 private int installLocationPolicy(PackageInfoLite pkgLite) { 11706 String packageName = pkgLite.packageName; 11707 int installLocation = pkgLite.installLocation; 11708 boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 11709 // reader 11710 synchronized (mPackages) { 11711 // Currently installed package which the new package is attempting to replace or 11712 // null if no such package is installed. 11713 PackageParser.Package installedPkg = mPackages.get(packageName); 11714 // Package which currently owns the data which the new package will own if installed. 11715 // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg 11716 // will be null whereas dataOwnerPkg will contain information about the package 11717 // which was uninstalled while keeping its data. 11718 PackageParser.Package dataOwnerPkg = installedPkg; 11719 if (dataOwnerPkg == null) { 11720 PackageSetting ps = mSettings.mPackages.get(packageName); 11721 if (ps != null) { 11722 dataOwnerPkg = ps.pkg; 11723 } 11724 } 11725 11726 if (dataOwnerPkg != null) { 11727 // If installed, the package will get access to data left on the device by its 11728 // predecessor. As a security measure, this is permited only if this is not a 11729 // version downgrade or if the predecessor package is marked as debuggable and 11730 // a downgrade is explicitly requested. 11731 if (((dataOwnerPkg.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) 11732 || ((installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) == 0)) { 11733 try { 11734 checkDowngrade(dataOwnerPkg, pkgLite); 11735 } catch (PackageManagerException e) { 11736 Slog.w(TAG, "Downgrade detected: " + e.getMessage()); 11737 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE; 11738 } 11739 } 11740 } 11741 11742 if (installedPkg != null) { 11743 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 11744 // Check for updated system application. 11745 if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11746 if (onSd) { 11747 Slog.w(TAG, "Cannot install update to system app on sdcard"); 11748 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION; 11749 } 11750 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 11751 } else { 11752 if (onSd) { 11753 // Install flag overrides everything. 11754 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 11755 } 11756 // If current upgrade specifies particular preference 11757 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) { 11758 // Application explicitly specified internal. 11759 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 11760 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) { 11761 // App explictly prefers external. Let policy decide 11762 } else { 11763 // Prefer previous location 11764 if (isExternal(installedPkg)) { 11765 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 11766 } 11767 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 11768 } 11769 } 11770 } else { 11771 // Invalid install. Return error code 11772 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS; 11773 } 11774 } 11775 } 11776 // All the special cases have been taken care of. 11777 // Return result based on recommended install location. 11778 if (onSd) { 11779 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 11780 } 11781 return pkgLite.recommendedInstallLocation; 11782 } 11783 11784 /* 11785 * Invoke remote method to get package information and install 11786 * location values. Override install location based on default 11787 * policy if needed and then create install arguments based 11788 * on the install location. 11789 */ 11790 public void handleStartCopy() throws RemoteException { 11791 int ret = PackageManager.INSTALL_SUCCEEDED; 11792 11793 // If we're already staged, we've firmly committed to an install location 11794 if (origin.staged) { 11795 if (origin.file != null) { 11796 installFlags |= PackageManager.INSTALL_INTERNAL; 11797 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 11798 } else if (origin.cid != null) { 11799 installFlags |= PackageManager.INSTALL_EXTERNAL; 11800 installFlags &= ~PackageManager.INSTALL_INTERNAL; 11801 } else { 11802 throw new IllegalStateException("Invalid stage location"); 11803 } 11804 } 11805 11806 final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 11807 final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0; 11808 final boolean ephemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; 11809 PackageInfoLite pkgLite = null; 11810 11811 if (onInt && onSd) { 11812 // Check if both bits are set. 11813 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external"); 11814 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 11815 } else if (onSd && ephemeral) { 11816 Slog.w(TAG, "Conflicting flags specified for installing ephemeral on external"); 11817 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 11818 } else { 11819 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags, 11820 packageAbiOverride); 11821 11822 if (DEBUG_EPHEMERAL && ephemeral) { 11823 Slog.v(TAG, "pkgLite for install: " + pkgLite); 11824 } 11825 11826 /* 11827 * If we have too little free space, try to free cache 11828 * before giving up. 11829 */ 11830 if (!origin.staged && pkgLite.recommendedInstallLocation 11831 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 11832 // TODO: focus freeing disk space on the target device 11833 final StorageManager storage = StorageManager.from(mContext); 11834 final long lowThreshold = storage.getStorageLowBytes( 11835 Environment.getDataDirectory()); 11836 11837 final long sizeBytes = mContainerService.calculateInstalledSize( 11838 origin.resolvedPath, isForwardLocked(), packageAbiOverride); 11839 11840 try { 11841 mInstaller.freeCache(null, sizeBytes + lowThreshold); 11842 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, 11843 installFlags, packageAbiOverride); 11844 } catch (InstallerException e) { 11845 Slog.w(TAG, "Failed to free cache", e); 11846 } 11847 11848 /* 11849 * The cache free must have deleted the file we 11850 * downloaded to install. 11851 * 11852 * TODO: fix the "freeCache" call to not delete 11853 * the file we care about. 11854 */ 11855 if (pkgLite.recommendedInstallLocation 11856 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 11857 pkgLite.recommendedInstallLocation 11858 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE; 11859 } 11860 } 11861 } 11862 11863 if (ret == PackageManager.INSTALL_SUCCEEDED) { 11864 int loc = pkgLite.recommendedInstallLocation; 11865 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) { 11866 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 11867 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) { 11868 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 11869 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 11870 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 11871 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) { 11872 ret = PackageManager.INSTALL_FAILED_INVALID_APK; 11873 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 11874 ret = PackageManager.INSTALL_FAILED_INVALID_URI; 11875 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) { 11876 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE; 11877 } else { 11878 // Override with defaults if needed. 11879 loc = installLocationPolicy(pkgLite); 11880 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) { 11881 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 11882 } else if (!onSd && !onInt) { 11883 // Override install location with flags 11884 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) { 11885 // Set the flag to install on external media. 11886 installFlags |= PackageManager.INSTALL_EXTERNAL; 11887 installFlags &= ~PackageManager.INSTALL_INTERNAL; 11888 } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) { 11889 if (DEBUG_EPHEMERAL) { 11890 Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag"); 11891 } 11892 installFlags |= PackageManager.INSTALL_EPHEMERAL; 11893 installFlags &= ~(PackageManager.INSTALL_EXTERNAL 11894 |PackageManager.INSTALL_INTERNAL); 11895 } else { 11896 // Make sure the flag for installing on external 11897 // media is unset 11898 installFlags |= PackageManager.INSTALL_INTERNAL; 11899 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 11900 } 11901 } 11902 } 11903 } 11904 11905 final InstallArgs args = createInstallArgs(this); 11906 mArgs = args; 11907 11908 if (ret == PackageManager.INSTALL_SUCCEEDED) { 11909 // TODO: http://b/22976637 11910 // Apps installed for "all" users use the device owner to verify the app 11911 UserHandle verifierUser = getUser(); 11912 if (verifierUser == UserHandle.ALL) { 11913 verifierUser = UserHandle.SYSTEM; 11914 } 11915 11916 /* 11917 * Determine if we have any installed package verifiers. If we 11918 * do, then we'll defer to them to verify the packages. 11919 */ 11920 final int requiredUid = mRequiredVerifierPackage == null ? -1 11921 : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 11922 verifierUser.getIdentifier()); 11923 if (!origin.existing && requiredUid != -1 11924 && isVerificationEnabled(verifierUser.getIdentifier(), installFlags)) { 11925 final Intent verification = new Intent( 11926 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 11927 verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 11928 verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)), 11929 PACKAGE_MIME_TYPE); 11930 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 11931 11932 // Query all live verifiers based on current user state 11933 final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification, 11934 PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier()); 11935 11936 if (DEBUG_VERIFY) { 11937 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent " 11938 + verification.toString() + " with " + pkgLite.verifiers.length 11939 + " optional verifiers"); 11940 } 11941 11942 final int verificationId = mPendingVerificationToken++; 11943 11944 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 11945 11946 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE, 11947 installerPackageName); 11948 11949 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, 11950 installFlags); 11951 11952 verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME, 11953 pkgLite.packageName); 11954 11955 verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE, 11956 pkgLite.versionCode); 11957 11958 if (verificationInfo != null) { 11959 if (verificationInfo.originatingUri != null) { 11960 verification.putExtra(Intent.EXTRA_ORIGINATING_URI, 11961 verificationInfo.originatingUri); 11962 } 11963 if (verificationInfo.referrer != null) { 11964 verification.putExtra(Intent.EXTRA_REFERRER, 11965 verificationInfo.referrer); 11966 } 11967 if (verificationInfo.originatingUid >= 0) { 11968 verification.putExtra(Intent.EXTRA_ORIGINATING_UID, 11969 verificationInfo.originatingUid); 11970 } 11971 if (verificationInfo.installerUid >= 0) { 11972 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID, 11973 verificationInfo.installerUid); 11974 } 11975 } 11976 11977 final PackageVerificationState verificationState = new PackageVerificationState( 11978 requiredUid, args); 11979 11980 mPendingVerification.append(verificationId, verificationState); 11981 11982 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite, 11983 receivers, verificationState); 11984 11985 /* 11986 * If any sufficient verifiers were listed in the package 11987 * manifest, attempt to ask them. 11988 */ 11989 if (sufficientVerifiers != null) { 11990 final int N = sufficientVerifiers.size(); 11991 if (N == 0) { 11992 Slog.i(TAG, "Additional verifiers required, but none installed."); 11993 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 11994 } else { 11995 for (int i = 0; i < N; i++) { 11996 final ComponentName verifierComponent = sufficientVerifiers.get(i); 11997 11998 final Intent sufficientIntent = new Intent(verification); 11999 sufficientIntent.setComponent(verifierComponent); 12000 mContext.sendBroadcastAsUser(sufficientIntent, verifierUser); 12001 } 12002 } 12003 } 12004 12005 final ComponentName requiredVerifierComponent = matchComponentForVerifier( 12006 mRequiredVerifierPackage, receivers); 12007 if (ret == PackageManager.INSTALL_SUCCEEDED 12008 && mRequiredVerifierPackage != null) { 12009 Trace.asyncTraceBegin( 12010 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 12011 /* 12012 * Send the intent to the required verification agent, 12013 * but only start the verification timeout after the 12014 * target BroadcastReceivers have run. 12015 */ 12016 verification.setComponent(requiredVerifierComponent); 12017 mContext.sendOrderedBroadcastAsUser(verification, verifierUser, 12018 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 12019 new BroadcastReceiver() { 12020 @Override 12021 public void onReceive(Context context, Intent intent) { 12022 final Message msg = mHandler 12023 .obtainMessage(CHECK_PENDING_VERIFICATION); 12024 msg.arg1 = verificationId; 12025 mHandler.sendMessageDelayed(msg, getVerificationTimeout()); 12026 } 12027 }, null, 0, null, null); 12028 12029 /* 12030 * We don't want the copy to proceed until verification 12031 * succeeds, so null out this field. 12032 */ 12033 mArgs = null; 12034 } 12035 } else { 12036 /* 12037 * No package verification is enabled, so immediately start 12038 * the remote call to initiate copy using temporary file. 12039 */ 12040 ret = args.copyApk(mContainerService, true); 12041 } 12042 } 12043 12044 mRet = ret; 12045 } 12046 12047 @Override 12048 void handleReturnCode() { 12049 // If mArgs is null, then MCS couldn't be reached. When it 12050 // reconnects, it will try again to install. At that point, this 12051 // will succeed. 12052 if (mArgs != null) { 12053 processPendingInstall(mArgs, mRet); 12054 } 12055 } 12056 12057 @Override 12058 void handleServiceError() { 12059 mArgs = createInstallArgs(this); 12060 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 12061 } 12062 12063 public boolean isForwardLocked() { 12064 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 12065 } 12066 } 12067 12068 /** 12069 * Used during creation of InstallArgs 12070 * 12071 * @param installFlags package installation flags 12072 * @return true if should be installed on external storage 12073 */ 12074 private static boolean installOnExternalAsec(int installFlags) { 12075 if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) { 12076 return false; 12077 } 12078 if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) { 12079 return true; 12080 } 12081 return false; 12082 } 12083 12084 /** 12085 * Used during creation of InstallArgs 12086 * 12087 * @param installFlags package installation flags 12088 * @return true if should be installed as forward locked 12089 */ 12090 private static boolean installForwardLocked(int installFlags) { 12091 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 12092 } 12093 12094 private InstallArgs createInstallArgs(InstallParams params) { 12095 if (params.move != null) { 12096 return new MoveInstallArgs(params); 12097 } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) { 12098 return new AsecInstallArgs(params); 12099 } else { 12100 return new FileInstallArgs(params); 12101 } 12102 } 12103 12104 /** 12105 * Create args that describe an existing installed package. Typically used 12106 * when cleaning up old installs, or used as a move source. 12107 */ 12108 private InstallArgs createInstallArgsForExisting(int installFlags, String codePath, 12109 String resourcePath, String[] instructionSets) { 12110 final boolean isInAsec; 12111 if (installOnExternalAsec(installFlags)) { 12112 /* Apps on SD card are always in ASEC containers. */ 12113 isInAsec = true; 12114 } else if (installForwardLocked(installFlags) 12115 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) { 12116 /* 12117 * Forward-locked apps are only in ASEC containers if they're the 12118 * new style 12119 */ 12120 isInAsec = true; 12121 } else { 12122 isInAsec = false; 12123 } 12124 12125 if (isInAsec) { 12126 return new AsecInstallArgs(codePath, instructionSets, 12127 installOnExternalAsec(installFlags), installForwardLocked(installFlags)); 12128 } else { 12129 return new FileInstallArgs(codePath, resourcePath, instructionSets); 12130 } 12131 } 12132 12133 static abstract class InstallArgs { 12134 /** @see InstallParams#origin */ 12135 final OriginInfo origin; 12136 /** @see InstallParams#move */ 12137 final MoveInfo move; 12138 12139 final IPackageInstallObserver2 observer; 12140 // Always refers to PackageManager flags only 12141 final int installFlags; 12142 final String installerPackageName; 12143 final String volumeUuid; 12144 final UserHandle user; 12145 final String abiOverride; 12146 final String[] installGrantPermissions; 12147 /** If non-null, drop an async trace when the install completes */ 12148 final String traceMethod; 12149 final int traceCookie; 12150 12151 // The list of instruction sets supported by this app. This is currently 12152 // only used during the rmdex() phase to clean up resources. We can get rid of this 12153 // if we move dex files under the common app path. 12154 /* nullable */ String[] instructionSets; 12155 12156 InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 12157 int installFlags, String installerPackageName, String volumeUuid, 12158 UserHandle user, String[] instructionSets, 12159 String abiOverride, String[] installGrantPermissions, 12160 String traceMethod, int traceCookie) { 12161 this.origin = origin; 12162 this.move = move; 12163 this.installFlags = installFlags; 12164 this.observer = observer; 12165 this.installerPackageName = installerPackageName; 12166 this.volumeUuid = volumeUuid; 12167 this.user = user; 12168 this.instructionSets = instructionSets; 12169 this.abiOverride = abiOverride; 12170 this.installGrantPermissions = installGrantPermissions; 12171 this.traceMethod = traceMethod; 12172 this.traceCookie = traceCookie; 12173 } 12174 12175 abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException; 12176 abstract int doPreInstall(int status); 12177 12178 /** 12179 * Rename package into final resting place. All paths on the given 12180 * scanned package should be updated to reflect the rename. 12181 */ 12182 abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath); 12183 abstract int doPostInstall(int status, int uid); 12184 12185 /** @see PackageSettingBase#codePathString */ 12186 abstract String getCodePath(); 12187 /** @see PackageSettingBase#resourcePathString */ 12188 abstract String getResourcePath(); 12189 12190 // Need installer lock especially for dex file removal. 12191 abstract void cleanUpResourcesLI(); 12192 abstract boolean doPostDeleteLI(boolean delete); 12193 12194 /** 12195 * Called before the source arguments are copied. This is used mostly 12196 * for MoveParams when it needs to read the source file to put it in the 12197 * destination. 12198 */ 12199 int doPreCopy() { 12200 return PackageManager.INSTALL_SUCCEEDED; 12201 } 12202 12203 /** 12204 * Called after the source arguments are copied. This is used mostly for 12205 * MoveParams when it needs to read the source file to put it in the 12206 * destination. 12207 * 12208 * @return 12209 */ 12210 int doPostCopy(int uid) { 12211 return PackageManager.INSTALL_SUCCEEDED; 12212 } 12213 12214 protected boolean isFwdLocked() { 12215 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 12216 } 12217 12218 protected boolean isExternalAsec() { 12219 return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 12220 } 12221 12222 protected boolean isEphemeral() { 12223 return (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; 12224 } 12225 12226 UserHandle getUser() { 12227 return user; 12228 } 12229 } 12230 12231 private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) { 12232 if (!allCodePaths.isEmpty()) { 12233 if (instructionSets == null) { 12234 throw new IllegalStateException("instructionSet == null"); 12235 } 12236 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); 12237 for (String codePath : allCodePaths) { 12238 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 12239 try { 12240 mInstaller.rmdex(codePath, dexCodeInstructionSet); 12241 } catch (InstallerException ignored) { 12242 } 12243 } 12244 } 12245 } 12246 } 12247 12248 /** 12249 * Logic to handle installation of non-ASEC applications, including copying 12250 * and renaming logic. 12251 */ 12252 class FileInstallArgs extends InstallArgs { 12253 private File codeFile; 12254 private File resourceFile; 12255 12256 // Example topology: 12257 // /data/app/com.example/base.apk 12258 // /data/app/com.example/split_foo.apk 12259 // /data/app/com.example/lib/arm/libfoo.so 12260 // /data/app/com.example/lib/arm64/libfoo.so 12261 // /data/app/com.example/dalvik/arm/base.apk@classes.dex 12262 12263 /** New install */ 12264 FileInstallArgs(InstallParams params) { 12265 super(params.origin, params.move, params.observer, params.installFlags, 12266 params.installerPackageName, params.volumeUuid, 12267 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 12268 params.grantedRuntimePermissions, 12269 params.traceMethod, params.traceCookie); 12270 if (isFwdLocked()) { 12271 throw new IllegalArgumentException("Forward locking only supported in ASEC"); 12272 } 12273 } 12274 12275 /** Existing install */ 12276 FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) { 12277 super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets, 12278 null, null, null, 0); 12279 this.codeFile = (codePath != null) ? new File(codePath) : null; 12280 this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null; 12281 } 12282 12283 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 12284 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk"); 12285 try { 12286 return doCopyApk(imcs, temp); 12287 } finally { 12288 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 12289 } 12290 } 12291 12292 private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 12293 if (origin.staged) { 12294 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy"); 12295 codeFile = origin.file; 12296 resourceFile = origin.file; 12297 return PackageManager.INSTALL_SUCCEEDED; 12298 } 12299 12300 try { 12301 final boolean isEphemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; 12302 final File tempDir = 12303 mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral); 12304 codeFile = tempDir; 12305 resourceFile = tempDir; 12306 } catch (IOException e) { 12307 Slog.w(TAG, "Failed to create copy file: " + e); 12308 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 12309 } 12310 12311 final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() { 12312 @Override 12313 public ParcelFileDescriptor open(String name, int mode) throws RemoteException { 12314 if (!FileUtils.isValidExtFilename(name)) { 12315 throw new IllegalArgumentException("Invalid filename: " + name); 12316 } 12317 try { 12318 final File file = new File(codeFile, name); 12319 final FileDescriptor fd = Os.open(file.getAbsolutePath(), 12320 O_RDWR | O_CREAT, 0644); 12321 Os.chmod(file.getAbsolutePath(), 0644); 12322 return new ParcelFileDescriptor(fd); 12323 } catch (ErrnoException e) { 12324 throw new RemoteException("Failed to open: " + e.getMessage()); 12325 } 12326 } 12327 }; 12328 12329 int ret = PackageManager.INSTALL_SUCCEEDED; 12330 ret = imcs.copyPackage(origin.file.getAbsolutePath(), target); 12331 if (ret != PackageManager.INSTALL_SUCCEEDED) { 12332 Slog.e(TAG, "Failed to copy package"); 12333 return ret; 12334 } 12335 12336 final File libraryRoot = new File(codeFile, LIB_DIR_NAME); 12337 NativeLibraryHelper.Handle handle = null; 12338 try { 12339 handle = NativeLibraryHelper.Handle.create(codeFile); 12340 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot, 12341 abiOverride); 12342 } catch (IOException e) { 12343 Slog.e(TAG, "Copying native libraries failed", e); 12344 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 12345 } finally { 12346 IoUtils.closeQuietly(handle); 12347 } 12348 12349 return ret; 12350 } 12351 12352 int doPreInstall(int status) { 12353 if (status != PackageManager.INSTALL_SUCCEEDED) { 12354 cleanUp(); 12355 } 12356 return status; 12357 } 12358 12359 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 12360 if (status != PackageManager.INSTALL_SUCCEEDED) { 12361 cleanUp(); 12362 return false; 12363 } 12364 12365 final File targetDir = codeFile.getParentFile(); 12366 final File beforeCodeFile = codeFile; 12367 final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName); 12368 12369 if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile); 12370 try { 12371 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath()); 12372 } catch (ErrnoException e) { 12373 Slog.w(TAG, "Failed to rename", e); 12374 return false; 12375 } 12376 12377 if (!SELinux.restoreconRecursive(afterCodeFile)) { 12378 Slog.w(TAG, "Failed to restorecon"); 12379 return false; 12380 } 12381 12382 // Reflect the rename internally 12383 codeFile = afterCodeFile; 12384 resourceFile = afterCodeFile; 12385 12386 // Reflect the rename in scanned details 12387 pkg.setCodePath(afterCodeFile.getAbsolutePath()); 12388 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile, 12389 afterCodeFile, pkg.baseCodePath)); 12390 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile, 12391 afterCodeFile, pkg.splitCodePaths)); 12392 12393 // Reflect the rename in app info 12394 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 12395 pkg.setApplicationInfoCodePath(pkg.codePath); 12396 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 12397 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 12398 pkg.setApplicationInfoResourcePath(pkg.codePath); 12399 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 12400 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 12401 12402 return true; 12403 } 12404 12405 int doPostInstall(int status, int uid) { 12406 if (status != PackageManager.INSTALL_SUCCEEDED) { 12407 cleanUp(); 12408 } 12409 return status; 12410 } 12411 12412 @Override 12413 String getCodePath() { 12414 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 12415 } 12416 12417 @Override 12418 String getResourcePath() { 12419 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 12420 } 12421 12422 private boolean cleanUp() { 12423 if (codeFile == null || !codeFile.exists()) { 12424 return false; 12425 } 12426 12427 removeCodePathLI(codeFile); 12428 12429 if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) { 12430 resourceFile.delete(); 12431 } 12432 12433 return true; 12434 } 12435 12436 void cleanUpResourcesLI() { 12437 // Try enumerating all code paths before deleting 12438 List<String> allCodePaths = Collections.EMPTY_LIST; 12439 if (codeFile != null && codeFile.exists()) { 12440 try { 12441 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 12442 allCodePaths = pkg.getAllCodePaths(); 12443 } catch (PackageParserException e) { 12444 // Ignored; we tried our best 12445 } 12446 } 12447 12448 cleanUp(); 12449 removeDexFiles(allCodePaths, instructionSets); 12450 } 12451 12452 boolean doPostDeleteLI(boolean delete) { 12453 // XXX err, shouldn't we respect the delete flag? 12454 cleanUpResourcesLI(); 12455 return true; 12456 } 12457 } 12458 12459 private boolean isAsecExternal(String cid) { 12460 final String asecPath = PackageHelper.getSdFilesystem(cid); 12461 return !asecPath.startsWith(mAsecInternalPath); 12462 } 12463 12464 private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws 12465 PackageManagerException { 12466 if (copyRet < 0) { 12467 if (copyRet != PackageManager.NO_NATIVE_LIBRARIES && 12468 copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) { 12469 throw new PackageManagerException(copyRet, message); 12470 } 12471 } 12472 } 12473 12474 /** 12475 * Extract the MountService "container ID" from the full code path of an 12476 * .apk. 12477 */ 12478 static String cidFromCodePath(String fullCodePath) { 12479 int eidx = fullCodePath.lastIndexOf("/"); 12480 String subStr1 = fullCodePath.substring(0, eidx); 12481 int sidx = subStr1.lastIndexOf("/"); 12482 return subStr1.substring(sidx+1, eidx); 12483 } 12484 12485 /** 12486 * Logic to handle installation of ASEC applications, including copying and 12487 * renaming logic. 12488 */ 12489 class AsecInstallArgs extends InstallArgs { 12490 static final String RES_FILE_NAME = "pkg.apk"; 12491 static final String PUBLIC_RES_FILE_NAME = "res.zip"; 12492 12493 String cid; 12494 String packagePath; 12495 String resourcePath; 12496 12497 /** New install */ 12498 AsecInstallArgs(InstallParams params) { 12499 super(params.origin, params.move, params.observer, params.installFlags, 12500 params.installerPackageName, params.volumeUuid, 12501 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 12502 params.grantedRuntimePermissions, 12503 params.traceMethod, params.traceCookie); 12504 } 12505 12506 /** Existing install */ 12507 AsecInstallArgs(String fullCodePath, String[] instructionSets, 12508 boolean isExternal, boolean isForwardLocked) { 12509 super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0) 12510 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, 12511 instructionSets, null, null, null, 0); 12512 // Hackily pretend we're still looking at a full code path 12513 if (!fullCodePath.endsWith(RES_FILE_NAME)) { 12514 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath(); 12515 } 12516 12517 // Extract cid from fullCodePath 12518 int eidx = fullCodePath.lastIndexOf("/"); 12519 String subStr1 = fullCodePath.substring(0, eidx); 12520 int sidx = subStr1.lastIndexOf("/"); 12521 cid = subStr1.substring(sidx+1, eidx); 12522 setMountPath(subStr1); 12523 } 12524 12525 AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) { 12526 super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0) 12527 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, 12528 instructionSets, null, null, null, 0); 12529 this.cid = cid; 12530 setMountPath(PackageHelper.getSdDir(cid)); 12531 } 12532 12533 void createCopyFile() { 12534 cid = mInstallerService.allocateExternalStageCidLegacy(); 12535 } 12536 12537 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 12538 if (origin.staged && origin.cid != null) { 12539 if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy"); 12540 cid = origin.cid; 12541 setMountPath(PackageHelper.getSdDir(cid)); 12542 return PackageManager.INSTALL_SUCCEEDED; 12543 } 12544 12545 if (temp) { 12546 createCopyFile(); 12547 } else { 12548 /* 12549 * Pre-emptively destroy the container since it's destroyed if 12550 * copying fails due to it existing anyway. 12551 */ 12552 PackageHelper.destroySdDir(cid); 12553 } 12554 12555 final String newMountPath = imcs.copyPackageToContainer( 12556 origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(), 12557 isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */)); 12558 12559 if (newMountPath != null) { 12560 setMountPath(newMountPath); 12561 return PackageManager.INSTALL_SUCCEEDED; 12562 } else { 12563 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 12564 } 12565 } 12566 12567 @Override 12568 String getCodePath() { 12569 return packagePath; 12570 } 12571 12572 @Override 12573 String getResourcePath() { 12574 return resourcePath; 12575 } 12576 12577 int doPreInstall(int status) { 12578 if (status != PackageManager.INSTALL_SUCCEEDED) { 12579 // Destroy container 12580 PackageHelper.destroySdDir(cid); 12581 } else { 12582 boolean mounted = PackageHelper.isContainerMounted(cid); 12583 if (!mounted) { 12584 String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(), 12585 Process.SYSTEM_UID); 12586 if (newMountPath != null) { 12587 setMountPath(newMountPath); 12588 } else { 12589 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 12590 } 12591 } 12592 } 12593 return status; 12594 } 12595 12596 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 12597 String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME); 12598 String newMountPath = null; 12599 if (PackageHelper.isContainerMounted(cid)) { 12600 // Unmount the container 12601 if (!PackageHelper.unMountSdDir(cid)) { 12602 Slog.i(TAG, "Failed to unmount " + cid + " before renaming"); 12603 return false; 12604 } 12605 } 12606 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 12607 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId + 12608 " which might be stale. Will try to clean up."); 12609 // Clean up the stale container and proceed to recreate. 12610 if (!PackageHelper.destroySdDir(newCacheId)) { 12611 Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId); 12612 return false; 12613 } 12614 // Successfully cleaned up stale container. Try to rename again. 12615 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 12616 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId 12617 + " inspite of cleaning it up."); 12618 return false; 12619 } 12620 } 12621 if (!PackageHelper.isContainerMounted(newCacheId)) { 12622 Slog.w(TAG, "Mounting container " + newCacheId); 12623 newMountPath = PackageHelper.mountSdDir(newCacheId, 12624 getEncryptKey(), Process.SYSTEM_UID); 12625 } else { 12626 newMountPath = PackageHelper.getSdDir(newCacheId); 12627 } 12628 if (newMountPath == null) { 12629 Slog.w(TAG, "Failed to get cache path for " + newCacheId); 12630 return false; 12631 } 12632 Log.i(TAG, "Succesfully renamed " + cid + 12633 " to " + newCacheId + 12634 " at new path: " + newMountPath); 12635 cid = newCacheId; 12636 12637 final File beforeCodeFile = new File(packagePath); 12638 setMountPath(newMountPath); 12639 final File afterCodeFile = new File(packagePath); 12640 12641 // Reflect the rename in scanned details 12642 pkg.setCodePath(afterCodeFile.getAbsolutePath()); 12643 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile, 12644 afterCodeFile, pkg.baseCodePath)); 12645 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile, 12646 afterCodeFile, pkg.splitCodePaths)); 12647 12648 // Reflect the rename in app info 12649 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 12650 pkg.setApplicationInfoCodePath(pkg.codePath); 12651 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 12652 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 12653 pkg.setApplicationInfoResourcePath(pkg.codePath); 12654 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 12655 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 12656 12657 return true; 12658 } 12659 12660 private void setMountPath(String mountPath) { 12661 final File mountFile = new File(mountPath); 12662 12663 final File monolithicFile = new File(mountFile, RES_FILE_NAME); 12664 if (monolithicFile.exists()) { 12665 packagePath = monolithicFile.getAbsolutePath(); 12666 if (isFwdLocked()) { 12667 resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath(); 12668 } else { 12669 resourcePath = packagePath; 12670 } 12671 } else { 12672 packagePath = mountFile.getAbsolutePath(); 12673 resourcePath = packagePath; 12674 } 12675 } 12676 12677 int doPostInstall(int status, int uid) { 12678 if (status != PackageManager.INSTALL_SUCCEEDED) { 12679 cleanUp(); 12680 } else { 12681 final int groupOwner; 12682 final String protectedFile; 12683 if (isFwdLocked()) { 12684 groupOwner = UserHandle.getSharedAppGid(uid); 12685 protectedFile = RES_FILE_NAME; 12686 } else { 12687 groupOwner = -1; 12688 protectedFile = null; 12689 } 12690 12691 if (uid < Process.FIRST_APPLICATION_UID 12692 || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) { 12693 Slog.e(TAG, "Failed to finalize " + cid); 12694 PackageHelper.destroySdDir(cid); 12695 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 12696 } 12697 12698 boolean mounted = PackageHelper.isContainerMounted(cid); 12699 if (!mounted) { 12700 PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid()); 12701 } 12702 } 12703 return status; 12704 } 12705 12706 private void cleanUp() { 12707 if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp"); 12708 12709 // Destroy secure container 12710 PackageHelper.destroySdDir(cid); 12711 } 12712 12713 private List<String> getAllCodePaths() { 12714 final File codeFile = new File(getCodePath()); 12715 if (codeFile != null && codeFile.exists()) { 12716 try { 12717 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 12718 return pkg.getAllCodePaths(); 12719 } catch (PackageParserException e) { 12720 // Ignored; we tried our best 12721 } 12722 } 12723 return Collections.EMPTY_LIST; 12724 } 12725 12726 void cleanUpResourcesLI() { 12727 // Enumerate all code paths before deleting 12728 cleanUpResourcesLI(getAllCodePaths()); 12729 } 12730 12731 private void cleanUpResourcesLI(List<String> allCodePaths) { 12732 cleanUp(); 12733 removeDexFiles(allCodePaths, instructionSets); 12734 } 12735 12736 String getPackageName() { 12737 return getAsecPackageName(cid); 12738 } 12739 12740 boolean doPostDeleteLI(boolean delete) { 12741 if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete); 12742 final List<String> allCodePaths = getAllCodePaths(); 12743 boolean mounted = PackageHelper.isContainerMounted(cid); 12744 if (mounted) { 12745 // Unmount first 12746 if (PackageHelper.unMountSdDir(cid)) { 12747 mounted = false; 12748 } 12749 } 12750 if (!mounted && delete) { 12751 cleanUpResourcesLI(allCodePaths); 12752 } 12753 return !mounted; 12754 } 12755 12756 @Override 12757 int doPreCopy() { 12758 if (isFwdLocked()) { 12759 if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE, 12760 MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) { 12761 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 12762 } 12763 } 12764 12765 return PackageManager.INSTALL_SUCCEEDED; 12766 } 12767 12768 @Override 12769 int doPostCopy(int uid) { 12770 if (isFwdLocked()) { 12771 if (uid < Process.FIRST_APPLICATION_UID 12772 || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid), 12773 RES_FILE_NAME)) { 12774 Slog.e(TAG, "Failed to finalize " + cid); 12775 PackageHelper.destroySdDir(cid); 12776 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 12777 } 12778 } 12779 12780 return PackageManager.INSTALL_SUCCEEDED; 12781 } 12782 } 12783 12784 /** 12785 * Logic to handle movement of existing installed applications. 12786 */ 12787 class MoveInstallArgs extends InstallArgs { 12788 private File codeFile; 12789 private File resourceFile; 12790 12791 /** New install */ 12792 MoveInstallArgs(InstallParams params) { 12793 super(params.origin, params.move, params.observer, params.installFlags, 12794 params.installerPackageName, params.volumeUuid, 12795 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 12796 params.grantedRuntimePermissions, 12797 params.traceMethod, params.traceCookie); 12798 } 12799 12800 int copyApk(IMediaContainerService imcs, boolean temp) { 12801 if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from " 12802 + move.fromUuid + " to " + move.toUuid); 12803 synchronized (mInstaller) { 12804 try { 12805 mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName, 12806 move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion); 12807 } catch (InstallerException e) { 12808 Slog.w(TAG, "Failed to move app", e); 12809 return PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 12810 } 12811 } 12812 12813 codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName); 12814 resourceFile = codeFile; 12815 if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile); 12816 12817 return PackageManager.INSTALL_SUCCEEDED; 12818 } 12819 12820 int doPreInstall(int status) { 12821 if (status != PackageManager.INSTALL_SUCCEEDED) { 12822 cleanUp(move.toUuid); 12823 } 12824 return status; 12825 } 12826 12827 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 12828 if (status != PackageManager.INSTALL_SUCCEEDED) { 12829 cleanUp(move.toUuid); 12830 return false; 12831 } 12832 12833 // Reflect the move in app info 12834 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 12835 pkg.setApplicationInfoCodePath(pkg.codePath); 12836 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 12837 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 12838 pkg.setApplicationInfoResourcePath(pkg.codePath); 12839 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 12840 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 12841 12842 return true; 12843 } 12844 12845 int doPostInstall(int status, int uid) { 12846 if (status == PackageManager.INSTALL_SUCCEEDED) { 12847 cleanUp(move.fromUuid); 12848 } else { 12849 cleanUp(move.toUuid); 12850 } 12851 return status; 12852 } 12853 12854 @Override 12855 String getCodePath() { 12856 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 12857 } 12858 12859 @Override 12860 String getResourcePath() { 12861 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 12862 } 12863 12864 private boolean cleanUp(String volumeUuid) { 12865 final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid), 12866 move.dataAppName); 12867 Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid); 12868 synchronized (mInstallLock) { 12869 // Clean up both app data and code 12870 removeDataDirsLI(volumeUuid, move.packageName); 12871 removeCodePathLI(codeFile); 12872 } 12873 return true; 12874 } 12875 12876 void cleanUpResourcesLI() { 12877 throw new UnsupportedOperationException(); 12878 } 12879 12880 boolean doPostDeleteLI(boolean delete) { 12881 throw new UnsupportedOperationException(); 12882 } 12883 } 12884 12885 static String getAsecPackageName(String packageCid) { 12886 int idx = packageCid.lastIndexOf("-"); 12887 if (idx == -1) { 12888 return packageCid; 12889 } 12890 return packageCid.substring(0, idx); 12891 } 12892 12893 // Utility method used to create code paths based on package name and available index. 12894 private static String getNextCodePath(String oldCodePath, String prefix, String suffix) { 12895 String idxStr = ""; 12896 int idx = 1; 12897 // Fall back to default value of idx=1 if prefix is not 12898 // part of oldCodePath 12899 if (oldCodePath != null) { 12900 String subStr = oldCodePath; 12901 // Drop the suffix right away 12902 if (suffix != null && subStr.endsWith(suffix)) { 12903 subStr = subStr.substring(0, subStr.length() - suffix.length()); 12904 } 12905 // If oldCodePath already contains prefix find out the 12906 // ending index to either increment or decrement. 12907 int sidx = subStr.lastIndexOf(prefix); 12908 if (sidx != -1) { 12909 subStr = subStr.substring(sidx + prefix.length()); 12910 if (subStr != null) { 12911 if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) { 12912 subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length()); 12913 } 12914 try { 12915 idx = Integer.parseInt(subStr); 12916 if (idx <= 1) { 12917 idx++; 12918 } else { 12919 idx--; 12920 } 12921 } catch(NumberFormatException e) { 12922 } 12923 } 12924 } 12925 } 12926 idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx); 12927 return prefix + idxStr; 12928 } 12929 12930 private File getNextCodePath(File targetDir, String packageName) { 12931 int suffix = 1; 12932 File result; 12933 do { 12934 result = new File(targetDir, packageName + "-" + suffix); 12935 suffix++; 12936 } while (result.exists()); 12937 return result; 12938 } 12939 12940 // Utility method that returns the relative package path with respect 12941 // to the installation directory. Like say for /data/data/com.test-1.apk 12942 // string com.test-1 is returned. 12943 static String deriveCodePathName(String codePath) { 12944 if (codePath == null) { 12945 return null; 12946 } 12947 final File codeFile = new File(codePath); 12948 final String name = codeFile.getName(); 12949 if (codeFile.isDirectory()) { 12950 return name; 12951 } else if (name.endsWith(".apk") || name.endsWith(".tmp")) { 12952 final int lastDot = name.lastIndexOf('.'); 12953 return name.substring(0, lastDot); 12954 } else { 12955 Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK"); 12956 return null; 12957 } 12958 } 12959 12960 static class PackageInstalledInfo { 12961 String name; 12962 int uid; 12963 // The set of users that originally had this package installed. 12964 int[] origUsers; 12965 // The set of users that now have this package installed. 12966 int[] newUsers; 12967 PackageParser.Package pkg; 12968 int returnCode; 12969 String returnMsg; 12970 PackageRemovedInfo removedInfo; 12971 ArrayMap<String, PackageInstalledInfo> addedChildPackages; 12972 12973 public void setError(int code, String msg) { 12974 setReturnCode(code); 12975 setReturnMessage(msg); 12976 Slog.w(TAG, msg); 12977 } 12978 12979 public void setError(String msg, PackageParserException e) { 12980 setReturnCode(e.error); 12981 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e)); 12982 Slog.w(TAG, msg, e); 12983 } 12984 12985 public void setError(String msg, PackageManagerException e) { 12986 returnCode = e.error; 12987 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e)); 12988 Slog.w(TAG, msg, e); 12989 } 12990 12991 public void setReturnCode(int returnCode) { 12992 this.returnCode = returnCode; 12993 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0; 12994 for (int i = 0; i < childCount; i++) { 12995 addedChildPackages.valueAt(i).returnCode = returnCode; 12996 } 12997 } 12998 12999 private void setReturnMessage(String returnMsg) { 13000 this.returnMsg = returnMsg; 13001 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0; 13002 for (int i = 0; i < childCount; i++) { 13003 addedChildPackages.valueAt(i).returnMsg = returnMsg; 13004 } 13005 } 13006 13007 // In some error cases we want to convey more info back to the observer 13008 String origPackage; 13009 String origPermission; 13010 } 13011 13012 /* 13013 * Install a non-existing package. 13014 */ 13015 private void installNewPackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, 13016 UserHandle user, String installerPackageName, String volumeUuid, 13017 PackageInstalledInfo res) { 13018 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage"); 13019 13020 // Remember this for later, in case we need to rollback this install 13021 String pkgName = pkg.packageName; 13022 13023 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg); 13024 13025 synchronized(mPackages) { 13026 if (mSettings.mRenamedPackages.containsKey(pkgName)) { 13027 // A package with the same name is already installed, though 13028 // it has been renamed to an older name. The package we 13029 // are trying to install should be installed as an update to 13030 // the existing one, but that has not been requested, so bail. 13031 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 13032 + " without first uninstalling package running as " 13033 + mSettings.mRenamedPackages.get(pkgName)); 13034 return; 13035 } 13036 if (mPackages.containsKey(pkgName)) { 13037 // Don't allow installation over an existing package with the same name. 13038 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 13039 + " without first uninstalling."); 13040 return; 13041 } 13042 } 13043 13044 try { 13045 PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags, 13046 System.currentTimeMillis(), user); 13047 13048 updateSettingsLI(newPackage, installerPackageName, null, res, user); 13049 13050 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 13051 prepareAppDataAfterInstall(newPackage); 13052 13053 } else { 13054 // Remove package from internal structures, but keep around any 13055 // data that might have already existed 13056 deletePackageLI(pkgName, UserHandle.ALL, false, null, 13057 PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null); 13058 } 13059 } catch (PackageManagerException e) { 13060 res.setError("Package couldn't be installed in " + pkg.codePath, e); 13061 } 13062 13063 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13064 } 13065 13066 private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) { 13067 // Can't rotate keys during boot or if sharedUser. 13068 if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null 13069 || !oldPs.keySetData.isUsingUpgradeKeySets()) { 13070 return false; 13071 } 13072 // app is using upgradeKeySets; make sure all are valid 13073 KeySetManagerService ksms = mSettings.mKeySetManagerService; 13074 long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets(); 13075 for (int i = 0; i < upgradeKeySets.length; i++) { 13076 if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) { 13077 Slog.wtf(TAG, "Package " 13078 + (oldPs.name != null ? oldPs.name : "<null>") 13079 + " contains upgrade-key-set reference to unknown key-set: " 13080 + upgradeKeySets[i] 13081 + " reverting to signatures check."); 13082 return false; 13083 } 13084 } 13085 return true; 13086 } 13087 13088 private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) { 13089 // Upgrade keysets are being used. Determine if new package has a superset of the 13090 // required keys. 13091 long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets(); 13092 KeySetManagerService ksms = mSettings.mKeySetManagerService; 13093 for (int i = 0; i < upgradeKeySets.length; i++) { 13094 Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]); 13095 if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) { 13096 return true; 13097 } 13098 } 13099 return false; 13100 } 13101 13102 private void replacePackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, 13103 UserHandle user, String installerPackageName, PackageInstalledInfo res) { 13104 final boolean isEphemeral = (parseFlags & PackageParser.PARSE_IS_EPHEMERAL) != 0; 13105 13106 final PackageParser.Package oldPackage; 13107 final String pkgName = pkg.packageName; 13108 final int[] allUsers; 13109 13110 // First find the old package info and check signatures 13111 synchronized(mPackages) { 13112 oldPackage = mPackages.get(pkgName); 13113 final boolean oldIsEphemeral = oldPackage.applicationInfo.isEphemeralApp(); 13114 if (isEphemeral && !oldIsEphemeral) { 13115 // can't downgrade from full to ephemeral 13116 Slog.w(TAG, "Can't replace app with ephemeral: " + pkgName); 13117 res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID); 13118 return; 13119 } 13120 if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage); 13121 final PackageSetting ps = mSettings.mPackages.get(pkgName); 13122 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { 13123 if (!checkUpgradeKeySetLP(ps, pkg)) { 13124 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 13125 "New package not signed by keys specified by upgrade-keysets: " 13126 + pkgName); 13127 return; 13128 } 13129 } else { 13130 // default to original signature matching 13131 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures) 13132 != PackageManager.SIGNATURE_MATCH) { 13133 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 13134 "New package has a different signature: " + pkgName); 13135 return; 13136 } 13137 } 13138 13139 // In case of rollback, remember per-user/profile install state 13140 allUsers = sUserManager.getUserIds(); 13141 } 13142 13143 // Update what is removed 13144 res.removedInfo = new PackageRemovedInfo(); 13145 res.removedInfo.uid = oldPackage.applicationInfo.uid; 13146 res.removedInfo.removedPackage = oldPackage.packageName; 13147 res.removedInfo.isUpdate = true; 13148 final int childCount = (oldPackage.childPackages != null) 13149 ? oldPackage.childPackages.size() : 0; 13150 for (int i = 0; i < childCount; i++) { 13151 boolean childPackageUpdated = false; 13152 PackageParser.Package childPkg = oldPackage.childPackages.get(i); 13153 if (res.addedChildPackages != null) { 13154 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName); 13155 if (childRes != null) { 13156 childRes.removedInfo.uid = childPkg.applicationInfo.uid; 13157 childRes.removedInfo.removedPackage = childPkg.packageName; 13158 childRes.removedInfo.isUpdate = true; 13159 childPackageUpdated = true; 13160 } 13161 } 13162 if (!childPackageUpdated) { 13163 PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(); 13164 childRemovedRes.removedPackage = childPkg.packageName; 13165 childRemovedRes.isUpdate = false; 13166 childRemovedRes.dataRemoved = true; 13167 synchronized (mPackages) { 13168 PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName); 13169 if (childPs != null) { 13170 childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true); 13171 } 13172 } 13173 if (res.removedInfo.removedChildPackages == null) { 13174 res.removedInfo.removedChildPackages = new ArrayMap<>(); 13175 } 13176 res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes); 13177 } 13178 } 13179 13180 boolean sysPkg = (isSystemApp(oldPackage)); 13181 if (sysPkg) { 13182 replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags, 13183 user, allUsers, installerPackageName, res); 13184 } else { 13185 replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags, 13186 user, allUsers, installerPackageName, res); 13187 } 13188 } 13189 13190 public List<String> getPreviousCodePaths(String packageName) { 13191 final PackageSetting ps = mSettings.mPackages.get(packageName); 13192 final List<String> result = new ArrayList<String>(); 13193 if (ps != null && ps.oldCodePaths != null) { 13194 result.addAll(ps.oldCodePaths); 13195 } 13196 return result; 13197 } 13198 13199 private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage, 13200 PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, 13201 int[] allUsers, String installerPackageName, PackageInstalledInfo res) { 13202 if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old=" 13203 + deletedPackage); 13204 13205 String pkgName = deletedPackage.packageName; 13206 boolean deletedPkg = true; 13207 boolean addedPkg = false; 13208 boolean updatedSettings = false; 13209 final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0; 13210 final int deleteFlags = PackageManager.DELETE_KEEP_DATA 13211 | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP); 13212 13213 final long origUpdateTime = (pkg.mExtras != null) 13214 ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0; 13215 13216 // First delete the existing package while retaining the data directory 13217 if (!deletePackageLI(pkgName, null, true, allUsers, deleteFlags, 13218 res.removedInfo, true, pkg)) { 13219 // If the existing package wasn't successfully deleted 13220 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI"); 13221 deletedPkg = false; 13222 } else { 13223 // Successfully deleted the old package; proceed with replace. 13224 13225 // If deleted package lived in a container, give users a chance to 13226 // relinquish resources before killing. 13227 if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) { 13228 if (DEBUG_INSTALL) { 13229 Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE"); 13230 } 13231 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid }; 13232 final ArrayList<String> pkgList = new ArrayList<String>(1); 13233 pkgList.add(deletedPackage.applicationInfo.packageName); 13234 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null); 13235 } 13236 13237 deleteCodeCacheDirsLI(pkg); 13238 13239 try { 13240 final PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags, 13241 scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user); 13242 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user); 13243 13244 // Update the in-memory copy of the previous code paths. 13245 PackageSetting ps = mSettings.mPackages.get(pkgName); 13246 if (!killApp) { 13247 if (ps.oldCodePaths == null) { 13248 ps.oldCodePaths = new ArraySet<>(); 13249 } 13250 Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath); 13251 if (deletedPackage.splitCodePaths != null) { 13252 Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths); 13253 } 13254 } else { 13255 ps.oldCodePaths = null; 13256 } 13257 if (ps.childPackageNames != null) { 13258 for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) { 13259 final String childPkgName = ps.childPackageNames.get(i); 13260 final PackageSetting childPs = mSettings.mPackages.get(childPkgName); 13261 childPs.oldCodePaths = ps.oldCodePaths; 13262 } 13263 } 13264 prepareAppDataAfterInstall(newPackage); 13265 addedPkg = true; 13266 } catch (PackageManagerException e) { 13267 res.setError("Package couldn't be installed in " + pkg.codePath, e); 13268 } 13269 } 13270 13271 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 13272 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName); 13273 13274 // Revert all internal state mutations and added folders for the failed install 13275 if (addedPkg) { 13276 deletePackageLI(pkgName, null, true, allUsers, deleteFlags, 13277 res.removedInfo, true, null); 13278 } 13279 13280 // Restore the old package 13281 if (deletedPkg) { 13282 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage); 13283 File restoreFile = new File(deletedPackage.codePath); 13284 // Parse old package 13285 boolean oldExternal = isExternal(deletedPackage); 13286 int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY | 13287 (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) | 13288 (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0); 13289 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME; 13290 try { 13291 scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, 13292 null); 13293 } catch (PackageManagerException e) { 13294 Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: " 13295 + e.getMessage()); 13296 return; 13297 } 13298 13299 synchronized (mPackages) { 13300 // Ensure the installer package name up to date 13301 setInstallerPackageNameLPw(deletedPackage, installerPackageName); 13302 13303 // Update permissions for restored package 13304 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL); 13305 13306 mSettings.writeLPr(); 13307 } 13308 13309 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade"); 13310 } 13311 } else { 13312 synchronized (mPackages) { 13313 PackageSetting ps = mSettings.peekPackageLPr(pkg.packageName); 13314 if (ps != null) { 13315 res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null; 13316 if (res.removedInfo.removedChildPackages != null) { 13317 final int childCount = res.removedInfo.removedChildPackages.size(); 13318 // Iterate in reverse as we may modify the collection 13319 for (int i = childCount - 1; i >= 0; i--) { 13320 String childPackageName = res.removedInfo.removedChildPackages.keyAt(i); 13321 if (res.addedChildPackages.containsKey(childPackageName)) { 13322 res.removedInfo.removedChildPackages.removeAt(i); 13323 } else { 13324 PackageRemovedInfo childInfo = res.removedInfo 13325 .removedChildPackages.valueAt(i); 13326 childInfo.removedForAllUsers = mPackages.get( 13327 childInfo.removedPackage) == null; 13328 } 13329 } 13330 } 13331 } 13332 } 13333 } 13334 } 13335 13336 private void replaceSystemPackageLI(PackageParser.Package deletedPackage, 13337 PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, 13338 int[] allUsers, String installerPackageName, PackageInstalledInfo res) { 13339 if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg 13340 + ", old=" + deletedPackage); 13341 13342 final boolean disabledSystem; 13343 13344 // Set the system/privileged flags as needed 13345 parseFlags |= PackageParser.PARSE_IS_SYSTEM; 13346 if ((deletedPackage.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) 13347 != 0) { 13348 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 13349 } 13350 13351 // Kill package processes including services, providers, etc. 13352 killPackage(deletedPackage, "replace sys pkg"); 13353 13354 // Remove existing system package 13355 removePackageLI(deletedPackage, true); 13356 13357 disabledSystem = disableSystemPackageLPw(deletedPackage, pkg); 13358 if (!disabledSystem) { 13359 // We didn't need to disable the .apk as a current system package, 13360 // which means we are replacing another update that is already 13361 // installed. We need to make sure to delete the older one's .apk. 13362 res.removedInfo.args = createInstallArgsForExisting(0, 13363 deletedPackage.applicationInfo.getCodePath(), 13364 deletedPackage.applicationInfo.getResourcePath(), 13365 getAppDexInstructionSets(deletedPackage.applicationInfo)); 13366 } else { 13367 res.removedInfo.args = null; 13368 } 13369 13370 // Successfully disabled the old package. Now proceed with re-installation 13371 deleteCodeCacheDirsLI(pkg); 13372 13373 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 13374 pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP, 13375 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP); 13376 13377 PackageParser.Package newPackage = null; 13378 try { 13379 // Add the package to the internal data structures 13380 newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags, 0, user); 13381 13382 // Set the update and install times 13383 PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras; 13384 setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime, 13385 System.currentTimeMillis()); 13386 13387 // Check for shared user id changes 13388 String invalidPackageName = getParentOrChildPackageChangedSharedUser( 13389 deletedPackage, newPackage); 13390 if (invalidPackageName != null) { 13391 res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 13392 "Forbidding shared user change from " + deletedPkgSetting.sharedUser 13393 + " to " + invalidPackageName); 13394 } 13395 13396 // Update the package dynamic state if succeeded 13397 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 13398 // Now that the install succeeded make sure we remove data 13399 // directories for any child package the update removed. 13400 final int deletedChildCount = (deletedPackage.childPackages != null) 13401 ? deletedPackage.childPackages.size() : 0; 13402 final int newChildCount = (newPackage.childPackages != null) 13403 ? newPackage.childPackages.size() : 0; 13404 for (int i = 0; i < deletedChildCount; i++) { 13405 PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i); 13406 boolean childPackageDeleted = true; 13407 for (int j = 0; j < newChildCount; j++) { 13408 PackageParser.Package newChildPkg = newPackage.childPackages.get(j); 13409 if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) { 13410 childPackageDeleted = false; 13411 break; 13412 } 13413 } 13414 if (childPackageDeleted) { 13415 PackageSetting ps = mSettings.getDisabledSystemPkgLPr( 13416 deletedChildPkg.packageName); 13417 if (ps != null && res.removedInfo.removedChildPackages != null) { 13418 PackageRemovedInfo removedChildRes = res.removedInfo 13419 .removedChildPackages.get(deletedChildPkg.packageName); 13420 removePackageDataLI(ps, allUsers, removedChildRes, 0, false); 13421 removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null; 13422 } 13423 } 13424 } 13425 13426 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user); 13427 prepareAppDataAfterInstall(newPackage); 13428 } 13429 } catch (PackageManagerException e) { 13430 res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR); 13431 res.setError("Package couldn't be installed in " + pkg.codePath, e); 13432 } 13433 13434 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 13435 // Re installation failed. Restore old information 13436 // Remove new pkg information 13437 if (newPackage != null) { 13438 removeInstalledPackageLI(newPackage, true); 13439 } 13440 // Add back the old system package 13441 try { 13442 scanPackageTracedLI(deletedPackage, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user); 13443 } catch (PackageManagerException e) { 13444 Slog.e(TAG, "Failed to restore original package: " + e.getMessage()); 13445 } 13446 13447 synchronized (mPackages) { 13448 if (disabledSystem) { 13449 enableSystemPackageLPw(deletedPackage); 13450 } 13451 13452 // Ensure the installer package name up to date 13453 setInstallerPackageNameLPw(deletedPackage, installerPackageName); 13454 13455 // Update permissions for restored package 13456 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL); 13457 13458 mSettings.writeLPr(); 13459 } 13460 13461 Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName 13462 + " after failed upgrade"); 13463 } 13464 } 13465 13466 /** 13467 * Checks whether the parent or any of the child packages have a change shared 13468 * user. For a package to be a valid update the shred users of the parent and 13469 * the children should match. We may later support changing child shared users. 13470 * @param oldPkg The updated package. 13471 * @param newPkg The update package. 13472 * @return The shared user that change between the versions. 13473 */ 13474 private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg, 13475 PackageParser.Package newPkg) { 13476 // Check parent shared user 13477 if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) { 13478 return newPkg.packageName; 13479 } 13480 // Check child shared users 13481 final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0; 13482 final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0; 13483 for (int i = 0; i < newChildCount; i++) { 13484 PackageParser.Package newChildPkg = newPkg.childPackages.get(i); 13485 // If this child was present, did it have the same shared user? 13486 for (int j = 0; j < oldChildCount; j++) { 13487 PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j); 13488 if (newChildPkg.packageName.equals(oldChildPkg.packageName) 13489 && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) { 13490 return newChildPkg.packageName; 13491 } 13492 } 13493 } 13494 return null; 13495 } 13496 13497 private void removeNativeBinariesLI(PackageSetting ps) { 13498 // Remove the lib path for the parent package 13499 if (ps != null) { 13500 NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString); 13501 // Remove the lib path for the child packages 13502 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0; 13503 for (int i = 0; i < childCount; i++) { 13504 PackageSetting childPs = null; 13505 synchronized (mPackages) { 13506 childPs = mSettings.peekPackageLPr(ps.childPackageNames.get(i)); 13507 } 13508 if (childPs != null) { 13509 NativeLibraryHelper.removeNativeBinariesLI(childPs 13510 .legacyNativeLibraryPathString); 13511 } 13512 } 13513 } 13514 } 13515 13516 private void enableSystemPackageLPw(PackageParser.Package pkg) { 13517 // Enable the parent package 13518 mSettings.enableSystemPackageLPw(pkg.packageName); 13519 // Enable the child packages 13520 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 13521 for (int i = 0; i < childCount; i++) { 13522 PackageParser.Package childPkg = pkg.childPackages.get(i); 13523 mSettings.enableSystemPackageLPw(childPkg.packageName); 13524 } 13525 } 13526 13527 private boolean disableSystemPackageLPw(PackageParser.Package oldPkg, 13528 PackageParser.Package newPkg) { 13529 // Disable the parent package (parent always replaced) 13530 boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true); 13531 // Disable the child packages 13532 final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0; 13533 for (int i = 0; i < childCount; i++) { 13534 PackageParser.Package childPkg = oldPkg.childPackages.get(i); 13535 final boolean replace = newPkg.hasChildPackage(childPkg.packageName); 13536 disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace); 13537 } 13538 return disabled; 13539 } 13540 13541 private void setInstallerPackageNameLPw(PackageParser.Package pkg, 13542 String installerPackageName) { 13543 // Enable the parent package 13544 mSettings.setInstallerPackageName(pkg.packageName, installerPackageName); 13545 // Enable the child packages 13546 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 13547 for (int i = 0; i < childCount; i++) { 13548 PackageParser.Package childPkg = pkg.childPackages.get(i); 13549 mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName); 13550 } 13551 } 13552 13553 private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) { 13554 // Collect all used permissions in the UID 13555 ArraySet<String> usedPermissions = new ArraySet<>(); 13556 final int packageCount = su.packages.size(); 13557 for (int i = 0; i < packageCount; i++) { 13558 PackageSetting ps = su.packages.valueAt(i); 13559 if (ps.pkg == null) { 13560 continue; 13561 } 13562 final int requestedPermCount = ps.pkg.requestedPermissions.size(); 13563 for (int j = 0; j < requestedPermCount; j++) { 13564 String permission = ps.pkg.requestedPermissions.get(j); 13565 BasePermission bp = mSettings.mPermissions.get(permission); 13566 if (bp != null) { 13567 usedPermissions.add(permission); 13568 } 13569 } 13570 } 13571 13572 PermissionsState permissionsState = su.getPermissionsState(); 13573 // Prune install permissions 13574 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates(); 13575 final int installPermCount = installPermStates.size(); 13576 for (int i = installPermCount - 1; i >= 0; i--) { 13577 PermissionState permissionState = installPermStates.get(i); 13578 if (!usedPermissions.contains(permissionState.getName())) { 13579 BasePermission bp = mSettings.mPermissions.get(permissionState.getName()); 13580 if (bp != null) { 13581 permissionsState.revokeInstallPermission(bp); 13582 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 13583 PackageManager.MASK_PERMISSION_FLAGS, 0); 13584 } 13585 } 13586 } 13587 13588 int[] runtimePermissionChangedUserIds = EmptyArray.INT; 13589 13590 // Prune runtime permissions 13591 for (int userId : allUserIds) { 13592 List<PermissionState> runtimePermStates = permissionsState 13593 .getRuntimePermissionStates(userId); 13594 final int runtimePermCount = runtimePermStates.size(); 13595 for (int i = runtimePermCount - 1; i >= 0; i--) { 13596 PermissionState permissionState = runtimePermStates.get(i); 13597 if (!usedPermissions.contains(permissionState.getName())) { 13598 BasePermission bp = mSettings.mPermissions.get(permissionState.getName()); 13599 if (bp != null) { 13600 permissionsState.revokeRuntimePermission(bp, userId); 13601 permissionsState.updatePermissionFlags(bp, userId, 13602 PackageManager.MASK_PERMISSION_FLAGS, 0); 13603 runtimePermissionChangedUserIds = ArrayUtils.appendInt( 13604 runtimePermissionChangedUserIds, userId); 13605 } 13606 } 13607 } 13608 } 13609 13610 return runtimePermissionChangedUserIds; 13611 } 13612 13613 private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, 13614 int[] allUsers, PackageInstalledInfo res, UserHandle user) { 13615 // Update the parent package setting 13616 updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers, 13617 res, user); 13618 // Update the child packages setting 13619 final int childCount = (newPackage.childPackages != null) 13620 ? newPackage.childPackages.size() : 0; 13621 for (int i = 0; i < childCount; i++) { 13622 PackageParser.Package childPackage = newPackage.childPackages.get(i); 13623 PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName); 13624 updateSettingsInternalLI(childPackage, installerPackageName, allUsers, 13625 childRes.origUsers, childRes, user); 13626 } 13627 } 13628 13629 private void updateSettingsInternalLI(PackageParser.Package newPackage, 13630 String installerPackageName, int[] allUsers, int[] installedForUsers, 13631 PackageInstalledInfo res, UserHandle user) { 13632 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 13633 13634 String pkgName = newPackage.packageName; 13635 synchronized (mPackages) { 13636 //write settings. the installStatus will be incomplete at this stage. 13637 //note that the new package setting would have already been 13638 //added to mPackages. It hasn't been persisted yet. 13639 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE); 13640 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings"); 13641 mSettings.writeLPr(); 13642 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13643 } 13644 13645 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath); 13646 synchronized (mPackages) { 13647 updatePermissionsLPw(newPackage.packageName, newPackage, 13648 UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0 13649 ? UPDATE_PERMISSIONS_ALL : 0)); 13650 // For system-bundled packages, we assume that installing an upgraded version 13651 // of the package implies that the user actually wants to run that new code, 13652 // so we enable the package. 13653 PackageSetting ps = mSettings.mPackages.get(pkgName); 13654 final int userId = user.getIdentifier(); 13655 if (ps != null) { 13656 if (isSystemApp(newPackage)) { 13657 if (DEBUG_INSTALL) { 13658 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName); 13659 } 13660 // Enable system package for requested users 13661 if (res.origUsers != null) { 13662 for (int origUserId : res.origUsers) { 13663 if (userId == UserHandle.USER_ALL || userId == origUserId) { 13664 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 13665 origUserId, installerPackageName); 13666 } 13667 } 13668 } 13669 // Also convey the prior install/uninstall state 13670 if (allUsers != null && installedForUsers != null) { 13671 for (int currentUserId : allUsers) { 13672 final boolean installed = ArrayUtils.contains( 13673 installedForUsers, currentUserId); 13674 if (DEBUG_INSTALL) { 13675 Slog.d(TAG, " user " + currentUserId + " => " + installed); 13676 } 13677 ps.setInstalled(installed, currentUserId); 13678 } 13679 // these install state changes will be persisted in the 13680 // upcoming call to mSettings.writeLPr(). 13681 } 13682 } 13683 // It's implied that when a user requests installation, they want the app to be 13684 // installed and enabled. 13685 if (userId != UserHandle.USER_ALL) { 13686 ps.setInstalled(true, userId); 13687 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName); 13688 } 13689 } 13690 res.name = pkgName; 13691 res.uid = newPackage.applicationInfo.uid; 13692 res.pkg = newPackage; 13693 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE); 13694 mSettings.setInstallerPackageName(pkgName, installerPackageName); 13695 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 13696 //to update install status 13697 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings"); 13698 mSettings.writeLPr(); 13699 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13700 } 13701 13702 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13703 } 13704 13705 private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) { 13706 try { 13707 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage"); 13708 installPackageLI(args, res); 13709 } finally { 13710 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13711 } 13712 } 13713 13714 private void installPackageLI(InstallArgs args, PackageInstalledInfo res) { 13715 final int installFlags = args.installFlags; 13716 final String installerPackageName = args.installerPackageName; 13717 final String volumeUuid = args.volumeUuid; 13718 final File tmpPackageFile = new File(args.getCodePath()); 13719 final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0); 13720 final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) 13721 || (args.volumeUuid != null)); 13722 final boolean ephemeral = ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0); 13723 boolean replace = false; 13724 int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE; 13725 if (args.move != null) { 13726 // moving a complete application; perform an initial scan on the new install location 13727 scanFlags |= SCAN_INITIAL; 13728 } 13729 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) { 13730 scanFlags |= SCAN_DONT_KILL_APP; 13731 } 13732 13733 // Result object to be returned 13734 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 13735 13736 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile); 13737 13738 // Sanity check 13739 if (ephemeral && (forwardLocked || onExternal)) { 13740 Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked 13741 + " external=" + onExternal); 13742 res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID); 13743 return; 13744 } 13745 13746 // Retrieve PackageSettings and parse package 13747 final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY 13748 | PackageParser.PARSE_ENFORCE_CODE 13749 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) 13750 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0) 13751 | (ephemeral ? PackageParser.PARSE_IS_EPHEMERAL : 0); 13752 PackageParser pp = new PackageParser(); 13753 pp.setSeparateProcesses(mSeparateProcesses); 13754 pp.setDisplayMetrics(mMetrics); 13755 13756 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage"); 13757 final PackageParser.Package pkg; 13758 try { 13759 pkg = pp.parsePackage(tmpPackageFile, parseFlags); 13760 } catch (PackageParserException e) { 13761 res.setError("Failed parse during installPackageLI", e); 13762 return; 13763 } finally { 13764 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13765 } 13766 13767 // If we are installing a clustered package add results for the children 13768 if (pkg.childPackages != null) { 13769 synchronized (mPackages) { 13770 final int childCount = pkg.childPackages.size(); 13771 for (int i = 0; i < childCount; i++) { 13772 PackageParser.Package childPkg = pkg.childPackages.get(i); 13773 PackageInstalledInfo childRes = new PackageInstalledInfo(); 13774 childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 13775 childRes.pkg = childPkg; 13776 childRes.name = childPkg.packageName; 13777 PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName); 13778 if (childPs != null) { 13779 childRes.origUsers = childPs.queryInstalledUsers( 13780 sUserManager.getUserIds(), true); 13781 } 13782 if ((mPackages.containsKey(childPkg.packageName))) { 13783 childRes.removedInfo = new PackageRemovedInfo(); 13784 childRes.removedInfo.removedPackage = childPkg.packageName; 13785 } 13786 if (res.addedChildPackages == null) { 13787 res.addedChildPackages = new ArrayMap<>(); 13788 } 13789 res.addedChildPackages.put(childPkg.packageName, childRes); 13790 } 13791 } 13792 } 13793 13794 // If package doesn't declare API override, mark that we have an install 13795 // time CPU ABI override. 13796 if (TextUtils.isEmpty(pkg.cpuAbiOverride)) { 13797 pkg.cpuAbiOverride = args.abiOverride; 13798 } 13799 13800 String pkgName = res.name = pkg.packageName; 13801 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) { 13802 if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) { 13803 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI"); 13804 return; 13805 } 13806 } 13807 13808 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates"); 13809 try { 13810 PackageParser.collectCertificates(pkg, parseFlags); 13811 } catch (PackageParserException e) { 13812 res.setError("Failed collect during installPackageLI", e); 13813 return; 13814 } finally { 13815 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13816 } 13817 13818 // Get rid of all references to package scan path via parser. 13819 pp = null; 13820 String oldCodePath = null; 13821 boolean systemApp = false; 13822 synchronized (mPackages) { 13823 // Check if installing already existing package 13824 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 13825 String oldName = mSettings.mRenamedPackages.get(pkgName); 13826 if (pkg.mOriginalPackages != null 13827 && pkg.mOriginalPackages.contains(oldName) 13828 && mPackages.containsKey(oldName)) { 13829 // This package is derived from an original package, 13830 // and this device has been updating from that original 13831 // name. We must continue using the original name, so 13832 // rename the new package here. 13833 pkg.setPackageName(oldName); 13834 pkgName = pkg.packageName; 13835 replace = true; 13836 if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName=" 13837 + oldName + " pkgName=" + pkgName); 13838 } else if (mPackages.containsKey(pkgName)) { 13839 // This package, under its official name, already exists 13840 // on the device; we should replace it. 13841 replace = true; 13842 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName); 13843 } 13844 13845 // Child packages are installed through the parent package 13846 if (pkg.parentPackage != null) { 13847 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME, 13848 "Package " + pkg.packageName + " is child of package " 13849 + pkg.parentPackage.parentPackage + ". Child packages " 13850 + "can be updated only through the parent package."); 13851 return; 13852 } 13853 13854 if (replace) { 13855 // Prevent apps opting out from runtime permissions 13856 PackageParser.Package oldPackage = mPackages.get(pkgName); 13857 final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion; 13858 final int newTargetSdk = pkg.applicationInfo.targetSdkVersion; 13859 if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1 13860 && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) { 13861 res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE, 13862 "Package " + pkg.packageName + " new target SDK " + newTargetSdk 13863 + " doesn't support runtime permissions but the old" 13864 + " target SDK " + oldTargetSdk + " does."); 13865 return; 13866 } 13867 13868 // Prevent installing of child packages 13869 if (oldPackage.parentPackage != null) { 13870 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME, 13871 "Package " + pkg.packageName + " is child of package " 13872 + oldPackage.parentPackage + ". Child packages " 13873 + "can be updated only through the parent package."); 13874 return; 13875 } 13876 } 13877 } 13878 13879 PackageSetting ps = mSettings.mPackages.get(pkgName); 13880 if (ps != null) { 13881 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps); 13882 13883 // Quick sanity check that we're signed correctly if updating; 13884 // we'll check this again later when scanning, but we want to 13885 // bail early here before tripping over redefined permissions. 13886 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { 13887 if (!checkUpgradeKeySetLP(ps, pkg)) { 13888 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 13889 + pkg.packageName + " upgrade keys do not match the " 13890 + "previously installed version"); 13891 return; 13892 } 13893 } else { 13894 try { 13895 verifySignaturesLP(ps, pkg); 13896 } catch (PackageManagerException e) { 13897 res.setError(e.error, e.getMessage()); 13898 return; 13899 } 13900 } 13901 13902 oldCodePath = mSettings.mPackages.get(pkgName).codePathString; 13903 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 13904 systemApp = (ps.pkg.applicationInfo.flags & 13905 ApplicationInfo.FLAG_SYSTEM) != 0; 13906 } 13907 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 13908 } 13909 13910 // Check whether the newly-scanned package wants to define an already-defined perm 13911 int N = pkg.permissions.size(); 13912 for (int i = N-1; i >= 0; i--) { 13913 PackageParser.Permission perm = pkg.permissions.get(i); 13914 BasePermission bp = mSettings.mPermissions.get(perm.info.name); 13915 if (bp != null) { 13916 // If the defining package is signed with our cert, it's okay. This 13917 // also includes the "updating the same package" case, of course. 13918 // "updating same package" could also involve key-rotation. 13919 final boolean sigsOk; 13920 if (bp.sourcePackage.equals(pkg.packageName) 13921 && (bp.packageSetting instanceof PackageSetting) 13922 && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting, 13923 scanFlags))) { 13924 sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg); 13925 } else { 13926 sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures, 13927 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 13928 } 13929 if (!sigsOk) { 13930 // If the owning package is the system itself, we log but allow 13931 // install to proceed; we fail the install on all other permission 13932 // redefinitions. 13933 if (!bp.sourcePackage.equals("android")) { 13934 res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package " 13935 + pkg.packageName + " attempting to redeclare permission " 13936 + perm.info.name + " already owned by " + bp.sourcePackage); 13937 res.origPermission = perm.info.name; 13938 res.origPackage = bp.sourcePackage; 13939 return; 13940 } else { 13941 Slog.w(TAG, "Package " + pkg.packageName 13942 + " attempting to redeclare system permission " 13943 + perm.info.name + "; ignoring new declaration"); 13944 pkg.permissions.remove(i); 13945 } 13946 } 13947 } 13948 } 13949 } 13950 13951 if (systemApp) { 13952 if (onExternal) { 13953 // Abort update; system app can't be replaced with app on sdcard 13954 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION, 13955 "Cannot install updates to system apps on sdcard"); 13956 return; 13957 } else if (ephemeral) { 13958 // Abort update; system app can't be replaced with an ephemeral app 13959 res.setError(INSTALL_FAILED_EPHEMERAL_INVALID, 13960 "Cannot update a system app with an ephemeral app"); 13961 return; 13962 } 13963 } 13964 13965 if (args.move != null) { 13966 // We did an in-place move, so dex is ready to roll 13967 scanFlags |= SCAN_NO_DEX; 13968 scanFlags |= SCAN_MOVE; 13969 13970 synchronized (mPackages) { 13971 final PackageSetting ps = mSettings.mPackages.get(pkgName); 13972 if (ps == null) { 13973 res.setError(INSTALL_FAILED_INTERNAL_ERROR, 13974 "Missing settings for moved package " + pkgName); 13975 } 13976 13977 // We moved the entire application as-is, so bring over the 13978 // previously derived ABI information. 13979 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString; 13980 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString; 13981 } 13982 13983 } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) { 13984 // Enable SCAN_NO_DEX flag to skip dexopt at a later stage 13985 scanFlags |= SCAN_NO_DEX; 13986 13987 try { 13988 String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ? 13989 args.abiOverride : pkg.cpuAbiOverride); 13990 derivePackageAbi(pkg, new File(pkg.codePath), abiOverride, 13991 true /* extract libs */); 13992 } catch (PackageManagerException pme) { 13993 Slog.e(TAG, "Error deriving application ABI", pme); 13994 res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI"); 13995 return; 13996 } 13997 13998 13999 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 14000 // Do not run PackageDexOptimizer through the local performDexOpt 14001 // method because `pkg` is not in `mPackages` yet. 14002 int result = mPackageDexOptimizer.performDexOpt(pkg, null /* instructionSets */, 14003 false /* checkProfiles */, getCompilerFilterForReason(REASON_INSTALL)); 14004 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14005 if (result == PackageDexOptimizer.DEX_OPT_FAILED) { 14006 String msg = "Extracking package failed for " + pkgName; 14007 res.setError(INSTALL_FAILED_DEXOPT, msg); 14008 return; 14009 } 14010 } 14011 14012 if (!args.doRename(res.returnCode, pkg, oldCodePath)) { 14013 res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename"); 14014 return; 14015 } 14016 14017 startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg); 14018 14019 if (replace) { 14020 replacePackageLI(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user, 14021 installerPackageName, res); 14022 } else { 14023 installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES, 14024 args.user, installerPackageName, volumeUuid, res); 14025 } 14026 synchronized (mPackages) { 14027 final PackageSetting ps = mSettings.mPackages.get(pkgName); 14028 if (ps != null) { 14029 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 14030 } 14031 14032 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 14033 for (int i = 0; i < childCount; i++) { 14034 PackageParser.Package childPkg = pkg.childPackages.get(i); 14035 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName); 14036 PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName); 14037 if (childPs != null) { 14038 childRes.newUsers = childPs.queryInstalledUsers( 14039 sUserManager.getUserIds(), true); 14040 } 14041 } 14042 } 14043 } 14044 14045 private void startIntentFilterVerifications(int userId, boolean replacing, 14046 PackageParser.Package pkg) { 14047 if (mIntentFilterVerifierComponent == null) { 14048 Slog.w(TAG, "No IntentFilter verification will not be done as " 14049 + "there is no IntentFilterVerifier available!"); 14050 return; 14051 } 14052 14053 final int verifierUid = getPackageUid( 14054 mIntentFilterVerifierComponent.getPackageName(), 14055 MATCH_DEBUG_TRIAGED_MISSING, 14056 (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId); 14057 14058 Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 14059 msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid); 14060 mHandler.sendMessage(msg); 14061 14062 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 14063 for (int i = 0; i < childCount; i++) { 14064 PackageParser.Package childPkg = pkg.childPackages.get(i); 14065 msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 14066 msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid); 14067 mHandler.sendMessage(msg); 14068 } 14069 } 14070 14071 private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing, 14072 PackageParser.Package pkg) { 14073 int size = pkg.activities.size(); 14074 if (size == 0) { 14075 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 14076 "No activity, so no need to verify any IntentFilter!"); 14077 return; 14078 } 14079 14080 final boolean hasDomainURLs = hasDomainURLs(pkg); 14081 if (!hasDomainURLs) { 14082 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 14083 "No domain URLs, so no need to verify any IntentFilter!"); 14084 return; 14085 } 14086 14087 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId 14088 + " if any IntentFilter from the " + size 14089 + " Activities needs verification ..."); 14090 14091 int count = 0; 14092 final String packageName = pkg.packageName; 14093 14094 synchronized (mPackages) { 14095 // If this is a new install and we see that we've already run verification for this 14096 // package, we have nothing to do: it means the state was restored from backup. 14097 if (!replacing) { 14098 IntentFilterVerificationInfo ivi = 14099 mSettings.getIntentFilterVerificationLPr(packageName); 14100 if (ivi != null) { 14101 if (DEBUG_DOMAIN_VERIFICATION) { 14102 Slog.i(TAG, "Package " + packageName+ " already verified: status=" 14103 + ivi.getStatusString()); 14104 } 14105 return; 14106 } 14107 } 14108 14109 // If any filters need to be verified, then all need to be. 14110 boolean needToVerify = false; 14111 for (PackageParser.Activity a : pkg.activities) { 14112 for (ActivityIntentInfo filter : a.intents) { 14113 if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) { 14114 if (DEBUG_DOMAIN_VERIFICATION) { 14115 Slog.d(TAG, "Intent filter needs verification, so processing all filters"); 14116 } 14117 needToVerify = true; 14118 break; 14119 } 14120 } 14121 } 14122 14123 if (needToVerify) { 14124 final int verificationId = mIntentFilterVerificationToken++; 14125 for (PackageParser.Activity a : pkg.activities) { 14126 for (ActivityIntentInfo filter : a.intents) { 14127 if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) { 14128 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 14129 "Verification needed for IntentFilter:" + filter.toString()); 14130 mIntentFilterVerifier.addOneIntentFilterVerification( 14131 verifierUid, userId, verificationId, filter, packageName); 14132 count++; 14133 } 14134 } 14135 } 14136 } 14137 } 14138 14139 if (count > 0) { 14140 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count 14141 + " IntentFilter verification" + (count > 1 ? "s" : "") 14142 + " for userId:" + userId); 14143 mIntentFilterVerifier.startVerifications(userId); 14144 } else { 14145 if (DEBUG_DOMAIN_VERIFICATION) { 14146 Slog.d(TAG, "No filters or not all autoVerify for " + packageName); 14147 } 14148 } 14149 } 14150 14151 private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) { 14152 final ComponentName cn = filter.activity.getComponentName(); 14153 final String packageName = cn.getPackageName(); 14154 14155 IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr( 14156 packageName); 14157 if (ivi == null) { 14158 return true; 14159 } 14160 int status = ivi.getStatus(); 14161 switch (status) { 14162 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 14163 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 14164 return true; 14165 14166 default: 14167 // Nothing to do 14168 return false; 14169 } 14170 } 14171 14172 private static boolean isMultiArch(ApplicationInfo info) { 14173 return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0; 14174 } 14175 14176 private static boolean isExternal(PackageParser.Package pkg) { 14177 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 14178 } 14179 14180 private static boolean isExternal(PackageSetting ps) { 14181 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 14182 } 14183 14184 private static boolean isEphemeral(PackageParser.Package pkg) { 14185 return pkg.applicationInfo.isEphemeralApp(); 14186 } 14187 14188 private static boolean isEphemeral(PackageSetting ps) { 14189 return ps.pkg != null && isEphemeral(ps.pkg); 14190 } 14191 14192 private static boolean isSystemApp(PackageParser.Package pkg) { 14193 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 14194 } 14195 14196 private static boolean isPrivilegedApp(PackageParser.Package pkg) { 14197 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; 14198 } 14199 14200 private static boolean hasDomainURLs(PackageParser.Package pkg) { 14201 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0; 14202 } 14203 14204 private static boolean isSystemApp(PackageSetting ps) { 14205 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0; 14206 } 14207 14208 private static boolean isUpdatedSystemApp(PackageSetting ps) { 14209 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; 14210 } 14211 14212 private int packageFlagsToInstallFlags(PackageSetting ps) { 14213 int installFlags = 0; 14214 if (isEphemeral(ps)) { 14215 installFlags |= PackageManager.INSTALL_EPHEMERAL; 14216 } 14217 if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) { 14218 // This existing package was an external ASEC install when we have 14219 // the external flag without a UUID 14220 installFlags |= PackageManager.INSTALL_EXTERNAL; 14221 } 14222 if (ps.isForwardLocked()) { 14223 installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 14224 } 14225 return installFlags; 14226 } 14227 14228 private String getVolumeUuidForPackage(PackageParser.Package pkg) { 14229 if (isExternal(pkg)) { 14230 if (TextUtils.isEmpty(pkg.volumeUuid)) { 14231 return StorageManager.UUID_PRIMARY_PHYSICAL; 14232 } else { 14233 return pkg.volumeUuid; 14234 } 14235 } else { 14236 return StorageManager.UUID_PRIVATE_INTERNAL; 14237 } 14238 } 14239 14240 private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) { 14241 if (isExternal(pkg)) { 14242 if (TextUtils.isEmpty(pkg.volumeUuid)) { 14243 return mSettings.getExternalVersion(); 14244 } else { 14245 return mSettings.findOrCreateVersion(pkg.volumeUuid); 14246 } 14247 } else { 14248 return mSettings.getInternalVersion(); 14249 } 14250 } 14251 14252 private void deleteTempPackageFiles() { 14253 final FilenameFilter filter = new FilenameFilter() { 14254 public boolean accept(File dir, String name) { 14255 return name.startsWith("vmdl") && name.endsWith(".tmp"); 14256 } 14257 }; 14258 for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) { 14259 file.delete(); 14260 } 14261 } 14262 14263 @Override 14264 public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId, 14265 int flags) { 14266 deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId, 14267 flags); 14268 } 14269 14270 @Override 14271 public void deletePackage(final String packageName, 14272 final IPackageDeleteObserver2 observer, final int userId, final int flags) { 14273 mContext.enforceCallingOrSelfPermission( 14274 android.Manifest.permission.DELETE_PACKAGES, null); 14275 Preconditions.checkNotNull(packageName); 14276 Preconditions.checkNotNull(observer); 14277 final int uid = Binder.getCallingUid(); 14278 final boolean deleteAllUsers = (flags & PackageManager.DELETE_ALL_USERS) != 0; 14279 final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId }; 14280 if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) { 14281 mContext.enforceCallingOrSelfPermission( 14282 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 14283 "deletePackage for user " + userId); 14284 } 14285 14286 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) { 14287 try { 14288 observer.onPackageDeleted(packageName, 14289 PackageManager.DELETE_FAILED_USER_RESTRICTED, null); 14290 } catch (RemoteException re) { 14291 } 14292 return; 14293 } 14294 14295 if (!deleteAllUsers && getBlockUninstallForUser(packageName, userId)) { 14296 try { 14297 observer.onPackageDeleted(packageName, 14298 PackageManager.DELETE_FAILED_OWNER_BLOCKED, null); 14299 } catch (RemoteException re) { 14300 } 14301 return; 14302 } 14303 14304 if (DEBUG_REMOVE) { 14305 Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId 14306 + " deleteAllUsers: " + deleteAllUsers ); 14307 } 14308 // Queue up an async operation since the package deletion may take a little while. 14309 mHandler.post(new Runnable() { 14310 public void run() { 14311 mHandler.removeCallbacks(this); 14312 int returnCode; 14313 if (!deleteAllUsers) { 14314 returnCode = deletePackageX(packageName, userId, flags); 14315 } else { 14316 int[] blockUninstallUserIds = getBlockUninstallForUsers(packageName, users); 14317 // If nobody is blocking uninstall, proceed with delete for all users 14318 if (ArrayUtils.isEmpty(blockUninstallUserIds)) { 14319 returnCode = deletePackageX(packageName, userId, flags); 14320 } else { 14321 // Otherwise uninstall individually for users with blockUninstalls=false 14322 final int userFlags = flags & ~PackageManager.DELETE_ALL_USERS; 14323 for (int userId : users) { 14324 if (!ArrayUtils.contains(blockUninstallUserIds, userId)) { 14325 returnCode = deletePackageX(packageName, userId, userFlags); 14326 if (returnCode != PackageManager.DELETE_SUCCEEDED) { 14327 Slog.w(TAG, "Package delete failed for user " + userId 14328 + ", returnCode " + returnCode); 14329 } 14330 } 14331 } 14332 // The app has only been marked uninstalled for certain users. 14333 // We still need to report that delete was blocked 14334 returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED; 14335 } 14336 } 14337 try { 14338 observer.onPackageDeleted(packageName, returnCode, null); 14339 } catch (RemoteException e) { 14340 Log.i(TAG, "Observer no longer exists."); 14341 } //end catch 14342 } //end run 14343 }); 14344 } 14345 14346 private int[] getBlockUninstallForUsers(String packageName, int[] userIds) { 14347 int[] result = EMPTY_INT_ARRAY; 14348 for (int userId : userIds) { 14349 if (getBlockUninstallForUser(packageName, userId)) { 14350 result = ArrayUtils.appendInt(result, userId); 14351 } 14352 } 14353 return result; 14354 } 14355 14356 @Override 14357 public boolean isPackageDeviceAdminOnAnyUser(String packageName) { 14358 return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL); 14359 } 14360 14361 private boolean isPackageDeviceAdmin(String packageName, int userId) { 14362 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface( 14363 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); 14364 try { 14365 if (dpm != null) { 14366 final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent( 14367 /* callingUserOnly =*/ false); 14368 final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null 14369 : deviceOwnerComponentName.getPackageName(); 14370 // Does the package contains the device owner? 14371 // TODO Do we have to do it even if userId != UserHandle.USER_ALL? Otherwise, 14372 // this check is probably not needed, since DO should be registered as a device 14373 // admin on some user too. (Original bug for this: b/17657954) 14374 if (packageName.equals(deviceOwnerPackageName)) { 14375 return true; 14376 } 14377 // Does it contain a device admin for any user? 14378 int[] users; 14379 if (userId == UserHandle.USER_ALL) { 14380 users = sUserManager.getUserIds(); 14381 } else { 14382 users = new int[]{userId}; 14383 } 14384 for (int i = 0; i < users.length; ++i) { 14385 if (dpm.packageHasActiveAdmins(packageName, users[i])) { 14386 return true; 14387 } 14388 } 14389 } 14390 } catch (RemoteException e) { 14391 } 14392 return false; 14393 } 14394 14395 private boolean shouldKeepUninstalledPackageLPr(String packageName) { 14396 return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName); 14397 } 14398 14399 /** 14400 * This method is an internal method that could be get invoked either 14401 * to delete an installed package or to clean up a failed installation. 14402 * After deleting an installed package, a broadcast is sent to notify any 14403 * listeners that the package has been installed. For cleaning up a failed 14404 * installation, the broadcast is not necessary since the package's 14405 * installation wouldn't have sent the initial broadcast either 14406 * The key steps in deleting a package are 14407 * deleting the package information in internal structures like mPackages, 14408 * deleting the packages base directories through installd 14409 * updating mSettings to reflect current status 14410 * persisting settings for later use 14411 * sending a broadcast if necessary 14412 */ 14413 private int deletePackageX(String packageName, int userId, int flags) { 14414 final PackageRemovedInfo info = new PackageRemovedInfo(); 14415 final boolean res; 14416 14417 final UserHandle removeForUser = (flags & PackageManager.DELETE_ALL_USERS) != 0 14418 ? UserHandle.ALL : new UserHandle(userId); 14419 14420 if (isPackageDeviceAdmin(packageName, removeForUser.getIdentifier())) { 14421 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin"); 14422 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER; 14423 } 14424 14425 PackageSetting uninstalledPs = null; 14426 14427 // for the uninstall-updates case and restricted profiles, remember the per- 14428 // user handle installed state 14429 int[] allUsers; 14430 synchronized (mPackages) { 14431 uninstalledPs = mSettings.mPackages.get(packageName); 14432 if (uninstalledPs == null) { 14433 Slog.w(TAG, "Not removing non-existent package " + packageName); 14434 return PackageManager.DELETE_FAILED_INTERNAL_ERROR; 14435 } 14436 allUsers = sUserManager.getUserIds(); 14437 info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true); 14438 } 14439 14440 synchronized (mInstallLock) { 14441 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId); 14442 res = deletePackageLI(packageName, removeForUser, true, allUsers, 14443 flags | REMOVE_CHATTY, info, true, null); 14444 synchronized (mPackages) { 14445 if (res) { 14446 mEphemeralApplicationRegistry.onPackageUninstalledLPw(uninstalledPs.pkg); 14447 } 14448 } 14449 } 14450 14451 if (res) { 14452 final boolean killApp = (flags & PackageManager.INSTALL_DONT_KILL_APP) == 0; 14453 info.sendPackageRemovedBroadcasts(killApp); 14454 info.sendSystemPackageUpdatedBroadcasts(); 14455 info.sendSystemPackageAppearedBroadcasts(); 14456 } 14457 // Force a gc here. 14458 Runtime.getRuntime().gc(); 14459 // Delete the resources here after sending the broadcast to let 14460 // other processes clean up before deleting resources. 14461 if (info.args != null) { 14462 synchronized (mInstallLock) { 14463 info.args.doPostDeleteLI(true); 14464 } 14465 } 14466 14467 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR; 14468 } 14469 14470 class PackageRemovedInfo { 14471 String removedPackage; 14472 int uid = -1; 14473 int removedAppId = -1; 14474 int[] origUsers; 14475 int[] removedUsers = null; 14476 boolean isRemovedPackageSystemUpdate = false; 14477 boolean isUpdate; 14478 boolean dataRemoved; 14479 boolean removedForAllUsers; 14480 // Clean up resources deleted packages. 14481 InstallArgs args = null; 14482 ArrayMap<String, PackageRemovedInfo> removedChildPackages; 14483 ArrayMap<String, PackageInstalledInfo> appearedChildPackages; 14484 14485 void sendPackageRemovedBroadcasts(boolean killApp) { 14486 sendPackageRemovedBroadcastInternal(killApp); 14487 final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0; 14488 for (int i = 0; i < childCount; i++) { 14489 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i); 14490 childInfo.sendPackageRemovedBroadcastInternal(killApp); 14491 } 14492 } 14493 14494 void sendSystemPackageUpdatedBroadcasts() { 14495 if (isRemovedPackageSystemUpdate) { 14496 sendSystemPackageUpdatedBroadcastsInternal(); 14497 final int childCount = (removedChildPackages != null) 14498 ? removedChildPackages.size() : 0; 14499 for (int i = 0; i < childCount; i++) { 14500 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i); 14501 if (childInfo.isRemovedPackageSystemUpdate) { 14502 childInfo.sendSystemPackageUpdatedBroadcastsInternal(); 14503 } 14504 } 14505 } 14506 } 14507 14508 void sendSystemPackageAppearedBroadcasts() { 14509 final int packageCount = (appearedChildPackages != null) 14510 ? appearedChildPackages.size() : 0; 14511 for (int i = 0; i < packageCount; i++) { 14512 PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i); 14513 for (int userId : installedInfo.newUsers) { 14514 sendPackageAddedForUser(installedInfo.name, true, 14515 UserHandle.getAppId(installedInfo.uid), userId); 14516 } 14517 } 14518 } 14519 14520 private void sendSystemPackageUpdatedBroadcastsInternal() { 14521 Bundle extras = new Bundle(2); 14522 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 14523 extras.putBoolean(Intent.EXTRA_REPLACING, true); 14524 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, removedPackage, 14525 extras, 0, null, null, null); 14526 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, removedPackage, 14527 extras, 0, null, null, null); 14528 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null, 14529 null, 0, removedPackage, null, null); 14530 } 14531 14532 private void sendPackageRemovedBroadcastInternal(boolean killApp) { 14533 Bundle extras = new Bundle(2); 14534 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 14535 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved); 14536 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp); 14537 if (isUpdate || isRemovedPackageSystemUpdate) { 14538 extras.putBoolean(Intent.EXTRA_REPLACING, true); 14539 } 14540 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers); 14541 if (removedPackage != null) { 14542 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, 14543 extras, 0, null, null, removedUsers); 14544 if (dataRemoved && !isRemovedPackageSystemUpdate) { 14545 sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, 14546 removedPackage, extras, 0, null, null, removedUsers); 14547 } 14548 } 14549 if (removedAppId >= 0) { 14550 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, 0, null, null, 14551 removedUsers); 14552 } 14553 } 14554 } 14555 14556 /* 14557 * This method deletes the package from internal data structures. If the DONT_DELETE_DATA 14558 * flag is not set, the data directory is removed as well. 14559 * make sure this flag is set for partially installed apps. If not its meaningless to 14560 * delete a partially installed application. 14561 */ 14562 private void removePackageDataLI(PackageSetting ps, int[] allUserHandles, 14563 PackageRemovedInfo outInfo, int flags, boolean writeSettings) { 14564 String packageName = ps.name; 14565 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps); 14566 removePackageLI(ps, (flags&REMOVE_CHATTY) != 0); 14567 // Retrieve object to delete permissions for shared user later on 14568 final PackageSetting deletedPs; 14569 // reader 14570 synchronized (mPackages) { 14571 deletedPs = mSettings.mPackages.get(packageName); 14572 if (outInfo != null) { 14573 outInfo.removedPackage = packageName; 14574 outInfo.removedUsers = deletedPs != null 14575 ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true) 14576 : null; 14577 } 14578 } 14579 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 14580 removeDataDirsLI(ps.volumeUuid, packageName); 14581 if (outInfo != null) { 14582 outInfo.dataRemoved = true; 14583 } 14584 schedulePackageCleaning(packageName, UserHandle.USER_ALL, true); 14585 } 14586 // writer 14587 synchronized (mPackages) { 14588 if (deletedPs != null) { 14589 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 14590 clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL); 14591 clearDefaultBrowserIfNeeded(packageName); 14592 if (outInfo != null) { 14593 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName); 14594 outInfo.removedAppId = mSettings.removePackageLPw(packageName); 14595 } 14596 updatePermissionsLPw(deletedPs.name, null, 0); 14597 if (deletedPs.sharedUser != null) { 14598 // Remove permissions associated with package. Since runtime 14599 // permissions are per user we have to kill the removed package 14600 // or packages running under the shared user of the removed 14601 // package if revoking the permissions requested only by the removed 14602 // package is successful and this causes a change in gids. 14603 for (int userId : UserManagerService.getInstance().getUserIds()) { 14604 final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs, 14605 userId); 14606 if (userIdToKill == UserHandle.USER_ALL 14607 || userIdToKill >= UserHandle.USER_SYSTEM) { 14608 // If gids changed for this user, kill all affected packages. 14609 mHandler.post(new Runnable() { 14610 @Override 14611 public void run() { 14612 // This has to happen with no lock held. 14613 killApplication(deletedPs.name, deletedPs.appId, 14614 KILL_APP_REASON_GIDS_CHANGED); 14615 } 14616 }); 14617 break; 14618 } 14619 } 14620 } 14621 clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL); 14622 } 14623 // make sure to preserve per-user disabled state if this removal was just 14624 // a downgrade of a system app to the factory package 14625 if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) { 14626 if (DEBUG_REMOVE) { 14627 Slog.d(TAG, "Propagating install state across downgrade"); 14628 } 14629 for (int userId : allUserHandles) { 14630 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId); 14631 if (DEBUG_REMOVE) { 14632 Slog.d(TAG, " user " + userId + " => " + installed); 14633 } 14634 ps.setInstalled(installed, userId); 14635 } 14636 } 14637 } 14638 // can downgrade to reader 14639 if (writeSettings) { 14640 // Save settings now 14641 mSettings.writeLPr(); 14642 } 14643 } 14644 if (outInfo != null) { 14645 // A user ID was deleted here. Go through all users and remove it 14646 // from KeyStore. 14647 removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId); 14648 } 14649 } 14650 14651 static boolean locationIsPrivileged(File path) { 14652 try { 14653 final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app") 14654 .getCanonicalPath(); 14655 return path.getCanonicalPath().startsWith(privilegedAppDir); 14656 } catch (IOException e) { 14657 Slog.e(TAG, "Unable to access code path " + path); 14658 } 14659 return false; 14660 } 14661 14662 /* 14663 * Tries to delete system package. 14664 */ 14665 private boolean deleteSystemPackageLI(PackageParser.Package deletedPkg, 14666 PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo, 14667 boolean writeSettings) { 14668 if (deletedPs.parentPackageName != null) { 14669 Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName); 14670 return false; 14671 } 14672 14673 final boolean applyUserRestrictions 14674 = (allUserHandles != null) && (outInfo.origUsers != null); 14675 final PackageSetting disabledPs; 14676 // Confirm if the system package has been updated 14677 // An updated system app can be deleted. This will also have to restore 14678 // the system pkg from system partition 14679 // reader 14680 synchronized (mPackages) { 14681 disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name); 14682 } 14683 14684 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName 14685 + " disabledPs=" + disabledPs); 14686 14687 if (disabledPs == null) { 14688 Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName); 14689 return false; 14690 } else if (DEBUG_REMOVE) { 14691 Slog.d(TAG, "Deleting system pkg from data partition"); 14692 } 14693 14694 if (DEBUG_REMOVE) { 14695 if (applyUserRestrictions) { 14696 Slog.d(TAG, "Remembering install states:"); 14697 for (int userId : allUserHandles) { 14698 final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId); 14699 Slog.d(TAG, " u=" + userId + " inst=" + finstalled); 14700 } 14701 } 14702 } 14703 14704 // Delete the updated package 14705 outInfo.isRemovedPackageSystemUpdate = true; 14706 if (outInfo.removedChildPackages != null) { 14707 final int childCount = (deletedPs.childPackageNames != null) 14708 ? deletedPs.childPackageNames.size() : 0; 14709 for (int i = 0; i < childCount; i++) { 14710 String childPackageName = deletedPs.childPackageNames.get(i); 14711 if (disabledPs.childPackageNames != null && disabledPs.childPackageNames 14712 .contains(childPackageName)) { 14713 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get( 14714 childPackageName); 14715 if (childInfo != null) { 14716 childInfo.isRemovedPackageSystemUpdate = true; 14717 } 14718 } 14719 } 14720 } 14721 14722 if (disabledPs.versionCode < deletedPs.versionCode) { 14723 // Delete data for downgrades 14724 flags &= ~PackageManager.DELETE_KEEP_DATA; 14725 } else { 14726 // Preserve data by setting flag 14727 flags |= PackageManager.DELETE_KEEP_DATA; 14728 } 14729 14730 boolean ret = deleteInstalledPackageLI(deletedPs, true, flags, allUserHandles, 14731 outInfo, writeSettings, disabledPs.pkg); 14732 if (!ret) { 14733 return false; 14734 } 14735 14736 // writer 14737 synchronized (mPackages) { 14738 // Reinstate the old system package 14739 enableSystemPackageLPw(disabledPs.pkg); 14740 // Remove any native libraries from the upgraded package. 14741 removeNativeBinariesLI(deletedPs); 14742 } 14743 14744 // Install the system package 14745 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs); 14746 int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM; 14747 if (locationIsPrivileged(disabledPs.codePath)) { 14748 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 14749 } 14750 14751 final PackageParser.Package newPkg; 14752 try { 14753 newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null); 14754 } catch (PackageManagerException e) { 14755 Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": " 14756 + e.getMessage()); 14757 return false; 14758 } 14759 14760 prepareAppDataAfterInstall(newPkg); 14761 14762 // writer 14763 synchronized (mPackages) { 14764 PackageSetting ps = mSettings.mPackages.get(newPkg.packageName); 14765 14766 // Propagate the permissions state as we do not want to drop on the floor 14767 // runtime permissions. The update permissions method below will take 14768 // care of removing obsolete permissions and grant install permissions. 14769 ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState()); 14770 updatePermissionsLPw(newPkg.packageName, newPkg, 14771 UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG); 14772 14773 if (applyUserRestrictions) { 14774 if (DEBUG_REMOVE) { 14775 Slog.d(TAG, "Propagating install state across reinstall"); 14776 } 14777 for (int userId : allUserHandles) { 14778 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId); 14779 if (DEBUG_REMOVE) { 14780 Slog.d(TAG, " user " + userId + " => " + installed); 14781 } 14782 ps.setInstalled(installed, userId); 14783 14784 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 14785 } 14786 // Regardless of writeSettings we need to ensure that this restriction 14787 // state propagation is persisted 14788 mSettings.writeAllUsersPackageRestrictionsLPr(); 14789 } 14790 // can downgrade to reader here 14791 if (writeSettings) { 14792 mSettings.writeLPr(); 14793 } 14794 } 14795 return true; 14796 } 14797 14798 private boolean deleteInstalledPackageLI(PackageSetting ps, 14799 boolean deleteCodeAndResources, int flags, int[] allUserHandles, 14800 PackageRemovedInfo outInfo, boolean writeSettings, 14801 PackageParser.Package replacingPackage) { 14802 synchronized (mPackages) { 14803 if (outInfo != null) { 14804 outInfo.uid = ps.appId; 14805 } 14806 14807 if (outInfo != null && outInfo.removedChildPackages != null) { 14808 final int childCount = (ps.childPackageNames != null) 14809 ? ps.childPackageNames.size() : 0; 14810 for (int i = 0; i < childCount; i++) { 14811 String childPackageName = ps.childPackageNames.get(i); 14812 PackageSetting childPs = mSettings.mPackages.get(childPackageName); 14813 if (childPs == null) { 14814 return false; 14815 } 14816 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get( 14817 childPackageName); 14818 if (childInfo != null) { 14819 childInfo.uid = childPs.appId; 14820 } 14821 } 14822 } 14823 } 14824 14825 // Delete package data from internal structures and also remove data if flag is set 14826 removePackageDataLI(ps, allUserHandles, outInfo, flags, writeSettings); 14827 14828 // Delete the child packages data 14829 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0; 14830 for (int i = 0; i < childCount; i++) { 14831 PackageSetting childPs; 14832 synchronized (mPackages) { 14833 childPs = mSettings.peekPackageLPr(ps.childPackageNames.get(i)); 14834 } 14835 if (childPs != null) { 14836 PackageRemovedInfo childOutInfo = (outInfo != null 14837 && outInfo.removedChildPackages != null) 14838 ? outInfo.removedChildPackages.get(childPs.name) : null; 14839 final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0 14840 && (replacingPackage != null 14841 && !replacingPackage.hasChildPackage(childPs.name)) 14842 ? flags & ~DELETE_KEEP_DATA : flags; 14843 removePackageDataLI(childPs, allUserHandles, childOutInfo, 14844 deleteFlags, writeSettings); 14845 } 14846 } 14847 14848 // Delete application code and resources only for parent packages 14849 if (ps.parentPackageName == null) { 14850 if (deleteCodeAndResources && (outInfo != null)) { 14851 outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 14852 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 14853 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args); 14854 } 14855 } 14856 14857 return true; 14858 } 14859 14860 @Override 14861 public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall, 14862 int userId) { 14863 mContext.enforceCallingOrSelfPermission( 14864 android.Manifest.permission.DELETE_PACKAGES, null); 14865 synchronized (mPackages) { 14866 PackageSetting ps = mSettings.mPackages.get(packageName); 14867 if (ps == null) { 14868 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName); 14869 return false; 14870 } 14871 if (!ps.getInstalled(userId)) { 14872 // Can't block uninstall for an app that is not installed or enabled. 14873 Log.i(TAG, "Package not installed in set block uninstall " + packageName); 14874 return false; 14875 } 14876 ps.setBlockUninstall(blockUninstall, userId); 14877 mSettings.writePackageRestrictionsLPr(userId); 14878 } 14879 return true; 14880 } 14881 14882 @Override 14883 public boolean getBlockUninstallForUser(String packageName, int userId) { 14884 synchronized (mPackages) { 14885 PackageSetting ps = mSettings.mPackages.get(packageName); 14886 if (ps == null) { 14887 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName); 14888 return false; 14889 } 14890 return ps.getBlockUninstall(userId); 14891 } 14892 } 14893 14894 @Override 14895 public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) { 14896 int callingUid = Binder.getCallingUid(); 14897 if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) { 14898 throw new SecurityException( 14899 "setRequiredForSystemUser can only be run by the system or root"); 14900 } 14901 synchronized (mPackages) { 14902 PackageSetting ps = mSettings.mPackages.get(packageName); 14903 if (ps == null) { 14904 Log.w(TAG, "Package doesn't exist: " + packageName); 14905 return false; 14906 } 14907 if (systemUserApp) { 14908 ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER; 14909 } else { 14910 ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER; 14911 } 14912 mSettings.writeLPr(); 14913 } 14914 return true; 14915 } 14916 14917 /* 14918 * This method handles package deletion in general 14919 */ 14920 private boolean deletePackageLI(String packageName, UserHandle user, 14921 boolean deleteCodeAndResources, int[] allUserHandles, int flags, 14922 PackageRemovedInfo outInfo, boolean writeSettings, 14923 PackageParser.Package replacingPackage) { 14924 if (packageName == null) { 14925 Slog.w(TAG, "Attempt to delete null packageName."); 14926 return false; 14927 } 14928 14929 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user); 14930 14931 PackageSetting ps; 14932 14933 synchronized (mPackages) { 14934 ps = mSettings.mPackages.get(packageName); 14935 if (ps == null) { 14936 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 14937 return false; 14938 } 14939 14940 if (ps.parentPackageName != null && (!isSystemApp(ps) 14941 || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) { 14942 if (DEBUG_REMOVE) { 14943 Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:" 14944 + ((user == null) ? UserHandle.USER_ALL : user)); 14945 } 14946 final int removedUserId = (user != null) ? user.getIdentifier() 14947 : UserHandle.USER_ALL; 14948 if (!clearPackageStateForUser(ps, removedUserId, outInfo)) { 14949 return false; 14950 } 14951 markPackageUninstalledForUserLPw(ps, user); 14952 scheduleWritePackageRestrictionsLocked(user); 14953 return true; 14954 } 14955 } 14956 14957 if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null 14958 && user.getIdentifier() != UserHandle.USER_ALL)) { 14959 // The caller is asking that the package only be deleted for a single 14960 // user. To do this, we just mark its uninstalled state and delete 14961 // its data. If this is a system app, we only allow this to happen if 14962 // they have set the special DELETE_SYSTEM_APP which requests different 14963 // semantics than normal for uninstalling system apps. 14964 markPackageUninstalledForUserLPw(ps, user); 14965 14966 if (!isSystemApp(ps)) { 14967 // Do not uninstall the APK if an app should be cached 14968 boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName); 14969 if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) { 14970 // Other user still have this package installed, so all 14971 // we need to do is clear this user's data and save that 14972 // it is uninstalled. 14973 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users"); 14974 if (!clearPackageStateForUser(ps, user.getIdentifier(), outInfo)) { 14975 return false; 14976 } 14977 scheduleWritePackageRestrictionsLocked(user); 14978 return true; 14979 } else { 14980 // We need to set it back to 'installed' so the uninstall 14981 // broadcasts will be sent correctly. 14982 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete"); 14983 ps.setInstalled(true, user.getIdentifier()); 14984 } 14985 } else { 14986 // This is a system app, so we assume that the 14987 // other users still have this package installed, so all 14988 // we need to do is clear this user's data and save that 14989 // it is uninstalled. 14990 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app"); 14991 if (!clearPackageStateForUser(ps, user.getIdentifier(), outInfo)) { 14992 return false; 14993 } 14994 scheduleWritePackageRestrictionsLocked(user); 14995 return true; 14996 } 14997 } 14998 14999 // If we are deleting a composite package for all users, keep track 15000 // of result for each child. 15001 if (ps.childPackageNames != null && outInfo != null) { 15002 synchronized (mPackages) { 15003 final int childCount = ps.childPackageNames.size(); 15004 outInfo.removedChildPackages = new ArrayMap<>(childCount); 15005 for (int i = 0; i < childCount; i++) { 15006 String childPackageName = ps.childPackageNames.get(i); 15007 PackageRemovedInfo childInfo = new PackageRemovedInfo(); 15008 childInfo.removedPackage = childPackageName; 15009 outInfo.removedChildPackages.put(childPackageName, childInfo); 15010 PackageSetting childPs = mSettings.peekPackageLPr(childPackageName); 15011 if (childPs != null) { 15012 childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true); 15013 } 15014 } 15015 } 15016 } 15017 15018 boolean ret = false; 15019 if (isSystemApp(ps)) { 15020 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name); 15021 // When an updated system application is deleted we delete the existing resources 15022 // as well and fall back to existing code in system partition 15023 ret = deleteSystemPackageLI(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings); 15024 } else { 15025 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name); 15026 // Kill application pre-emptively especially for apps on sd. 15027 final boolean killApp = (flags & PackageManager.DELETE_DONT_KILL_APP) == 0; 15028 if (killApp) { 15029 killApplication(packageName, ps.appId, "uninstall pkg"); 15030 } 15031 ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags, allUserHandles, 15032 outInfo, writeSettings, replacingPackage); 15033 } 15034 15035 // Take a note whether we deleted the package for all users 15036 if (outInfo != null) { 15037 outInfo.removedForAllUsers = mPackages.get(ps.name) == null; 15038 if (outInfo.removedChildPackages != null) { 15039 synchronized (mPackages) { 15040 final int childCount = outInfo.removedChildPackages.size(); 15041 for (int i = 0; i < childCount; i++) { 15042 PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i); 15043 if (childInfo != null) { 15044 childInfo.removedForAllUsers = mPackages.get( 15045 childInfo.removedPackage) == null; 15046 } 15047 } 15048 } 15049 } 15050 // If we uninstalled an update to a system app there may be some 15051 // child packages that appeared as they are declared in the system 15052 // app but were not declared in the update. 15053 if (isSystemApp(ps)) { 15054 synchronized (mPackages) { 15055 PackageSetting updatedPs = mSettings.peekPackageLPr(ps.name); 15056 final int childCount = (updatedPs.childPackageNames != null) 15057 ? updatedPs.childPackageNames.size() : 0; 15058 for (int i = 0; i < childCount; i++) { 15059 String childPackageName = updatedPs.childPackageNames.get(i); 15060 if (outInfo.removedChildPackages == null 15061 || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) { 15062 PackageSetting childPs = mSettings.peekPackageLPr(childPackageName); 15063 if (childPs == null) { 15064 continue; 15065 } 15066 PackageInstalledInfo installRes = new PackageInstalledInfo(); 15067 installRes.name = childPackageName; 15068 installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true); 15069 installRes.pkg = mPackages.get(childPackageName); 15070 installRes.uid = childPs.pkg.applicationInfo.uid; 15071 if (outInfo.appearedChildPackages == null) { 15072 outInfo.appearedChildPackages = new ArrayMap<>(); 15073 } 15074 outInfo.appearedChildPackages.put(childPackageName, installRes); 15075 } 15076 } 15077 } 15078 } 15079 } 15080 15081 return ret; 15082 } 15083 15084 private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) { 15085 final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL) 15086 ? sUserManager.getUserIds() : new int[] {user.getIdentifier()}; 15087 for (int nextUserId : userIds) { 15088 if (DEBUG_REMOVE) { 15089 Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId); 15090 } 15091 ps.setUserState(nextUserId, COMPONENT_ENABLED_STATE_DEFAULT, 15092 false /*installed*/, true /*stopped*/, true /*notLaunched*/, 15093 false /*hidden*/, false /*suspended*/, null, null, null, 15094 false /*blockUninstall*/, 15095 ps.readUserState(nextUserId).domainVerificationStatus, 0); 15096 } 15097 } 15098 15099 private boolean clearPackageStateForUser(PackageSetting ps, int userId, 15100 PackageRemovedInfo outInfo) { 15101 final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() 15102 : new int[] {userId}; 15103 for (int nextUserId : userIds) { 15104 if (DEBUG_REMOVE) { 15105 Slog.d(TAG, "Updating package:" + ps.name + " install state for user:" 15106 + nextUserId); 15107 } 15108 final int flags = StorageManager.FLAG_STORAGE_CE| StorageManager.FLAG_STORAGE_DE; 15109 try { 15110 mInstaller.destroyAppData(ps.volumeUuid, ps.name, nextUserId, flags); 15111 } catch (InstallerException e) { 15112 Slog.w(TAG, "Couldn't remove cache files for package " + ps.name, e); 15113 return false; 15114 } 15115 removeKeystoreDataIfNeeded(nextUserId, ps.appId); 15116 schedulePackageCleaning(ps.name, nextUserId, false); 15117 synchronized (mPackages) { 15118 if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) { 15119 scheduleWritePackageRestrictionsLocked(nextUserId); 15120 } 15121 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId); 15122 } 15123 } 15124 15125 if (outInfo != null) { 15126 outInfo.removedPackage = ps.name; 15127 outInfo.removedAppId = ps.appId; 15128 outInfo.removedUsers = userIds; 15129 } 15130 15131 return true; 15132 } 15133 15134 private final class ClearStorageConnection implements ServiceConnection { 15135 IMediaContainerService mContainerService; 15136 15137 @Override 15138 public void onServiceConnected(ComponentName name, IBinder service) { 15139 synchronized (this) { 15140 mContainerService = IMediaContainerService.Stub.asInterface(service); 15141 notifyAll(); 15142 } 15143 } 15144 15145 @Override 15146 public void onServiceDisconnected(ComponentName name) { 15147 } 15148 } 15149 15150 private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) { 15151 final boolean mounted; 15152 if (Environment.isExternalStorageEmulated()) { 15153 mounted = true; 15154 } else { 15155 final String status = Environment.getExternalStorageState(); 15156 15157 mounted = status.equals(Environment.MEDIA_MOUNTED) 15158 || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY); 15159 } 15160 15161 if (!mounted) { 15162 return; 15163 } 15164 15165 final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 15166 int[] users; 15167 if (userId == UserHandle.USER_ALL) { 15168 users = sUserManager.getUserIds(); 15169 } else { 15170 users = new int[] { userId }; 15171 } 15172 final ClearStorageConnection conn = new ClearStorageConnection(); 15173 if (mContext.bindServiceAsUser( 15174 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) { 15175 try { 15176 for (int curUser : users) { 15177 long timeout = SystemClock.uptimeMillis() + 5000; 15178 synchronized (conn) { 15179 long now = SystemClock.uptimeMillis(); 15180 while (conn.mContainerService == null && now < timeout) { 15181 try { 15182 conn.wait(timeout - now); 15183 } catch (InterruptedException e) { 15184 } 15185 } 15186 } 15187 if (conn.mContainerService == null) { 15188 return; 15189 } 15190 15191 final UserEnvironment userEnv = new UserEnvironment(curUser); 15192 clearDirectory(conn.mContainerService, 15193 userEnv.buildExternalStorageAppCacheDirs(packageName)); 15194 if (allData) { 15195 clearDirectory(conn.mContainerService, 15196 userEnv.buildExternalStorageAppDataDirs(packageName)); 15197 clearDirectory(conn.mContainerService, 15198 userEnv.buildExternalStorageAppMediaDirs(packageName)); 15199 } 15200 } 15201 } finally { 15202 mContext.unbindService(conn); 15203 } 15204 } 15205 } 15206 15207 @Override 15208 public void clearApplicationProfileData(String packageName) { 15209 enforceSystemOrRoot("Only the system can clear all profile data"); 15210 try { 15211 mInstaller.rmProfiles(packageName); 15212 } catch (InstallerException ex) { 15213 Log.e(TAG, "Could not clear profile data of package " + packageName); 15214 } 15215 } 15216 15217 @Override 15218 public void clearApplicationUserData(final String packageName, 15219 final IPackageDataObserver observer, final int userId) { 15220 mContext.enforceCallingOrSelfPermission( 15221 android.Manifest.permission.CLEAR_APP_USER_DATA, null); 15222 15223 enforceCrossUserPermission(Binder.getCallingUid(), userId, 15224 true /* requireFullPermission */, false /* checkShell */, "clear application data"); 15225 15226 final DevicePolicyManagerInternal dpmi = LocalServices 15227 .getService(DevicePolicyManagerInternal.class); 15228 if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) { 15229 throw new SecurityException("Cannot clear data for a device owner or a profile owner"); 15230 } 15231 // Queue up an async operation since the package deletion may take a little while. 15232 mHandler.post(new Runnable() { 15233 public void run() { 15234 mHandler.removeCallbacks(this); 15235 final boolean succeeded; 15236 synchronized (mInstallLock) { 15237 succeeded = clearApplicationUserDataLI(packageName, userId); 15238 } 15239 clearExternalStorageDataSync(packageName, userId, true); 15240 if (succeeded) { 15241 // invoke DeviceStorageMonitor's update method to clear any notifications 15242 DeviceStorageMonitorInternal dsm = LocalServices 15243 .getService(DeviceStorageMonitorInternal.class); 15244 if (dsm != null) { 15245 dsm.checkMemory(); 15246 } 15247 } 15248 if(observer != null) { 15249 try { 15250 observer.onRemoveCompleted(packageName, succeeded); 15251 } catch (RemoteException e) { 15252 Log.i(TAG, "Observer no longer exists."); 15253 } 15254 } //end if observer 15255 } //end run 15256 }); 15257 } 15258 15259 private boolean clearApplicationUserDataLI(String packageName, int userId) { 15260 if (packageName == null) { 15261 Slog.w(TAG, "Attempt to delete null packageName."); 15262 return false; 15263 } 15264 15265 // Try finding details about the requested package 15266 PackageParser.Package pkg; 15267 synchronized (mPackages) { 15268 pkg = mPackages.get(packageName); 15269 if (pkg == null) { 15270 final PackageSetting ps = mSettings.mPackages.get(packageName); 15271 if (ps != null) { 15272 pkg = ps.pkg; 15273 } 15274 } 15275 15276 if (pkg == null) { 15277 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 15278 return false; 15279 } 15280 15281 PackageSetting ps = (PackageSetting) pkg.mExtras; 15282 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 15283 } 15284 15285 // Always delete data directories for package, even if we found no other 15286 // record of app. This helps users recover from UID mismatches without 15287 // resorting to a full data wipe. 15288 // TODO: triage flags as part of 26466827 15289 final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE; 15290 try { 15291 mInstaller.clearAppData(pkg.volumeUuid, packageName, userId, flags); 15292 } catch (InstallerException e) { 15293 Slog.w(TAG, "Couldn't remove cache files for package " + packageName, e); 15294 return false; 15295 } 15296 15297 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); 15298 removeKeystoreDataIfNeeded(userId, appId); 15299 15300 // Create a native library symlink only if we have native libraries 15301 // and if the native libraries are 32 bit libraries. We do not provide 15302 // this symlink for 64 bit libraries. 15303 if (pkg.applicationInfo.primaryCpuAbi != null && 15304 !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) { 15305 final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir; 15306 try { 15307 mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName, 15308 nativeLibPath, userId); 15309 } catch (InstallerException e) { 15310 Slog.w(TAG, "Failed linking native library dir", e); 15311 return false; 15312 } 15313 } 15314 15315 return true; 15316 } 15317 15318 /** 15319 * Reverts user permission state changes (permissions and flags) in 15320 * all packages for a given user. 15321 * 15322 * @param userId The device user for which to do a reset. 15323 */ 15324 private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) { 15325 final int packageCount = mPackages.size(); 15326 for (int i = 0; i < packageCount; i++) { 15327 PackageParser.Package pkg = mPackages.valueAt(i); 15328 PackageSetting ps = (PackageSetting) pkg.mExtras; 15329 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 15330 } 15331 } 15332 15333 /** 15334 * Reverts user permission state changes (permissions and flags). 15335 * 15336 * @param ps The package for which to reset. 15337 * @param userId The device user for which to do a reset. 15338 */ 15339 private void resetUserChangesToRuntimePermissionsAndFlagsLPw( 15340 final PackageSetting ps, final int userId) { 15341 if (ps.pkg == null) { 15342 return; 15343 } 15344 15345 // These are flags that can change base on user actions. 15346 final int userSettableMask = FLAG_PERMISSION_USER_SET 15347 | FLAG_PERMISSION_USER_FIXED 15348 | FLAG_PERMISSION_REVOKE_ON_UPGRADE 15349 | FLAG_PERMISSION_REVIEW_REQUIRED; 15350 15351 final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED 15352 | FLAG_PERMISSION_POLICY_FIXED; 15353 15354 boolean writeInstallPermissions = false; 15355 boolean writeRuntimePermissions = false; 15356 15357 final int permissionCount = ps.pkg.requestedPermissions.size(); 15358 for (int i = 0; i < permissionCount; i++) { 15359 String permission = ps.pkg.requestedPermissions.get(i); 15360 15361 BasePermission bp = mSettings.mPermissions.get(permission); 15362 if (bp == null) { 15363 continue; 15364 } 15365 15366 // If shared user we just reset the state to which only this app contributed. 15367 if (ps.sharedUser != null) { 15368 boolean used = false; 15369 final int packageCount = ps.sharedUser.packages.size(); 15370 for (int j = 0; j < packageCount; j++) { 15371 PackageSetting pkg = ps.sharedUser.packages.valueAt(j); 15372 if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName) 15373 && pkg.pkg.requestedPermissions.contains(permission)) { 15374 used = true; 15375 break; 15376 } 15377 } 15378 if (used) { 15379 continue; 15380 } 15381 } 15382 15383 PermissionsState permissionsState = ps.getPermissionsState(); 15384 15385 final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId); 15386 15387 // Always clear the user settable flags. 15388 final boolean hasInstallState = permissionsState.getInstallPermissionState( 15389 bp.name) != null; 15390 // If permission review is enabled and this is a legacy app, mark the 15391 // permission as requiring a review as this is the initial state. 15392 int flags = 0; 15393 if (Build.PERMISSIONS_REVIEW_REQUIRED 15394 && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 15395 flags |= FLAG_PERMISSION_REVIEW_REQUIRED; 15396 } 15397 if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) { 15398 if (hasInstallState) { 15399 writeInstallPermissions = true; 15400 } else { 15401 writeRuntimePermissions = true; 15402 } 15403 } 15404 15405 // Below is only runtime permission handling. 15406 if (!bp.isRuntime()) { 15407 continue; 15408 } 15409 15410 // Never clobber system or policy. 15411 if ((oldFlags & policyOrSystemFlags) != 0) { 15412 continue; 15413 } 15414 15415 // If this permission was granted by default, make sure it is. 15416 if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) { 15417 if (permissionsState.grantRuntimePermission(bp, userId) 15418 != PERMISSION_OPERATION_FAILURE) { 15419 writeRuntimePermissions = true; 15420 } 15421 // If permission review is enabled the permissions for a legacy apps 15422 // are represented as constantly granted runtime ones, so don't revoke. 15423 } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) { 15424 // Otherwise, reset the permission. 15425 final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId); 15426 switch (revokeResult) { 15427 case PERMISSION_OPERATION_SUCCESS: { 15428 writeRuntimePermissions = true; 15429 } break; 15430 15431 case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 15432 writeRuntimePermissions = true; 15433 final int appId = ps.appId; 15434 mHandler.post(new Runnable() { 15435 @Override 15436 public void run() { 15437 killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED); 15438 } 15439 }); 15440 } break; 15441 } 15442 } 15443 } 15444 15445 // Synchronously write as we are taking permissions away. 15446 if (writeRuntimePermissions) { 15447 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 15448 } 15449 15450 // Synchronously write as we are taking permissions away. 15451 if (writeInstallPermissions) { 15452 mSettings.writeLPr(); 15453 } 15454 } 15455 15456 /** 15457 * Remove entries from the keystore daemon. Will only remove it if the 15458 * {@code appId} is valid. 15459 */ 15460 private static void removeKeystoreDataIfNeeded(int userId, int appId) { 15461 if (appId < 0) { 15462 return; 15463 } 15464 15465 final KeyStore keyStore = KeyStore.getInstance(); 15466 if (keyStore != null) { 15467 if (userId == UserHandle.USER_ALL) { 15468 for (final int individual : sUserManager.getUserIds()) { 15469 keyStore.clearUid(UserHandle.getUid(individual, appId)); 15470 } 15471 } else { 15472 keyStore.clearUid(UserHandle.getUid(userId, appId)); 15473 } 15474 } else { 15475 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId); 15476 } 15477 } 15478 15479 @Override 15480 public void deleteApplicationCacheFiles(final String packageName, 15481 final IPackageDataObserver observer) { 15482 mContext.enforceCallingOrSelfPermission( 15483 android.Manifest.permission.DELETE_CACHE_FILES, null); 15484 // Queue up an async operation since the package deletion may take a little while. 15485 final int userId = UserHandle.getCallingUserId(); 15486 mHandler.post(new Runnable() { 15487 public void run() { 15488 mHandler.removeCallbacks(this); 15489 final boolean succeded; 15490 synchronized (mInstallLock) { 15491 succeded = deleteApplicationCacheFilesLI(packageName, userId); 15492 } 15493 clearExternalStorageDataSync(packageName, userId, false); 15494 if (observer != null) { 15495 try { 15496 observer.onRemoveCompleted(packageName, succeded); 15497 } catch (RemoteException e) { 15498 Log.i(TAG, "Observer no longer exists."); 15499 } 15500 } //end if observer 15501 } //end run 15502 }); 15503 } 15504 15505 private boolean deleteApplicationCacheFilesLI(String packageName, int userId) { 15506 if (packageName == null) { 15507 Slog.w(TAG, "Attempt to delete null packageName."); 15508 return false; 15509 } 15510 PackageParser.Package p; 15511 synchronized (mPackages) { 15512 p = mPackages.get(packageName); 15513 } 15514 if (p == null) { 15515 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 15516 return false; 15517 } 15518 final ApplicationInfo applicationInfo = p.applicationInfo; 15519 if (applicationInfo == null) { 15520 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 15521 return false; 15522 } 15523 // TODO: triage flags as part of 26466827 15524 final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE; 15525 try { 15526 mInstaller.clearAppData(p.volumeUuid, packageName, userId, 15527 flags | Installer.FLAG_CLEAR_CACHE_ONLY); 15528 } catch (InstallerException e) { 15529 Slog.w(TAG, "Couldn't remove cache files for package " 15530 + packageName + " u" + userId, e); 15531 return false; 15532 } 15533 return true; 15534 } 15535 15536 @Override 15537 public void getPackageSizeInfo(final String packageName, int userHandle, 15538 final IPackageStatsObserver observer) { 15539 mContext.enforceCallingOrSelfPermission( 15540 android.Manifest.permission.GET_PACKAGE_SIZE, null); 15541 if (packageName == null) { 15542 throw new IllegalArgumentException("Attempt to get size of null packageName"); 15543 } 15544 15545 PackageStats stats = new PackageStats(packageName, userHandle); 15546 15547 /* 15548 * Queue up an async operation since the package measurement may take a 15549 * little while. 15550 */ 15551 Message msg = mHandler.obtainMessage(INIT_COPY); 15552 msg.obj = new MeasureParams(stats, observer); 15553 mHandler.sendMessage(msg); 15554 } 15555 15556 private boolean getPackageSizeInfoLI(String packageName, int userHandle, 15557 PackageStats pStats) { 15558 if (packageName == null) { 15559 Slog.w(TAG, "Attempt to get size of null packageName."); 15560 return false; 15561 } 15562 PackageParser.Package p; 15563 boolean dataOnly = false; 15564 String libDirRoot = null; 15565 String asecPath = null; 15566 PackageSetting ps = null; 15567 synchronized (mPackages) { 15568 p = mPackages.get(packageName); 15569 ps = mSettings.mPackages.get(packageName); 15570 if(p == null) { 15571 dataOnly = true; 15572 if((ps == null) || (ps.pkg == null)) { 15573 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 15574 return false; 15575 } 15576 p = ps.pkg; 15577 } 15578 if (ps != null) { 15579 libDirRoot = ps.legacyNativeLibraryPathString; 15580 } 15581 if (p != null && (p.isForwardLocked() || p.applicationInfo.isExternalAsec())) { 15582 final long token = Binder.clearCallingIdentity(); 15583 try { 15584 String secureContainerId = cidFromCodePath(p.applicationInfo.getBaseCodePath()); 15585 if (secureContainerId != null) { 15586 asecPath = PackageHelper.getSdFilesystem(secureContainerId); 15587 } 15588 } finally { 15589 Binder.restoreCallingIdentity(token); 15590 } 15591 } 15592 } 15593 String publicSrcDir = null; 15594 if(!dataOnly) { 15595 final ApplicationInfo applicationInfo = p.applicationInfo; 15596 if (applicationInfo == null) { 15597 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 15598 return false; 15599 } 15600 if (p.isForwardLocked()) { 15601 publicSrcDir = applicationInfo.getBaseResourcePath(); 15602 } 15603 } 15604 // TODO: extend to measure size of split APKs 15605 // TODO(multiArch): Extend getSizeInfo to look at the full subdirectory tree, 15606 // not just the first level. 15607 // TODO(multiArch): Extend getSizeInfo to look at *all* instruction sets, not 15608 // just the primary. 15609 String[] dexCodeInstructionSets = getDexCodeInstructionSets(getAppDexInstructionSets(ps)); 15610 15611 String apkPath; 15612 File packageDir = new File(p.codePath); 15613 15614 if (packageDir.isDirectory() && p.canHaveOatDir()) { 15615 apkPath = packageDir.getAbsolutePath(); 15616 // If libDirRoot is inside a package dir, set it to null to avoid it being counted twice 15617 if (libDirRoot != null && libDirRoot.startsWith(apkPath)) { 15618 libDirRoot = null; 15619 } 15620 } else { 15621 apkPath = p.baseCodePath; 15622 } 15623 15624 // TODO: triage flags as part of 26466827 15625 final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE; 15626 try { 15627 mInstaller.getAppSize(p.volumeUuid, packageName, userHandle, flags, apkPath, 15628 libDirRoot, publicSrcDir, asecPath, dexCodeInstructionSets, pStats); 15629 } catch (InstallerException e) { 15630 return false; 15631 } 15632 15633 // Fix-up for forward-locked applications in ASEC containers. 15634 if (!isExternal(p)) { 15635 pStats.codeSize += pStats.externalCodeSize; 15636 pStats.externalCodeSize = 0L; 15637 } 15638 15639 return true; 15640 } 15641 15642 private int getUidTargetSdkVersionLockedLPr(int uid) { 15643 Object obj = mSettings.getUserIdLPr(uid); 15644 if (obj instanceof SharedUserSetting) { 15645 final SharedUserSetting sus = (SharedUserSetting) obj; 15646 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT; 15647 final Iterator<PackageSetting> it = sus.packages.iterator(); 15648 while (it.hasNext()) { 15649 final PackageSetting ps = it.next(); 15650 if (ps.pkg != null) { 15651 int v = ps.pkg.applicationInfo.targetSdkVersion; 15652 if (v < vers) vers = v; 15653 } 15654 } 15655 return vers; 15656 } else if (obj instanceof PackageSetting) { 15657 final PackageSetting ps = (PackageSetting) obj; 15658 if (ps.pkg != null) { 15659 return ps.pkg.applicationInfo.targetSdkVersion; 15660 } 15661 } 15662 return Build.VERSION_CODES.CUR_DEVELOPMENT; 15663 } 15664 15665 @Override 15666 public void addPreferredActivity(IntentFilter filter, int match, 15667 ComponentName[] set, ComponentName activity, int userId) { 15668 addPreferredActivityInternal(filter, match, set, activity, true, userId, 15669 "Adding preferred"); 15670 } 15671 15672 private void addPreferredActivityInternal(IntentFilter filter, int match, 15673 ComponentName[] set, ComponentName activity, boolean always, int userId, 15674 String opname) { 15675 // writer 15676 int callingUid = Binder.getCallingUid(); 15677 enforceCrossUserPermission(callingUid, userId, 15678 true /* requireFullPermission */, false /* checkShell */, "add preferred activity"); 15679 if (filter.countActions() == 0) { 15680 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 15681 return; 15682 } 15683 synchronized (mPackages) { 15684 if (mContext.checkCallingOrSelfPermission( 15685 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 15686 != PackageManager.PERMISSION_GRANTED) { 15687 if (getUidTargetSdkVersionLockedLPr(callingUid) 15688 < Build.VERSION_CODES.FROYO) { 15689 Slog.w(TAG, "Ignoring addPreferredActivity() from uid " 15690 + callingUid); 15691 return; 15692 } 15693 mContext.enforceCallingOrSelfPermission( 15694 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 15695 } 15696 15697 PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId); 15698 Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user " 15699 + userId + ":"); 15700 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 15701 pir.addFilter(new PreferredActivity(filter, match, set, activity, always)); 15702 scheduleWritePackageRestrictionsLocked(userId); 15703 } 15704 } 15705 15706 @Override 15707 public void replacePreferredActivity(IntentFilter filter, int match, 15708 ComponentName[] set, ComponentName activity, int userId) { 15709 if (filter.countActions() != 1) { 15710 throw new IllegalArgumentException( 15711 "replacePreferredActivity expects filter to have only 1 action."); 15712 } 15713 if (filter.countDataAuthorities() != 0 15714 || filter.countDataPaths() != 0 15715 || filter.countDataSchemes() > 1 15716 || filter.countDataTypes() != 0) { 15717 throw new IllegalArgumentException( 15718 "replacePreferredActivity expects filter to have no data authorities, " + 15719 "paths, or types; and at most one scheme."); 15720 } 15721 15722 final int callingUid = Binder.getCallingUid(); 15723 enforceCrossUserPermission(callingUid, userId, 15724 true /* requireFullPermission */, false /* checkShell */, 15725 "replace preferred activity"); 15726 synchronized (mPackages) { 15727 if (mContext.checkCallingOrSelfPermission( 15728 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 15729 != PackageManager.PERMISSION_GRANTED) { 15730 if (getUidTargetSdkVersionLockedLPr(callingUid) 15731 < Build.VERSION_CODES.FROYO) { 15732 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid " 15733 + Binder.getCallingUid()); 15734 return; 15735 } 15736 mContext.enforceCallingOrSelfPermission( 15737 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 15738 } 15739 15740 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 15741 if (pir != null) { 15742 // Get all of the existing entries that exactly match this filter. 15743 ArrayList<PreferredActivity> existing = pir.findFilters(filter); 15744 if (existing != null && existing.size() == 1) { 15745 PreferredActivity cur = existing.get(0); 15746 if (DEBUG_PREFERRED) { 15747 Slog.i(TAG, "Checking replace of preferred:"); 15748 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 15749 if (!cur.mPref.mAlways) { 15750 Slog.i(TAG, " -- CUR; not mAlways!"); 15751 } else { 15752 Slog.i(TAG, " -- CUR: mMatch=" + cur.mPref.mMatch); 15753 Slog.i(TAG, " -- CUR: mSet=" 15754 + Arrays.toString(cur.mPref.mSetComponents)); 15755 Slog.i(TAG, " -- CUR: mComponent=" + cur.mPref.mShortComponent); 15756 Slog.i(TAG, " -- NEW: mMatch=" 15757 + (match&IntentFilter.MATCH_CATEGORY_MASK)); 15758 Slog.i(TAG, " -- CUR: mSet=" + Arrays.toString(set)); 15759 Slog.i(TAG, " -- CUR: mComponent=" + activity.flattenToShortString()); 15760 } 15761 } 15762 if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity) 15763 && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK) 15764 && cur.mPref.sameSet(set)) { 15765 // Setting the preferred activity to what it happens to be already 15766 if (DEBUG_PREFERRED) { 15767 Slog.i(TAG, "Replacing with same preferred activity " 15768 + cur.mPref.mShortComponent + " for user " 15769 + userId + ":"); 15770 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 15771 } 15772 return; 15773 } 15774 } 15775 15776 if (existing != null) { 15777 if (DEBUG_PREFERRED) { 15778 Slog.i(TAG, existing.size() + " existing preferred matches for:"); 15779 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 15780 } 15781 for (int i = 0; i < existing.size(); i++) { 15782 PreferredActivity pa = existing.get(i); 15783 if (DEBUG_PREFERRED) { 15784 Slog.i(TAG, "Removing existing preferred activity " 15785 + pa.mPref.mComponent + ":"); 15786 pa.dump(new LogPrinter(Log.INFO, TAG), " "); 15787 } 15788 pir.removeFilter(pa); 15789 } 15790 } 15791 } 15792 addPreferredActivityInternal(filter, match, set, activity, true, userId, 15793 "Replacing preferred"); 15794 } 15795 } 15796 15797 @Override 15798 public void clearPackagePreferredActivities(String packageName) { 15799 final int uid = Binder.getCallingUid(); 15800 // writer 15801 synchronized (mPackages) { 15802 PackageParser.Package pkg = mPackages.get(packageName); 15803 if (pkg == null || pkg.applicationInfo.uid != uid) { 15804 if (mContext.checkCallingOrSelfPermission( 15805 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 15806 != PackageManager.PERMISSION_GRANTED) { 15807 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid()) 15808 < Build.VERSION_CODES.FROYO) { 15809 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid " 15810 + Binder.getCallingUid()); 15811 return; 15812 } 15813 mContext.enforceCallingOrSelfPermission( 15814 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 15815 } 15816 } 15817 15818 int user = UserHandle.getCallingUserId(); 15819 if (clearPackagePreferredActivitiesLPw(packageName, user)) { 15820 scheduleWritePackageRestrictionsLocked(user); 15821 } 15822 } 15823 } 15824 15825 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 15826 boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) { 15827 ArrayList<PreferredActivity> removed = null; 15828 boolean changed = false; 15829 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 15830 final int thisUserId = mSettings.mPreferredActivities.keyAt(i); 15831 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 15832 if (userId != UserHandle.USER_ALL && userId != thisUserId) { 15833 continue; 15834 } 15835 Iterator<PreferredActivity> it = pir.filterIterator(); 15836 while (it.hasNext()) { 15837 PreferredActivity pa = it.next(); 15838 // Mark entry for removal only if it matches the package name 15839 // and the entry is of type "always". 15840 if (packageName == null || 15841 (pa.mPref.mComponent.getPackageName().equals(packageName) 15842 && pa.mPref.mAlways)) { 15843 if (removed == null) { 15844 removed = new ArrayList<PreferredActivity>(); 15845 } 15846 removed.add(pa); 15847 } 15848 } 15849 if (removed != null) { 15850 for (int j=0; j<removed.size(); j++) { 15851 PreferredActivity pa = removed.get(j); 15852 pir.removeFilter(pa); 15853 } 15854 changed = true; 15855 } 15856 } 15857 return changed; 15858 } 15859 15860 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 15861 private void clearIntentFilterVerificationsLPw(int userId) { 15862 final int packageCount = mPackages.size(); 15863 for (int i = 0; i < packageCount; i++) { 15864 PackageParser.Package pkg = mPackages.valueAt(i); 15865 clearIntentFilterVerificationsLPw(pkg.packageName, userId); 15866 } 15867 } 15868 15869 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 15870 void clearIntentFilterVerificationsLPw(String packageName, int userId) { 15871 if (userId == UserHandle.USER_ALL) { 15872 if (mSettings.removeIntentFilterVerificationLPw(packageName, 15873 sUserManager.getUserIds())) { 15874 for (int oneUserId : sUserManager.getUserIds()) { 15875 scheduleWritePackageRestrictionsLocked(oneUserId); 15876 } 15877 } 15878 } else { 15879 if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) { 15880 scheduleWritePackageRestrictionsLocked(userId); 15881 } 15882 } 15883 } 15884 15885 void clearDefaultBrowserIfNeeded(String packageName) { 15886 for (int oneUserId : sUserManager.getUserIds()) { 15887 String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId); 15888 if (TextUtils.isEmpty(defaultBrowserPackageName)) continue; 15889 if (packageName.equals(defaultBrowserPackageName)) { 15890 setDefaultBrowserPackageName(null, oneUserId); 15891 } 15892 } 15893 } 15894 15895 @Override 15896 public void resetApplicationPreferences(int userId) { 15897 mContext.enforceCallingOrSelfPermission( 15898 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 15899 // writer 15900 synchronized (mPackages) { 15901 final long identity = Binder.clearCallingIdentity(); 15902 try { 15903 clearPackagePreferredActivitiesLPw(null, userId); 15904 mSettings.applyDefaultPreferredAppsLPw(this, userId); 15905 // TODO: We have to reset the default SMS and Phone. This requires 15906 // significant refactoring to keep all default apps in the package 15907 // manager (cleaner but more work) or have the services provide 15908 // callbacks to the package manager to request a default app reset. 15909 applyFactoryDefaultBrowserLPw(userId); 15910 clearIntentFilterVerificationsLPw(userId); 15911 primeDomainVerificationsLPw(userId); 15912 resetUserChangesToRuntimePermissionsAndFlagsLPw(userId); 15913 scheduleWritePackageRestrictionsLocked(userId); 15914 } finally { 15915 Binder.restoreCallingIdentity(identity); 15916 } 15917 } 15918 } 15919 15920 @Override 15921 public int getPreferredActivities(List<IntentFilter> outFilters, 15922 List<ComponentName> outActivities, String packageName) { 15923 15924 int num = 0; 15925 final int userId = UserHandle.getCallingUserId(); 15926 // reader 15927 synchronized (mPackages) { 15928 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 15929 if (pir != null) { 15930 final Iterator<PreferredActivity> it = pir.filterIterator(); 15931 while (it.hasNext()) { 15932 final PreferredActivity pa = it.next(); 15933 if (packageName == null 15934 || (pa.mPref.mComponent.getPackageName().equals(packageName) 15935 && pa.mPref.mAlways)) { 15936 if (outFilters != null) { 15937 outFilters.add(new IntentFilter(pa)); 15938 } 15939 if (outActivities != null) { 15940 outActivities.add(pa.mPref.mComponent); 15941 } 15942 } 15943 } 15944 } 15945 } 15946 15947 return num; 15948 } 15949 15950 @Override 15951 public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity, 15952 int userId) { 15953 int callingUid = Binder.getCallingUid(); 15954 if (callingUid != Process.SYSTEM_UID) { 15955 throw new SecurityException( 15956 "addPersistentPreferredActivity can only be run by the system"); 15957 } 15958 if (filter.countActions() == 0) { 15959 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 15960 return; 15961 } 15962 synchronized (mPackages) { 15963 Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId + 15964 ":"); 15965 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 15966 mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter( 15967 new PersistentPreferredActivity(filter, activity)); 15968 scheduleWritePackageRestrictionsLocked(userId); 15969 } 15970 } 15971 15972 @Override 15973 public void clearPackagePersistentPreferredActivities(String packageName, int userId) { 15974 int callingUid = Binder.getCallingUid(); 15975 if (callingUid != Process.SYSTEM_UID) { 15976 throw new SecurityException( 15977 "clearPackagePersistentPreferredActivities can only be run by the system"); 15978 } 15979 ArrayList<PersistentPreferredActivity> removed = null; 15980 boolean changed = false; 15981 synchronized (mPackages) { 15982 for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) { 15983 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i); 15984 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 15985 .valueAt(i); 15986 if (userId != thisUserId) { 15987 continue; 15988 } 15989 Iterator<PersistentPreferredActivity> it = ppir.filterIterator(); 15990 while (it.hasNext()) { 15991 PersistentPreferredActivity ppa = it.next(); 15992 // Mark entry for removal only if it matches the package name. 15993 if (ppa.mComponent.getPackageName().equals(packageName)) { 15994 if (removed == null) { 15995 removed = new ArrayList<PersistentPreferredActivity>(); 15996 } 15997 removed.add(ppa); 15998 } 15999 } 16000 if (removed != null) { 16001 for (int j=0; j<removed.size(); j++) { 16002 PersistentPreferredActivity ppa = removed.get(j); 16003 ppir.removeFilter(ppa); 16004 } 16005 changed = true; 16006 } 16007 } 16008 16009 if (changed) { 16010 scheduleWritePackageRestrictionsLocked(userId); 16011 } 16012 } 16013 } 16014 16015 /** 16016 * Common machinery for picking apart a restored XML blob and passing 16017 * it to a caller-supplied functor to be applied to the running system. 16018 */ 16019 private void restoreFromXml(XmlPullParser parser, int userId, 16020 String expectedStartTag, BlobXmlRestorer functor) 16021 throws IOException, XmlPullParserException { 16022 int type; 16023 while ((type = parser.next()) != XmlPullParser.START_TAG 16024 && type != XmlPullParser.END_DOCUMENT) { 16025 } 16026 if (type != XmlPullParser.START_TAG) { 16027 // oops didn't find a start tag?! 16028 if (DEBUG_BACKUP) { 16029 Slog.e(TAG, "Didn't find start tag during restore"); 16030 } 16031 return; 16032 } 16033Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName()); 16034 // this is supposed to be TAG_PREFERRED_BACKUP 16035 if (!expectedStartTag.equals(parser.getName())) { 16036 if (DEBUG_BACKUP) { 16037 Slog.e(TAG, "Found unexpected tag " + parser.getName()); 16038 } 16039 return; 16040 } 16041 16042 // skip interfering stuff, then we're aligned with the backing implementation 16043 while ((type = parser.next()) == XmlPullParser.TEXT) { } 16044Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); 16045 functor.apply(parser, userId); 16046 } 16047 16048 private interface BlobXmlRestorer { 16049 public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException; 16050 } 16051 16052 /** 16053 * Non-Binder method, support for the backup/restore mechanism: write the 16054 * full set of preferred activities in its canonical XML format. Returns the 16055 * XML output as a byte array, or null if there is none. 16056 */ 16057 @Override 16058 public byte[] getPreferredActivityBackup(int userId) { 16059 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16060 throw new SecurityException("Only the system may call getPreferredActivityBackup()"); 16061 } 16062 16063 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 16064 try { 16065 final XmlSerializer serializer = new FastXmlSerializer(); 16066 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 16067 serializer.startDocument(null, true); 16068 serializer.startTag(null, TAG_PREFERRED_BACKUP); 16069 16070 synchronized (mPackages) { 16071 mSettings.writePreferredActivitiesLPr(serializer, userId, true); 16072 } 16073 16074 serializer.endTag(null, TAG_PREFERRED_BACKUP); 16075 serializer.endDocument(); 16076 serializer.flush(); 16077 } catch (Exception e) { 16078 if (DEBUG_BACKUP) { 16079 Slog.e(TAG, "Unable to write preferred activities for backup", e); 16080 } 16081 return null; 16082 } 16083 16084 return dataStream.toByteArray(); 16085 } 16086 16087 @Override 16088 public void restorePreferredActivities(byte[] backup, int userId) { 16089 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16090 throw new SecurityException("Only the system may call restorePreferredActivities()"); 16091 } 16092 16093 try { 16094 final XmlPullParser parser = Xml.newPullParser(); 16095 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 16096 restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP, 16097 new BlobXmlRestorer() { 16098 @Override 16099 public void apply(XmlPullParser parser, int userId) 16100 throws XmlPullParserException, IOException { 16101 synchronized (mPackages) { 16102 mSettings.readPreferredActivitiesLPw(parser, userId); 16103 } 16104 } 16105 } ); 16106 } catch (Exception e) { 16107 if (DEBUG_BACKUP) { 16108 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 16109 } 16110 } 16111 } 16112 16113 /** 16114 * Non-Binder method, support for the backup/restore mechanism: write the 16115 * default browser (etc) settings in its canonical XML format. Returns the default 16116 * browser XML representation as a byte array, or null if there is none. 16117 */ 16118 @Override 16119 public byte[] getDefaultAppsBackup(int userId) { 16120 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16121 throw new SecurityException("Only the system may call getDefaultAppsBackup()"); 16122 } 16123 16124 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 16125 try { 16126 final XmlSerializer serializer = new FastXmlSerializer(); 16127 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 16128 serializer.startDocument(null, true); 16129 serializer.startTag(null, TAG_DEFAULT_APPS); 16130 16131 synchronized (mPackages) { 16132 mSettings.writeDefaultAppsLPr(serializer, userId); 16133 } 16134 16135 serializer.endTag(null, TAG_DEFAULT_APPS); 16136 serializer.endDocument(); 16137 serializer.flush(); 16138 } catch (Exception e) { 16139 if (DEBUG_BACKUP) { 16140 Slog.e(TAG, "Unable to write default apps for backup", e); 16141 } 16142 return null; 16143 } 16144 16145 return dataStream.toByteArray(); 16146 } 16147 16148 @Override 16149 public void restoreDefaultApps(byte[] backup, int userId) { 16150 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16151 throw new SecurityException("Only the system may call restoreDefaultApps()"); 16152 } 16153 16154 try { 16155 final XmlPullParser parser = Xml.newPullParser(); 16156 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 16157 restoreFromXml(parser, userId, TAG_DEFAULT_APPS, 16158 new BlobXmlRestorer() { 16159 @Override 16160 public void apply(XmlPullParser parser, int userId) 16161 throws XmlPullParserException, IOException { 16162 synchronized (mPackages) { 16163 mSettings.readDefaultAppsLPw(parser, userId); 16164 } 16165 } 16166 } ); 16167 } catch (Exception e) { 16168 if (DEBUG_BACKUP) { 16169 Slog.e(TAG, "Exception restoring default apps: " + e.getMessage()); 16170 } 16171 } 16172 } 16173 16174 @Override 16175 public byte[] getIntentFilterVerificationBackup(int userId) { 16176 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16177 throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()"); 16178 } 16179 16180 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 16181 try { 16182 final XmlSerializer serializer = new FastXmlSerializer(); 16183 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 16184 serializer.startDocument(null, true); 16185 serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION); 16186 16187 synchronized (mPackages) { 16188 mSettings.writeAllDomainVerificationsLPr(serializer, userId); 16189 } 16190 16191 serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION); 16192 serializer.endDocument(); 16193 serializer.flush(); 16194 } catch (Exception e) { 16195 if (DEBUG_BACKUP) { 16196 Slog.e(TAG, "Unable to write default apps for backup", e); 16197 } 16198 return null; 16199 } 16200 16201 return dataStream.toByteArray(); 16202 } 16203 16204 @Override 16205 public void restoreIntentFilterVerification(byte[] backup, int userId) { 16206 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16207 throw new SecurityException("Only the system may call restorePreferredActivities()"); 16208 } 16209 16210 try { 16211 final XmlPullParser parser = Xml.newPullParser(); 16212 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 16213 restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION, 16214 new BlobXmlRestorer() { 16215 @Override 16216 public void apply(XmlPullParser parser, int userId) 16217 throws XmlPullParserException, IOException { 16218 synchronized (mPackages) { 16219 mSettings.readAllDomainVerificationsLPr(parser, userId); 16220 mSettings.writeLPr(); 16221 } 16222 } 16223 } ); 16224 } catch (Exception e) { 16225 if (DEBUG_BACKUP) { 16226 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 16227 } 16228 } 16229 } 16230 16231 @Override 16232 public byte[] getPermissionGrantBackup(int userId) { 16233 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16234 throw new SecurityException("Only the system may call getPermissionGrantBackup()"); 16235 } 16236 16237 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 16238 try { 16239 final XmlSerializer serializer = new FastXmlSerializer(); 16240 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 16241 serializer.startDocument(null, true); 16242 serializer.startTag(null, TAG_PERMISSION_BACKUP); 16243 16244 synchronized (mPackages) { 16245 serializeRuntimePermissionGrantsLPr(serializer, userId); 16246 } 16247 16248 serializer.endTag(null, TAG_PERMISSION_BACKUP); 16249 serializer.endDocument(); 16250 serializer.flush(); 16251 } catch (Exception e) { 16252 if (DEBUG_BACKUP) { 16253 Slog.e(TAG, "Unable to write default apps for backup", e); 16254 } 16255 return null; 16256 } 16257 16258 return dataStream.toByteArray(); 16259 } 16260 16261 @Override 16262 public void restorePermissionGrants(byte[] backup, int userId) { 16263 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16264 throw new SecurityException("Only the system may call restorePermissionGrants()"); 16265 } 16266 16267 try { 16268 final XmlPullParser parser = Xml.newPullParser(); 16269 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 16270 restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP, 16271 new BlobXmlRestorer() { 16272 @Override 16273 public void apply(XmlPullParser parser, int userId) 16274 throws XmlPullParserException, IOException { 16275 synchronized (mPackages) { 16276 processRestoredPermissionGrantsLPr(parser, userId); 16277 } 16278 } 16279 } ); 16280 } catch (Exception e) { 16281 if (DEBUG_BACKUP) { 16282 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 16283 } 16284 } 16285 } 16286 16287 private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId) 16288 throws IOException { 16289 serializer.startTag(null, TAG_ALL_GRANTS); 16290 16291 final int N = mSettings.mPackages.size(); 16292 for (int i = 0; i < N; i++) { 16293 final PackageSetting ps = mSettings.mPackages.valueAt(i); 16294 boolean pkgGrantsKnown = false; 16295 16296 PermissionsState packagePerms = ps.getPermissionsState(); 16297 16298 for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) { 16299 final int grantFlags = state.getFlags(); 16300 // only look at grants that are not system/policy fixed 16301 if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) { 16302 final boolean isGranted = state.isGranted(); 16303 // And only back up the user-twiddled state bits 16304 if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) { 16305 final String packageName = mSettings.mPackages.keyAt(i); 16306 if (!pkgGrantsKnown) { 16307 serializer.startTag(null, TAG_GRANT); 16308 serializer.attribute(null, ATTR_PACKAGE_NAME, packageName); 16309 pkgGrantsKnown = true; 16310 } 16311 16312 final boolean userSet = 16313 (grantFlags & FLAG_PERMISSION_USER_SET) != 0; 16314 final boolean userFixed = 16315 (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0; 16316 final boolean revoke = 16317 (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0; 16318 16319 serializer.startTag(null, TAG_PERMISSION); 16320 serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName()); 16321 if (isGranted) { 16322 serializer.attribute(null, ATTR_IS_GRANTED, "true"); 16323 } 16324 if (userSet) { 16325 serializer.attribute(null, ATTR_USER_SET, "true"); 16326 } 16327 if (userFixed) { 16328 serializer.attribute(null, ATTR_USER_FIXED, "true"); 16329 } 16330 if (revoke) { 16331 serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true"); 16332 } 16333 serializer.endTag(null, TAG_PERMISSION); 16334 } 16335 } 16336 } 16337 16338 if (pkgGrantsKnown) { 16339 serializer.endTag(null, TAG_GRANT); 16340 } 16341 } 16342 16343 serializer.endTag(null, TAG_ALL_GRANTS); 16344 } 16345 16346 private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId) 16347 throws XmlPullParserException, IOException { 16348 String pkgName = null; 16349 int outerDepth = parser.getDepth(); 16350 int type; 16351 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 16352 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 16353 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 16354 continue; 16355 } 16356 16357 final String tagName = parser.getName(); 16358 if (tagName.equals(TAG_GRANT)) { 16359 pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME); 16360 if (DEBUG_BACKUP) { 16361 Slog.v(TAG, "+++ Restoring grants for package " + pkgName); 16362 } 16363 } else if (tagName.equals(TAG_PERMISSION)) { 16364 16365 final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED)); 16366 final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME); 16367 16368 int newFlagSet = 0; 16369 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) { 16370 newFlagSet |= FLAG_PERMISSION_USER_SET; 16371 } 16372 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) { 16373 newFlagSet |= FLAG_PERMISSION_USER_FIXED; 16374 } 16375 if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) { 16376 newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE; 16377 } 16378 if (DEBUG_BACKUP) { 16379 Slog.v(TAG, " + Restoring grant: pkg=" + pkgName + " perm=" + permName 16380 + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet)); 16381 } 16382 final PackageSetting ps = mSettings.mPackages.get(pkgName); 16383 if (ps != null) { 16384 // Already installed so we apply the grant immediately 16385 if (DEBUG_BACKUP) { 16386 Slog.v(TAG, " + already installed; applying"); 16387 } 16388 PermissionsState perms = ps.getPermissionsState(); 16389 BasePermission bp = mSettings.mPermissions.get(permName); 16390 if (bp != null) { 16391 if (isGranted) { 16392 perms.grantRuntimePermission(bp, userId); 16393 } 16394 if (newFlagSet != 0) { 16395 perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet); 16396 } 16397 } 16398 } else { 16399 // Need to wait for post-restore install to apply the grant 16400 if (DEBUG_BACKUP) { 16401 Slog.v(TAG, " - not yet installed; saving for later"); 16402 } 16403 mSettings.processRestoredPermissionGrantLPr(pkgName, permName, 16404 isGranted, newFlagSet, userId); 16405 } 16406 } else { 16407 PackageManagerService.reportSettingsProblem(Log.WARN, 16408 "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName); 16409 XmlUtils.skipCurrentTag(parser); 16410 } 16411 } 16412 16413 scheduleWriteSettingsLocked(); 16414 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 16415 } 16416 16417 @Override 16418 public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage, 16419 int sourceUserId, int targetUserId, int flags) { 16420 mContext.enforceCallingOrSelfPermission( 16421 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 16422 int callingUid = Binder.getCallingUid(); 16423 enforceOwnerRights(ownerPackage, callingUid); 16424 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 16425 if (intentFilter.countActions() == 0) { 16426 Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions"); 16427 return; 16428 } 16429 synchronized (mPackages) { 16430 CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter, 16431 ownerPackage, targetUserId, flags); 16432 CrossProfileIntentResolver resolver = 16433 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 16434 ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter); 16435 // We have all those whose filter is equal. Now checking if the rest is equal as well. 16436 if (existing != null) { 16437 int size = existing.size(); 16438 for (int i = 0; i < size; i++) { 16439 if (newFilter.equalsIgnoreFilter(existing.get(i))) { 16440 return; 16441 } 16442 } 16443 } 16444 resolver.addFilter(newFilter); 16445 scheduleWritePackageRestrictionsLocked(sourceUserId); 16446 } 16447 } 16448 16449 @Override 16450 public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) { 16451 mContext.enforceCallingOrSelfPermission( 16452 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 16453 int callingUid = Binder.getCallingUid(); 16454 enforceOwnerRights(ownerPackage, callingUid); 16455 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 16456 synchronized (mPackages) { 16457 CrossProfileIntentResolver resolver = 16458 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 16459 ArraySet<CrossProfileIntentFilter> set = 16460 new ArraySet<CrossProfileIntentFilter>(resolver.filterSet()); 16461 for (CrossProfileIntentFilter filter : set) { 16462 if (filter.getOwnerPackage().equals(ownerPackage)) { 16463 resolver.removeFilter(filter); 16464 } 16465 } 16466 scheduleWritePackageRestrictionsLocked(sourceUserId); 16467 } 16468 } 16469 16470 // Enforcing that callingUid is owning pkg on userId 16471 private void enforceOwnerRights(String pkg, int callingUid) { 16472 // The system owns everything. 16473 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) { 16474 return; 16475 } 16476 int callingUserId = UserHandle.getUserId(callingUid); 16477 PackageInfo pi = getPackageInfo(pkg, 0, callingUserId); 16478 if (pi == null) { 16479 throw new IllegalArgumentException("Unknown package " + pkg + " on user " 16480 + callingUserId); 16481 } 16482 if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) { 16483 throw new SecurityException("Calling uid " + callingUid 16484 + " does not own package " + pkg); 16485 } 16486 } 16487 16488 @Override 16489 public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) { 16490 return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId()); 16491 } 16492 16493 private Intent getHomeIntent() { 16494 Intent intent = new Intent(Intent.ACTION_MAIN); 16495 intent.addCategory(Intent.CATEGORY_HOME); 16496 return intent; 16497 } 16498 16499 private IntentFilter getHomeFilter() { 16500 IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN); 16501 filter.addCategory(Intent.CATEGORY_HOME); 16502 filter.addCategory(Intent.CATEGORY_DEFAULT); 16503 return filter; 16504 } 16505 16506 ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, 16507 int userId) { 16508 Intent intent = getHomeIntent(); 16509 List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null, 16510 PackageManager.GET_META_DATA, userId); 16511 ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0, 16512 true, false, false, userId); 16513 16514 allHomeCandidates.clear(); 16515 if (list != null) { 16516 for (ResolveInfo ri : list) { 16517 allHomeCandidates.add(ri); 16518 } 16519 } 16520 return (preferred == null || preferred.activityInfo == null) 16521 ? null 16522 : new ComponentName(preferred.activityInfo.packageName, 16523 preferred.activityInfo.name); 16524 } 16525 16526 @Override 16527 public void setHomeActivity(ComponentName comp, int userId) { 16528 ArrayList<ResolveInfo> homeActivities = new ArrayList<>(); 16529 getHomeActivitiesAsUser(homeActivities, userId); 16530 16531 boolean found = false; 16532 16533 final int size = homeActivities.size(); 16534 final ComponentName[] set = new ComponentName[size]; 16535 for (int i = 0; i < size; i++) { 16536 final ResolveInfo candidate = homeActivities.get(i); 16537 final ActivityInfo info = candidate.activityInfo; 16538 final ComponentName activityName = new ComponentName(info.packageName, info.name); 16539 set[i] = activityName; 16540 if (!found && activityName.equals(comp)) { 16541 found = true; 16542 } 16543 } 16544 if (!found) { 16545 throw new IllegalArgumentException("Component " + comp + " cannot be home on user " 16546 + userId); 16547 } 16548 replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY, 16549 set, comp, userId); 16550 } 16551 16552 @Override 16553 public void setApplicationEnabledSetting(String appPackageName, 16554 int newState, int flags, int userId, String callingPackage) { 16555 if (!sUserManager.exists(userId)) return; 16556 if (callingPackage == null) { 16557 callingPackage = Integer.toString(Binder.getCallingUid()); 16558 } 16559 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage); 16560 } 16561 16562 @Override 16563 public void setComponentEnabledSetting(ComponentName componentName, 16564 int newState, int flags, int userId) { 16565 if (!sUserManager.exists(userId)) return; 16566 setEnabledSetting(componentName.getPackageName(), 16567 componentName.getClassName(), newState, flags, userId, null); 16568 } 16569 16570 private void setEnabledSetting(final String packageName, String className, int newState, 16571 final int flags, int userId, String callingPackage) { 16572 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT 16573 || newState == COMPONENT_ENABLED_STATE_ENABLED 16574 || newState == COMPONENT_ENABLED_STATE_DISABLED 16575 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER 16576 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) { 16577 throw new IllegalArgumentException("Invalid new component state: " 16578 + newState); 16579 } 16580 PackageSetting pkgSetting; 16581 final int uid = Binder.getCallingUid(); 16582 final int permission = mContext.checkCallingOrSelfPermission( 16583 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 16584 enforceCrossUserPermission(uid, userId, 16585 false /* requireFullPermission */, true /* checkShell */, "set enabled"); 16586 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 16587 boolean sendNow = false; 16588 boolean isApp = (className == null); 16589 String componentName = isApp ? packageName : className; 16590 int packageUid = -1; 16591 ArrayList<String> components; 16592 16593 // writer 16594 synchronized (mPackages) { 16595 pkgSetting = mSettings.mPackages.get(packageName); 16596 if (pkgSetting == null) { 16597 if (className == null) { 16598 throw new IllegalArgumentException("Unknown package: " + packageName); 16599 } 16600 throw new IllegalArgumentException( 16601 "Unknown component: " + packageName + "/" + className); 16602 } 16603 // Allow root and verify that userId is not being specified by a different user 16604 if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) { 16605 throw new SecurityException( 16606 "Permission Denial: attempt to change component state from pid=" 16607 + Binder.getCallingPid() 16608 + ", uid=" + uid + ", package uid=" + pkgSetting.appId); 16609 } 16610 if (className == null) { 16611 // We're dealing with an application/package level state change 16612 if (pkgSetting.getEnabled(userId) == newState) { 16613 // Nothing to do 16614 return; 16615 } 16616 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT 16617 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { 16618 // Don't care about who enables an app. 16619 callingPackage = null; 16620 } 16621 pkgSetting.setEnabled(newState, userId, callingPackage); 16622 // pkgSetting.pkg.mSetEnabled = newState; 16623 } else { 16624 // We're dealing with a component level state change 16625 // First, verify that this is a valid class name. 16626 PackageParser.Package pkg = pkgSetting.pkg; 16627 if (pkg == null || !pkg.hasComponentClassName(className)) { 16628 if (pkg != null && 16629 pkg.applicationInfo.targetSdkVersion >= 16630 Build.VERSION_CODES.JELLY_BEAN) { 16631 throw new IllegalArgumentException("Component class " + className 16632 + " does not exist in " + packageName); 16633 } else { 16634 Slog.w(TAG, "Failed setComponentEnabledSetting: component class " 16635 + className + " does not exist in " + packageName); 16636 } 16637 } 16638 switch (newState) { 16639 case COMPONENT_ENABLED_STATE_ENABLED: 16640 if (!pkgSetting.enableComponentLPw(className, userId)) { 16641 return; 16642 } 16643 break; 16644 case COMPONENT_ENABLED_STATE_DISABLED: 16645 if (!pkgSetting.disableComponentLPw(className, userId)) { 16646 return; 16647 } 16648 break; 16649 case COMPONENT_ENABLED_STATE_DEFAULT: 16650 if (!pkgSetting.restoreComponentLPw(className, userId)) { 16651 return; 16652 } 16653 break; 16654 default: 16655 Slog.e(TAG, "Invalid new component state: " + newState); 16656 return; 16657 } 16658 } 16659 scheduleWritePackageRestrictionsLocked(userId); 16660 components = mPendingBroadcasts.get(userId, packageName); 16661 final boolean newPackage = components == null; 16662 if (newPackage) { 16663 components = new ArrayList<String>(); 16664 } 16665 if (!components.contains(componentName)) { 16666 components.add(componentName); 16667 } 16668 if ((flags&PackageManager.DONT_KILL_APP) == 0) { 16669 sendNow = true; 16670 // Purge entry from pending broadcast list if another one exists already 16671 // since we are sending one right away. 16672 mPendingBroadcasts.remove(userId, packageName); 16673 } else { 16674 if (newPackage) { 16675 mPendingBroadcasts.put(userId, packageName, components); 16676 } 16677 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) { 16678 // Schedule a message 16679 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY); 16680 } 16681 } 16682 } 16683 16684 long callingId = Binder.clearCallingIdentity(); 16685 try { 16686 if (sendNow) { 16687 packageUid = UserHandle.getUid(userId, pkgSetting.appId); 16688 sendPackageChangedBroadcast(packageName, 16689 (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid); 16690 } 16691 } finally { 16692 Binder.restoreCallingIdentity(callingId); 16693 } 16694 } 16695 16696 @Override 16697 public void flushPackageRestrictionsAsUser(int userId) { 16698 if (!sUserManager.exists(userId)) { 16699 return; 16700 } 16701 enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/, 16702 false /* checkShell */, "flushPackageRestrictions"); 16703 synchronized (mPackages) { 16704 mSettings.writePackageRestrictionsLPr(userId); 16705 mDirtyUsers.remove(userId); 16706 if (mDirtyUsers.isEmpty()) { 16707 mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS); 16708 } 16709 } 16710 } 16711 16712 private void sendPackageChangedBroadcast(String packageName, 16713 boolean killFlag, ArrayList<String> componentNames, int packageUid) { 16714 if (DEBUG_INSTALL) 16715 Log.v(TAG, "Sending package changed: package=" + packageName + " components=" 16716 + componentNames); 16717 Bundle extras = new Bundle(4); 16718 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0)); 16719 String nameList[] = new String[componentNames.size()]; 16720 componentNames.toArray(nameList); 16721 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList); 16722 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag); 16723 extras.putInt(Intent.EXTRA_UID, packageUid); 16724 // If this is not reporting a change of the overall package, then only send it 16725 // to registered receivers. We don't want to launch a swath of apps for every 16726 // little component state change. 16727 final int flags = !componentNames.contains(packageName) 16728 ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0; 16729 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, flags, null, null, 16730 new int[] {UserHandle.getUserId(packageUid)}); 16731 } 16732 16733 @Override 16734 public void setPackageStoppedState(String packageName, boolean stopped, int userId) { 16735 if (!sUserManager.exists(userId)) return; 16736 final int uid = Binder.getCallingUid(); 16737 final int permission = mContext.checkCallingOrSelfPermission( 16738 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 16739 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 16740 enforceCrossUserPermission(uid, userId, 16741 true /* requireFullPermission */, true /* checkShell */, "stop package"); 16742 // writer 16743 synchronized (mPackages) { 16744 if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped, 16745 allowedByPermission, uid, userId)) { 16746 scheduleWritePackageRestrictionsLocked(userId); 16747 } 16748 } 16749 } 16750 16751 @Override 16752 public String getInstallerPackageName(String packageName) { 16753 // reader 16754 synchronized (mPackages) { 16755 return mSettings.getInstallerPackageNameLPr(packageName); 16756 } 16757 } 16758 16759 @Override 16760 public int getApplicationEnabledSetting(String packageName, int userId) { 16761 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 16762 int uid = Binder.getCallingUid(); 16763 enforceCrossUserPermission(uid, userId, 16764 false /* requireFullPermission */, false /* checkShell */, "get enabled"); 16765 // reader 16766 synchronized (mPackages) { 16767 return mSettings.getApplicationEnabledSettingLPr(packageName, userId); 16768 } 16769 } 16770 16771 @Override 16772 public int getComponentEnabledSetting(ComponentName componentName, int userId) { 16773 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 16774 int uid = Binder.getCallingUid(); 16775 enforceCrossUserPermission(uid, userId, 16776 false /* requireFullPermission */, false /* checkShell */, "get component enabled"); 16777 // reader 16778 synchronized (mPackages) { 16779 return mSettings.getComponentEnabledSettingLPr(componentName, userId); 16780 } 16781 } 16782 16783 @Override 16784 public void enterSafeMode() { 16785 enforceSystemOrRoot("Only the system can request entering safe mode"); 16786 16787 if (!mSystemReady) { 16788 mSafeMode = true; 16789 } 16790 } 16791 16792 @Override 16793 public void systemReady() { 16794 mSystemReady = true; 16795 16796 // Read the compatibilty setting when the system is ready. 16797 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt( 16798 mContext.getContentResolver(), 16799 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1; 16800 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled); 16801 if (DEBUG_SETTINGS) { 16802 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled); 16803 } 16804 16805 int[] grantPermissionsUserIds = EMPTY_INT_ARRAY; 16806 16807 synchronized (mPackages) { 16808 // Verify that all of the preferred activity components actually 16809 // exist. It is possible for applications to be updated and at 16810 // that point remove a previously declared activity component that 16811 // had been set as a preferred activity. We try to clean this up 16812 // the next time we encounter that preferred activity, but it is 16813 // possible for the user flow to never be able to return to that 16814 // situation so here we do a sanity check to make sure we haven't 16815 // left any junk around. 16816 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>(); 16817 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 16818 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 16819 removed.clear(); 16820 for (PreferredActivity pa : pir.filterSet()) { 16821 if (mActivities.mActivities.get(pa.mPref.mComponent) == null) { 16822 removed.add(pa); 16823 } 16824 } 16825 if (removed.size() > 0) { 16826 for (int r=0; r<removed.size(); r++) { 16827 PreferredActivity pa = removed.get(r); 16828 Slog.w(TAG, "Removing dangling preferred activity: " 16829 + pa.mPref.mComponent); 16830 pir.removeFilter(pa); 16831 } 16832 mSettings.writePackageRestrictionsLPr( 16833 mSettings.mPreferredActivities.keyAt(i)); 16834 } 16835 } 16836 16837 for (int userId : UserManagerService.getInstance().getUserIds()) { 16838 if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) { 16839 grantPermissionsUserIds = ArrayUtils.appendInt( 16840 grantPermissionsUserIds, userId); 16841 } 16842 } 16843 } 16844 sUserManager.systemReady(); 16845 16846 // If we upgraded grant all default permissions before kicking off. 16847 for (int userId : grantPermissionsUserIds) { 16848 mDefaultPermissionPolicy.grantDefaultPermissions(userId); 16849 } 16850 16851 // Kick off any messages waiting for system ready 16852 if (mPostSystemReadyMessages != null) { 16853 for (Message msg : mPostSystemReadyMessages) { 16854 msg.sendToTarget(); 16855 } 16856 mPostSystemReadyMessages = null; 16857 } 16858 16859 // Watch for external volumes that come and go over time 16860 final StorageManager storage = mContext.getSystemService(StorageManager.class); 16861 storage.registerListener(mStorageListener); 16862 16863 mInstallerService.systemReady(); 16864 mPackageDexOptimizer.systemReady(); 16865 16866 MountServiceInternal mountServiceInternal = LocalServices.getService( 16867 MountServiceInternal.class); 16868 mountServiceInternal.addExternalStoragePolicy( 16869 new MountServiceInternal.ExternalStorageMountPolicy() { 16870 @Override 16871 public int getMountMode(int uid, String packageName) { 16872 if (Process.isIsolated(uid)) { 16873 return Zygote.MOUNT_EXTERNAL_NONE; 16874 } 16875 if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) { 16876 return Zygote.MOUNT_EXTERNAL_DEFAULT; 16877 } 16878 if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { 16879 return Zygote.MOUNT_EXTERNAL_DEFAULT; 16880 } 16881 if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { 16882 return Zygote.MOUNT_EXTERNAL_READ; 16883 } 16884 return Zygote.MOUNT_EXTERNAL_WRITE; 16885 } 16886 16887 @Override 16888 public boolean hasExternalStorage(int uid, String packageName) { 16889 return true; 16890 } 16891 }); 16892 } 16893 16894 @Override 16895 public boolean isSafeMode() { 16896 return mSafeMode; 16897 } 16898 16899 @Override 16900 public boolean hasSystemUidErrors() { 16901 return mHasSystemUidErrors; 16902 } 16903 16904 static String arrayToString(int[] array) { 16905 StringBuffer buf = new StringBuffer(128); 16906 buf.append('['); 16907 if (array != null) { 16908 for (int i=0; i<array.length; i++) { 16909 if (i > 0) buf.append(", "); 16910 buf.append(array[i]); 16911 } 16912 } 16913 buf.append(']'); 16914 return buf.toString(); 16915 } 16916 16917 static class DumpState { 16918 public static final int DUMP_LIBS = 1 << 0; 16919 public static final int DUMP_FEATURES = 1 << 1; 16920 public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2; 16921 public static final int DUMP_SERVICE_RESOLVERS = 1 << 3; 16922 public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4; 16923 public static final int DUMP_CONTENT_RESOLVERS = 1 << 5; 16924 public static final int DUMP_PERMISSIONS = 1 << 6; 16925 public static final int DUMP_PACKAGES = 1 << 7; 16926 public static final int DUMP_SHARED_USERS = 1 << 8; 16927 public static final int DUMP_MESSAGES = 1 << 9; 16928 public static final int DUMP_PROVIDERS = 1 << 10; 16929 public static final int DUMP_VERIFIERS = 1 << 11; 16930 public static final int DUMP_PREFERRED = 1 << 12; 16931 public static final int DUMP_PREFERRED_XML = 1 << 13; 16932 public static final int DUMP_KEYSETS = 1 << 14; 16933 public static final int DUMP_VERSION = 1 << 15; 16934 public static final int DUMP_INSTALLS = 1 << 16; 16935 public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17; 16936 public static final int DUMP_DOMAIN_PREFERRED = 1 << 18; 16937 16938 public static final int OPTION_SHOW_FILTERS = 1 << 0; 16939 16940 private int mTypes; 16941 16942 private int mOptions; 16943 16944 private boolean mTitlePrinted; 16945 16946 private SharedUserSetting mSharedUser; 16947 16948 public boolean isDumping(int type) { 16949 if (mTypes == 0 && type != DUMP_PREFERRED_XML) { 16950 return true; 16951 } 16952 16953 return (mTypes & type) != 0; 16954 } 16955 16956 public void setDump(int type) { 16957 mTypes |= type; 16958 } 16959 16960 public boolean isOptionEnabled(int option) { 16961 return (mOptions & option) != 0; 16962 } 16963 16964 public void setOptionEnabled(int option) { 16965 mOptions |= option; 16966 } 16967 16968 public boolean onTitlePrinted() { 16969 final boolean printed = mTitlePrinted; 16970 mTitlePrinted = true; 16971 return printed; 16972 } 16973 16974 public boolean getTitlePrinted() { 16975 return mTitlePrinted; 16976 } 16977 16978 public void setTitlePrinted(boolean enabled) { 16979 mTitlePrinted = enabled; 16980 } 16981 16982 public SharedUserSetting getSharedUser() { 16983 return mSharedUser; 16984 } 16985 16986 public void setSharedUser(SharedUserSetting user) { 16987 mSharedUser = user; 16988 } 16989 } 16990 16991 @Override 16992 public void onShellCommand(FileDescriptor in, FileDescriptor out, 16993 FileDescriptor err, String[] args, ResultReceiver resultReceiver) { 16994 (new PackageManagerShellCommand(this)).exec( 16995 this, in, out, err, args, resultReceiver); 16996 } 16997 16998 @Override 16999 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 17000 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 17001 != PackageManager.PERMISSION_GRANTED) { 17002 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 17003 + Binder.getCallingPid() 17004 + ", uid=" + Binder.getCallingUid() 17005 + " without permission " 17006 + android.Manifest.permission.DUMP); 17007 return; 17008 } 17009 17010 DumpState dumpState = new DumpState(); 17011 boolean fullPreferred = false; 17012 boolean checkin = false; 17013 17014 String packageName = null; 17015 ArraySet<String> permissionNames = null; 17016 17017 int opti = 0; 17018 while (opti < args.length) { 17019 String opt = args[opti]; 17020 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 17021 break; 17022 } 17023 opti++; 17024 17025 if ("-a".equals(opt)) { 17026 // Right now we only know how to print all. 17027 } else if ("-h".equals(opt)) { 17028 pw.println("Package manager dump options:"); 17029 pw.println(" [-h] [-f] [--checkin] [cmd] ..."); 17030 pw.println(" --checkin: dump for a checkin"); 17031 pw.println(" -f: print details of intent filters"); 17032 pw.println(" -h: print this help"); 17033 pw.println(" cmd may be one of:"); 17034 pw.println(" l[ibraries]: list known shared libraries"); 17035 pw.println(" f[eatures]: list device features"); 17036 pw.println(" k[eysets]: print known keysets"); 17037 pw.println(" r[esolvers] [activity|service|receiver|content]: dump intent resolvers"); 17038 pw.println(" perm[issions]: dump permissions"); 17039 pw.println(" permission [name ...]: dump declaration and use of given permission"); 17040 pw.println(" pref[erred]: print preferred package settings"); 17041 pw.println(" preferred-xml [--full]: print preferred package settings as xml"); 17042 pw.println(" prov[iders]: dump content providers"); 17043 pw.println(" p[ackages]: dump installed packages"); 17044 pw.println(" s[hared-users]: dump shared user IDs"); 17045 pw.println(" m[essages]: print collected runtime messages"); 17046 pw.println(" v[erifiers]: print package verifier info"); 17047 pw.println(" d[omain-preferred-apps]: print domains preferred apps"); 17048 pw.println(" i[ntent-filter-verifiers]|ifv: print intent filter verifier info"); 17049 pw.println(" version: print database version info"); 17050 pw.println(" write: write current settings now"); 17051 pw.println(" installs: details about install sessions"); 17052 pw.println(" check-permission <permission> <package> [<user>]: does pkg hold perm?"); 17053 pw.println(" <package.name>: info about given package"); 17054 return; 17055 } else if ("--checkin".equals(opt)) { 17056 checkin = true; 17057 } else if ("-f".equals(opt)) { 17058 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 17059 } else { 17060 pw.println("Unknown argument: " + opt + "; use -h for help"); 17061 } 17062 } 17063 17064 // Is the caller requesting to dump a particular piece of data? 17065 if (opti < args.length) { 17066 String cmd = args[opti]; 17067 opti++; 17068 // Is this a package name? 17069 if ("android".equals(cmd) || cmd.contains(".")) { 17070 packageName = cmd; 17071 // When dumping a single package, we always dump all of its 17072 // filter information since the amount of data will be reasonable. 17073 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 17074 } else if ("check-permission".equals(cmd)) { 17075 if (opti >= args.length) { 17076 pw.println("Error: check-permission missing permission argument"); 17077 return; 17078 } 17079 String perm = args[opti]; 17080 opti++; 17081 if (opti >= args.length) { 17082 pw.println("Error: check-permission missing package argument"); 17083 return; 17084 } 17085 String pkg = args[opti]; 17086 opti++; 17087 int user = UserHandle.getUserId(Binder.getCallingUid()); 17088 if (opti < args.length) { 17089 try { 17090 user = Integer.parseInt(args[opti]); 17091 } catch (NumberFormatException e) { 17092 pw.println("Error: check-permission user argument is not a number: " 17093 + args[opti]); 17094 return; 17095 } 17096 } 17097 pw.println(checkPermission(perm, pkg, user)); 17098 return; 17099 } else if ("l".equals(cmd) || "libraries".equals(cmd)) { 17100 dumpState.setDump(DumpState.DUMP_LIBS); 17101 } else if ("f".equals(cmd) || "features".equals(cmd)) { 17102 dumpState.setDump(DumpState.DUMP_FEATURES); 17103 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) { 17104 if (opti >= args.length) { 17105 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS 17106 | DumpState.DUMP_SERVICE_RESOLVERS 17107 | DumpState.DUMP_RECEIVER_RESOLVERS 17108 | DumpState.DUMP_CONTENT_RESOLVERS); 17109 } else { 17110 while (opti < args.length) { 17111 String name = args[opti]; 17112 if ("a".equals(name) || "activity".equals(name)) { 17113 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS); 17114 } else if ("s".equals(name) || "service".equals(name)) { 17115 dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS); 17116 } else if ("r".equals(name) || "receiver".equals(name)) { 17117 dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS); 17118 } else if ("c".equals(name) || "content".equals(name)) { 17119 dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS); 17120 } else { 17121 pw.println("Error: unknown resolver table type: " + name); 17122 return; 17123 } 17124 opti++; 17125 } 17126 } 17127 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) { 17128 dumpState.setDump(DumpState.DUMP_PERMISSIONS); 17129 } else if ("permission".equals(cmd)) { 17130 if (opti >= args.length) { 17131 pw.println("Error: permission requires permission name"); 17132 return; 17133 } 17134 permissionNames = new ArraySet<>(); 17135 while (opti < args.length) { 17136 permissionNames.add(args[opti]); 17137 opti++; 17138 } 17139 dumpState.setDump(DumpState.DUMP_PERMISSIONS 17140 | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS); 17141 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) { 17142 dumpState.setDump(DumpState.DUMP_PREFERRED); 17143 } else if ("preferred-xml".equals(cmd)) { 17144 dumpState.setDump(DumpState.DUMP_PREFERRED_XML); 17145 if (opti < args.length && "--full".equals(args[opti])) { 17146 fullPreferred = true; 17147 opti++; 17148 } 17149 } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) { 17150 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED); 17151 } else if ("p".equals(cmd) || "packages".equals(cmd)) { 17152 dumpState.setDump(DumpState.DUMP_PACKAGES); 17153 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) { 17154 dumpState.setDump(DumpState.DUMP_SHARED_USERS); 17155 } else if ("prov".equals(cmd) || "providers".equals(cmd)) { 17156 dumpState.setDump(DumpState.DUMP_PROVIDERS); 17157 } else if ("m".equals(cmd) || "messages".equals(cmd)) { 17158 dumpState.setDump(DumpState.DUMP_MESSAGES); 17159 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) { 17160 dumpState.setDump(DumpState.DUMP_VERIFIERS); 17161 } else if ("i".equals(cmd) || "ifv".equals(cmd) 17162 || "intent-filter-verifiers".equals(cmd)) { 17163 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS); 17164 } else if ("version".equals(cmd)) { 17165 dumpState.setDump(DumpState.DUMP_VERSION); 17166 } else if ("k".equals(cmd) || "keysets".equals(cmd)) { 17167 dumpState.setDump(DumpState.DUMP_KEYSETS); 17168 } else if ("installs".equals(cmd)) { 17169 dumpState.setDump(DumpState.DUMP_INSTALLS); 17170 } else if ("write".equals(cmd)) { 17171 synchronized (mPackages) { 17172 mSettings.writeLPr(); 17173 pw.println("Settings written."); 17174 return; 17175 } 17176 } 17177 } 17178 17179 if (checkin) { 17180 pw.println("vers,1"); 17181 } 17182 17183 // reader 17184 synchronized (mPackages) { 17185 if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) { 17186 if (!checkin) { 17187 if (dumpState.onTitlePrinted()) 17188 pw.println(); 17189 pw.println("Database versions:"); 17190 mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, " ")); 17191 } 17192 } 17193 17194 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) { 17195 if (!checkin) { 17196 if (dumpState.onTitlePrinted()) 17197 pw.println(); 17198 pw.println("Verifiers:"); 17199 pw.print(" Required: "); 17200 pw.print(mRequiredVerifierPackage); 17201 pw.print(" (uid="); 17202 pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 17203 UserHandle.USER_SYSTEM)); 17204 pw.println(")"); 17205 } else if (mRequiredVerifierPackage != null) { 17206 pw.print("vrfy,"); pw.print(mRequiredVerifierPackage); 17207 pw.print(","); 17208 pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 17209 UserHandle.USER_SYSTEM)); 17210 } 17211 } 17212 17213 if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) && 17214 packageName == null) { 17215 if (mIntentFilterVerifierComponent != null) { 17216 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName(); 17217 if (!checkin) { 17218 if (dumpState.onTitlePrinted()) 17219 pw.println(); 17220 pw.println("Intent Filter Verifier:"); 17221 pw.print(" Using: "); 17222 pw.print(verifierPackageName); 17223 pw.print(" (uid="); 17224 pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING, 17225 UserHandle.USER_SYSTEM)); 17226 pw.println(")"); 17227 } else if (verifierPackageName != null) { 17228 pw.print("ifv,"); pw.print(verifierPackageName); 17229 pw.print(","); 17230 pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING, 17231 UserHandle.USER_SYSTEM)); 17232 } 17233 } else { 17234 pw.println(); 17235 pw.println("No Intent Filter Verifier available!"); 17236 } 17237 } 17238 17239 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) { 17240 boolean printedHeader = false; 17241 final Iterator<String> it = mSharedLibraries.keySet().iterator(); 17242 while (it.hasNext()) { 17243 String name = it.next(); 17244 SharedLibraryEntry ent = mSharedLibraries.get(name); 17245 if (!checkin) { 17246 if (!printedHeader) { 17247 if (dumpState.onTitlePrinted()) 17248 pw.println(); 17249 pw.println("Libraries:"); 17250 printedHeader = true; 17251 } 17252 pw.print(" "); 17253 } else { 17254 pw.print("lib,"); 17255 } 17256 pw.print(name); 17257 if (!checkin) { 17258 pw.print(" -> "); 17259 } 17260 if (ent.path != null) { 17261 if (!checkin) { 17262 pw.print("(jar) "); 17263 pw.print(ent.path); 17264 } else { 17265 pw.print(",jar,"); 17266 pw.print(ent.path); 17267 } 17268 } else { 17269 if (!checkin) { 17270 pw.print("(apk) "); 17271 pw.print(ent.apk); 17272 } else { 17273 pw.print(",apk,"); 17274 pw.print(ent.apk); 17275 } 17276 } 17277 pw.println(); 17278 } 17279 } 17280 17281 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) { 17282 if (dumpState.onTitlePrinted()) 17283 pw.println(); 17284 if (!checkin) { 17285 pw.println("Features:"); 17286 } 17287 17288 for (FeatureInfo feat : mAvailableFeatures.values()) { 17289 if (checkin) { 17290 pw.print("feat,"); 17291 pw.print(feat.name); 17292 pw.print(","); 17293 pw.println(feat.version); 17294 } else { 17295 pw.print(" "); 17296 pw.print(feat.name); 17297 if (feat.version > 0) { 17298 pw.print(" version="); 17299 pw.print(feat.version); 17300 } 17301 pw.println(); 17302 } 17303 } 17304 } 17305 17306 if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) { 17307 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:" 17308 : "Activity Resolver Table:", " ", packageName, 17309 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 17310 dumpState.setTitlePrinted(true); 17311 } 17312 } 17313 if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) { 17314 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:" 17315 : "Receiver Resolver Table:", " ", packageName, 17316 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 17317 dumpState.setTitlePrinted(true); 17318 } 17319 } 17320 if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) { 17321 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:" 17322 : "Service Resolver Table:", " ", packageName, 17323 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 17324 dumpState.setTitlePrinted(true); 17325 } 17326 } 17327 if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) { 17328 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:" 17329 : "Provider Resolver Table:", " ", packageName, 17330 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 17331 dumpState.setTitlePrinted(true); 17332 } 17333 } 17334 17335 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) { 17336 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 17337 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 17338 int user = mSettings.mPreferredActivities.keyAt(i); 17339 if (pir.dump(pw, 17340 dumpState.getTitlePrinted() 17341 ? "\nPreferred Activities User " + user + ":" 17342 : "Preferred Activities User " + user + ":", " ", 17343 packageName, true, false)) { 17344 dumpState.setTitlePrinted(true); 17345 } 17346 } 17347 } 17348 17349 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) { 17350 pw.flush(); 17351 FileOutputStream fout = new FileOutputStream(fd); 17352 BufferedOutputStream str = new BufferedOutputStream(fout); 17353 XmlSerializer serializer = new FastXmlSerializer(); 17354 try { 17355 serializer.setOutput(str, StandardCharsets.UTF_8.name()); 17356 serializer.startDocument(null, true); 17357 serializer.setFeature( 17358 "http://xmlpull.org/v1/doc/features.html#indent-output", true); 17359 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred); 17360 serializer.endDocument(); 17361 serializer.flush(); 17362 } catch (IllegalArgumentException e) { 17363 pw.println("Failed writing: " + e); 17364 } catch (IllegalStateException e) { 17365 pw.println("Failed writing: " + e); 17366 } catch (IOException e) { 17367 pw.println("Failed writing: " + e); 17368 } 17369 } 17370 17371 if (!checkin 17372 && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED) 17373 && packageName == null) { 17374 pw.println(); 17375 int count = mSettings.mPackages.size(); 17376 if (count == 0) { 17377 pw.println("No applications!"); 17378 pw.println(); 17379 } else { 17380 final String prefix = " "; 17381 Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values(); 17382 if (allPackageSettings.size() == 0) { 17383 pw.println("No domain preferred apps!"); 17384 pw.println(); 17385 } else { 17386 pw.println("App verification status:"); 17387 pw.println(); 17388 count = 0; 17389 for (PackageSetting ps : allPackageSettings) { 17390 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo(); 17391 if (ivi == null || ivi.getPackageName() == null) continue; 17392 pw.println(prefix + "Package: " + ivi.getPackageName()); 17393 pw.println(prefix + "Domains: " + ivi.getDomainsString()); 17394 pw.println(prefix + "Status: " + ivi.getStatusString()); 17395 pw.println(); 17396 count++; 17397 } 17398 if (count == 0) { 17399 pw.println(prefix + "No app verification established."); 17400 pw.println(); 17401 } 17402 for (int userId : sUserManager.getUserIds()) { 17403 pw.println("App linkages for user " + userId + ":"); 17404 pw.println(); 17405 count = 0; 17406 for (PackageSetting ps : allPackageSettings) { 17407 final long status = ps.getDomainVerificationStatusForUser(userId); 17408 if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 17409 continue; 17410 } 17411 pw.println(prefix + "Package: " + ps.name); 17412 pw.println(prefix + "Domains: " + dumpDomainString(ps.name)); 17413 String statusStr = IntentFilterVerificationInfo. 17414 getStatusStringFromValue(status); 17415 pw.println(prefix + "Status: " + statusStr); 17416 pw.println(); 17417 count++; 17418 } 17419 if (count == 0) { 17420 pw.println(prefix + "No configured app linkages."); 17421 pw.println(); 17422 } 17423 } 17424 } 17425 } 17426 } 17427 17428 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) { 17429 mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState); 17430 if (packageName == null && permissionNames == null) { 17431 for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) { 17432 if (iperm == 0) { 17433 if (dumpState.onTitlePrinted()) 17434 pw.println(); 17435 pw.println("AppOp Permissions:"); 17436 } 17437 pw.print(" AppOp Permission "); 17438 pw.print(mAppOpPermissionPackages.keyAt(iperm)); 17439 pw.println(":"); 17440 ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm); 17441 for (int ipkg=0; ipkg<pkgs.size(); ipkg++) { 17442 pw.print(" "); pw.println(pkgs.valueAt(ipkg)); 17443 } 17444 } 17445 } 17446 } 17447 17448 if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) { 17449 boolean printedSomething = false; 17450 for (PackageParser.Provider p : mProviders.mProviders.values()) { 17451 if (packageName != null && !packageName.equals(p.info.packageName)) { 17452 continue; 17453 } 17454 if (!printedSomething) { 17455 if (dumpState.onTitlePrinted()) 17456 pw.println(); 17457 pw.println("Registered ContentProviders:"); 17458 printedSomething = true; 17459 } 17460 pw.print(" "); p.printComponentShortName(pw); pw.println(":"); 17461 pw.print(" "); pw.println(p.toString()); 17462 } 17463 printedSomething = false; 17464 for (Map.Entry<String, PackageParser.Provider> entry : 17465 mProvidersByAuthority.entrySet()) { 17466 PackageParser.Provider p = entry.getValue(); 17467 if (packageName != null && !packageName.equals(p.info.packageName)) { 17468 continue; 17469 } 17470 if (!printedSomething) { 17471 if (dumpState.onTitlePrinted()) 17472 pw.println(); 17473 pw.println("ContentProvider Authorities:"); 17474 printedSomething = true; 17475 } 17476 pw.print(" ["); pw.print(entry.getKey()); pw.println("]:"); 17477 pw.print(" "); pw.println(p.toString()); 17478 if (p.info != null && p.info.applicationInfo != null) { 17479 final String appInfo = p.info.applicationInfo.toString(); 17480 pw.print(" applicationInfo="); pw.println(appInfo); 17481 } 17482 } 17483 } 17484 17485 if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) { 17486 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState); 17487 } 17488 17489 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) { 17490 mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin); 17491 } 17492 17493 if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) { 17494 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin); 17495 } 17496 17497 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) { 17498 mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState); 17499 } 17500 17501 if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) { 17502 // XXX should handle packageName != null by dumping only install data that 17503 // the given package is involved with. 17504 if (dumpState.onTitlePrinted()) pw.println(); 17505 mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120)); 17506 } 17507 17508 if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) { 17509 if (dumpState.onTitlePrinted()) pw.println(); 17510 mSettings.dumpReadMessagesLPr(pw, dumpState); 17511 17512 pw.println(); 17513 pw.println("Package warning messages:"); 17514 BufferedReader in = null; 17515 String line = null; 17516 try { 17517 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 17518 while ((line = in.readLine()) != null) { 17519 if (line.contains("ignored: updated version")) continue; 17520 pw.println(line); 17521 } 17522 } catch (IOException ignored) { 17523 } finally { 17524 IoUtils.closeQuietly(in); 17525 } 17526 } 17527 17528 if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) { 17529 BufferedReader in = null; 17530 String line = null; 17531 try { 17532 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 17533 while ((line = in.readLine()) != null) { 17534 if (line.contains("ignored: updated version")) continue; 17535 pw.print("msg,"); 17536 pw.println(line); 17537 } 17538 } catch (IOException ignored) { 17539 } finally { 17540 IoUtils.closeQuietly(in); 17541 } 17542 } 17543 } 17544 } 17545 17546 private String dumpDomainString(String packageName) { 17547 List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName) 17548 .getList(); 17549 List<IntentFilter> filters = getAllIntentFilters(packageName).getList(); 17550 17551 ArraySet<String> result = new ArraySet<>(); 17552 if (iviList.size() > 0) { 17553 for (IntentFilterVerificationInfo ivi : iviList) { 17554 for (String host : ivi.getDomains()) { 17555 result.add(host); 17556 } 17557 } 17558 } 17559 if (filters != null && filters.size() > 0) { 17560 for (IntentFilter filter : filters) { 17561 if (filter.hasCategory(Intent.CATEGORY_BROWSABLE) 17562 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 17563 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) { 17564 result.addAll(filter.getHostsList()); 17565 } 17566 } 17567 } 17568 17569 StringBuilder sb = new StringBuilder(result.size() * 16); 17570 for (String domain : result) { 17571 if (sb.length() > 0) sb.append(" "); 17572 sb.append(domain); 17573 } 17574 return sb.toString(); 17575 } 17576 17577 // ------- apps on sdcard specific code ------- 17578 static final boolean DEBUG_SD_INSTALL = false; 17579 17580 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD"; 17581 17582 private static final String SD_ENCRYPTION_ALGORITHM = "AES"; 17583 17584 private boolean mMediaMounted = false; 17585 17586 static String getEncryptKey() { 17587 try { 17588 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString( 17589 SD_ENCRYPTION_KEYSTORE_NAME); 17590 if (sdEncKey == null) { 17591 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128, 17592 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME); 17593 if (sdEncKey == null) { 17594 Slog.e(TAG, "Failed to create encryption keys"); 17595 return null; 17596 } 17597 } 17598 return sdEncKey; 17599 } catch (NoSuchAlgorithmException nsae) { 17600 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae); 17601 return null; 17602 } catch (IOException ioe) { 17603 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe); 17604 return null; 17605 } 17606 } 17607 17608 /* 17609 * Update media status on PackageManager. 17610 */ 17611 @Override 17612 public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) { 17613 int callingUid = Binder.getCallingUid(); 17614 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 17615 throw new SecurityException("Media status can only be updated by the system"); 17616 } 17617 // reader; this apparently protects mMediaMounted, but should probably 17618 // be a different lock in that case. 17619 synchronized (mPackages) { 17620 Log.i(TAG, "Updating external media status from " 17621 + (mMediaMounted ? "mounted" : "unmounted") + " to " 17622 + (mediaStatus ? "mounted" : "unmounted")); 17623 if (DEBUG_SD_INSTALL) 17624 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus 17625 + ", mMediaMounted=" + mMediaMounted); 17626 if (mediaStatus == mMediaMounted) { 17627 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 17628 : 0, -1); 17629 mHandler.sendMessage(msg); 17630 return; 17631 } 17632 mMediaMounted = mediaStatus; 17633 } 17634 // Queue up an async operation since the package installation may take a 17635 // little while. 17636 mHandler.post(new Runnable() { 17637 public void run() { 17638 updateExternalMediaStatusInner(mediaStatus, reportStatus, true); 17639 } 17640 }); 17641 } 17642 17643 /** 17644 * Called by MountService when the initial ASECs to scan are available. 17645 * Should block until all the ASEC containers are finished being scanned. 17646 */ 17647 public void scanAvailableAsecs() { 17648 updateExternalMediaStatusInner(true, false, false); 17649 } 17650 17651 /* 17652 * Collect information of applications on external media, map them against 17653 * existing containers and update information based on current mount status. 17654 * Please note that we always have to report status if reportStatus has been 17655 * set to true especially when unloading packages. 17656 */ 17657 private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus, 17658 boolean externalStorage) { 17659 ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>(); 17660 int[] uidArr = EmptyArray.INT; 17661 17662 final String[] list = PackageHelper.getSecureContainerList(); 17663 if (ArrayUtils.isEmpty(list)) { 17664 Log.i(TAG, "No secure containers found"); 17665 } else { 17666 // Process list of secure containers and categorize them 17667 // as active or stale based on their package internal state. 17668 17669 // reader 17670 synchronized (mPackages) { 17671 for (String cid : list) { 17672 // Leave stages untouched for now; installer service owns them 17673 if (PackageInstallerService.isStageName(cid)) continue; 17674 17675 if (DEBUG_SD_INSTALL) 17676 Log.i(TAG, "Processing container " + cid); 17677 String pkgName = getAsecPackageName(cid); 17678 if (pkgName == null) { 17679 Slog.i(TAG, "Found stale container " + cid + " with no package name"); 17680 continue; 17681 } 17682 if (DEBUG_SD_INSTALL) 17683 Log.i(TAG, "Looking for pkg : " + pkgName); 17684 17685 final PackageSetting ps = mSettings.mPackages.get(pkgName); 17686 if (ps == null) { 17687 Slog.i(TAG, "Found stale container " + cid + " with no matching settings"); 17688 continue; 17689 } 17690 17691 /* 17692 * Skip packages that are not external if we're unmounting 17693 * external storage. 17694 */ 17695 if (externalStorage && !isMounted && !isExternal(ps)) { 17696 continue; 17697 } 17698 17699 final AsecInstallArgs args = new AsecInstallArgs(cid, 17700 getAppDexInstructionSets(ps), ps.isForwardLocked()); 17701 // The package status is changed only if the code path 17702 // matches between settings and the container id. 17703 if (ps.codePathString != null 17704 && ps.codePathString.startsWith(args.getCodePath())) { 17705 if (DEBUG_SD_INSTALL) { 17706 Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName 17707 + " at code path: " + ps.codePathString); 17708 } 17709 17710 // We do have a valid package installed on sdcard 17711 processCids.put(args, ps.codePathString); 17712 final int uid = ps.appId; 17713 if (uid != -1) { 17714 uidArr = ArrayUtils.appendInt(uidArr, uid); 17715 } 17716 } else { 17717 Slog.i(TAG, "Found stale container " + cid + ": expected codePath=" 17718 + ps.codePathString); 17719 } 17720 } 17721 } 17722 17723 Arrays.sort(uidArr); 17724 } 17725 17726 // Process packages with valid entries. 17727 if (isMounted) { 17728 if (DEBUG_SD_INSTALL) 17729 Log.i(TAG, "Loading packages"); 17730 loadMediaPackages(processCids, uidArr, externalStorage); 17731 startCleaningPackages(); 17732 mInstallerService.onSecureContainersAvailable(); 17733 } else { 17734 if (DEBUG_SD_INSTALL) 17735 Log.i(TAG, "Unloading packages"); 17736 unloadMediaPackages(processCids, uidArr, reportStatus); 17737 } 17738 } 17739 17740 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 17741 ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) { 17742 final int size = infos.size(); 17743 final String[] packageNames = new String[size]; 17744 final int[] packageUids = new int[size]; 17745 for (int i = 0; i < size; i++) { 17746 final ApplicationInfo info = infos.get(i); 17747 packageNames[i] = info.packageName; 17748 packageUids[i] = info.uid; 17749 } 17750 sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids, 17751 finishedReceiver); 17752 } 17753 17754 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 17755 ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 17756 sendResourcesChangedBroadcast(mediaStatus, replacing, 17757 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver); 17758 } 17759 17760 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 17761 String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 17762 int size = pkgList.length; 17763 if (size > 0) { 17764 // Send broadcasts here 17765 Bundle extras = new Bundle(); 17766 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 17767 if (uidArr != null) { 17768 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr); 17769 } 17770 if (replacing) { 17771 extras.putBoolean(Intent.EXTRA_REPLACING, replacing); 17772 } 17773 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE 17774 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE; 17775 sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null); 17776 } 17777 } 17778 17779 /* 17780 * Look at potentially valid container ids from processCids If package 17781 * information doesn't match the one on record or package scanning fails, 17782 * the cid is added to list of removeCids. We currently don't delete stale 17783 * containers. 17784 */ 17785 private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr, 17786 boolean externalStorage) { 17787 ArrayList<String> pkgList = new ArrayList<String>(); 17788 Set<AsecInstallArgs> keys = processCids.keySet(); 17789 17790 for (AsecInstallArgs args : keys) { 17791 String codePath = processCids.get(args); 17792 if (DEBUG_SD_INSTALL) 17793 Log.i(TAG, "Loading container : " + args.cid); 17794 int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 17795 try { 17796 // Make sure there are no container errors first. 17797 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) { 17798 Slog.e(TAG, "Failed to mount cid : " + args.cid 17799 + " when installing from sdcard"); 17800 continue; 17801 } 17802 // Check code path here. 17803 if (codePath == null || !codePath.startsWith(args.getCodePath())) { 17804 Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath() 17805 + " does not match one in settings " + codePath); 17806 continue; 17807 } 17808 // Parse package 17809 int parseFlags = mDefParseFlags; 17810 if (args.isExternalAsec()) { 17811 parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE; 17812 } 17813 if (args.isFwdLocked()) { 17814 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 17815 } 17816 17817 synchronized (mInstallLock) { 17818 PackageParser.Package pkg = null; 17819 try { 17820 pkg = scanPackageTracedLI(new File(codePath), parseFlags, 0, 0, null); 17821 } catch (PackageManagerException e) { 17822 Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage()); 17823 } 17824 // Scan the package 17825 if (pkg != null) { 17826 /* 17827 * TODO why is the lock being held? doPostInstall is 17828 * called in other places without the lock. This needs 17829 * to be straightened out. 17830 */ 17831 // writer 17832 synchronized (mPackages) { 17833 retCode = PackageManager.INSTALL_SUCCEEDED; 17834 pkgList.add(pkg.packageName); 17835 // Post process args 17836 args.doPostInstall(PackageManager.INSTALL_SUCCEEDED, 17837 pkg.applicationInfo.uid); 17838 } 17839 } else { 17840 Slog.i(TAG, "Failed to install pkg from " + codePath + " from sdcard"); 17841 } 17842 } 17843 17844 } finally { 17845 if (retCode != PackageManager.INSTALL_SUCCEEDED) { 17846 Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode); 17847 } 17848 } 17849 } 17850 // writer 17851 synchronized (mPackages) { 17852 // If the platform SDK has changed since the last time we booted, 17853 // we need to re-grant app permission to catch any new ones that 17854 // appear. This is really a hack, and means that apps can in some 17855 // cases get permissions that the user didn't initially explicitly 17856 // allow... it would be nice to have some better way to handle 17857 // this situation. 17858 final VersionInfo ver = externalStorage ? mSettings.getExternalVersion() 17859 : mSettings.getInternalVersion(); 17860 final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL 17861 : StorageManager.UUID_PRIVATE_INTERNAL; 17862 17863 int updateFlags = UPDATE_PERMISSIONS_ALL; 17864 if (ver.sdkVersion != mSdkVersion) { 17865 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " 17866 + mSdkVersion + "; regranting permissions for external"); 17867 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 17868 } 17869 updatePermissionsLPw(null, null, volumeUuid, updateFlags); 17870 17871 // Yay, everything is now upgraded 17872 ver.forceCurrent(); 17873 17874 // can downgrade to reader 17875 // Persist settings 17876 mSettings.writeLPr(); 17877 } 17878 // Send a broadcast to let everyone know we are done processing 17879 if (pkgList.size() > 0) { 17880 sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null); 17881 } 17882 } 17883 17884 /* 17885 * Utility method to unload a list of specified containers 17886 */ 17887 private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) { 17888 // Just unmount all valid containers. 17889 for (AsecInstallArgs arg : cidArgs) { 17890 synchronized (mInstallLock) { 17891 arg.doPostDeleteLI(false); 17892 } 17893 } 17894 } 17895 17896 /* 17897 * Unload packages mounted on external media. This involves deleting package 17898 * data from internal structures, sending broadcasts about disabled packages, 17899 * gc'ing to free up references, unmounting all secure containers 17900 * corresponding to packages on external media, and posting a 17901 * UPDATED_MEDIA_STATUS message if status has been requested. Please note 17902 * that we always have to post this message if status has been requested no 17903 * matter what. 17904 */ 17905 private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[], 17906 final boolean reportStatus) { 17907 if (DEBUG_SD_INSTALL) 17908 Log.i(TAG, "unloading media packages"); 17909 ArrayList<String> pkgList = new ArrayList<String>(); 17910 ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>(); 17911 final Set<AsecInstallArgs> keys = processCids.keySet(); 17912 for (AsecInstallArgs args : keys) { 17913 String pkgName = args.getPackageName(); 17914 if (DEBUG_SD_INSTALL) 17915 Log.i(TAG, "Trying to unload pkg : " + pkgName); 17916 // Delete package internally 17917 PackageRemovedInfo outInfo = new PackageRemovedInfo(); 17918 synchronized (mInstallLock) { 17919 boolean res = deletePackageLI(pkgName, null, false, null, 17920 PackageManager.DELETE_KEEP_DATA, outInfo, false, null); 17921 if (res) { 17922 pkgList.add(pkgName); 17923 } else { 17924 Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName); 17925 failedList.add(args); 17926 } 17927 } 17928 } 17929 17930 // reader 17931 synchronized (mPackages) { 17932 // We didn't update the settings after removing each package; 17933 // write them now for all packages. 17934 mSettings.writeLPr(); 17935 } 17936 17937 // We have to absolutely send UPDATED_MEDIA_STATUS only 17938 // after confirming that all the receivers processed the ordered 17939 // broadcast when packages get disabled, force a gc to clean things up. 17940 // and unload all the containers. 17941 if (pkgList.size() > 0) { 17942 sendResourcesChangedBroadcast(false, false, pkgList, uidArr, 17943 new IIntentReceiver.Stub() { 17944 public void performReceive(Intent intent, int resultCode, String data, 17945 Bundle extras, boolean ordered, boolean sticky, 17946 int sendingUser) throws RemoteException { 17947 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, 17948 reportStatus ? 1 : 0, 1, keys); 17949 mHandler.sendMessage(msg); 17950 } 17951 }); 17952 } else { 17953 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1, 17954 keys); 17955 mHandler.sendMessage(msg); 17956 } 17957 } 17958 17959 private void loadPrivatePackages(final VolumeInfo vol) { 17960 mHandler.post(new Runnable() { 17961 @Override 17962 public void run() { 17963 loadPrivatePackagesInner(vol); 17964 } 17965 }); 17966 } 17967 17968 private void loadPrivatePackagesInner(VolumeInfo vol) { 17969 final String volumeUuid = vol.fsUuid; 17970 if (TextUtils.isEmpty(volumeUuid)) { 17971 Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring"); 17972 return; 17973 } 17974 17975 final ArrayList<ApplicationInfo> loaded = new ArrayList<>(); 17976 final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE; 17977 17978 final VersionInfo ver; 17979 final List<PackageSetting> packages; 17980 synchronized (mPackages) { 17981 ver = mSettings.findOrCreateVersion(volumeUuid); 17982 packages = mSettings.getVolumePackagesLPr(volumeUuid); 17983 } 17984 17985 // TODO: introduce a new concept similar to "frozen" to prevent these 17986 // apps from being launched until after data has been fully reconciled 17987 for (PackageSetting ps : packages) { 17988 synchronized (mInstallLock) { 17989 final PackageParser.Package pkg; 17990 try { 17991 pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null); 17992 loaded.add(pkg.applicationInfo); 17993 17994 } catch (PackageManagerException e) { 17995 Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage()); 17996 } 17997 17998 if (!Build.FINGERPRINT.equals(ver.fingerprint)) { 17999 deleteCodeCacheDirsLI(ps.volumeUuid, ps.name); 18000 } 18001 } 18002 } 18003 18004 // Reconcile app data for all started/unlocked users 18005 final StorageManager sm = mContext.getSystemService(StorageManager.class); 18006 final UserManager um = mContext.getSystemService(UserManager.class); 18007 for (UserInfo user : um.getUsers()) { 18008 final int flags; 18009 if (um.isUserUnlocked(user.id)) { 18010 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 18011 } else if (um.isUserRunning(user.id)) { 18012 flags = StorageManager.FLAG_STORAGE_DE; 18013 } else { 18014 continue; 18015 } 18016 18017 sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags); 18018 reconcileAppsData(volumeUuid, user.id, flags); 18019 } 18020 18021 synchronized (mPackages) { 18022 int updateFlags = UPDATE_PERMISSIONS_ALL; 18023 if (ver.sdkVersion != mSdkVersion) { 18024 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " 18025 + mSdkVersion + "; regranting permissions for " + volumeUuid); 18026 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 18027 } 18028 updatePermissionsLPw(null, null, volumeUuid, updateFlags); 18029 18030 // Yay, everything is now upgraded 18031 ver.forceCurrent(); 18032 18033 mSettings.writeLPr(); 18034 } 18035 18036 if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded); 18037 sendResourcesChangedBroadcast(true, false, loaded, null); 18038 } 18039 18040 private void unloadPrivatePackages(final VolumeInfo vol) { 18041 mHandler.post(new Runnable() { 18042 @Override 18043 public void run() { 18044 unloadPrivatePackagesInner(vol); 18045 } 18046 }); 18047 } 18048 18049 private void unloadPrivatePackagesInner(VolumeInfo vol) { 18050 final String volumeUuid = vol.fsUuid; 18051 if (TextUtils.isEmpty(volumeUuid)) { 18052 Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring"); 18053 return; 18054 } 18055 18056 final ArrayList<ApplicationInfo> unloaded = new ArrayList<>(); 18057 synchronized (mInstallLock) { 18058 synchronized (mPackages) { 18059 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid); 18060 for (PackageSetting ps : packages) { 18061 if (ps.pkg == null) continue; 18062 18063 final ApplicationInfo info = ps.pkg.applicationInfo; 18064 final PackageRemovedInfo outInfo = new PackageRemovedInfo(); 18065 if (deletePackageLI(ps.name, null, false, null, 18066 PackageManager.DELETE_KEEP_DATA, outInfo, false, null)) { 18067 unloaded.add(info); 18068 } else { 18069 Slog.w(TAG, "Failed to unload " + ps.codePath); 18070 } 18071 } 18072 18073 mSettings.writeLPr(); 18074 } 18075 } 18076 18077 if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded); 18078 sendResourcesChangedBroadcast(false, false, unloaded, null); 18079 } 18080 18081 /** 18082 * Examine all users present on given mounted volume, and destroy data 18083 * belonging to users that are no longer valid, or whose user ID has been 18084 * recycled. 18085 */ 18086 private void reconcileUsers(String volumeUuid) { 18087 // TODO: also reconcile DE directories 18088 final File[] files = FileUtils 18089 .listFilesOrEmpty(Environment.getDataUserCeDirectory(volumeUuid)); 18090 for (File file : files) { 18091 if (!file.isDirectory()) continue; 18092 18093 final int userId; 18094 final UserInfo info; 18095 try { 18096 userId = Integer.parseInt(file.getName()); 18097 info = sUserManager.getUserInfo(userId); 18098 } catch (NumberFormatException e) { 18099 Slog.w(TAG, "Invalid user directory " + file); 18100 continue; 18101 } 18102 18103 boolean destroyUser = false; 18104 if (info == null) { 18105 logCriticalInfo(Log.WARN, "Destroying user directory " + file 18106 + " because no matching user was found"); 18107 destroyUser = true; 18108 } else { 18109 try { 18110 UserManagerService.enforceSerialNumber(file, info.serialNumber); 18111 } catch (IOException e) { 18112 logCriticalInfo(Log.WARN, "Destroying user directory " + file 18113 + " because we failed to enforce serial number: " + e); 18114 destroyUser = true; 18115 } 18116 } 18117 18118 if (destroyUser) { 18119 synchronized (mInstallLock) { 18120 try { 18121 mInstaller.removeUserDataDirs(volumeUuid, userId); 18122 } catch (InstallerException e) { 18123 Slog.w(TAG, "Failed to clean up user dirs", e); 18124 } 18125 } 18126 } 18127 } 18128 } 18129 18130 private void assertPackageKnown(String volumeUuid, String packageName) 18131 throws PackageManagerException { 18132 synchronized (mPackages) { 18133 final PackageSetting ps = mSettings.mPackages.get(packageName); 18134 if (ps == null) { 18135 throw new PackageManagerException("Package " + packageName + " is unknown"); 18136 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) { 18137 throw new PackageManagerException( 18138 "Package " + packageName + " found on unknown volume " + volumeUuid 18139 + "; expected volume " + ps.volumeUuid); 18140 } 18141 } 18142 } 18143 18144 private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId) 18145 throws PackageManagerException { 18146 synchronized (mPackages) { 18147 final PackageSetting ps = mSettings.mPackages.get(packageName); 18148 if (ps == null) { 18149 throw new PackageManagerException("Package " + packageName + " is unknown"); 18150 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) { 18151 throw new PackageManagerException( 18152 "Package " + packageName + " found on unknown volume " + volumeUuid 18153 + "; expected volume " + ps.volumeUuid); 18154 } else if (!ps.getInstalled(userId)) { 18155 throw new PackageManagerException( 18156 "Package " + packageName + " not installed for user " + userId); 18157 } 18158 } 18159 } 18160 18161 /** 18162 * Examine all apps present on given mounted volume, and destroy apps that 18163 * aren't expected, either due to uninstallation or reinstallation on 18164 * another volume. 18165 */ 18166 private void reconcileApps(String volumeUuid) { 18167 final File[] files = FileUtils 18168 .listFilesOrEmpty(Environment.getDataAppDirectory(volumeUuid)); 18169 for (File file : files) { 18170 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 18171 && !PackageInstallerService.isStageName(file.getName()); 18172 if (!isPackage) { 18173 // Ignore entries which are not packages 18174 continue; 18175 } 18176 18177 try { 18178 final PackageLite pkg = PackageParser.parsePackageLite(file, 18179 PackageParser.PARSE_MUST_BE_APK); 18180 assertPackageKnown(volumeUuid, pkg.packageName); 18181 18182 } catch (PackageParserException | PackageManagerException e) { 18183 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 18184 synchronized (mInstallLock) { 18185 removeCodePathLI(file); 18186 } 18187 } 18188 } 18189 } 18190 18191 /** 18192 * Reconcile all app data for the given user. 18193 * <p> 18194 * Verifies that directories exist and that ownership and labeling is 18195 * correct for all installed apps on all mounted volumes. 18196 */ 18197 void reconcileAppsData(int userId, int flags) { 18198 final StorageManager storage = mContext.getSystemService(StorageManager.class); 18199 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 18200 final String volumeUuid = vol.getFsUuid(); 18201 reconcileAppsData(volumeUuid, userId, flags); 18202 } 18203 } 18204 18205 /** 18206 * Reconcile all app data on given mounted volume. 18207 * <p> 18208 * Destroys app data that isn't expected, either due to uninstallation or 18209 * reinstallation on another volume. 18210 * <p> 18211 * Verifies that directories exist and that ownership and labeling is 18212 * correct for all installed apps. 18213 */ 18214 private void reconcileAppsData(String volumeUuid, int userId, int flags) { 18215 Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x" 18216 + Integer.toHexString(flags)); 18217 18218 final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId); 18219 final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId); 18220 18221 boolean restoreconNeeded = false; 18222 18223 // First look for stale data that doesn't belong, and check if things 18224 // have changed since we did our last restorecon 18225 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 18226 if (!isUserKeyUnlocked(userId)) { 18227 throw new RuntimeException( 18228 "Yikes, someone asked us to reconcile CE storage while " + userId 18229 + " was still locked; this would have caused massive data loss!"); 18230 } 18231 18232 restoreconNeeded |= SELinuxMMAC.isRestoreconNeeded(ceDir); 18233 18234 final File[] files = FileUtils.listFilesOrEmpty(ceDir); 18235 for (File file : files) { 18236 final String packageName = file.getName(); 18237 try { 18238 assertPackageKnownAndInstalled(volumeUuid, packageName, userId); 18239 } catch (PackageManagerException e) { 18240 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 18241 synchronized (mInstallLock) { 18242 destroyAppDataLI(volumeUuid, packageName, userId, 18243 StorageManager.FLAG_STORAGE_CE); 18244 } 18245 } 18246 } 18247 } 18248 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) { 18249 restoreconNeeded |= SELinuxMMAC.isRestoreconNeeded(deDir); 18250 18251 final File[] files = FileUtils.listFilesOrEmpty(deDir); 18252 for (File file : files) { 18253 final String packageName = file.getName(); 18254 try { 18255 assertPackageKnownAndInstalled(volumeUuid, packageName, userId); 18256 } catch (PackageManagerException e) { 18257 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 18258 synchronized (mInstallLock) { 18259 destroyAppDataLI(volumeUuid, packageName, userId, 18260 StorageManager.FLAG_STORAGE_DE); 18261 } 18262 } 18263 } 18264 } 18265 18266 // Ensure that data directories are ready to roll for all packages 18267 // installed for this volume and user 18268 final List<PackageSetting> packages; 18269 synchronized (mPackages) { 18270 packages = mSettings.getVolumePackagesLPr(volumeUuid); 18271 } 18272 int preparedCount = 0; 18273 for (PackageSetting ps : packages) { 18274 final String packageName = ps.name; 18275 if (ps.pkg == null) { 18276 Slog.w(TAG, "Odd, missing scanned package " + packageName); 18277 // TODO: might be due to legacy ASEC apps; we should circle back 18278 // and reconcile again once they're scanned 18279 continue; 18280 } 18281 18282 if (ps.getInstalled(userId)) { 18283 prepareAppData(volumeUuid, userId, flags, ps.pkg, restoreconNeeded); 18284 18285 if (maybeMigrateAppData(volumeUuid, userId, ps.pkg)) { 18286 // We may have just shuffled around app data directories, so 18287 // prepare them one more time 18288 prepareAppData(volumeUuid, userId, flags, ps.pkg, restoreconNeeded); 18289 } 18290 18291 preparedCount++; 18292 } 18293 } 18294 18295 if (restoreconNeeded) { 18296 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 18297 SELinuxMMAC.setRestoreconDone(ceDir); 18298 } 18299 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) { 18300 SELinuxMMAC.setRestoreconDone(deDir); 18301 } 18302 } 18303 18304 Slog.v(TAG, "reconcileAppsData finished " + preparedCount 18305 + " packages; restoreconNeeded was " + restoreconNeeded); 18306 } 18307 18308 /** 18309 * Prepare app data for the given app just after it was installed or 18310 * upgraded. This method carefully only touches users that it's installed 18311 * for, and it forces a restorecon to handle any seinfo changes. 18312 * <p> 18313 * Verifies that directories exist and that ownership and labeling is 18314 * correct for all installed apps. If there is an ownership mismatch, it 18315 * will try recovering system apps by wiping data; third-party app data is 18316 * left intact. 18317 * <p> 18318 * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em> 18319 */ 18320 private void prepareAppDataAfterInstall(PackageParser.Package pkg) { 18321 prepareAppDataAfterInstallInternal(pkg); 18322 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 18323 for (int i = 0; i < childCount; i++) { 18324 PackageParser.Package childPackage = pkg.childPackages.get(i); 18325 prepareAppDataAfterInstallInternal(childPackage); 18326 } 18327 } 18328 18329 private void prepareAppDataAfterInstallInternal(PackageParser.Package pkg) { 18330 final PackageSetting ps; 18331 synchronized (mPackages) { 18332 ps = mSettings.mPackages.get(pkg.packageName); 18333 mSettings.writeKernelMappingLPr(ps); 18334 } 18335 18336 final UserManager um = mContext.getSystemService(UserManager.class); 18337 for (UserInfo user : um.getUsers()) { 18338 final int flags; 18339 if (um.isUserUnlocked(user.id)) { 18340 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 18341 } else if (um.isUserRunning(user.id)) { 18342 flags = StorageManager.FLAG_STORAGE_DE; 18343 } else { 18344 continue; 18345 } 18346 18347 if (ps.getInstalled(user.id)) { 18348 // Whenever an app changes, force a restorecon of its data 18349 // TODO: when user data is locked, mark that we're still dirty 18350 prepareAppData(pkg.volumeUuid, user.id, flags, pkg, true); 18351 } 18352 } 18353 } 18354 18355 /** 18356 * Prepare app data for the given app. 18357 * <p> 18358 * Verifies that directories exist and that ownership and labeling is 18359 * correct for all installed apps. If there is an ownership mismatch, this 18360 * will try recovering system apps by wiping data; third-party app data is 18361 * left intact. 18362 */ 18363 private void prepareAppData(String volumeUuid, int userId, int flags, 18364 PackageParser.Package pkg, boolean restoreconNeeded) { 18365 if (DEBUG_APP_DATA) { 18366 Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x" 18367 + Integer.toHexString(flags) + (restoreconNeeded ? " restoreconNeeded" : "")); 18368 } 18369 18370 final String packageName = pkg.packageName; 18371 final ApplicationInfo app = pkg.applicationInfo; 18372 final int appId = UserHandle.getAppId(app.uid); 18373 18374 Preconditions.checkNotNull(app.seinfo); 18375 18376 synchronized (mInstallLock) { 18377 try { 18378 mInstaller.createAppData(volumeUuid, packageName, userId, flags, 18379 appId, app.seinfo, app.targetSdkVersion); 18380 } catch (InstallerException e) { 18381 if (app.isSystemApp()) { 18382 logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName 18383 + ", but trying to recover: " + e); 18384 destroyAppDataLI(volumeUuid, packageName, userId, flags); 18385 try { 18386 mInstaller.createAppData(volumeUuid, packageName, userId, flags, 18387 appId, app.seinfo, app.targetSdkVersion); 18388 logCriticalInfo(Log.DEBUG, "Recovery succeeded!"); 18389 } catch (InstallerException e2) { 18390 logCriticalInfo(Log.DEBUG, "Recovery failed!"); 18391 } 18392 } else { 18393 Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e); 18394 } 18395 } 18396 18397 if (restoreconNeeded) { 18398 restoreconAppDataLI(volumeUuid, packageName, userId, flags, appId, app.seinfo); 18399 } 18400 18401 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 18402 // Create a native library symlink only if we have native libraries 18403 // and if the native libraries are 32 bit libraries. We do not provide 18404 // this symlink for 64 bit libraries. 18405 if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) { 18406 final String nativeLibPath = app.nativeLibraryDir; 18407 try { 18408 mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName, 18409 nativeLibPath, userId); 18410 } catch (InstallerException e) { 18411 Slog.e(TAG, "Failed to link native for " + packageName + ": " + e); 18412 } 18413 } 18414 } 18415 } 18416 } 18417 18418 /** 18419 * For system apps on non-FBE devices, this method migrates any existing 18420 * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag 18421 * requested by the app. 18422 */ 18423 private boolean maybeMigrateAppData(String volumeUuid, int userId, PackageParser.Package pkg) { 18424 if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated() 18425 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) { 18426 final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage() 18427 ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE; 18428 synchronized (mInstallLock) { 18429 try { 18430 mInstaller.migrateAppData(volumeUuid, pkg.packageName, userId, storageTarget); 18431 } catch (InstallerException e) { 18432 logCriticalInfo(Log.WARN, 18433 "Failed to migrate " + pkg.packageName + ": " + e.getMessage()); 18434 } 18435 } 18436 return true; 18437 } else { 18438 return false; 18439 } 18440 } 18441 18442 private void unfreezePackage(String packageName) { 18443 synchronized (mPackages) { 18444 final PackageSetting ps = mSettings.mPackages.get(packageName); 18445 if (ps != null) { 18446 ps.frozen = false; 18447 } 18448 } 18449 } 18450 18451 @Override 18452 public int movePackage(final String packageName, final String volumeUuid) { 18453 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 18454 18455 final int moveId = mNextMoveId.getAndIncrement(); 18456 mHandler.post(new Runnable() { 18457 @Override 18458 public void run() { 18459 try { 18460 movePackageInternal(packageName, volumeUuid, moveId); 18461 } catch (PackageManagerException e) { 18462 Slog.w(TAG, "Failed to move " + packageName, e); 18463 mMoveCallbacks.notifyStatusChanged(moveId, 18464 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 18465 } 18466 } 18467 }); 18468 return moveId; 18469 } 18470 18471 private void movePackageInternal(final String packageName, final String volumeUuid, 18472 final int moveId) throws PackageManagerException { 18473 final UserHandle user = new UserHandle(UserHandle.getCallingUserId()); 18474 final StorageManager storage = mContext.getSystemService(StorageManager.class); 18475 final PackageManager pm = mContext.getPackageManager(); 18476 18477 final boolean currentAsec; 18478 final String currentVolumeUuid; 18479 final File codeFile; 18480 final String installerPackageName; 18481 final String packageAbiOverride; 18482 final int appId; 18483 final String seinfo; 18484 final String label; 18485 final int targetSdkVersion; 18486 18487 // reader 18488 synchronized (mPackages) { 18489 final PackageParser.Package pkg = mPackages.get(packageName); 18490 final PackageSetting ps = mSettings.mPackages.get(packageName); 18491 if (pkg == null || ps == null) { 18492 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package"); 18493 } 18494 18495 if (pkg.applicationInfo.isSystemApp()) { 18496 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE, 18497 "Cannot move system application"); 18498 } 18499 18500 if (pkg.applicationInfo.isExternalAsec()) { 18501 currentAsec = true; 18502 currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL; 18503 } else if (pkg.applicationInfo.isForwardLocked()) { 18504 currentAsec = true; 18505 currentVolumeUuid = "forward_locked"; 18506 } else { 18507 currentAsec = false; 18508 currentVolumeUuid = ps.volumeUuid; 18509 18510 final File probe = new File(pkg.codePath); 18511 final File probeOat = new File(probe, "oat"); 18512 if (!probe.isDirectory() || !probeOat.isDirectory()) { 18513 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 18514 "Move only supported for modern cluster style installs"); 18515 } 18516 } 18517 18518 if (Objects.equals(currentVolumeUuid, volumeUuid)) { 18519 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 18520 "Package already moved to " + volumeUuid); 18521 } 18522 if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) { 18523 throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN, 18524 "Device admin cannot be moved"); 18525 } 18526 18527 if (ps.frozen) { 18528 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING, 18529 "Failed to move already frozen package"); 18530 } 18531 ps.frozen = true; 18532 18533 codeFile = new File(pkg.codePath); 18534 installerPackageName = ps.installerPackageName; 18535 packageAbiOverride = ps.cpuAbiOverrideString; 18536 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 18537 seinfo = pkg.applicationInfo.seinfo; 18538 label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo)); 18539 targetSdkVersion = pkg.applicationInfo.targetSdkVersion; 18540 } 18541 18542 // Now that we're guarded by frozen state, kill app during move 18543 final long token = Binder.clearCallingIdentity(); 18544 try { 18545 killApplication(packageName, appId, "move pkg"); 18546 } finally { 18547 Binder.restoreCallingIdentity(token); 18548 } 18549 18550 final Bundle extras = new Bundle(); 18551 extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName); 18552 extras.putString(Intent.EXTRA_TITLE, label); 18553 mMoveCallbacks.notifyCreated(moveId, extras); 18554 18555 int installFlags; 18556 final boolean moveCompleteApp; 18557 final File measurePath; 18558 18559 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) { 18560 installFlags = INSTALL_INTERNAL; 18561 moveCompleteApp = !currentAsec; 18562 measurePath = Environment.getDataAppDirectory(volumeUuid); 18563 } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) { 18564 installFlags = INSTALL_EXTERNAL; 18565 moveCompleteApp = false; 18566 measurePath = storage.getPrimaryPhysicalVolume().getPath(); 18567 } else { 18568 final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid); 18569 if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE 18570 || !volume.isMountedWritable()) { 18571 unfreezePackage(packageName); 18572 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 18573 "Move location not mounted private volume"); 18574 } 18575 18576 Preconditions.checkState(!currentAsec); 18577 18578 installFlags = INSTALL_INTERNAL; 18579 moveCompleteApp = true; 18580 measurePath = Environment.getDataAppDirectory(volumeUuid); 18581 } 18582 18583 final PackageStats stats = new PackageStats(null, -1); 18584 synchronized (mInstaller) { 18585 if (!getPackageSizeInfoLI(packageName, -1, stats)) { 18586 unfreezePackage(packageName); 18587 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 18588 "Failed to measure package size"); 18589 } 18590 } 18591 18592 if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size " 18593 + stats.dataSize); 18594 18595 final long startFreeBytes = measurePath.getFreeSpace(); 18596 final long sizeBytes; 18597 if (moveCompleteApp) { 18598 sizeBytes = stats.codeSize + stats.dataSize; 18599 } else { 18600 sizeBytes = stats.codeSize; 18601 } 18602 18603 if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) { 18604 unfreezePackage(packageName); 18605 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 18606 "Not enough free space to move"); 18607 } 18608 18609 mMoveCallbacks.notifyStatusChanged(moveId, 10); 18610 18611 final CountDownLatch installedLatch = new CountDownLatch(1); 18612 final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() { 18613 @Override 18614 public void onUserActionRequired(Intent intent) throws RemoteException { 18615 throw new IllegalStateException(); 18616 } 18617 18618 @Override 18619 public void onPackageInstalled(String basePackageName, int returnCode, String msg, 18620 Bundle extras) throws RemoteException { 18621 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: " 18622 + PackageManager.installStatusToString(returnCode, msg)); 18623 18624 installedLatch.countDown(); 18625 18626 // Regardless of success or failure of the move operation, 18627 // always unfreeze the package 18628 unfreezePackage(packageName); 18629 18630 final int status = PackageManager.installStatusToPublicStatus(returnCode); 18631 switch (status) { 18632 case PackageInstaller.STATUS_SUCCESS: 18633 mMoveCallbacks.notifyStatusChanged(moveId, 18634 PackageManager.MOVE_SUCCEEDED); 18635 break; 18636 case PackageInstaller.STATUS_FAILURE_STORAGE: 18637 mMoveCallbacks.notifyStatusChanged(moveId, 18638 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE); 18639 break; 18640 default: 18641 mMoveCallbacks.notifyStatusChanged(moveId, 18642 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 18643 break; 18644 } 18645 } 18646 }; 18647 18648 final MoveInfo move; 18649 if (moveCompleteApp) { 18650 // Kick off a thread to report progress estimates 18651 new Thread() { 18652 @Override 18653 public void run() { 18654 while (true) { 18655 try { 18656 if (installedLatch.await(1, TimeUnit.SECONDS)) { 18657 break; 18658 } 18659 } catch (InterruptedException ignored) { 18660 } 18661 18662 final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace(); 18663 final int progress = 10 + (int) MathUtils.constrain( 18664 ((deltaFreeBytes * 80) / sizeBytes), 0, 80); 18665 mMoveCallbacks.notifyStatusChanged(moveId, progress); 18666 } 18667 } 18668 }.start(); 18669 18670 final String dataAppName = codeFile.getName(); 18671 move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName, 18672 dataAppName, appId, seinfo, targetSdkVersion); 18673 } else { 18674 move = null; 18675 } 18676 18677 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 18678 18679 final Message msg = mHandler.obtainMessage(INIT_COPY); 18680 final OriginInfo origin = OriginInfo.fromExistingFile(codeFile); 18681 final InstallParams params = new InstallParams(origin, move, installObserver, installFlags, 18682 installerPackageName, volumeUuid, null /*verificationInfo*/, user, 18683 packageAbiOverride, null); 18684 params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params)); 18685 msg.obj = params; 18686 18687 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage", 18688 System.identityHashCode(msg.obj)); 18689 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 18690 System.identityHashCode(msg.obj)); 18691 18692 mHandler.sendMessage(msg); 18693 } 18694 18695 @Override 18696 public int movePrimaryStorage(String volumeUuid) throws RemoteException { 18697 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 18698 18699 final int realMoveId = mNextMoveId.getAndIncrement(); 18700 final Bundle extras = new Bundle(); 18701 extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid); 18702 mMoveCallbacks.notifyCreated(realMoveId, extras); 18703 18704 final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() { 18705 @Override 18706 public void onCreated(int moveId, Bundle extras) { 18707 // Ignored 18708 } 18709 18710 @Override 18711 public void onStatusChanged(int moveId, int status, long estMillis) { 18712 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis); 18713 } 18714 }; 18715 18716 final StorageManager storage = mContext.getSystemService(StorageManager.class); 18717 storage.setPrimaryStorageUuid(volumeUuid, callback); 18718 return realMoveId; 18719 } 18720 18721 @Override 18722 public int getMoveStatus(int moveId) { 18723 mContext.enforceCallingOrSelfPermission( 18724 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 18725 return mMoveCallbacks.mLastStatus.get(moveId); 18726 } 18727 18728 @Override 18729 public void registerMoveCallback(IPackageMoveObserver callback) { 18730 mContext.enforceCallingOrSelfPermission( 18731 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 18732 mMoveCallbacks.register(callback); 18733 } 18734 18735 @Override 18736 public void unregisterMoveCallback(IPackageMoveObserver callback) { 18737 mContext.enforceCallingOrSelfPermission( 18738 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 18739 mMoveCallbacks.unregister(callback); 18740 } 18741 18742 @Override 18743 public boolean setInstallLocation(int loc) { 18744 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, 18745 null); 18746 if (getInstallLocation() == loc) { 18747 return true; 18748 } 18749 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL 18750 || loc == PackageHelper.APP_INSTALL_EXTERNAL) { 18751 android.provider.Settings.Global.putInt(mContext.getContentResolver(), 18752 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc); 18753 return true; 18754 } 18755 return false; 18756 } 18757 18758 @Override 18759 public int getInstallLocation() { 18760 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 18761 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, 18762 PackageHelper.APP_INSTALL_AUTO); 18763 } 18764 18765 /** Called by UserManagerService */ 18766 void cleanUpUser(UserManagerService userManager, int userHandle) { 18767 synchronized (mPackages) { 18768 mDirtyUsers.remove(userHandle); 18769 mUserNeedsBadging.delete(userHandle); 18770 mSettings.removeUserLPw(userHandle); 18771 mPendingBroadcasts.remove(userHandle); 18772 mEphemeralApplicationRegistry.onUserRemovedLPw(userHandle); 18773 } 18774 synchronized (mInstallLock) { 18775 final StorageManager storage = mContext.getSystemService(StorageManager.class); 18776 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 18777 final String volumeUuid = vol.getFsUuid(); 18778 if (DEBUG_INSTALL) Slog.d(TAG, "Removing user data on volume " + volumeUuid); 18779 try { 18780 mInstaller.removeUserDataDirs(volumeUuid, userHandle); 18781 } catch (InstallerException e) { 18782 Slog.w(TAG, "Failed to remove user data", e); 18783 } 18784 } 18785 synchronized (mPackages) { 18786 removeUnusedPackagesLILPw(userManager, userHandle); 18787 } 18788 } 18789 } 18790 18791 /** 18792 * We're removing userHandle and would like to remove any downloaded packages 18793 * that are no longer in use by any other user. 18794 * @param userHandle the user being removed 18795 */ 18796 private void removeUnusedPackagesLILPw(UserManagerService userManager, final int userHandle) { 18797 final boolean DEBUG_CLEAN_APKS = false; 18798 int [] users = userManager.getUserIds(); 18799 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 18800 while (psit.hasNext()) { 18801 PackageSetting ps = psit.next(); 18802 if (ps.pkg == null) { 18803 continue; 18804 } 18805 final String packageName = ps.pkg.packageName; 18806 // Skip over if system app 18807 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) { 18808 continue; 18809 } 18810 if (DEBUG_CLEAN_APKS) { 18811 Slog.i(TAG, "Checking package " + packageName); 18812 } 18813 boolean keep = shouldKeepUninstalledPackageLPr(packageName); 18814 if (keep) { 18815 if (DEBUG_CLEAN_APKS) { 18816 Slog.i(TAG, " Keeping package " + packageName + " - requested by DO"); 18817 } 18818 } else { 18819 for (int i = 0; i < users.length; i++) { 18820 if (users[i] != userHandle && ps.getInstalled(users[i])) { 18821 keep = true; 18822 if (DEBUG_CLEAN_APKS) { 18823 Slog.i(TAG, " Keeping package " + packageName + " for user " 18824 + users[i]); 18825 } 18826 break; 18827 } 18828 } 18829 } 18830 if (!keep) { 18831 if (DEBUG_CLEAN_APKS) { 18832 Slog.i(TAG, " Removing package " + packageName); 18833 } 18834 mHandler.post(new Runnable() { 18835 public void run() { 18836 deletePackageX(packageName, userHandle, 0); 18837 } //end run 18838 }); 18839 } 18840 } 18841 } 18842 18843 /** Called by UserManagerService */ 18844 void createNewUser(int userHandle) { 18845 synchronized (mInstallLock) { 18846 try { 18847 mInstaller.createUserConfig(userHandle); 18848 } catch (InstallerException e) { 18849 Slog.w(TAG, "Failed to create user config", e); 18850 } 18851 mSettings.createNewUserLI(this, mInstaller, userHandle); 18852 } 18853 synchronized (mPackages) { 18854 applyFactoryDefaultBrowserLPw(userHandle); 18855 primeDomainVerificationsLPw(userHandle); 18856 } 18857 } 18858 18859 void newUserCreated(final int userHandle) { 18860 mDefaultPermissionPolicy.grantDefaultPermissions(userHandle); 18861 // If permission review for legacy apps is required, we represent 18862 // dagerous permissions for such apps as always granted runtime 18863 // permissions to keep per user flag state whether review is needed. 18864 // Hence, if a new user is added we have to propagate dangerous 18865 // permission grants for these legacy apps. 18866 if (Build.PERMISSIONS_REVIEW_REQUIRED) { 18867 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL 18868 | UPDATE_PERMISSIONS_REPLACE_ALL); 18869 } 18870 } 18871 18872 @Override 18873 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException { 18874 mContext.enforceCallingOrSelfPermission( 18875 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 18876 "Only package verification agents can read the verifier device identity"); 18877 18878 synchronized (mPackages) { 18879 return mSettings.getVerifierDeviceIdentityLPw(); 18880 } 18881 } 18882 18883 @Override 18884 public void setPermissionEnforced(String permission, boolean enforced) { 18885 // TODO: Now that we no longer change GID for storage, this should to away. 18886 mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 18887 "setPermissionEnforced"); 18888 if (READ_EXTERNAL_STORAGE.equals(permission)) { 18889 synchronized (mPackages) { 18890 if (mSettings.mReadExternalStorageEnforced == null 18891 || mSettings.mReadExternalStorageEnforced != enforced) { 18892 mSettings.mReadExternalStorageEnforced = enforced; 18893 mSettings.writeLPr(); 18894 } 18895 } 18896 // kill any non-foreground processes so we restart them and 18897 // grant/revoke the GID. 18898 final IActivityManager am = ActivityManagerNative.getDefault(); 18899 if (am != null) { 18900 final long token = Binder.clearCallingIdentity(); 18901 try { 18902 am.killProcessesBelowForeground("setPermissionEnforcement"); 18903 } catch (RemoteException e) { 18904 } finally { 18905 Binder.restoreCallingIdentity(token); 18906 } 18907 } 18908 } else { 18909 throw new IllegalArgumentException("No selective enforcement for " + permission); 18910 } 18911 } 18912 18913 @Override 18914 @Deprecated 18915 public boolean isPermissionEnforced(String permission) { 18916 return true; 18917 } 18918 18919 @Override 18920 public boolean isStorageLow() { 18921 final long token = Binder.clearCallingIdentity(); 18922 try { 18923 final DeviceStorageMonitorInternal 18924 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 18925 if (dsm != null) { 18926 return dsm.isMemoryLow(); 18927 } else { 18928 return false; 18929 } 18930 } finally { 18931 Binder.restoreCallingIdentity(token); 18932 } 18933 } 18934 18935 @Override 18936 public IPackageInstaller getPackageInstaller() { 18937 return mInstallerService; 18938 } 18939 18940 private boolean userNeedsBadging(int userId) { 18941 int index = mUserNeedsBadging.indexOfKey(userId); 18942 if (index < 0) { 18943 final UserInfo userInfo; 18944 final long token = Binder.clearCallingIdentity(); 18945 try { 18946 userInfo = sUserManager.getUserInfo(userId); 18947 } finally { 18948 Binder.restoreCallingIdentity(token); 18949 } 18950 final boolean b; 18951 if (userInfo != null && userInfo.isManagedProfile()) { 18952 b = true; 18953 } else { 18954 b = false; 18955 } 18956 mUserNeedsBadging.put(userId, b); 18957 return b; 18958 } 18959 return mUserNeedsBadging.valueAt(index); 18960 } 18961 18962 @Override 18963 public KeySet getKeySetByAlias(String packageName, String alias) { 18964 if (packageName == null || alias == null) { 18965 return null; 18966 } 18967 synchronized(mPackages) { 18968 final PackageParser.Package pkg = mPackages.get(packageName); 18969 if (pkg == null) { 18970 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 18971 throw new IllegalArgumentException("Unknown package: " + packageName); 18972 } 18973 KeySetManagerService ksms = mSettings.mKeySetManagerService; 18974 return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias)); 18975 } 18976 } 18977 18978 @Override 18979 public KeySet getSigningKeySet(String packageName) { 18980 if (packageName == null) { 18981 return null; 18982 } 18983 synchronized(mPackages) { 18984 final PackageParser.Package pkg = mPackages.get(packageName); 18985 if (pkg == null) { 18986 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 18987 throw new IllegalArgumentException("Unknown package: " + packageName); 18988 } 18989 if (pkg.applicationInfo.uid != Binder.getCallingUid() 18990 && Process.SYSTEM_UID != Binder.getCallingUid()) { 18991 throw new SecurityException("May not access signing KeySet of other apps."); 18992 } 18993 KeySetManagerService ksms = mSettings.mKeySetManagerService; 18994 return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName)); 18995 } 18996 } 18997 18998 @Override 18999 public boolean isPackageSignedByKeySet(String packageName, KeySet ks) { 19000 if (packageName == null || ks == null) { 19001 return false; 19002 } 19003 synchronized(mPackages) { 19004 final PackageParser.Package pkg = mPackages.get(packageName); 19005 if (pkg == null) { 19006 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 19007 throw new IllegalArgumentException("Unknown package: " + packageName); 19008 } 19009 IBinder ksh = ks.getToken(); 19010 if (ksh instanceof KeySetHandle) { 19011 KeySetManagerService ksms = mSettings.mKeySetManagerService; 19012 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh); 19013 } 19014 return false; 19015 } 19016 } 19017 19018 @Override 19019 public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) { 19020 if (packageName == null || ks == null) { 19021 return false; 19022 } 19023 synchronized(mPackages) { 19024 final PackageParser.Package pkg = mPackages.get(packageName); 19025 if (pkg == null) { 19026 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 19027 throw new IllegalArgumentException("Unknown package: " + packageName); 19028 } 19029 IBinder ksh = ks.getToken(); 19030 if (ksh instanceof KeySetHandle) { 19031 KeySetManagerService ksms = mSettings.mKeySetManagerService; 19032 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh); 19033 } 19034 return false; 19035 } 19036 } 19037 19038 private void deletePackageIfUnusedLPr(final String packageName) { 19039 PackageSetting ps = mSettings.mPackages.get(packageName); 19040 if (ps == null) { 19041 return; 19042 } 19043 if (!ps.isAnyInstalled(sUserManager.getUserIds())) { 19044 // TODO Implement atomic delete if package is unused 19045 // It is currently possible that the package will be deleted even if it is installed 19046 // after this method returns. 19047 mHandler.post(new Runnable() { 19048 public void run() { 19049 deletePackageX(packageName, 0, PackageManager.DELETE_ALL_USERS); 19050 } 19051 }); 19052 } 19053 } 19054 19055 /** 19056 * Check and throw if the given before/after packages would be considered a 19057 * downgrade. 19058 */ 19059 private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after) 19060 throws PackageManagerException { 19061 if (after.versionCode < before.mVersionCode) { 19062 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 19063 "Update version code " + after.versionCode + " is older than current " 19064 + before.mVersionCode); 19065 } else if (after.versionCode == before.mVersionCode) { 19066 if (after.baseRevisionCode < before.baseRevisionCode) { 19067 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 19068 "Update base revision code " + after.baseRevisionCode 19069 + " is older than current " + before.baseRevisionCode); 19070 } 19071 19072 if (!ArrayUtils.isEmpty(after.splitNames)) { 19073 for (int i = 0; i < after.splitNames.length; i++) { 19074 final String splitName = after.splitNames[i]; 19075 final int j = ArrayUtils.indexOf(before.splitNames, splitName); 19076 if (j != -1) { 19077 if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) { 19078 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 19079 "Update split " + splitName + " revision code " 19080 + after.splitRevisionCodes[i] + " is older than current " 19081 + before.splitRevisionCodes[j]); 19082 } 19083 } 19084 } 19085 } 19086 } 19087 } 19088 19089 private static class MoveCallbacks extends Handler { 19090 private static final int MSG_CREATED = 1; 19091 private static final int MSG_STATUS_CHANGED = 2; 19092 19093 private final RemoteCallbackList<IPackageMoveObserver> 19094 mCallbacks = new RemoteCallbackList<>(); 19095 19096 private final SparseIntArray mLastStatus = new SparseIntArray(); 19097 19098 public MoveCallbacks(Looper looper) { 19099 super(looper); 19100 } 19101 19102 public void register(IPackageMoveObserver callback) { 19103 mCallbacks.register(callback); 19104 } 19105 19106 public void unregister(IPackageMoveObserver callback) { 19107 mCallbacks.unregister(callback); 19108 } 19109 19110 @Override 19111 public void handleMessage(Message msg) { 19112 final SomeArgs args = (SomeArgs) msg.obj; 19113 final int n = mCallbacks.beginBroadcast(); 19114 for (int i = 0; i < n; i++) { 19115 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i); 19116 try { 19117 invokeCallback(callback, msg.what, args); 19118 } catch (RemoteException ignored) { 19119 } 19120 } 19121 mCallbacks.finishBroadcast(); 19122 args.recycle(); 19123 } 19124 19125 private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args) 19126 throws RemoteException { 19127 switch (what) { 19128 case MSG_CREATED: { 19129 callback.onCreated(args.argi1, (Bundle) args.arg2); 19130 break; 19131 } 19132 case MSG_STATUS_CHANGED: { 19133 callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3); 19134 break; 19135 } 19136 } 19137 } 19138 19139 private void notifyCreated(int moveId, Bundle extras) { 19140 Slog.v(TAG, "Move " + moveId + " created " + extras.toString()); 19141 19142 final SomeArgs args = SomeArgs.obtain(); 19143 args.argi1 = moveId; 19144 args.arg2 = extras; 19145 obtainMessage(MSG_CREATED, args).sendToTarget(); 19146 } 19147 19148 private void notifyStatusChanged(int moveId, int status) { 19149 notifyStatusChanged(moveId, status, -1); 19150 } 19151 19152 private void notifyStatusChanged(int moveId, int status, long estMillis) { 19153 Slog.v(TAG, "Move " + moveId + " status " + status); 19154 19155 final SomeArgs args = SomeArgs.obtain(); 19156 args.argi1 = moveId; 19157 args.argi2 = status; 19158 args.arg3 = estMillis; 19159 obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget(); 19160 19161 synchronized (mLastStatus) { 19162 mLastStatus.put(moveId, status); 19163 } 19164 } 19165 } 19166 19167 private final static class OnPermissionChangeListeners extends Handler { 19168 private static final int MSG_ON_PERMISSIONS_CHANGED = 1; 19169 19170 private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners = 19171 new RemoteCallbackList<>(); 19172 19173 public OnPermissionChangeListeners(Looper looper) { 19174 super(looper); 19175 } 19176 19177 @Override 19178 public void handleMessage(Message msg) { 19179 switch (msg.what) { 19180 case MSG_ON_PERMISSIONS_CHANGED: { 19181 final int uid = msg.arg1; 19182 handleOnPermissionsChanged(uid); 19183 } break; 19184 } 19185 } 19186 19187 public void addListenerLocked(IOnPermissionsChangeListener listener) { 19188 mPermissionListeners.register(listener); 19189 19190 } 19191 19192 public void removeListenerLocked(IOnPermissionsChangeListener listener) { 19193 mPermissionListeners.unregister(listener); 19194 } 19195 19196 public void onPermissionsChanged(int uid) { 19197 if (mPermissionListeners.getRegisteredCallbackCount() > 0) { 19198 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget(); 19199 } 19200 } 19201 19202 private void handleOnPermissionsChanged(int uid) { 19203 final int count = mPermissionListeners.beginBroadcast(); 19204 try { 19205 for (int i = 0; i < count; i++) { 19206 IOnPermissionsChangeListener callback = mPermissionListeners 19207 .getBroadcastItem(i); 19208 try { 19209 callback.onPermissionsChanged(uid); 19210 } catch (RemoteException e) { 19211 Log.e(TAG, "Permission listener is dead", e); 19212 } 19213 } 19214 } finally { 19215 mPermissionListeners.finishBroadcast(); 19216 } 19217 } 19218 } 19219 19220 private class PackageManagerInternalImpl extends PackageManagerInternal { 19221 @Override 19222 public void setLocationPackagesProvider(PackagesProvider provider) { 19223 synchronized (mPackages) { 19224 mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider); 19225 } 19226 } 19227 19228 @Override 19229 public void setVoiceInteractionPackagesProvider(PackagesProvider provider) { 19230 synchronized (mPackages) { 19231 mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider); 19232 } 19233 } 19234 19235 @Override 19236 public void setSmsAppPackagesProvider(PackagesProvider provider) { 19237 synchronized (mPackages) { 19238 mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider); 19239 } 19240 } 19241 19242 @Override 19243 public void setDialerAppPackagesProvider(PackagesProvider provider) { 19244 synchronized (mPackages) { 19245 mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider); 19246 } 19247 } 19248 19249 @Override 19250 public void setSimCallManagerPackagesProvider(PackagesProvider provider) { 19251 synchronized (mPackages) { 19252 mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider); 19253 } 19254 } 19255 19256 @Override 19257 public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) { 19258 synchronized (mPackages) { 19259 mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider); 19260 } 19261 } 19262 19263 @Override 19264 public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) { 19265 synchronized (mPackages) { 19266 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr( 19267 packageName, userId); 19268 } 19269 } 19270 19271 @Override 19272 public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) { 19273 synchronized (mPackages) { 19274 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr( 19275 packageName, userId); 19276 } 19277 } 19278 19279 @Override 19280 public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) { 19281 synchronized (mPackages) { 19282 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr( 19283 packageName, userId); 19284 } 19285 } 19286 19287 @Override 19288 public void setKeepUninstalledPackages(final List<String> packageList) { 19289 Preconditions.checkNotNull(packageList); 19290 List<String> removedFromList = null; 19291 synchronized (mPackages) { 19292 if (mKeepUninstalledPackages != null) { 19293 final int packagesCount = mKeepUninstalledPackages.size(); 19294 for (int i = 0; i < packagesCount; i++) { 19295 String oldPackage = mKeepUninstalledPackages.get(i); 19296 if (packageList != null && packageList.contains(oldPackage)) { 19297 continue; 19298 } 19299 if (removedFromList == null) { 19300 removedFromList = new ArrayList<>(); 19301 } 19302 removedFromList.add(oldPackage); 19303 } 19304 } 19305 mKeepUninstalledPackages = new ArrayList<>(packageList); 19306 if (removedFromList != null) { 19307 final int removedCount = removedFromList.size(); 19308 for (int i = 0; i < removedCount; i++) { 19309 deletePackageIfUnusedLPr(removedFromList.get(i)); 19310 } 19311 } 19312 } 19313 } 19314 19315 @Override 19316 public boolean isPermissionsReviewRequired(String packageName, int userId) { 19317 synchronized (mPackages) { 19318 // If we do not support permission review, done. 19319 if (!Build.PERMISSIONS_REVIEW_REQUIRED) { 19320 return false; 19321 } 19322 19323 PackageSetting packageSetting = mSettings.mPackages.get(packageName); 19324 if (packageSetting == null) { 19325 return false; 19326 } 19327 19328 // Permission review applies only to apps not supporting the new permission model. 19329 if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) { 19330 return false; 19331 } 19332 19333 // Legacy apps have the permission and get user consent on launch. 19334 PermissionsState permissionsState = packageSetting.getPermissionsState(); 19335 return permissionsState.isPermissionReviewRequired(userId); 19336 } 19337 } 19338 19339 @Override 19340 public ApplicationInfo getApplicationInfo(String packageName, int userId) { 19341 return PackageManagerService.this.getApplicationInfo(packageName, 0 /*flags*/, userId); 19342 } 19343 19344 @Override 19345 public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, 19346 int userId) { 19347 return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId); 19348 } 19349 } 19350 19351 @Override 19352 public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) { 19353 enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps"); 19354 synchronized (mPackages) { 19355 final long identity = Binder.clearCallingIdentity(); 19356 try { 19357 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr( 19358 packageNames, userId); 19359 } finally { 19360 Binder.restoreCallingIdentity(identity); 19361 } 19362 } 19363 } 19364 19365 private static void enforceSystemOrPhoneCaller(String tag) { 19366 int callingUid = Binder.getCallingUid(); 19367 if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) { 19368 throw new SecurityException( 19369 "Cannot call " + tag + " from UID " + callingUid); 19370 } 19371 } 19372 19373 boolean isHistoricalPackageUsageAvailable() { 19374 return mPackageUsage.isHistoricalPackageUsageAvailable(); 19375 } 19376 19377 /** 19378 * Return a <b>copy</b> of the collection of packages known to the package manager. 19379 * @return A copy of the values of mPackages. 19380 */ 19381 Collection<PackageParser.Package> getPackages() { 19382 synchronized (mPackages) { 19383 return new ArrayList<>(mPackages.values()); 19384 } 19385 } 19386} 19387