PackageManagerService.java revision b5e72702e4ddfaba9f3d723446e60408e169800b
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_FIRST_BOOT = 0; 448 public static final int REASON_BOOT = 1; 449 public static final int REASON_INSTALL = 2; 450 public static final int REASON_BACKGROUND_DEXOPT = 3; 451 public static final int REASON_AB_OTA = 4; 452 public static final int REASON_NON_SYSTEM_LIBRARY = 5; 453 public static final int REASON_SHARED_APK = 6; 454 public static final int REASON_FORCED_DEXOPT = 7; 455 456 public static final int REASON_LAST = REASON_FORCED_DEXOPT; 457 458 final ServiceThread mHandlerThread; 459 460 final PackageHandler mHandler; 461 462 /** 463 * Messages for {@link #mHandler} that need to wait for system ready before 464 * being dispatched. 465 */ 466 private ArrayList<Message> mPostSystemReadyMessages; 467 468 final int mSdkVersion = Build.VERSION.SDK_INT; 469 470 final Context mContext; 471 final boolean mFactoryTest; 472 final boolean mOnlyCore; 473 final DisplayMetrics mMetrics; 474 final int mDefParseFlags; 475 final String[] mSeparateProcesses; 476 final boolean mIsUpgrade; 477 final boolean mIsPreNUpgrade; 478 479 /** The location for ASEC container files on internal storage. */ 480 final String mAsecInternalPath; 481 482 // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages 483 // LOCK HELD. Can be called with mInstallLock held. 484 @GuardedBy("mInstallLock") 485 final Installer mInstaller; 486 487 /** Directory where installed third-party apps stored */ 488 final File mAppInstallDir; 489 final File mEphemeralInstallDir; 490 491 /** 492 * Directory to which applications installed internally have their 493 * 32 bit native libraries copied. 494 */ 495 private File mAppLib32InstallDir; 496 497 // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked 498 // apps. 499 final File mDrmAppPrivateInstallDir; 500 501 // ---------------------------------------------------------------- 502 503 // Lock for state used when installing and doing other long running 504 // operations. Methods that must be called with this lock held have 505 // the suffix "LI". 506 final Object mInstallLock = new Object(); 507 508 // ---------------------------------------------------------------- 509 510 // Keys are String (package name), values are Package. This also serves 511 // as the lock for the global state. Methods that must be called with 512 // this lock held have the prefix "LP". 513 @GuardedBy("mPackages") 514 final ArrayMap<String, PackageParser.Package> mPackages = 515 new ArrayMap<String, PackageParser.Package>(); 516 517 final ArrayMap<String, Set<String>> mKnownCodebase = 518 new ArrayMap<String, Set<String>>(); 519 520 // Tracks available target package names -> overlay package paths. 521 final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays = 522 new ArrayMap<String, ArrayMap<String, PackageParser.Package>>(); 523 524 /** 525 * Tracks new system packages [received in an OTA] that we expect to 526 * find updated user-installed versions. Keys are package name, values 527 * are package location. 528 */ 529 final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>(); 530 531 /** 532 * Tracks existing system packages prior to receiving an OTA. Keys are package name. 533 */ 534 final private ArraySet<String> mExistingSystemPackages = new ArraySet<>(); 535 /** 536 * Whether or not system app permissions should be promoted from install to runtime. 537 */ 538 boolean mPromoteSystemApps; 539 540 final Settings mSettings; 541 boolean mRestoredSettings; 542 543 // System configuration read by SystemConfig. 544 final int[] mGlobalGids; 545 final SparseArray<ArraySet<String>> mSystemPermissions; 546 final ArrayMap<String, FeatureInfo> mAvailableFeatures; 547 548 // If mac_permissions.xml was found for seinfo labeling. 549 boolean mFoundPolicyFile; 550 551 private final EphemeralApplicationRegistry mEphemeralApplicationRegistry; 552 553 public static final class SharedLibraryEntry { 554 public final String path; 555 public final String apk; 556 557 SharedLibraryEntry(String _path, String _apk) { 558 path = _path; 559 apk = _apk; 560 } 561 } 562 563 // Currently known shared libraries. 564 final ArrayMap<String, SharedLibraryEntry> mSharedLibraries = 565 new ArrayMap<String, SharedLibraryEntry>(); 566 567 // All available activities, for your resolving pleasure. 568 final ActivityIntentResolver mActivities = 569 new ActivityIntentResolver(); 570 571 // All available receivers, for your resolving pleasure. 572 final ActivityIntentResolver mReceivers = 573 new ActivityIntentResolver(); 574 575 // All available services, for your resolving pleasure. 576 final ServiceIntentResolver mServices = new ServiceIntentResolver(); 577 578 // All available providers, for your resolving pleasure. 579 final ProviderIntentResolver mProviders = new ProviderIntentResolver(); 580 581 // Mapping from provider base names (first directory in content URI codePath) 582 // to the provider information. 583 final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority = 584 new ArrayMap<String, PackageParser.Provider>(); 585 586 // Mapping from instrumentation class names to info about them. 587 final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation = 588 new ArrayMap<ComponentName, PackageParser.Instrumentation>(); 589 590 // Mapping from permission names to info about them. 591 final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups = 592 new ArrayMap<String, PackageParser.PermissionGroup>(); 593 594 // Packages whose data we have transfered into another package, thus 595 // should no longer exist. 596 final ArraySet<String> mTransferedPackages = new ArraySet<String>(); 597 598 // Broadcast actions that are only available to the system. 599 final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>(); 600 601 /** List of packages waiting for verification. */ 602 final SparseArray<PackageVerificationState> mPendingVerification 603 = new SparseArray<PackageVerificationState>(); 604 605 /** Set of packages associated with each app op permission. */ 606 final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>(); 607 608 final PackageInstallerService mInstallerService; 609 610 private final PackageDexOptimizer mPackageDexOptimizer; 611 612 private AtomicInteger mNextMoveId = new AtomicInteger(); 613 private final MoveCallbacks mMoveCallbacks; 614 615 private final OnPermissionChangeListeners mOnPermissionChangeListeners; 616 617 // Cache of users who need badging. 618 SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray(); 619 620 /** Token for keys in mPendingVerification. */ 621 private int mPendingVerificationToken = 0; 622 623 volatile boolean mSystemReady; 624 volatile boolean mSafeMode; 625 volatile boolean mHasSystemUidErrors; 626 627 ApplicationInfo mAndroidApplication; 628 final ActivityInfo mResolveActivity = new ActivityInfo(); 629 final ResolveInfo mResolveInfo = new ResolveInfo(); 630 ComponentName mResolveComponentName; 631 PackageParser.Package mPlatformPackage; 632 ComponentName mCustomResolverComponentName; 633 634 boolean mResolverReplaced = false; 635 636 private final @Nullable ComponentName mIntentFilterVerifierComponent; 637 private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier; 638 639 private int mIntentFilterVerificationToken = 0; 640 641 /** Component that knows whether or not an ephemeral application exists */ 642 final ComponentName mEphemeralResolverComponent; 643 /** The service connection to the ephemeral resolver */ 644 final EphemeralResolverConnection mEphemeralResolverConnection; 645 646 /** Component used to install ephemeral applications */ 647 final ComponentName mEphemeralInstallerComponent; 648 final ActivityInfo mEphemeralInstallerActivity = new ActivityInfo(); 649 final ResolveInfo mEphemeralInstallerInfo = new ResolveInfo(); 650 651 final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates 652 = new SparseArray<IntentFilterVerificationState>(); 653 654 final DefaultPermissionGrantPolicy mDefaultPermissionPolicy = 655 new DefaultPermissionGrantPolicy(this); 656 657 // List of packages names to keep cached, even if they are uninstalled for all users 658 private List<String> mKeepUninstalledPackages; 659 660 private static class IFVerificationParams { 661 PackageParser.Package pkg; 662 boolean replacing; 663 int userId; 664 int verifierUid; 665 666 public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing, 667 int _userId, int _verifierUid) { 668 pkg = _pkg; 669 replacing = _replacing; 670 userId = _userId; 671 replacing = _replacing; 672 verifierUid = _verifierUid; 673 } 674 } 675 676 private interface IntentFilterVerifier<T extends IntentFilter> { 677 boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId, 678 T filter, String packageName); 679 void startVerifications(int userId); 680 void receiveVerificationResponse(int verificationId); 681 } 682 683 private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> { 684 private Context mContext; 685 private ComponentName mIntentFilterVerifierComponent; 686 private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>(); 687 688 public IntentVerifierProxy(Context context, ComponentName verifierComponent) { 689 mContext = context; 690 mIntentFilterVerifierComponent = verifierComponent; 691 } 692 693 private String getDefaultScheme() { 694 return IntentFilter.SCHEME_HTTPS; 695 } 696 697 @Override 698 public void startVerifications(int userId) { 699 // Launch verifications requests 700 int count = mCurrentIntentFilterVerifications.size(); 701 for (int n=0; n<count; n++) { 702 int verificationId = mCurrentIntentFilterVerifications.get(n); 703 final IntentFilterVerificationState ivs = 704 mIntentFilterVerificationStates.get(verificationId); 705 706 String packageName = ivs.getPackageName(); 707 708 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 709 final int filterCount = filters.size(); 710 ArraySet<String> domainsSet = new ArraySet<>(); 711 for (int m=0; m<filterCount; m++) { 712 PackageParser.ActivityIntentInfo filter = filters.get(m); 713 domainsSet.addAll(filter.getHostsList()); 714 } 715 ArrayList<String> domainsList = new ArrayList<>(domainsSet); 716 synchronized (mPackages) { 717 if (mSettings.createIntentFilterVerificationIfNeededLPw( 718 packageName, domainsList) != null) { 719 scheduleWriteSettingsLocked(); 720 } 721 } 722 sendVerificationRequest(userId, verificationId, ivs); 723 } 724 mCurrentIntentFilterVerifications.clear(); 725 } 726 727 private void sendVerificationRequest(int userId, int verificationId, 728 IntentFilterVerificationState ivs) { 729 730 Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 731 verificationIntent.putExtra( 732 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID, 733 verificationId); 734 verificationIntent.putExtra( 735 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME, 736 getDefaultScheme()); 737 verificationIntent.putExtra( 738 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS, 739 ivs.getHostsString()); 740 verificationIntent.putExtra( 741 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME, 742 ivs.getPackageName()); 743 verificationIntent.setComponent(mIntentFilterVerifierComponent); 744 verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 745 746 UserHandle user = new UserHandle(userId); 747 mContext.sendBroadcastAsUser(verificationIntent, user); 748 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 749 "Sending IntentFilter verification broadcast"); 750 } 751 752 public void receiveVerificationResponse(int verificationId) { 753 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 754 755 final boolean verified = ivs.isVerified(); 756 757 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 758 final int count = filters.size(); 759 if (DEBUG_DOMAIN_VERIFICATION) { 760 Slog.i(TAG, "Received verification response " + verificationId 761 + " for " + count + " filters, verified=" + verified); 762 } 763 for (int n=0; n<count; n++) { 764 PackageParser.ActivityIntentInfo filter = filters.get(n); 765 filter.setVerified(verified); 766 767 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString() 768 + " verified with result:" + verified + " and hosts:" 769 + ivs.getHostsString()); 770 } 771 772 mIntentFilterVerificationStates.remove(verificationId); 773 774 final String packageName = ivs.getPackageName(); 775 IntentFilterVerificationInfo ivi = null; 776 777 synchronized (mPackages) { 778 ivi = mSettings.getIntentFilterVerificationLPr(packageName); 779 } 780 if (ivi == null) { 781 Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:" 782 + verificationId + " packageName:" + packageName); 783 return; 784 } 785 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 786 "Updating IntentFilterVerificationInfo for package " + packageName 787 +" verificationId:" + verificationId); 788 789 synchronized (mPackages) { 790 if (verified) { 791 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS); 792 } else { 793 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK); 794 } 795 scheduleWriteSettingsLocked(); 796 797 final int userId = ivs.getUserId(); 798 if (userId != UserHandle.USER_ALL) { 799 final int userStatus = 800 mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 801 802 int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 803 boolean needUpdate = false; 804 805 // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have 806 // already been set by the User thru the Disambiguation dialog 807 switch (userStatus) { 808 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 809 if (verified) { 810 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 811 } else { 812 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 813 } 814 needUpdate = true; 815 break; 816 817 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 818 if (verified) { 819 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 820 needUpdate = true; 821 } 822 break; 823 824 default: 825 // Nothing to do 826 } 827 828 if (needUpdate) { 829 mSettings.updateIntentFilterVerificationStatusLPw( 830 packageName, updatedStatus, userId); 831 scheduleWritePackageRestrictionsLocked(userId); 832 } 833 } 834 } 835 } 836 837 @Override 838 public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId, 839 ActivityIntentInfo filter, String packageName) { 840 if (!hasValidDomains(filter)) { 841 return false; 842 } 843 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 844 if (ivs == null) { 845 ivs = createDomainVerificationState(verifierUid, userId, verificationId, 846 packageName); 847 } 848 if (DEBUG_DOMAIN_VERIFICATION) { 849 Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter); 850 } 851 ivs.addFilter(filter); 852 return true; 853 } 854 855 private IntentFilterVerificationState createDomainVerificationState(int verifierUid, 856 int userId, int verificationId, String packageName) { 857 IntentFilterVerificationState ivs = new IntentFilterVerificationState( 858 verifierUid, userId, packageName); 859 ivs.setPendingState(); 860 synchronized (mPackages) { 861 mIntentFilterVerificationStates.append(verificationId, ivs); 862 mCurrentIntentFilterVerifications.add(verificationId); 863 } 864 return ivs; 865 } 866 } 867 868 private static boolean hasValidDomains(ActivityIntentInfo filter) { 869 return filter.hasCategory(Intent.CATEGORY_BROWSABLE) 870 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 871 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS)); 872 } 873 874 // Set of pending broadcasts for aggregating enable/disable of components. 875 static class PendingPackageBroadcasts { 876 // for each user id, a map of <package name -> components within that package> 877 final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap; 878 879 public PendingPackageBroadcasts() { 880 mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2); 881 } 882 883 public ArrayList<String> get(int userId, String packageName) { 884 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 885 return packages.get(packageName); 886 } 887 888 public void put(int userId, String packageName, ArrayList<String> components) { 889 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 890 packages.put(packageName, components); 891 } 892 893 public void remove(int userId, String packageName) { 894 ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId); 895 if (packages != null) { 896 packages.remove(packageName); 897 } 898 } 899 900 public void remove(int userId) { 901 mUidMap.remove(userId); 902 } 903 904 public int userIdCount() { 905 return mUidMap.size(); 906 } 907 908 public int userIdAt(int n) { 909 return mUidMap.keyAt(n); 910 } 911 912 public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) { 913 return mUidMap.get(userId); 914 } 915 916 public int size() { 917 // total number of pending broadcast entries across all userIds 918 int num = 0; 919 for (int i = 0; i< mUidMap.size(); i++) { 920 num += mUidMap.valueAt(i).size(); 921 } 922 return num; 923 } 924 925 public void clear() { 926 mUidMap.clear(); 927 } 928 929 private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) { 930 ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId); 931 if (map == null) { 932 map = new ArrayMap<String, ArrayList<String>>(); 933 mUidMap.put(userId, map); 934 } 935 return map; 936 } 937 } 938 final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts(); 939 940 // Service Connection to remote media container service to copy 941 // package uri's from external media onto secure containers 942 // or internal storage. 943 private IMediaContainerService mContainerService = null; 944 945 static final int SEND_PENDING_BROADCAST = 1; 946 static final int MCS_BOUND = 3; 947 static final int END_COPY = 4; 948 static final int INIT_COPY = 5; 949 static final int MCS_UNBIND = 6; 950 static final int START_CLEANING_PACKAGE = 7; 951 static final int FIND_INSTALL_LOC = 8; 952 static final int POST_INSTALL = 9; 953 static final int MCS_RECONNECT = 10; 954 static final int MCS_GIVE_UP = 11; 955 static final int UPDATED_MEDIA_STATUS = 12; 956 static final int WRITE_SETTINGS = 13; 957 static final int WRITE_PACKAGE_RESTRICTIONS = 14; 958 static final int PACKAGE_VERIFIED = 15; 959 static final int CHECK_PENDING_VERIFICATION = 16; 960 static final int START_INTENT_FILTER_VERIFICATIONS = 17; 961 static final int INTENT_FILTER_VERIFIED = 18; 962 963 static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds 964 965 // Delay time in millisecs 966 static final int BROADCAST_DELAY = 10 * 1000; 967 968 static UserManagerService sUserManager; 969 970 // Stores a list of users whose package restrictions file needs to be updated 971 private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>(); 972 973 final private DefaultContainerConnection mDefContainerConn = 974 new DefaultContainerConnection(); 975 class DefaultContainerConnection implements ServiceConnection { 976 public void onServiceConnected(ComponentName name, IBinder service) { 977 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected"); 978 IMediaContainerService imcs = 979 IMediaContainerService.Stub.asInterface(service); 980 mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs)); 981 } 982 983 public void onServiceDisconnected(ComponentName name) { 984 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected"); 985 } 986 } 987 988 // Recordkeeping of restore-after-install operations that are currently in flight 989 // between the Package Manager and the Backup Manager 990 static class PostInstallData { 991 public InstallArgs args; 992 public PackageInstalledInfo res; 993 994 PostInstallData(InstallArgs _a, PackageInstalledInfo _r) { 995 args = _a; 996 res = _r; 997 } 998 } 999 1000 final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>(); 1001 int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows 1002 1003 // XML tags for backup/restore of various bits of state 1004 private static final String TAG_PREFERRED_BACKUP = "pa"; 1005 private static final String TAG_DEFAULT_APPS = "da"; 1006 private static final String TAG_INTENT_FILTER_VERIFICATION = "iv"; 1007 1008 private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup"; 1009 private static final String TAG_ALL_GRANTS = "rt-grants"; 1010 private static final String TAG_GRANT = "grant"; 1011 private static final String ATTR_PACKAGE_NAME = "pkg"; 1012 1013 private static final String TAG_PERMISSION = "perm"; 1014 private static final String ATTR_PERMISSION_NAME = "name"; 1015 private static final String ATTR_IS_GRANTED = "g"; 1016 private static final String ATTR_USER_SET = "set"; 1017 private static final String ATTR_USER_FIXED = "fixed"; 1018 private static final String ATTR_REVOKE_ON_UPGRADE = "rou"; 1019 1020 // System/policy permission grants are not backed up 1021 private static final int SYSTEM_RUNTIME_GRANT_MASK = 1022 FLAG_PERMISSION_POLICY_FIXED 1023 | FLAG_PERMISSION_SYSTEM_FIXED 1024 | FLAG_PERMISSION_GRANTED_BY_DEFAULT; 1025 1026 // And we back up these user-adjusted states 1027 private static final int USER_RUNTIME_GRANT_MASK = 1028 FLAG_PERMISSION_USER_SET 1029 | FLAG_PERMISSION_USER_FIXED 1030 | FLAG_PERMISSION_REVOKE_ON_UPGRADE; 1031 1032 final @Nullable String mRequiredVerifierPackage; 1033 final @Nullable String mRequiredInstallerPackage; 1034 1035 private final PackageUsage mPackageUsage = new PackageUsage(); 1036 1037 private class PackageUsage { 1038 private static final int WRITE_INTERVAL 1039 = (DEBUG_DEXOPT) ? 0 : 30*60*1000; // 30m in ms 1040 1041 private final Object mFileLock = new Object(); 1042 private final AtomicLong mLastWritten = new AtomicLong(0); 1043 private final AtomicBoolean mBackgroundWriteRunning = new AtomicBoolean(false); 1044 1045 private boolean mIsHistoricalPackageUsageAvailable = true; 1046 1047 boolean isHistoricalPackageUsageAvailable() { 1048 return mIsHistoricalPackageUsageAvailable; 1049 } 1050 1051 void write(boolean force) { 1052 if (force) { 1053 writeInternal(); 1054 return; 1055 } 1056 if (SystemClock.elapsedRealtime() - mLastWritten.get() < WRITE_INTERVAL 1057 && !DEBUG_DEXOPT) { 1058 return; 1059 } 1060 if (mBackgroundWriteRunning.compareAndSet(false, true)) { 1061 new Thread("PackageUsage_DiskWriter") { 1062 @Override 1063 public void run() { 1064 try { 1065 writeInternal(); 1066 } finally { 1067 mBackgroundWriteRunning.set(false); 1068 } 1069 } 1070 }.start(); 1071 } 1072 } 1073 1074 private void writeInternal() { 1075 synchronized (mPackages) { 1076 synchronized (mFileLock) { 1077 AtomicFile file = getFile(); 1078 FileOutputStream f = null; 1079 try { 1080 f = file.startWrite(); 1081 BufferedOutputStream out = new BufferedOutputStream(f); 1082 FileUtils.setPermissions(file.getBaseFile().getPath(), 0640, SYSTEM_UID, PACKAGE_INFO_GID); 1083 StringBuilder sb = new StringBuilder(); 1084 for (PackageParser.Package pkg : mPackages.values()) { 1085 if (pkg.mLastPackageUsageTimeInMills == 0) { 1086 continue; 1087 } 1088 sb.setLength(0); 1089 sb.append(pkg.packageName); 1090 sb.append(' '); 1091 sb.append((long)pkg.mLastPackageUsageTimeInMills); 1092 sb.append('\n'); 1093 out.write(sb.toString().getBytes(StandardCharsets.US_ASCII)); 1094 } 1095 out.flush(); 1096 file.finishWrite(f); 1097 } catch (IOException e) { 1098 if (f != null) { 1099 file.failWrite(f); 1100 } 1101 Log.e(TAG, "Failed to write package usage times", e); 1102 } 1103 } 1104 } 1105 mLastWritten.set(SystemClock.elapsedRealtime()); 1106 } 1107 1108 void readLP() { 1109 synchronized (mFileLock) { 1110 AtomicFile file = getFile(); 1111 BufferedInputStream in = null; 1112 try { 1113 in = new BufferedInputStream(file.openRead()); 1114 StringBuffer sb = new StringBuffer(); 1115 while (true) { 1116 String packageName = readToken(in, sb, ' '); 1117 if (packageName == null) { 1118 break; 1119 } 1120 String timeInMillisString = readToken(in, sb, '\n'); 1121 if (timeInMillisString == null) { 1122 throw new IOException("Failed to find last usage time for package " 1123 + packageName); 1124 } 1125 PackageParser.Package pkg = mPackages.get(packageName); 1126 if (pkg == null) { 1127 continue; 1128 } 1129 long timeInMillis; 1130 try { 1131 timeInMillis = Long.parseLong(timeInMillisString); 1132 } catch (NumberFormatException e) { 1133 throw new IOException("Failed to parse " + timeInMillisString 1134 + " as a long.", e); 1135 } 1136 pkg.mLastPackageUsageTimeInMills = timeInMillis; 1137 } 1138 } catch (FileNotFoundException expected) { 1139 mIsHistoricalPackageUsageAvailable = false; 1140 } catch (IOException e) { 1141 Log.w(TAG, "Failed to read package usage times", e); 1142 } finally { 1143 IoUtils.closeQuietly(in); 1144 } 1145 } 1146 mLastWritten.set(SystemClock.elapsedRealtime()); 1147 } 1148 1149 private String readToken(InputStream in, StringBuffer sb, char endOfToken) 1150 throws IOException { 1151 sb.setLength(0); 1152 while (true) { 1153 int ch = in.read(); 1154 if (ch == -1) { 1155 if (sb.length() == 0) { 1156 return null; 1157 } 1158 throw new IOException("Unexpected EOF"); 1159 } 1160 if (ch == endOfToken) { 1161 return sb.toString(); 1162 } 1163 sb.append((char)ch); 1164 } 1165 } 1166 1167 private AtomicFile getFile() { 1168 File dataDir = Environment.getDataDirectory(); 1169 File systemDir = new File(dataDir, "system"); 1170 File fname = new File(systemDir, "package-usage.list"); 1171 return new AtomicFile(fname); 1172 } 1173 } 1174 1175 class PackageHandler extends Handler { 1176 private boolean mBound = false; 1177 final ArrayList<HandlerParams> mPendingInstalls = 1178 new ArrayList<HandlerParams>(); 1179 1180 private boolean connectToService() { 1181 if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" + 1182 " DefaultContainerService"); 1183 Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 1184 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1185 if (mContext.bindServiceAsUser(service, mDefContainerConn, 1186 Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) { 1187 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1188 mBound = true; 1189 return true; 1190 } 1191 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1192 return false; 1193 } 1194 1195 private void disconnectService() { 1196 mContainerService = null; 1197 mBound = false; 1198 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1199 mContext.unbindService(mDefContainerConn); 1200 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1201 } 1202 1203 PackageHandler(Looper looper) { 1204 super(looper); 1205 } 1206 1207 public void handleMessage(Message msg) { 1208 try { 1209 doHandleMessage(msg); 1210 } finally { 1211 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1212 } 1213 } 1214 1215 void doHandleMessage(Message msg) { 1216 switch (msg.what) { 1217 case INIT_COPY: { 1218 HandlerParams params = (HandlerParams) msg.obj; 1219 int idx = mPendingInstalls.size(); 1220 if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params); 1221 // If a bind was already initiated we dont really 1222 // need to do anything. The pending install 1223 // will be processed later on. 1224 if (!mBound) { 1225 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1226 System.identityHashCode(mHandler)); 1227 // If this is the only one pending we might 1228 // have to bind to the service again. 1229 if (!connectToService()) { 1230 Slog.e(TAG, "Failed to bind to media container service"); 1231 params.serviceError(); 1232 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1233 System.identityHashCode(mHandler)); 1234 if (params.traceMethod != null) { 1235 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod, 1236 params.traceCookie); 1237 } 1238 return; 1239 } else { 1240 // Once we bind to the service, the first 1241 // pending request will be processed. 1242 mPendingInstalls.add(idx, params); 1243 } 1244 } else { 1245 mPendingInstalls.add(idx, params); 1246 // Already bound to the service. Just make 1247 // sure we trigger off processing the first request. 1248 if (idx == 0) { 1249 mHandler.sendEmptyMessage(MCS_BOUND); 1250 } 1251 } 1252 break; 1253 } 1254 case MCS_BOUND: { 1255 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound"); 1256 if (msg.obj != null) { 1257 mContainerService = (IMediaContainerService) msg.obj; 1258 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1259 System.identityHashCode(mHandler)); 1260 } 1261 if (mContainerService == null) { 1262 if (!mBound) { 1263 // Something seriously wrong since we are not bound and we are not 1264 // waiting for connection. Bail out. 1265 Slog.e(TAG, "Cannot bind to media container service"); 1266 for (HandlerParams params : mPendingInstalls) { 1267 // Indicate service bind error 1268 params.serviceError(); 1269 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1270 System.identityHashCode(params)); 1271 if (params.traceMethod != null) { 1272 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, 1273 params.traceMethod, params.traceCookie); 1274 } 1275 return; 1276 } 1277 mPendingInstalls.clear(); 1278 } else { 1279 Slog.w(TAG, "Waiting to connect to media container service"); 1280 } 1281 } else if (mPendingInstalls.size() > 0) { 1282 HandlerParams params = mPendingInstalls.get(0); 1283 if (params != null) { 1284 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1285 System.identityHashCode(params)); 1286 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy"); 1287 if (params.startCopy()) { 1288 // We are done... look for more work or to 1289 // go idle. 1290 if (DEBUG_SD_INSTALL) Log.i(TAG, 1291 "Checking for more work or unbind..."); 1292 // Delete pending install 1293 if (mPendingInstalls.size() > 0) { 1294 mPendingInstalls.remove(0); 1295 } 1296 if (mPendingInstalls.size() == 0) { 1297 if (mBound) { 1298 if (DEBUG_SD_INSTALL) Log.i(TAG, 1299 "Posting delayed MCS_UNBIND"); 1300 removeMessages(MCS_UNBIND); 1301 Message ubmsg = obtainMessage(MCS_UNBIND); 1302 // Unbind after a little delay, to avoid 1303 // continual thrashing. 1304 sendMessageDelayed(ubmsg, 10000); 1305 } 1306 } else { 1307 // There are more pending requests in queue. 1308 // Just post MCS_BOUND message to trigger processing 1309 // of next pending install. 1310 if (DEBUG_SD_INSTALL) Log.i(TAG, 1311 "Posting MCS_BOUND for next work"); 1312 mHandler.sendEmptyMessage(MCS_BOUND); 1313 } 1314 } 1315 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 1316 } 1317 } else { 1318 // Should never happen ideally. 1319 Slog.w(TAG, "Empty queue"); 1320 } 1321 break; 1322 } 1323 case MCS_RECONNECT: { 1324 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect"); 1325 if (mPendingInstalls.size() > 0) { 1326 if (mBound) { 1327 disconnectService(); 1328 } 1329 if (!connectToService()) { 1330 Slog.e(TAG, "Failed to bind to media container service"); 1331 for (HandlerParams params : mPendingInstalls) { 1332 // Indicate service bind error 1333 params.serviceError(); 1334 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1335 System.identityHashCode(params)); 1336 } 1337 mPendingInstalls.clear(); 1338 } 1339 } 1340 break; 1341 } 1342 case MCS_UNBIND: { 1343 // If there is no actual work left, then time to unbind. 1344 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind"); 1345 1346 if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) { 1347 if (mBound) { 1348 if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()"); 1349 1350 disconnectService(); 1351 } 1352 } else if (mPendingInstalls.size() > 0) { 1353 // There are more pending requests in queue. 1354 // Just post MCS_BOUND message to trigger processing 1355 // of next pending install. 1356 mHandler.sendEmptyMessage(MCS_BOUND); 1357 } 1358 1359 break; 1360 } 1361 case MCS_GIVE_UP: { 1362 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries"); 1363 HandlerParams params = mPendingInstalls.remove(0); 1364 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1365 System.identityHashCode(params)); 1366 break; 1367 } 1368 case SEND_PENDING_BROADCAST: { 1369 String packages[]; 1370 ArrayList<String> components[]; 1371 int size = 0; 1372 int uids[]; 1373 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1374 synchronized (mPackages) { 1375 if (mPendingBroadcasts == null) { 1376 return; 1377 } 1378 size = mPendingBroadcasts.size(); 1379 if (size <= 0) { 1380 // Nothing to be done. Just return 1381 return; 1382 } 1383 packages = new String[size]; 1384 components = new ArrayList[size]; 1385 uids = new int[size]; 1386 int i = 0; // filling out the above arrays 1387 1388 for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) { 1389 int packageUserId = mPendingBroadcasts.userIdAt(n); 1390 Iterator<Map.Entry<String, ArrayList<String>>> it 1391 = mPendingBroadcasts.packagesForUserId(packageUserId) 1392 .entrySet().iterator(); 1393 while (it.hasNext() && i < size) { 1394 Map.Entry<String, ArrayList<String>> ent = it.next(); 1395 packages[i] = ent.getKey(); 1396 components[i] = ent.getValue(); 1397 PackageSetting ps = mSettings.mPackages.get(ent.getKey()); 1398 uids[i] = (ps != null) 1399 ? UserHandle.getUid(packageUserId, ps.appId) 1400 : -1; 1401 i++; 1402 } 1403 } 1404 size = i; 1405 mPendingBroadcasts.clear(); 1406 } 1407 // Send broadcasts 1408 for (int i = 0; i < size; i++) { 1409 sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]); 1410 } 1411 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1412 break; 1413 } 1414 case START_CLEANING_PACKAGE: { 1415 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1416 final String packageName = (String)msg.obj; 1417 final int userId = msg.arg1; 1418 final boolean andCode = msg.arg2 != 0; 1419 synchronized (mPackages) { 1420 if (userId == UserHandle.USER_ALL) { 1421 int[] users = sUserManager.getUserIds(); 1422 for (int user : users) { 1423 mSettings.addPackageToCleanLPw( 1424 new PackageCleanItem(user, packageName, andCode)); 1425 } 1426 } else { 1427 mSettings.addPackageToCleanLPw( 1428 new PackageCleanItem(userId, packageName, andCode)); 1429 } 1430 } 1431 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1432 startCleaningPackages(); 1433 } break; 1434 case POST_INSTALL: { 1435 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1); 1436 1437 PostInstallData data = mRunningInstalls.get(msg.arg1); 1438 mRunningInstalls.delete(msg.arg1); 1439 1440 if (data != null) { 1441 InstallArgs args = data.args; 1442 PackageInstalledInfo parentRes = data.res; 1443 1444 final boolean grantPermissions = (args.installFlags 1445 & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0; 1446 final boolean killApp = (args.installFlags 1447 & PackageManager.INSTALL_DONT_KILL_APP) == 0; 1448 final String[] grantedPermissions = args.installGrantPermissions; 1449 1450 // Handle the parent package 1451 handlePackagePostInstall(parentRes, grantPermissions, killApp, 1452 grantedPermissions, args.observer); 1453 1454 // Handle the child packages 1455 final int childCount = (parentRes.addedChildPackages != null) 1456 ? parentRes.addedChildPackages.size() : 0; 1457 for (int i = 0; i < childCount; i++) { 1458 PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i); 1459 handlePackagePostInstall(childRes, grantPermissions, killApp, 1460 grantedPermissions, args.observer); 1461 } 1462 1463 // Log tracing if needed 1464 if (args.traceMethod != null) { 1465 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod, 1466 args.traceCookie); 1467 } 1468 } else { 1469 Slog.e(TAG, "Bogus post-install token " + msg.arg1); 1470 } 1471 1472 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1); 1473 } break; 1474 case UPDATED_MEDIA_STATUS: { 1475 if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS"); 1476 boolean reportStatus = msg.arg1 == 1; 1477 boolean doGc = msg.arg2 == 1; 1478 if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc); 1479 if (doGc) { 1480 // Force a gc to clear up stale containers. 1481 Runtime.getRuntime().gc(); 1482 } 1483 if (msg.obj != null) { 1484 @SuppressWarnings("unchecked") 1485 Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj; 1486 if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers"); 1487 // Unload containers 1488 unloadAllContainers(args); 1489 } 1490 if (reportStatus) { 1491 try { 1492 if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back"); 1493 PackageHelper.getMountService().finishMediaUpdate(); 1494 } catch (RemoteException e) { 1495 Log.e(TAG, "MountService not running?"); 1496 } 1497 } 1498 } break; 1499 case WRITE_SETTINGS: { 1500 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1501 synchronized (mPackages) { 1502 removeMessages(WRITE_SETTINGS); 1503 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1504 mSettings.writeLPr(); 1505 mDirtyUsers.clear(); 1506 } 1507 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1508 } break; 1509 case WRITE_PACKAGE_RESTRICTIONS: { 1510 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1511 synchronized (mPackages) { 1512 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1513 for (int userId : mDirtyUsers) { 1514 mSettings.writePackageRestrictionsLPr(userId); 1515 } 1516 mDirtyUsers.clear(); 1517 } 1518 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1519 } break; 1520 case CHECK_PENDING_VERIFICATION: { 1521 final int verificationId = msg.arg1; 1522 final PackageVerificationState state = mPendingVerification.get(verificationId); 1523 1524 if ((state != null) && !state.timeoutExtended()) { 1525 final InstallArgs args = state.getInstallArgs(); 1526 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1527 1528 Slog.i(TAG, "Verification timed out for " + originUri); 1529 mPendingVerification.remove(verificationId); 1530 1531 int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1532 1533 if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) { 1534 Slog.i(TAG, "Continuing with installation of " + originUri); 1535 state.setVerifierResponse(Binder.getCallingUid(), 1536 PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT); 1537 broadcastPackageVerified(verificationId, originUri, 1538 PackageManager.VERIFICATION_ALLOW, 1539 state.getInstallArgs().getUser()); 1540 try { 1541 ret = args.copyApk(mContainerService, true); 1542 } catch (RemoteException e) { 1543 Slog.e(TAG, "Could not contact the ContainerService"); 1544 } 1545 } else { 1546 broadcastPackageVerified(verificationId, originUri, 1547 PackageManager.VERIFICATION_REJECT, 1548 state.getInstallArgs().getUser()); 1549 } 1550 1551 Trace.asyncTraceEnd( 1552 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 1553 1554 processPendingInstall(args, ret); 1555 mHandler.sendEmptyMessage(MCS_UNBIND); 1556 } 1557 break; 1558 } 1559 case PACKAGE_VERIFIED: { 1560 final int verificationId = msg.arg1; 1561 1562 final PackageVerificationState state = mPendingVerification.get(verificationId); 1563 if (state == null) { 1564 Slog.w(TAG, "Invalid verification token " + verificationId + " received"); 1565 break; 1566 } 1567 1568 final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj; 1569 1570 state.setVerifierResponse(response.callerUid, response.code); 1571 1572 if (state.isVerificationComplete()) { 1573 mPendingVerification.remove(verificationId); 1574 1575 final InstallArgs args = state.getInstallArgs(); 1576 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1577 1578 int ret; 1579 if (state.isInstallAllowed()) { 1580 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 1581 broadcastPackageVerified(verificationId, originUri, 1582 response.code, state.getInstallArgs().getUser()); 1583 try { 1584 ret = args.copyApk(mContainerService, true); 1585 } catch (RemoteException e) { 1586 Slog.e(TAG, "Could not contact the ContainerService"); 1587 } 1588 } else { 1589 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1590 } 1591 1592 Trace.asyncTraceEnd( 1593 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 1594 1595 processPendingInstall(args, ret); 1596 mHandler.sendEmptyMessage(MCS_UNBIND); 1597 } 1598 1599 break; 1600 } 1601 case START_INTENT_FILTER_VERIFICATIONS: { 1602 IFVerificationParams params = (IFVerificationParams) msg.obj; 1603 verifyIntentFiltersIfNeeded(params.userId, params.verifierUid, 1604 params.replacing, params.pkg); 1605 break; 1606 } 1607 case INTENT_FILTER_VERIFIED: { 1608 final int verificationId = msg.arg1; 1609 1610 final IntentFilterVerificationState state = mIntentFilterVerificationStates.get( 1611 verificationId); 1612 if (state == null) { 1613 Slog.w(TAG, "Invalid IntentFilter verification token " 1614 + verificationId + " received"); 1615 break; 1616 } 1617 1618 final int userId = state.getUserId(); 1619 1620 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1621 "Processing IntentFilter verification with token:" 1622 + verificationId + " and userId:" + userId); 1623 1624 final IntentFilterVerificationResponse response = 1625 (IntentFilterVerificationResponse) msg.obj; 1626 1627 state.setVerifierResponse(response.callerUid, response.code); 1628 1629 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1630 "IntentFilter verification with token:" + verificationId 1631 + " and userId:" + userId 1632 + " is settings verifier response with response code:" 1633 + response.code); 1634 1635 if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) { 1636 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: " 1637 + response.getFailedDomainsString()); 1638 } 1639 1640 if (state.isVerificationComplete()) { 1641 mIntentFilterVerifier.receiveVerificationResponse(verificationId); 1642 } else { 1643 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1644 "IntentFilter verification with token:" + verificationId 1645 + " was not said to be complete"); 1646 } 1647 1648 break; 1649 } 1650 } 1651 } 1652 } 1653 1654 private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions, 1655 boolean killApp, String[] grantedPermissions, 1656 IPackageInstallObserver2 installObserver) { 1657 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 1658 // Send the removed broadcasts 1659 if (res.removedInfo != null) { 1660 res.removedInfo.sendPackageRemovedBroadcasts(killApp); 1661 } 1662 1663 // Now that we successfully installed the package, grant runtime 1664 // permissions if requested before broadcasting the install. 1665 if (grantPermissions && res.pkg.applicationInfo.targetSdkVersion 1666 >= Build.VERSION_CODES.M) { 1667 grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions); 1668 } 1669 1670 final boolean update = res.removedInfo != null 1671 && res.removedInfo.removedPackage != null; 1672 1673 // If this is the first time we have child packages for a disabled privileged 1674 // app that had no children, we grant requested runtime permissions to the new 1675 // children if the parent on the system image had them already granted. 1676 if (res.pkg.parentPackage != null) { 1677 synchronized (mPackages) { 1678 grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg); 1679 } 1680 } 1681 1682 synchronized (mPackages) { 1683 mEphemeralApplicationRegistry.onPackageInstalledLPw(res.pkg); 1684 } 1685 1686 final String packageName = res.pkg.applicationInfo.packageName; 1687 Bundle extras = new Bundle(1); 1688 extras.putInt(Intent.EXTRA_UID, res.uid); 1689 1690 // Determine the set of users who are adding this package for 1691 // the first time vs. those who are seeing an update. 1692 int[] firstUsers = EMPTY_INT_ARRAY; 1693 int[] updateUsers = EMPTY_INT_ARRAY; 1694 if (res.origUsers == null || res.origUsers.length == 0) { 1695 firstUsers = res.newUsers; 1696 } else { 1697 for (int newUser : res.newUsers) { 1698 boolean isNew = true; 1699 for (int origUser : res.origUsers) { 1700 if (origUser == newUser) { 1701 isNew = false; 1702 break; 1703 } 1704 } 1705 if (isNew) { 1706 firstUsers = ArrayUtils.appendInt(firstUsers, newUser); 1707 } else { 1708 updateUsers = ArrayUtils.appendInt(updateUsers, newUser); 1709 } 1710 } 1711 } 1712 1713 // Send installed broadcasts if the install/update is not ephemeral 1714 if (!isEphemeral(res.pkg)) { 1715 // Send added for users that see the package for the first time 1716 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, 1717 extras, 0 /*flags*/, null /*targetPackage*/, 1718 null /*finishedReceiver*/, firstUsers); 1719 1720 // Send added for users that don't see the package for the first time 1721 if (update) { 1722 extras.putBoolean(Intent.EXTRA_REPLACING, true); 1723 } 1724 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, 1725 extras, 0 /*flags*/, null /*targetPackage*/, 1726 null /*finishedReceiver*/, updateUsers); 1727 1728 // Send replaced for users that don't see the package for the first time 1729 if (update) { 1730 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, 1731 packageName, extras, 0 /*flags*/, 1732 null /*targetPackage*/, null /*finishedReceiver*/, 1733 updateUsers); 1734 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, 1735 null /*package*/, null /*extras*/, 0 /*flags*/, 1736 packageName /*targetPackage*/, 1737 null /*finishedReceiver*/, updateUsers); 1738 } 1739 1740 // Send broadcast package appeared if forward locked/external for all users 1741 // treat asec-hosted packages like removable media on upgrade 1742 if (res.pkg.isForwardLocked() || isExternal(res.pkg)) { 1743 if (DEBUG_INSTALL) { 1744 Slog.i(TAG, "upgrading pkg " + res.pkg 1745 + " is ASEC-hosted -> AVAILABLE"); 1746 } 1747 final int[] uidArray = new int[]{res.pkg.applicationInfo.uid}; 1748 ArrayList<String> pkgList = new ArrayList<>(1); 1749 pkgList.add(packageName); 1750 sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null); 1751 } 1752 } 1753 1754 // Work that needs to happen on first install within each user 1755 if (firstUsers != null && firstUsers.length > 0) { 1756 synchronized (mPackages) { 1757 for (int userId : firstUsers) { 1758 // If this app is a browser and it's newly-installed for some 1759 // users, clear any default-browser state in those users. The 1760 // app's nature doesn't depend on the user, so we can just check 1761 // its browser nature in any user and generalize. 1762 if (packageIsBrowser(packageName, userId)) { 1763 mSettings.setDefaultBrowserPackageNameLPw(null, userId); 1764 } 1765 1766 // We may also need to apply pending (restored) runtime 1767 // permission grants within these users. 1768 mSettings.applyPendingPermissionGrantsLPw(packageName, userId); 1769 } 1770 } 1771 } 1772 1773 // Log current value of "unknown sources" setting 1774 EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED, 1775 getUnknownSourcesSettings()); 1776 1777 // Force a gc to clear up things 1778 Runtime.getRuntime().gc(); 1779 1780 // Remove the replaced package's older resources safely now 1781 // We delete after a gc for applications on sdcard. 1782 if (res.removedInfo != null && res.removedInfo.args != null) { 1783 synchronized (mInstallLock) { 1784 res.removedInfo.args.doPostDeleteLI(true); 1785 } 1786 } 1787 } 1788 1789 // If someone is watching installs - notify them 1790 if (installObserver != null) { 1791 try { 1792 Bundle extras = extrasForInstallResult(res); 1793 installObserver.onPackageInstalled(res.name, res.returnCode, 1794 res.returnMsg, extras); 1795 } catch (RemoteException e) { 1796 Slog.i(TAG, "Observer no longer exists."); 1797 } 1798 } 1799 } 1800 1801 private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw( 1802 PackageParser.Package pkg) { 1803 if (pkg.parentPackage == null) { 1804 return; 1805 } 1806 if (pkg.requestedPermissions == null) { 1807 return; 1808 } 1809 final PackageSetting disabledSysParentPs = mSettings 1810 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName); 1811 if (disabledSysParentPs == null || disabledSysParentPs.pkg == null 1812 || !disabledSysParentPs.isPrivileged() 1813 || (disabledSysParentPs.childPackageNames != null 1814 && !disabledSysParentPs.childPackageNames.isEmpty())) { 1815 return; 1816 } 1817 final int[] allUserIds = sUserManager.getUserIds(); 1818 final int permCount = pkg.requestedPermissions.size(); 1819 for (int i = 0; i < permCount; i++) { 1820 String permission = pkg.requestedPermissions.get(i); 1821 BasePermission bp = mSettings.mPermissions.get(permission); 1822 if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) { 1823 continue; 1824 } 1825 for (int userId : allUserIds) { 1826 if (disabledSysParentPs.getPermissionsState().hasRuntimePermission( 1827 permission, userId)) { 1828 grantRuntimePermission(pkg.packageName, permission, userId); 1829 } 1830 } 1831 } 1832 } 1833 1834 private StorageEventListener mStorageListener = new StorageEventListener() { 1835 @Override 1836 public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) { 1837 if (vol.type == VolumeInfo.TYPE_PRIVATE) { 1838 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1839 final String volumeUuid = vol.getFsUuid(); 1840 1841 // Clean up any users or apps that were removed or recreated 1842 // while this volume was missing 1843 reconcileUsers(volumeUuid); 1844 reconcileApps(volumeUuid); 1845 1846 // Clean up any install sessions that expired or were 1847 // cancelled while this volume was missing 1848 mInstallerService.onPrivateVolumeMounted(volumeUuid); 1849 1850 loadPrivatePackages(vol); 1851 1852 } else if (vol.state == VolumeInfo.STATE_EJECTING) { 1853 unloadPrivatePackages(vol); 1854 } 1855 } 1856 1857 if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) { 1858 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1859 updateExternalMediaStatus(true, false); 1860 } else if (vol.state == VolumeInfo.STATE_EJECTING) { 1861 updateExternalMediaStatus(false, false); 1862 } 1863 } 1864 } 1865 1866 @Override 1867 public void onVolumeForgotten(String fsUuid) { 1868 if (TextUtils.isEmpty(fsUuid)) { 1869 Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring"); 1870 return; 1871 } 1872 1873 // Remove any apps installed on the forgotten volume 1874 synchronized (mPackages) { 1875 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid); 1876 for (PackageSetting ps : packages) { 1877 Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten"); 1878 deletePackage(ps.name, new LegacyPackageDeleteObserver(null).getBinder(), 1879 UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS); 1880 } 1881 1882 mSettings.onVolumeForgotten(fsUuid); 1883 mSettings.writeLPr(); 1884 } 1885 } 1886 }; 1887 1888 private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds, 1889 String[] grantedPermissions) { 1890 for (int userId : userIds) { 1891 grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions); 1892 } 1893 1894 // We could have touched GID membership, so flush out packages.list 1895 synchronized (mPackages) { 1896 mSettings.writePackageListLPr(); 1897 } 1898 } 1899 1900 private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId, 1901 String[] grantedPermissions) { 1902 SettingBase sb = (SettingBase) pkg.mExtras; 1903 if (sb == null) { 1904 return; 1905 } 1906 1907 PermissionsState permissionsState = sb.getPermissionsState(); 1908 1909 final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 1910 | PackageManager.FLAG_PERMISSION_POLICY_FIXED; 1911 1912 synchronized (mPackages) { 1913 for (String permission : pkg.requestedPermissions) { 1914 BasePermission bp = mSettings.mPermissions.get(permission); 1915 if (bp != null && (bp.isRuntime() || bp.isDevelopment()) 1916 && (grantedPermissions == null 1917 || ArrayUtils.contains(grantedPermissions, permission))) { 1918 final int flags = permissionsState.getPermissionFlags(permission, userId); 1919 // Installer cannot change immutable permissions. 1920 if ((flags & immutableFlags) == 0) { 1921 grantRuntimePermission(pkg.packageName, permission, userId); 1922 } 1923 } 1924 } 1925 } 1926 } 1927 1928 Bundle extrasForInstallResult(PackageInstalledInfo res) { 1929 Bundle extras = null; 1930 switch (res.returnCode) { 1931 case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: { 1932 extras = new Bundle(); 1933 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION, 1934 res.origPermission); 1935 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE, 1936 res.origPackage); 1937 break; 1938 } 1939 case PackageManager.INSTALL_SUCCEEDED: { 1940 extras = new Bundle(); 1941 extras.putBoolean(Intent.EXTRA_REPLACING, 1942 res.removedInfo != null && res.removedInfo.removedPackage != null); 1943 break; 1944 } 1945 } 1946 return extras; 1947 } 1948 1949 void scheduleWriteSettingsLocked() { 1950 if (!mHandler.hasMessages(WRITE_SETTINGS)) { 1951 mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY); 1952 } 1953 } 1954 1955 void scheduleWritePackageRestrictionsLocked(UserHandle user) { 1956 final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier(); 1957 scheduleWritePackageRestrictionsLocked(userId); 1958 } 1959 1960 void scheduleWritePackageRestrictionsLocked(int userId) { 1961 final int[] userIds = (userId == UserHandle.USER_ALL) 1962 ? sUserManager.getUserIds() : new int[]{userId}; 1963 for (int nextUserId : userIds) { 1964 if (!sUserManager.exists(nextUserId)) return; 1965 mDirtyUsers.add(nextUserId); 1966 if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) { 1967 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY); 1968 } 1969 } 1970 } 1971 1972 public static PackageManagerService main(Context context, Installer installer, 1973 boolean factoryTest, boolean onlyCore) { 1974 // Self-check for initial settings. 1975 PackageManagerServiceCompilerMapping.checkProperties(); 1976 1977 PackageManagerService m = new PackageManagerService(context, installer, 1978 factoryTest, onlyCore); 1979 m.enableSystemUserPackages(); 1980 ServiceManager.addService("package", m); 1981 return m; 1982 } 1983 1984 private void enableSystemUserPackages() { 1985 if (!UserManager.isSplitSystemUser()) { 1986 return; 1987 } 1988 // For system user, enable apps based on the following conditions: 1989 // - app is whitelisted or belong to one of these groups: 1990 // -- system app which has no launcher icons 1991 // -- system app which has INTERACT_ACROSS_USERS permission 1992 // -- system IME app 1993 // - app is not in the blacklist 1994 AppsQueryHelper queryHelper = new AppsQueryHelper(this); 1995 Set<String> enableApps = new ArraySet<>(); 1996 enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS 1997 | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM 1998 | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM)); 1999 ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps(); 2000 enableApps.addAll(wlApps); 2001 enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER, 2002 /* systemAppsOnly */ false, UserHandle.SYSTEM)); 2003 ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps(); 2004 enableApps.removeAll(blApps); 2005 Log.i(TAG, "Applications installed for system user: " + enableApps); 2006 List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false, 2007 UserHandle.SYSTEM); 2008 final int allAppsSize = allAps.size(); 2009 synchronized (mPackages) { 2010 for (int i = 0; i < allAppsSize; i++) { 2011 String pName = allAps.get(i); 2012 PackageSetting pkgSetting = mSettings.mPackages.get(pName); 2013 // Should not happen, but we shouldn't be failing if it does 2014 if (pkgSetting == null) { 2015 continue; 2016 } 2017 boolean install = enableApps.contains(pName); 2018 if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) { 2019 Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName 2020 + " for system user"); 2021 pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM); 2022 } 2023 } 2024 } 2025 } 2026 2027 private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) { 2028 DisplayManager displayManager = (DisplayManager) context.getSystemService( 2029 Context.DISPLAY_SERVICE); 2030 displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics); 2031 } 2032 2033 public PackageManagerService(Context context, Installer installer, 2034 boolean factoryTest, boolean onlyCore) { 2035 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START, 2036 SystemClock.uptimeMillis()); 2037 2038 if (mSdkVersion <= 0) { 2039 Slog.w(TAG, "**** ro.build.version.sdk not set!"); 2040 } 2041 2042 mContext = context; 2043 mFactoryTest = factoryTest; 2044 mOnlyCore = onlyCore; 2045 mMetrics = new DisplayMetrics(); 2046 mSettings = new Settings(mPackages); 2047 mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID, 2048 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2049 mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, 2050 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2051 mSettings.addSharedUserLPw("android.uid.log", LOG_UID, 2052 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2053 mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, 2054 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2055 mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID, 2056 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2057 mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID, 2058 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2059 2060 String separateProcesses = SystemProperties.get("debug.separate_processes"); 2061 if (separateProcesses != null && separateProcesses.length() > 0) { 2062 if ("*".equals(separateProcesses)) { 2063 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES; 2064 mSeparateProcesses = null; 2065 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)"); 2066 } else { 2067 mDefParseFlags = 0; 2068 mSeparateProcesses = separateProcesses.split(","); 2069 Slog.w(TAG, "Running with debug.separate_processes: " 2070 + separateProcesses); 2071 } 2072 } else { 2073 mDefParseFlags = 0; 2074 mSeparateProcesses = null; 2075 } 2076 2077 mInstaller = installer; 2078 mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context, 2079 "*dexopt*"); 2080 mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper()); 2081 2082 mOnPermissionChangeListeners = new OnPermissionChangeListeners( 2083 FgThread.get().getLooper()); 2084 2085 getDefaultDisplayMetrics(context, mMetrics); 2086 2087 SystemConfig systemConfig = SystemConfig.getInstance(); 2088 mGlobalGids = systemConfig.getGlobalGids(); 2089 mSystemPermissions = systemConfig.getSystemPermissions(); 2090 mAvailableFeatures = systemConfig.getAvailableFeatures(); 2091 2092 synchronized (mInstallLock) { 2093 // writer 2094 synchronized (mPackages) { 2095 mHandlerThread = new ServiceThread(TAG, 2096 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/); 2097 mHandlerThread.start(); 2098 mHandler = new PackageHandler(mHandlerThread.getLooper()); 2099 Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT); 2100 2101 File dataDir = Environment.getDataDirectory(); 2102 mAppInstallDir = new File(dataDir, "app"); 2103 mAppLib32InstallDir = new File(dataDir, "app-lib"); 2104 mEphemeralInstallDir = new File(dataDir, "app-ephemeral"); 2105 mAsecInternalPath = new File(dataDir, "app-asec").getPath(); 2106 mDrmAppPrivateInstallDir = new File(dataDir, "app-private"); 2107 2108 sUserManager = new UserManagerService(context, this, mPackages); 2109 2110 // Propagate permission configuration in to package manager. 2111 ArrayMap<String, SystemConfig.PermissionEntry> permConfig 2112 = systemConfig.getPermissions(); 2113 for (int i=0; i<permConfig.size(); i++) { 2114 SystemConfig.PermissionEntry perm = permConfig.valueAt(i); 2115 BasePermission bp = mSettings.mPermissions.get(perm.name); 2116 if (bp == null) { 2117 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN); 2118 mSettings.mPermissions.put(perm.name, bp); 2119 } 2120 if (perm.gids != null) { 2121 bp.setGids(perm.gids, perm.perUser); 2122 } 2123 } 2124 2125 ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries(); 2126 for (int i=0; i<libConfig.size(); i++) { 2127 mSharedLibraries.put(libConfig.keyAt(i), 2128 new SharedLibraryEntry(libConfig.valueAt(i), null)); 2129 } 2130 2131 mFoundPolicyFile = SELinuxMMAC.readInstallPolicy(); 2132 2133 mRestoredSettings = mSettings.readLPw(sUserManager.getUsers(false)); 2134 2135 String customResolverActivity = Resources.getSystem().getString( 2136 R.string.config_customResolverActivity); 2137 if (TextUtils.isEmpty(customResolverActivity)) { 2138 customResolverActivity = null; 2139 } else { 2140 mCustomResolverComponentName = ComponentName.unflattenFromString( 2141 customResolverActivity); 2142 } 2143 2144 long startTime = SystemClock.uptimeMillis(); 2145 2146 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START, 2147 startTime); 2148 2149 // Set flag to monitor and not change apk file paths when 2150 // scanning install directories. 2151 final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING | SCAN_INITIAL; 2152 2153 final String bootClassPath = System.getenv("BOOTCLASSPATH"); 2154 final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH"); 2155 2156 if (bootClassPath == null) { 2157 Slog.w(TAG, "No BOOTCLASSPATH found!"); 2158 } 2159 2160 if (systemServerClassPath == null) { 2161 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!"); 2162 } 2163 2164 final List<String> allInstructionSets = InstructionSets.getAllInstructionSets(); 2165 final String[] dexCodeInstructionSets = 2166 getDexCodeInstructionSets( 2167 allInstructionSets.toArray(new String[allInstructionSets.size()])); 2168 2169 /** 2170 * Ensure all external libraries have had dexopt run on them. 2171 */ 2172 if (mSharedLibraries.size() > 0) { 2173 // NOTE: For now, we're compiling these system "shared libraries" 2174 // (and framework jars) into all available architectures. It's possible 2175 // to compile them only when we come across an app that uses them (there's 2176 // already logic for that in scanPackageLI) but that adds some complexity. 2177 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 2178 for (SharedLibraryEntry libEntry : mSharedLibraries.values()) { 2179 final String lib = libEntry.path; 2180 if (lib == null) { 2181 continue; 2182 } 2183 2184 try { 2185 // Shared libraries do not have profiles so we perform a full 2186 // AOT compilation (if needed). 2187 int dexoptNeeded = DexFile.getDexOptNeeded( 2188 lib, dexCodeInstructionSet, 2189 getCompilerFilterForReason(REASON_SHARED_APK), 2190 false /* newProfile */); 2191 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { 2192 mInstaller.dexopt(lib, Process.SYSTEM_UID, dexCodeInstructionSet, 2193 dexoptNeeded, DEXOPT_PUBLIC /*dexFlags*/, 2194 getCompilerFilterForReason(REASON_SHARED_APK), 2195 StorageManager.UUID_PRIVATE_INTERNAL); 2196 } 2197 } catch (FileNotFoundException e) { 2198 Slog.w(TAG, "Library not found: " + lib); 2199 } catch (IOException | InstallerException e) { 2200 Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? " 2201 + e.getMessage()); 2202 } 2203 } 2204 } 2205 } 2206 2207 File frameworkDir = new File(Environment.getRootDirectory(), "framework"); 2208 2209 final VersionInfo ver = mSettings.getInternalVersion(); 2210 mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint); 2211 2212 // when upgrading from pre-M, promote system app permissions from install to runtime 2213 mPromoteSystemApps = 2214 mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1; 2215 2216 // save off the names of pre-existing system packages prior to scanning; we don't 2217 // want to automatically grant runtime permissions for new system apps 2218 if (mPromoteSystemApps) { 2219 Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator(); 2220 while (pkgSettingIter.hasNext()) { 2221 PackageSetting ps = pkgSettingIter.next(); 2222 if (isSystemApp(ps)) { 2223 mExistingSystemPackages.add(ps.name); 2224 } 2225 } 2226 } 2227 2228 // When upgrading form pre-N, we need to handle package extraction like first boot, 2229 // as there is no profiling data available. 2230 mIsPreNUpgrade = ver.sdkVersion <= Build.VERSION_CODES.M; 2231 2232 // Collect vendor overlay packages. 2233 // (Do this before scanning any apps.) 2234 // For security and version matching reason, only consider 2235 // overlay packages if they reside in VENDOR_OVERLAY_DIR. 2236 File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR); 2237 scanDirTracedLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM 2238 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0); 2239 2240 // Find base frameworks (resource packages without code). 2241 scanDirTracedLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM 2242 | PackageParser.PARSE_IS_SYSTEM_DIR 2243 | PackageParser.PARSE_IS_PRIVILEGED, 2244 scanFlags | SCAN_NO_DEX, 0); 2245 2246 // Collected privileged system packages. 2247 final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app"); 2248 scanDirTracedLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM 2249 | PackageParser.PARSE_IS_SYSTEM_DIR 2250 | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0); 2251 2252 // Collect ordinary system packages. 2253 final File systemAppDir = new File(Environment.getRootDirectory(), "app"); 2254 scanDirTracedLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM 2255 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2256 2257 // Collect all vendor packages. 2258 File vendorAppDir = new File("/vendor/app"); 2259 try { 2260 vendorAppDir = vendorAppDir.getCanonicalFile(); 2261 } catch (IOException e) { 2262 // failed to look up canonical path, continue with original one 2263 } 2264 scanDirTracedLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM 2265 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2266 2267 // Collect all OEM packages. 2268 final File oemAppDir = new File(Environment.getOemDirectory(), "app"); 2269 scanDirTracedLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM 2270 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2271 2272 // Prune any system packages that no longer exist. 2273 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>(); 2274 if (!mOnlyCore) { 2275 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 2276 while (psit.hasNext()) { 2277 PackageSetting ps = psit.next(); 2278 2279 /* 2280 * If this is not a system app, it can't be a 2281 * disable system app. 2282 */ 2283 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) { 2284 continue; 2285 } 2286 2287 /* 2288 * If the package is scanned, it's not erased. 2289 */ 2290 final PackageParser.Package scannedPkg = mPackages.get(ps.name); 2291 if (scannedPkg != null) { 2292 /* 2293 * If the system app is both scanned and in the 2294 * disabled packages list, then it must have been 2295 * added via OTA. Remove it from the currently 2296 * scanned package so the previously user-installed 2297 * application can be scanned. 2298 */ 2299 if (mSettings.isDisabledSystemPackageLPr(ps.name)) { 2300 logCriticalInfo(Log.WARN, "Expecting better updated system app for " 2301 + ps.name + "; removing system app. Last known codePath=" 2302 + ps.codePathString + ", installStatus=" + ps.installStatus 2303 + ", versionCode=" + ps.versionCode + "; scanned versionCode=" 2304 + scannedPkg.mVersionCode); 2305 removePackageLI(scannedPkg, true); 2306 mExpectingBetter.put(ps.name, ps.codePath); 2307 } 2308 2309 continue; 2310 } 2311 2312 if (!mSettings.isDisabledSystemPackageLPr(ps.name)) { 2313 psit.remove(); 2314 logCriticalInfo(Log.WARN, "System package " + ps.name 2315 + " no longer exists; wiping its data"); 2316 removeDataDirsLI(null, ps.name); 2317 } else { 2318 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name); 2319 if (disabledPs.codePath == null || !disabledPs.codePath.exists()) { 2320 possiblyDeletedUpdatedSystemApps.add(ps.name); 2321 } 2322 } 2323 } 2324 } 2325 2326 //look for any incomplete package installations 2327 ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr(); 2328 //clean up list 2329 for(int i = 0; i < deletePkgsList.size(); i++) { 2330 //clean up here 2331 cleanupInstallFailedPackage(deletePkgsList.get(i)); 2332 } 2333 //delete tmp files 2334 deleteTempPackageFiles(); 2335 2336 // Remove any shared userIDs that have no associated packages 2337 mSettings.pruneSharedUsersLPw(); 2338 2339 if (!mOnlyCore) { 2340 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START, 2341 SystemClock.uptimeMillis()); 2342 scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0); 2343 2344 scanDirTracedLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK, 2345 scanFlags | SCAN_REQUIRE_KNOWN, 0); 2346 2347 scanDirLI(mEphemeralInstallDir, PackageParser.PARSE_IS_EPHEMERAL, 2348 scanFlags | SCAN_REQUIRE_KNOWN, 0); 2349 2350 /** 2351 * Remove disable package settings for any updated system 2352 * apps that were removed via an OTA. If they're not a 2353 * previously-updated app, remove them completely. 2354 * Otherwise, just revoke their system-level permissions. 2355 */ 2356 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) { 2357 PackageParser.Package deletedPkg = mPackages.get(deletedAppName); 2358 mSettings.removeDisabledSystemPackageLPw(deletedAppName); 2359 2360 String msg; 2361 if (deletedPkg == null) { 2362 msg = "Updated system package " + deletedAppName 2363 + " no longer exists; wiping its data"; 2364 removeDataDirsLI(null, deletedAppName); 2365 } else { 2366 msg = "Updated system app + " + deletedAppName 2367 + " no longer present; removing system privileges for " 2368 + deletedAppName; 2369 2370 deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM; 2371 2372 PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName); 2373 deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM; 2374 } 2375 logCriticalInfo(Log.WARN, msg); 2376 } 2377 2378 /** 2379 * Make sure all system apps that we expected to appear on 2380 * the userdata partition actually showed up. If they never 2381 * appeared, crawl back and revive the system version. 2382 */ 2383 for (int i = 0; i < mExpectingBetter.size(); i++) { 2384 final String packageName = mExpectingBetter.keyAt(i); 2385 if (!mPackages.containsKey(packageName)) { 2386 final File scanFile = mExpectingBetter.valueAt(i); 2387 2388 logCriticalInfo(Log.WARN, "Expected better " + packageName 2389 + " but never showed up; reverting to system"); 2390 2391 final int reparseFlags; 2392 if (FileUtils.contains(privilegedAppDir, scanFile)) { 2393 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2394 | PackageParser.PARSE_IS_SYSTEM_DIR 2395 | PackageParser.PARSE_IS_PRIVILEGED; 2396 } else if (FileUtils.contains(systemAppDir, scanFile)) { 2397 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2398 | PackageParser.PARSE_IS_SYSTEM_DIR; 2399 } else if (FileUtils.contains(vendorAppDir, scanFile)) { 2400 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2401 | PackageParser.PARSE_IS_SYSTEM_DIR; 2402 } else if (FileUtils.contains(oemAppDir, scanFile)) { 2403 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2404 | PackageParser.PARSE_IS_SYSTEM_DIR; 2405 } else { 2406 Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile); 2407 continue; 2408 } 2409 2410 mSettings.enableSystemPackageLPw(packageName); 2411 2412 try { 2413 scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null); 2414 } catch (PackageManagerException e) { 2415 Slog.e(TAG, "Failed to parse original system package: " 2416 + e.getMessage()); 2417 } 2418 } 2419 } 2420 } 2421 mExpectingBetter.clear(); 2422 2423 // Now that we know all of the shared libraries, update all clients to have 2424 // the correct library paths. 2425 updateAllSharedLibrariesLPw(); 2426 2427 for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) { 2428 // NOTE: We ignore potential failures here during a system scan (like 2429 // the rest of the commands above) because there's precious little we 2430 // can do about it. A settings error is reported, though. 2431 adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */, 2432 false /* boot complete */); 2433 } 2434 2435 // Now that we know all the packages we are keeping, 2436 // read and update their last usage times. 2437 mPackageUsage.readLP(); 2438 2439 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END, 2440 SystemClock.uptimeMillis()); 2441 Slog.i(TAG, "Time to scan packages: " 2442 + ((SystemClock.uptimeMillis()-startTime)/1000f) 2443 + " seconds"); 2444 2445 // If the platform SDK has changed since the last time we booted, 2446 // we need to re-grant app permission to catch any new ones that 2447 // appear. This is really a hack, and means that apps can in some 2448 // cases get permissions that the user didn't initially explicitly 2449 // allow... it would be nice to have some better way to handle 2450 // this situation. 2451 int updateFlags = UPDATE_PERMISSIONS_ALL; 2452 if (ver.sdkVersion != mSdkVersion) { 2453 Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to " 2454 + mSdkVersion + "; regranting permissions for internal storage"); 2455 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 2456 } 2457 updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags); 2458 ver.sdkVersion = mSdkVersion; 2459 2460 // If this is the first boot or an update from pre-M, and it is a normal 2461 // boot, then we need to initialize the default preferred apps across 2462 // all defined users. 2463 if (!onlyCore && (mPromoteSystemApps || !mRestoredSettings)) { 2464 for (UserInfo user : sUserManager.getUsers(true)) { 2465 mSettings.applyDefaultPreferredAppsLPw(this, user.id); 2466 applyFactoryDefaultBrowserLPw(user.id); 2467 primeDomainVerificationsLPw(user.id); 2468 } 2469 } 2470 2471 // Prepare storage for system user really early during boot, 2472 // since core system apps like SettingsProvider and SystemUI 2473 // can't wait for user to start 2474 final int storageFlags; 2475 if (StorageManager.isFileEncryptedNativeOrEmulated()) { 2476 storageFlags = StorageManager.FLAG_STORAGE_DE; 2477 } else { 2478 storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 2479 } 2480 reconcileAppsData(StorageManager.UUID_PRIVATE_INTERNAL, UserHandle.USER_SYSTEM, 2481 storageFlags); 2482 2483 // If this is first boot after an OTA, and a normal boot, then 2484 // we need to clear code cache directories. 2485 if (mIsUpgrade && !onlyCore) { 2486 Slog.i(TAG, "Build fingerprint changed; clearing code caches"); 2487 for (int i = 0; i < mSettings.mPackages.size(); i++) { 2488 final PackageSetting ps = mSettings.mPackages.valueAt(i); 2489 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) { 2490 deleteCodeCacheDirsLI(ps.volumeUuid, ps.name); 2491 } 2492 } 2493 ver.fingerprint = Build.FINGERPRINT; 2494 } 2495 2496 checkDefaultBrowser(); 2497 2498 // clear only after permissions and other defaults have been updated 2499 mExistingSystemPackages.clear(); 2500 mPromoteSystemApps = false; 2501 2502 // All the changes are done during package scanning. 2503 ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION; 2504 2505 // can downgrade to reader 2506 mSettings.writeLPr(); 2507 2508 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY, 2509 SystemClock.uptimeMillis()); 2510 2511 if (!mOnlyCore) { 2512 mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr(); 2513 mRequiredInstallerPackage = getRequiredInstallerLPr(); 2514 mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr(); 2515 mIntentFilterVerifier = new IntentVerifierProxy(mContext, 2516 mIntentFilterVerifierComponent); 2517 } else { 2518 mRequiredVerifierPackage = null; 2519 mRequiredInstallerPackage = null; 2520 mIntentFilterVerifierComponent = null; 2521 mIntentFilterVerifier = null; 2522 } 2523 2524 mInstallerService = new PackageInstallerService(context, this); 2525 2526 final ComponentName ephemeralResolverComponent = getEphemeralResolverLPr(); 2527 final ComponentName ephemeralInstallerComponent = getEphemeralInstallerLPr(); 2528 // both the installer and resolver must be present to enable ephemeral 2529 if (ephemeralInstallerComponent != null && ephemeralResolverComponent != null) { 2530 if (DEBUG_EPHEMERAL) { 2531 Slog.i(TAG, "Ephemeral activated; resolver: " + ephemeralResolverComponent 2532 + " installer:" + ephemeralInstallerComponent); 2533 } 2534 mEphemeralResolverComponent = ephemeralResolverComponent; 2535 mEphemeralInstallerComponent = ephemeralInstallerComponent; 2536 setUpEphemeralInstallerActivityLP(mEphemeralInstallerComponent); 2537 mEphemeralResolverConnection = 2538 new EphemeralResolverConnection(mContext, mEphemeralResolverComponent); 2539 } else { 2540 if (DEBUG_EPHEMERAL) { 2541 final String missingComponent = 2542 (ephemeralResolverComponent == null) 2543 ? (ephemeralInstallerComponent == null) 2544 ? "resolver and installer" 2545 : "resolver" 2546 : "installer"; 2547 Slog.i(TAG, "Ephemeral deactivated; missing " + missingComponent); 2548 } 2549 mEphemeralResolverComponent = null; 2550 mEphemeralInstallerComponent = null; 2551 mEphemeralResolverConnection = null; 2552 } 2553 2554 mEphemeralApplicationRegistry = new EphemeralApplicationRegistry(this); 2555 } // synchronized (mPackages) 2556 } // synchronized (mInstallLock) 2557 2558 // Now after opening every single application zip, make sure they 2559 // are all flushed. Not really needed, but keeps things nice and 2560 // tidy. 2561 Runtime.getRuntime().gc(); 2562 2563 // The initial scanning above does many calls into installd while 2564 // holding the mPackages lock, but we're mostly interested in yelling 2565 // once we have a booted system. 2566 mInstaller.setWarnIfHeld(mPackages); 2567 2568 // Expose private service for system components to use. 2569 LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl()); 2570 } 2571 2572 @Override 2573 public boolean isFirstBoot() { 2574 return !mRestoredSettings; 2575 } 2576 2577 @Override 2578 public boolean isOnlyCoreApps() { 2579 return mOnlyCore; 2580 } 2581 2582 @Override 2583 public boolean isUpgrade() { 2584 return mIsUpgrade; 2585 } 2586 2587 private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() { 2588 final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 2589 2590 final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE, 2591 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 2592 UserHandle.USER_SYSTEM); 2593 if (matches.size() == 1) { 2594 return matches.get(0).getComponentInfo().packageName; 2595 } else { 2596 Log.e(TAG, "There should probably be exactly one verifier; found " + matches); 2597 return null; 2598 } 2599 } 2600 2601 private @NonNull String getRequiredInstallerLPr() { 2602 final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE); 2603 intent.addCategory(Intent.CATEGORY_DEFAULT); 2604 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE); 2605 2606 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE, 2607 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 2608 UserHandle.USER_SYSTEM); 2609 if (matches.size() == 1) { 2610 return matches.get(0).getComponentInfo().packageName; 2611 } else { 2612 throw new RuntimeException("There must be exactly one installer; found " + matches); 2613 } 2614 } 2615 2616 private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() { 2617 final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 2618 2619 final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE, 2620 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 2621 UserHandle.USER_SYSTEM); 2622 ResolveInfo best = null; 2623 final int N = matches.size(); 2624 for (int i = 0; i < N; i++) { 2625 final ResolveInfo cur = matches.get(i); 2626 final String packageName = cur.getComponentInfo().packageName; 2627 if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 2628 packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) { 2629 continue; 2630 } 2631 2632 if (best == null || cur.priority > best.priority) { 2633 best = cur; 2634 } 2635 } 2636 2637 if (best != null) { 2638 return best.getComponentInfo().getComponentName(); 2639 } else { 2640 throw new RuntimeException("There must be at least one intent filter verifier"); 2641 } 2642 } 2643 2644 private @Nullable ComponentName getEphemeralResolverLPr() { 2645 final String[] packageArray = 2646 mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage); 2647 if (packageArray.length == 0) { 2648 if (DEBUG_EPHEMERAL) { 2649 Slog.d(TAG, "Ephemeral resolver NOT found; empty package list"); 2650 } 2651 return null; 2652 } 2653 2654 final Intent resolverIntent = new Intent(Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE); 2655 final List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null, 2656 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 2657 UserHandle.USER_SYSTEM); 2658 2659 final int N = resolvers.size(); 2660 if (N == 0) { 2661 if (DEBUG_EPHEMERAL) { 2662 Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters"); 2663 } 2664 return null; 2665 } 2666 2667 final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray)); 2668 for (int i = 0; i < N; i++) { 2669 final ResolveInfo info = resolvers.get(i); 2670 2671 if (info.serviceInfo == null) { 2672 continue; 2673 } 2674 2675 final String packageName = info.serviceInfo.packageName; 2676 if (!possiblePackages.contains(packageName)) { 2677 if (DEBUG_EPHEMERAL) { 2678 Slog.d(TAG, "Ephemeral resolver not in allowed package list;" 2679 + " pkg: " + packageName + ", info:" + info); 2680 } 2681 continue; 2682 } 2683 2684 if (DEBUG_EPHEMERAL) { 2685 Slog.v(TAG, "Ephemeral resolver found;" 2686 + " pkg: " + packageName + ", info:" + info); 2687 } 2688 return new ComponentName(packageName, info.serviceInfo.name); 2689 } 2690 if (DEBUG_EPHEMERAL) { 2691 Slog.v(TAG, "Ephemeral resolver NOT found"); 2692 } 2693 return null; 2694 } 2695 2696 private @Nullable ComponentName getEphemeralInstallerLPr() { 2697 final Intent intent = new Intent(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE); 2698 intent.addCategory(Intent.CATEGORY_DEFAULT); 2699 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE); 2700 2701 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE, 2702 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 2703 UserHandle.USER_SYSTEM); 2704 if (matches.size() == 0) { 2705 return null; 2706 } else if (matches.size() == 1) { 2707 return matches.get(0).getComponentInfo().getComponentName(); 2708 } else { 2709 throw new RuntimeException( 2710 "There must be at most one ephemeral installer; found " + matches); 2711 } 2712 } 2713 2714 private void primeDomainVerificationsLPw(int userId) { 2715 if (DEBUG_DOMAIN_VERIFICATION) { 2716 Slog.d(TAG, "Priming domain verifications in user " + userId); 2717 } 2718 2719 SystemConfig systemConfig = SystemConfig.getInstance(); 2720 ArraySet<String> packages = systemConfig.getLinkedApps(); 2721 ArraySet<String> domains = new ArraySet<String>(); 2722 2723 for (String packageName : packages) { 2724 PackageParser.Package pkg = mPackages.get(packageName); 2725 if (pkg != null) { 2726 if (!pkg.isSystemApp()) { 2727 Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>"); 2728 continue; 2729 } 2730 2731 domains.clear(); 2732 for (PackageParser.Activity a : pkg.activities) { 2733 for (ActivityIntentInfo filter : a.intents) { 2734 if (hasValidDomains(filter)) { 2735 domains.addAll(filter.getHostsList()); 2736 } 2737 } 2738 } 2739 2740 if (domains.size() > 0) { 2741 if (DEBUG_DOMAIN_VERIFICATION) { 2742 Slog.v(TAG, " + " + packageName); 2743 } 2744 // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual 2745 // state w.r.t. the formal app-linkage "no verification attempted" state; 2746 // and then 'always' in the per-user state actually used for intent resolution. 2747 final IntentFilterVerificationInfo ivi; 2748 ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, 2749 new ArrayList<String>(domains)); 2750 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED); 2751 mSettings.updateIntentFilterVerificationStatusLPw(packageName, 2752 INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId); 2753 } else { 2754 Slog.w(TAG, "Sysconfig <app-link> package '" + packageName 2755 + "' does not handle web links"); 2756 } 2757 } else { 2758 Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>"); 2759 } 2760 } 2761 2762 scheduleWritePackageRestrictionsLocked(userId); 2763 scheduleWriteSettingsLocked(); 2764 } 2765 2766 private void applyFactoryDefaultBrowserLPw(int userId) { 2767 // The default browser app's package name is stored in a string resource, 2768 // with a product-specific overlay used for vendor customization. 2769 String browserPkg = mContext.getResources().getString( 2770 com.android.internal.R.string.default_browser); 2771 if (!TextUtils.isEmpty(browserPkg)) { 2772 // non-empty string => required to be a known package 2773 PackageSetting ps = mSettings.mPackages.get(browserPkg); 2774 if (ps == null) { 2775 Slog.e(TAG, "Product default browser app does not exist: " + browserPkg); 2776 browserPkg = null; 2777 } else { 2778 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId); 2779 } 2780 } 2781 2782 // Nothing valid explicitly set? Make the factory-installed browser the explicit 2783 // default. If there's more than one, just leave everything alone. 2784 if (browserPkg == null) { 2785 calculateDefaultBrowserLPw(userId); 2786 } 2787 } 2788 2789 private void calculateDefaultBrowserLPw(int userId) { 2790 List<String> allBrowsers = resolveAllBrowserApps(userId); 2791 final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null; 2792 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId); 2793 } 2794 2795 private List<String> resolveAllBrowserApps(int userId) { 2796 // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set 2797 List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null, 2798 PackageManager.MATCH_ALL, userId); 2799 2800 final int count = list.size(); 2801 List<String> result = new ArrayList<String>(count); 2802 for (int i=0; i<count; i++) { 2803 ResolveInfo info = list.get(i); 2804 if (info.activityInfo == null 2805 || !info.handleAllWebDataURI 2806 || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0 2807 || result.contains(info.activityInfo.packageName)) { 2808 continue; 2809 } 2810 result.add(info.activityInfo.packageName); 2811 } 2812 2813 return result; 2814 } 2815 2816 private boolean packageIsBrowser(String packageName, int userId) { 2817 List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null, 2818 PackageManager.MATCH_ALL, userId); 2819 final int N = list.size(); 2820 for (int i = 0; i < N; i++) { 2821 ResolveInfo info = list.get(i); 2822 if (packageName.equals(info.activityInfo.packageName)) { 2823 return true; 2824 } 2825 } 2826 return false; 2827 } 2828 2829 private void checkDefaultBrowser() { 2830 final int myUserId = UserHandle.myUserId(); 2831 final String packageName = getDefaultBrowserPackageName(myUserId); 2832 if (packageName != null) { 2833 PackageInfo info = getPackageInfo(packageName, 0, myUserId); 2834 if (info == null) { 2835 Slog.w(TAG, "Default browser no longer installed: " + packageName); 2836 synchronized (mPackages) { 2837 applyFactoryDefaultBrowserLPw(myUserId); // leaves ambiguous when > 1 2838 } 2839 } 2840 } 2841 } 2842 2843 @Override 2844 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2845 throws RemoteException { 2846 try { 2847 return super.onTransact(code, data, reply, flags); 2848 } catch (RuntimeException e) { 2849 if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) { 2850 Slog.wtf(TAG, "Package Manager Crash", e); 2851 } 2852 throw e; 2853 } 2854 } 2855 2856 void cleanupInstallFailedPackage(PackageSetting ps) { 2857 logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + ps.name); 2858 2859 removeDataDirsLI(ps.volumeUuid, ps.name); 2860 if (ps.codePath != null) { 2861 removeCodePathLI(ps.codePath); 2862 } 2863 if (ps.resourcePath != null && !ps.resourcePath.equals(ps.codePath)) { 2864 if (ps.resourcePath.isDirectory()) { 2865 FileUtils.deleteContents(ps.resourcePath); 2866 } 2867 ps.resourcePath.delete(); 2868 } 2869 mSettings.removePackageLPw(ps.name); 2870 } 2871 2872 static int[] appendInts(int[] cur, int[] add) { 2873 if (add == null) return cur; 2874 if (cur == null) return add; 2875 final int N = add.length; 2876 for (int i=0; i<N; i++) { 2877 cur = appendInt(cur, add[i]); 2878 } 2879 return cur; 2880 } 2881 2882 PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) { 2883 if (!sUserManager.exists(userId)) return null; 2884 final PackageSetting ps = (PackageSetting) p.mExtras; 2885 if (ps == null) { 2886 return null; 2887 } 2888 2889 final PermissionsState permissionsState = ps.getPermissionsState(); 2890 2891 final int[] gids = permissionsState.computeGids(userId); 2892 final Set<String> permissions = permissionsState.getPermissions(userId); 2893 final PackageUserState state = ps.readUserState(userId); 2894 2895 return PackageParser.generatePackageInfo(p, gids, flags, 2896 ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId); 2897 } 2898 2899 @Override 2900 public void checkPackageStartable(String packageName, int userId) { 2901 final boolean userKeyUnlocked = isUserKeyUnlocked(userId); 2902 2903 synchronized (mPackages) { 2904 final PackageSetting ps = mSettings.mPackages.get(packageName); 2905 if (ps == null) { 2906 throw new SecurityException("Package " + packageName + " was not found!"); 2907 } 2908 2909 if (!ps.getInstalled(userId)) { 2910 throw new SecurityException( 2911 "Package " + packageName + " was not installed for user " + userId + "!"); 2912 } 2913 2914 if (mSafeMode && !ps.isSystem()) { 2915 throw new SecurityException("Package " + packageName + " not a system app!"); 2916 } 2917 2918 if (ps.frozen) { 2919 throw new SecurityException("Package " + packageName + " is currently frozen!"); 2920 } 2921 2922 if (!userKeyUnlocked && !(ps.pkg.applicationInfo.isDirectBootAware() 2923 || ps.pkg.applicationInfo.isPartiallyDirectBootAware())) { 2924 throw new SecurityException("Package " + packageName + " is not encryption aware!"); 2925 } 2926 } 2927 } 2928 2929 @Override 2930 public boolean isPackageAvailable(String packageName, int userId) { 2931 if (!sUserManager.exists(userId)) return false; 2932 enforceCrossUserPermission(Binder.getCallingUid(), userId, 2933 false /* requireFullPermission */, false /* checkShell */, "is package available"); 2934 synchronized (mPackages) { 2935 PackageParser.Package p = mPackages.get(packageName); 2936 if (p != null) { 2937 final PackageSetting ps = (PackageSetting) p.mExtras; 2938 if (ps != null) { 2939 final PackageUserState state = ps.readUserState(userId); 2940 if (state != null) { 2941 return PackageParser.isAvailable(state); 2942 } 2943 } 2944 } 2945 } 2946 return false; 2947 } 2948 2949 @Override 2950 public PackageInfo getPackageInfo(String packageName, int flags, int userId) { 2951 if (!sUserManager.exists(userId)) return null; 2952 flags = updateFlagsForPackage(flags, userId, packageName); 2953 enforceCrossUserPermission(Binder.getCallingUid(), userId, 2954 false /* requireFullPermission */, false /* checkShell */, "get package info"); 2955 // reader 2956 synchronized (mPackages) { 2957 PackageParser.Package p = mPackages.get(packageName); 2958 if (DEBUG_PACKAGE_INFO) 2959 Log.v(TAG, "getPackageInfo " + packageName + ": " + p); 2960 if (p != null) { 2961 return generatePackageInfo(p, flags, userId); 2962 } 2963 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 2964 return generatePackageInfoFromSettingsLPw(packageName, flags, userId); 2965 } 2966 } 2967 return null; 2968 } 2969 2970 @Override 2971 public String[] currentToCanonicalPackageNames(String[] names) { 2972 String[] out = new String[names.length]; 2973 // reader 2974 synchronized (mPackages) { 2975 for (int i=names.length-1; i>=0; i--) { 2976 PackageSetting ps = mSettings.mPackages.get(names[i]); 2977 out[i] = ps != null && ps.realName != null ? ps.realName : names[i]; 2978 } 2979 } 2980 return out; 2981 } 2982 2983 @Override 2984 public String[] canonicalToCurrentPackageNames(String[] names) { 2985 String[] out = new String[names.length]; 2986 // reader 2987 synchronized (mPackages) { 2988 for (int i=names.length-1; i>=0; i--) { 2989 String cur = mSettings.mRenamedPackages.get(names[i]); 2990 out[i] = cur != null ? cur : names[i]; 2991 } 2992 } 2993 return out; 2994 } 2995 2996 @Override 2997 public int getPackageUid(String packageName, int flags, int userId) { 2998 if (!sUserManager.exists(userId)) return -1; 2999 flags = updateFlagsForPackage(flags, userId, packageName); 3000 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3001 false /* requireFullPermission */, false /* checkShell */, "get package uid"); 3002 3003 // reader 3004 synchronized (mPackages) { 3005 final PackageParser.Package p = mPackages.get(packageName); 3006 if (p != null && p.isMatch(flags)) { 3007 return UserHandle.getUid(userId, p.applicationInfo.uid); 3008 } 3009 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 3010 final PackageSetting ps = mSettings.mPackages.get(packageName); 3011 if (ps != null && ps.isMatch(flags)) { 3012 return UserHandle.getUid(userId, ps.appId); 3013 } 3014 } 3015 } 3016 3017 return -1; 3018 } 3019 3020 @Override 3021 public int[] getPackageGids(String packageName, int flags, int userId) { 3022 if (!sUserManager.exists(userId)) return null; 3023 flags = updateFlagsForPackage(flags, userId, packageName); 3024 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3025 false /* requireFullPermission */, false /* checkShell */, 3026 "getPackageGids"); 3027 3028 // reader 3029 synchronized (mPackages) { 3030 final PackageParser.Package p = mPackages.get(packageName); 3031 if (p != null && p.isMatch(flags)) { 3032 PackageSetting ps = (PackageSetting) p.mExtras; 3033 return ps.getPermissionsState().computeGids(userId); 3034 } 3035 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 3036 final PackageSetting ps = mSettings.mPackages.get(packageName); 3037 if (ps != null && ps.isMatch(flags)) { 3038 return ps.getPermissionsState().computeGids(userId); 3039 } 3040 } 3041 } 3042 3043 return null; 3044 } 3045 3046 static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) { 3047 if (bp.perm != null) { 3048 return PackageParser.generatePermissionInfo(bp.perm, flags); 3049 } 3050 PermissionInfo pi = new PermissionInfo(); 3051 pi.name = bp.name; 3052 pi.packageName = bp.sourcePackage; 3053 pi.nonLocalizedLabel = bp.name; 3054 pi.protectionLevel = bp.protectionLevel; 3055 return pi; 3056 } 3057 3058 @Override 3059 public PermissionInfo getPermissionInfo(String name, int flags) { 3060 // reader 3061 synchronized (mPackages) { 3062 final BasePermission p = mSettings.mPermissions.get(name); 3063 if (p != null) { 3064 return generatePermissionInfo(p, flags); 3065 } 3066 return null; 3067 } 3068 } 3069 3070 @Override 3071 public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group, 3072 int flags) { 3073 // reader 3074 synchronized (mPackages) { 3075 if (group != null && !mPermissionGroups.containsKey(group)) { 3076 // This is thrown as NameNotFoundException 3077 return null; 3078 } 3079 3080 ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10); 3081 for (BasePermission p : mSettings.mPermissions.values()) { 3082 if (group == null) { 3083 if (p.perm == null || p.perm.info.group == null) { 3084 out.add(generatePermissionInfo(p, flags)); 3085 } 3086 } else { 3087 if (p.perm != null && group.equals(p.perm.info.group)) { 3088 out.add(PackageParser.generatePermissionInfo(p.perm, flags)); 3089 } 3090 } 3091 } 3092 return new ParceledListSlice<>(out); 3093 } 3094 } 3095 3096 @Override 3097 public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) { 3098 // reader 3099 synchronized (mPackages) { 3100 return PackageParser.generatePermissionGroupInfo( 3101 mPermissionGroups.get(name), flags); 3102 } 3103 } 3104 3105 @Override 3106 public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) { 3107 // reader 3108 synchronized (mPackages) { 3109 final int N = mPermissionGroups.size(); 3110 ArrayList<PermissionGroupInfo> out 3111 = new ArrayList<PermissionGroupInfo>(N); 3112 for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) { 3113 out.add(PackageParser.generatePermissionGroupInfo(pg, flags)); 3114 } 3115 return new ParceledListSlice<>(out); 3116 } 3117 } 3118 3119 private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags, 3120 int userId) { 3121 if (!sUserManager.exists(userId)) return null; 3122 PackageSetting ps = mSettings.mPackages.get(packageName); 3123 if (ps != null) { 3124 if (ps.pkg == null) { 3125 PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName, 3126 flags, userId); 3127 if (pInfo != null) { 3128 return pInfo.applicationInfo; 3129 } 3130 return null; 3131 } 3132 return PackageParser.generateApplicationInfo(ps.pkg, flags, 3133 ps.readUserState(userId), userId); 3134 } 3135 return null; 3136 } 3137 3138 private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags, 3139 int userId) { 3140 if (!sUserManager.exists(userId)) return null; 3141 PackageSetting ps = mSettings.mPackages.get(packageName); 3142 if (ps != null) { 3143 PackageParser.Package pkg = ps.pkg; 3144 if (pkg == null) { 3145 if ((flags & MATCH_UNINSTALLED_PACKAGES) == 0) { 3146 return null; 3147 } 3148 // Only data remains, so we aren't worried about code paths 3149 pkg = new PackageParser.Package(packageName); 3150 pkg.applicationInfo.packageName = packageName; 3151 pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY; 3152 pkg.applicationInfo.privateFlags = ps.pkgPrivateFlags; 3153 pkg.applicationInfo.uid = ps.appId; 3154 pkg.applicationInfo.initForUser(userId); 3155 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString; 3156 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString; 3157 } 3158 return generatePackageInfo(pkg, flags, userId); 3159 } 3160 return null; 3161 } 3162 3163 @Override 3164 public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) { 3165 if (!sUserManager.exists(userId)) return null; 3166 flags = updateFlagsForApplication(flags, userId, packageName); 3167 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3168 false /* requireFullPermission */, false /* checkShell */, "get application info"); 3169 // writer 3170 synchronized (mPackages) { 3171 PackageParser.Package p = mPackages.get(packageName); 3172 if (DEBUG_PACKAGE_INFO) Log.v( 3173 TAG, "getApplicationInfo " + packageName 3174 + ": " + p); 3175 if (p != null) { 3176 PackageSetting ps = mSettings.mPackages.get(packageName); 3177 if (ps == null) return null; 3178 // Note: isEnabledLP() does not apply here - always return info 3179 return PackageParser.generateApplicationInfo( 3180 p, flags, ps.readUserState(userId), userId); 3181 } 3182 if ("android".equals(packageName)||"system".equals(packageName)) { 3183 return mAndroidApplication; 3184 } 3185 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 3186 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId); 3187 } 3188 } 3189 return null; 3190 } 3191 3192 @Override 3193 public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize, 3194 final IPackageDataObserver observer) { 3195 mContext.enforceCallingOrSelfPermission( 3196 android.Manifest.permission.CLEAR_APP_CACHE, null); 3197 // Queue up an async operation since clearing cache may take a little while. 3198 mHandler.post(new Runnable() { 3199 public void run() { 3200 mHandler.removeCallbacks(this); 3201 boolean success = true; 3202 synchronized (mInstallLock) { 3203 try { 3204 mInstaller.freeCache(volumeUuid, freeStorageSize); 3205 } catch (InstallerException e) { 3206 Slog.w(TAG, "Couldn't clear application caches: " + e); 3207 success = false; 3208 } 3209 } 3210 if (observer != null) { 3211 try { 3212 observer.onRemoveCompleted(null, success); 3213 } catch (RemoteException e) { 3214 Slog.w(TAG, "RemoveException when invoking call back"); 3215 } 3216 } 3217 } 3218 }); 3219 } 3220 3221 @Override 3222 public void freeStorage(final String volumeUuid, final long freeStorageSize, 3223 final IntentSender pi) { 3224 mContext.enforceCallingOrSelfPermission( 3225 android.Manifest.permission.CLEAR_APP_CACHE, null); 3226 // Queue up an async operation since clearing cache may take a little while. 3227 mHandler.post(new Runnable() { 3228 public void run() { 3229 mHandler.removeCallbacks(this); 3230 boolean success = true; 3231 synchronized (mInstallLock) { 3232 try { 3233 mInstaller.freeCache(volumeUuid, freeStorageSize); 3234 } catch (InstallerException e) { 3235 Slog.w(TAG, "Couldn't clear application caches: " + e); 3236 success = false; 3237 } 3238 } 3239 if(pi != null) { 3240 try { 3241 // Callback via pending intent 3242 int code = success ? 1 : 0; 3243 pi.sendIntent(null, code, null, 3244 null, null); 3245 } catch (SendIntentException e1) { 3246 Slog.i(TAG, "Failed to send pending intent"); 3247 } 3248 } 3249 } 3250 }); 3251 } 3252 3253 void freeStorage(String volumeUuid, long freeStorageSize) throws IOException { 3254 synchronized (mInstallLock) { 3255 try { 3256 mInstaller.freeCache(volumeUuid, freeStorageSize); 3257 } catch (InstallerException e) { 3258 throw new IOException("Failed to free enough space", e); 3259 } 3260 } 3261 } 3262 3263 /** 3264 * Return if the user key is currently unlocked. 3265 */ 3266 private boolean isUserKeyUnlocked(int userId) { 3267 if (StorageManager.isFileEncryptedNativeOrEmulated()) { 3268 final IMountService mount = IMountService.Stub 3269 .asInterface(ServiceManager.getService("mount")); 3270 if (mount == null) { 3271 Slog.w(TAG, "Early during boot, assuming locked"); 3272 return false; 3273 } 3274 final long token = Binder.clearCallingIdentity(); 3275 try { 3276 return mount.isUserKeyUnlocked(userId); 3277 } catch (RemoteException e) { 3278 throw e.rethrowAsRuntimeException(); 3279 } finally { 3280 Binder.restoreCallingIdentity(token); 3281 } 3282 } else { 3283 return true; 3284 } 3285 } 3286 3287 /** 3288 * Update given flags based on encryption status of current user. 3289 */ 3290 private int updateFlags(int flags, int userId) { 3291 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE 3292 | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) { 3293 // Caller expressed an explicit opinion about what encryption 3294 // aware/unaware components they want to see, so fall through and 3295 // give them what they want 3296 } else { 3297 // Caller expressed no opinion, so match based on user state 3298 if (isUserKeyUnlocked(userId)) { 3299 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE; 3300 } else { 3301 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE; 3302 } 3303 } 3304 return flags; 3305 } 3306 3307 /** 3308 * Update given flags when being used to request {@link PackageInfo}. 3309 */ 3310 private int updateFlagsForPackage(int flags, int userId, Object cookie) { 3311 boolean triaged = true; 3312 if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS 3313 | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) { 3314 // Caller is asking for component details, so they'd better be 3315 // asking for specific encryption matching behavior, or be triaged 3316 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE 3317 | PackageManager.MATCH_DIRECT_BOOT_AWARE 3318 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3319 triaged = false; 3320 } 3321 } 3322 if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES 3323 | PackageManager.MATCH_SYSTEM_ONLY 3324 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3325 triaged = false; 3326 } 3327 if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) { 3328 Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie 3329 + " with flags 0x" + Integer.toHexString(flags), new Throwable()); 3330 } 3331 return updateFlags(flags, userId); 3332 } 3333 3334 /** 3335 * Update given flags when being used to request {@link ApplicationInfo}. 3336 */ 3337 private int updateFlagsForApplication(int flags, int userId, Object cookie) { 3338 return updateFlagsForPackage(flags, userId, cookie); 3339 } 3340 3341 /** 3342 * Update given flags when being used to request {@link ComponentInfo}. 3343 */ 3344 private int updateFlagsForComponent(int flags, int userId, Object cookie) { 3345 if (cookie instanceof Intent) { 3346 if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) { 3347 flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING; 3348 } 3349 } 3350 3351 boolean triaged = true; 3352 // Caller is asking for component details, so they'd better be 3353 // asking for specific encryption matching behavior, or be triaged 3354 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE 3355 | PackageManager.MATCH_DIRECT_BOOT_AWARE 3356 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3357 triaged = false; 3358 } 3359 if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) { 3360 Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie 3361 + " with flags 0x" + Integer.toHexString(flags), new Throwable()); 3362 } 3363 3364 return updateFlags(flags, userId); 3365 } 3366 3367 /** 3368 * Update given flags when being used to request {@link ResolveInfo}. 3369 */ 3370 int updateFlagsForResolve(int flags, int userId, Object cookie) { 3371 // Safe mode means we shouldn't match any third-party components 3372 if (mSafeMode) { 3373 flags |= PackageManager.MATCH_SYSTEM_ONLY; 3374 } 3375 3376 return updateFlagsForComponent(flags, userId, cookie); 3377 } 3378 3379 @Override 3380 public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) { 3381 if (!sUserManager.exists(userId)) return null; 3382 flags = updateFlagsForComponent(flags, userId, component); 3383 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3384 false /* requireFullPermission */, false /* checkShell */, "get activity info"); 3385 synchronized (mPackages) { 3386 PackageParser.Activity a = mActivities.mActivities.get(component); 3387 3388 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a); 3389 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) { 3390 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3391 if (ps == null) return null; 3392 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 3393 userId); 3394 } 3395 if (mResolveComponentName.equals(component)) { 3396 return PackageParser.generateActivityInfo(mResolveActivity, flags, 3397 new PackageUserState(), userId); 3398 } 3399 } 3400 return null; 3401 } 3402 3403 @Override 3404 public boolean activitySupportsIntent(ComponentName component, Intent intent, 3405 String resolvedType) { 3406 synchronized (mPackages) { 3407 if (component.equals(mResolveComponentName)) { 3408 // The resolver supports EVERYTHING! 3409 return true; 3410 } 3411 PackageParser.Activity a = mActivities.mActivities.get(component); 3412 if (a == null) { 3413 return false; 3414 } 3415 for (int i=0; i<a.intents.size(); i++) { 3416 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(), 3417 intent.getData(), intent.getCategories(), TAG) >= 0) { 3418 return true; 3419 } 3420 } 3421 return false; 3422 } 3423 } 3424 3425 @Override 3426 public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) { 3427 if (!sUserManager.exists(userId)) return null; 3428 flags = updateFlagsForComponent(flags, userId, component); 3429 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3430 false /* requireFullPermission */, false /* checkShell */, "get receiver info"); 3431 synchronized (mPackages) { 3432 PackageParser.Activity a = mReceivers.mActivities.get(component); 3433 if (DEBUG_PACKAGE_INFO) Log.v( 3434 TAG, "getReceiverInfo " + component + ": " + a); 3435 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) { 3436 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3437 if (ps == null) return null; 3438 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 3439 userId); 3440 } 3441 } 3442 return null; 3443 } 3444 3445 @Override 3446 public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) { 3447 if (!sUserManager.exists(userId)) return null; 3448 flags = updateFlagsForComponent(flags, userId, component); 3449 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3450 false /* requireFullPermission */, false /* checkShell */, "get service info"); 3451 synchronized (mPackages) { 3452 PackageParser.Service s = mServices.mServices.get(component); 3453 if (DEBUG_PACKAGE_INFO) Log.v( 3454 TAG, "getServiceInfo " + component + ": " + s); 3455 if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) { 3456 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3457 if (ps == null) return null; 3458 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId), 3459 userId); 3460 } 3461 } 3462 return null; 3463 } 3464 3465 @Override 3466 public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) { 3467 if (!sUserManager.exists(userId)) return null; 3468 flags = updateFlagsForComponent(flags, userId, component); 3469 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3470 false /* requireFullPermission */, false /* checkShell */, "get provider info"); 3471 synchronized (mPackages) { 3472 PackageParser.Provider p = mProviders.mProviders.get(component); 3473 if (DEBUG_PACKAGE_INFO) Log.v( 3474 TAG, "getProviderInfo " + component + ": " + p); 3475 if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) { 3476 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3477 if (ps == null) return null; 3478 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId), 3479 userId); 3480 } 3481 } 3482 return null; 3483 } 3484 3485 @Override 3486 public String[] getSystemSharedLibraryNames() { 3487 Set<String> libSet; 3488 synchronized (mPackages) { 3489 libSet = mSharedLibraries.keySet(); 3490 int size = libSet.size(); 3491 if (size > 0) { 3492 String[] libs = new String[size]; 3493 libSet.toArray(libs); 3494 return libs; 3495 } 3496 } 3497 return null; 3498 } 3499 3500 @Override 3501 public @Nullable String getServicesSystemSharedLibraryPackageName() { 3502 synchronized (mPackages) { 3503 SharedLibraryEntry libraryEntry = mSharedLibraries.get( 3504 PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES); 3505 if (libraryEntry != null) { 3506 return libraryEntry.apk; 3507 } 3508 } 3509 return null; 3510 } 3511 3512 @Override 3513 public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() { 3514 synchronized (mPackages) { 3515 final ArrayList<FeatureInfo> res = new ArrayList<>(mAvailableFeatures.values()); 3516 3517 final FeatureInfo fi = new FeatureInfo(); 3518 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version", 3519 FeatureInfo.GL_ES_VERSION_UNDEFINED); 3520 res.add(fi); 3521 3522 return new ParceledListSlice<>(res); 3523 } 3524 } 3525 3526 @Override 3527 public boolean hasSystemFeature(String name, int version) { 3528 synchronized (mPackages) { 3529 final FeatureInfo feat = mAvailableFeatures.get(name); 3530 if (feat == null) { 3531 return false; 3532 } else { 3533 return feat.version >= version; 3534 } 3535 } 3536 } 3537 3538 @Override 3539 public int checkPermission(String permName, String pkgName, int userId) { 3540 if (!sUserManager.exists(userId)) { 3541 return PackageManager.PERMISSION_DENIED; 3542 } 3543 3544 synchronized (mPackages) { 3545 final PackageParser.Package p = mPackages.get(pkgName); 3546 if (p != null && p.mExtras != null) { 3547 final PackageSetting ps = (PackageSetting) p.mExtras; 3548 final PermissionsState permissionsState = ps.getPermissionsState(); 3549 if (permissionsState.hasPermission(permName, userId)) { 3550 return PackageManager.PERMISSION_GRANTED; 3551 } 3552 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION 3553 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState 3554 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { 3555 return PackageManager.PERMISSION_GRANTED; 3556 } 3557 } 3558 } 3559 3560 return PackageManager.PERMISSION_DENIED; 3561 } 3562 3563 @Override 3564 public int checkUidPermission(String permName, int uid) { 3565 final int userId = UserHandle.getUserId(uid); 3566 3567 if (!sUserManager.exists(userId)) { 3568 return PackageManager.PERMISSION_DENIED; 3569 } 3570 3571 synchronized (mPackages) { 3572 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 3573 if (obj != null) { 3574 final SettingBase ps = (SettingBase) obj; 3575 final PermissionsState permissionsState = ps.getPermissionsState(); 3576 if (permissionsState.hasPermission(permName, userId)) { 3577 return PackageManager.PERMISSION_GRANTED; 3578 } 3579 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION 3580 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState 3581 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { 3582 return PackageManager.PERMISSION_GRANTED; 3583 } 3584 } else { 3585 ArraySet<String> perms = mSystemPermissions.get(uid); 3586 if (perms != null) { 3587 if (perms.contains(permName)) { 3588 return PackageManager.PERMISSION_GRANTED; 3589 } 3590 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms 3591 .contains(Manifest.permission.ACCESS_FINE_LOCATION)) { 3592 return PackageManager.PERMISSION_GRANTED; 3593 } 3594 } 3595 } 3596 } 3597 3598 return PackageManager.PERMISSION_DENIED; 3599 } 3600 3601 @Override 3602 public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) { 3603 if (UserHandle.getCallingUserId() != userId) { 3604 mContext.enforceCallingPermission( 3605 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 3606 "isPermissionRevokedByPolicy for user " + userId); 3607 } 3608 3609 if (checkPermission(permission, packageName, userId) 3610 == PackageManager.PERMISSION_GRANTED) { 3611 return false; 3612 } 3613 3614 final long identity = Binder.clearCallingIdentity(); 3615 try { 3616 final int flags = getPermissionFlags(permission, packageName, userId); 3617 return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0; 3618 } finally { 3619 Binder.restoreCallingIdentity(identity); 3620 } 3621 } 3622 3623 @Override 3624 public String getPermissionControllerPackageName() { 3625 synchronized (mPackages) { 3626 return mRequiredInstallerPackage; 3627 } 3628 } 3629 3630 /** 3631 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS 3632 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller. 3633 * @param checkShell whether to prevent shell from access if there's a debugging restriction 3634 * @param message the message to log on security exception 3635 */ 3636 void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, 3637 boolean checkShell, String message) { 3638 if (userId < 0) { 3639 throw new IllegalArgumentException("Invalid userId " + userId); 3640 } 3641 if (checkShell) { 3642 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); 3643 } 3644 if (userId == UserHandle.getUserId(callingUid)) return; 3645 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 3646 if (requireFullPermission) { 3647 mContext.enforceCallingOrSelfPermission( 3648 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 3649 } else { 3650 try { 3651 mContext.enforceCallingOrSelfPermission( 3652 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 3653 } catch (SecurityException se) { 3654 mContext.enforceCallingOrSelfPermission( 3655 android.Manifest.permission.INTERACT_ACROSS_USERS, message); 3656 } 3657 } 3658 } 3659 } 3660 3661 void enforceShellRestriction(String restriction, int callingUid, int userHandle) { 3662 if (callingUid == Process.SHELL_UID) { 3663 if (userHandle >= 0 3664 && sUserManager.hasUserRestriction(restriction, userHandle)) { 3665 throw new SecurityException("Shell does not have permission to access user " 3666 + userHandle); 3667 } else if (userHandle < 0) { 3668 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t" 3669 + Debug.getCallers(3)); 3670 } 3671 } 3672 } 3673 3674 private BasePermission findPermissionTreeLP(String permName) { 3675 for(BasePermission bp : mSettings.mPermissionTrees.values()) { 3676 if (permName.startsWith(bp.name) && 3677 permName.length() > bp.name.length() && 3678 permName.charAt(bp.name.length()) == '.') { 3679 return bp; 3680 } 3681 } 3682 return null; 3683 } 3684 3685 private BasePermission checkPermissionTreeLP(String permName) { 3686 if (permName != null) { 3687 BasePermission bp = findPermissionTreeLP(permName); 3688 if (bp != null) { 3689 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) { 3690 return bp; 3691 } 3692 throw new SecurityException("Calling uid " 3693 + Binder.getCallingUid() 3694 + " is not allowed to add to permission tree " 3695 + bp.name + " owned by uid " + bp.uid); 3696 } 3697 } 3698 throw new SecurityException("No permission tree found for " + permName); 3699 } 3700 3701 static boolean compareStrings(CharSequence s1, CharSequence s2) { 3702 if (s1 == null) { 3703 return s2 == null; 3704 } 3705 if (s2 == null) { 3706 return false; 3707 } 3708 if (s1.getClass() != s2.getClass()) { 3709 return false; 3710 } 3711 return s1.equals(s2); 3712 } 3713 3714 static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) { 3715 if (pi1.icon != pi2.icon) return false; 3716 if (pi1.logo != pi2.logo) return false; 3717 if (pi1.protectionLevel != pi2.protectionLevel) return false; 3718 if (!compareStrings(pi1.name, pi2.name)) return false; 3719 if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false; 3720 // We'll take care of setting this one. 3721 if (!compareStrings(pi1.packageName, pi2.packageName)) return false; 3722 // These are not currently stored in settings. 3723 //if (!compareStrings(pi1.group, pi2.group)) return false; 3724 //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false; 3725 //if (pi1.labelRes != pi2.labelRes) return false; 3726 //if (pi1.descriptionRes != pi2.descriptionRes) return false; 3727 return true; 3728 } 3729 3730 int permissionInfoFootprint(PermissionInfo info) { 3731 int size = info.name.length(); 3732 if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length(); 3733 if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length(); 3734 return size; 3735 } 3736 3737 int calculateCurrentPermissionFootprintLocked(BasePermission tree) { 3738 int size = 0; 3739 for (BasePermission perm : mSettings.mPermissions.values()) { 3740 if (perm.uid == tree.uid) { 3741 size += perm.name.length() + permissionInfoFootprint(perm.perm.info); 3742 } 3743 } 3744 return size; 3745 } 3746 3747 void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) { 3748 // We calculate the max size of permissions defined by this uid and throw 3749 // if that plus the size of 'info' would exceed our stated maximum. 3750 if (tree.uid != Process.SYSTEM_UID) { 3751 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree); 3752 if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) { 3753 throw new SecurityException("Permission tree size cap exceeded"); 3754 } 3755 } 3756 } 3757 3758 boolean addPermissionLocked(PermissionInfo info, boolean async) { 3759 if (info.labelRes == 0 && info.nonLocalizedLabel == null) { 3760 throw new SecurityException("Label must be specified in permission"); 3761 } 3762 BasePermission tree = checkPermissionTreeLP(info.name); 3763 BasePermission bp = mSettings.mPermissions.get(info.name); 3764 boolean added = bp == null; 3765 boolean changed = true; 3766 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel); 3767 if (added) { 3768 enforcePermissionCapLocked(info, tree); 3769 bp = new BasePermission(info.name, tree.sourcePackage, 3770 BasePermission.TYPE_DYNAMIC); 3771 } else if (bp.type != BasePermission.TYPE_DYNAMIC) { 3772 throw new SecurityException( 3773 "Not allowed to modify non-dynamic permission " 3774 + info.name); 3775 } else { 3776 if (bp.protectionLevel == fixedLevel 3777 && bp.perm.owner.equals(tree.perm.owner) 3778 && bp.uid == tree.uid 3779 && comparePermissionInfos(bp.perm.info, info)) { 3780 changed = false; 3781 } 3782 } 3783 bp.protectionLevel = fixedLevel; 3784 info = new PermissionInfo(info); 3785 info.protectionLevel = fixedLevel; 3786 bp.perm = new PackageParser.Permission(tree.perm.owner, info); 3787 bp.perm.info.packageName = tree.perm.info.packageName; 3788 bp.uid = tree.uid; 3789 if (added) { 3790 mSettings.mPermissions.put(info.name, bp); 3791 } 3792 if (changed) { 3793 if (!async) { 3794 mSettings.writeLPr(); 3795 } else { 3796 scheduleWriteSettingsLocked(); 3797 } 3798 } 3799 return added; 3800 } 3801 3802 @Override 3803 public boolean addPermission(PermissionInfo info) { 3804 synchronized (mPackages) { 3805 return addPermissionLocked(info, false); 3806 } 3807 } 3808 3809 @Override 3810 public boolean addPermissionAsync(PermissionInfo info) { 3811 synchronized (mPackages) { 3812 return addPermissionLocked(info, true); 3813 } 3814 } 3815 3816 @Override 3817 public void removePermission(String name) { 3818 synchronized (mPackages) { 3819 checkPermissionTreeLP(name); 3820 BasePermission bp = mSettings.mPermissions.get(name); 3821 if (bp != null) { 3822 if (bp.type != BasePermission.TYPE_DYNAMIC) { 3823 throw new SecurityException( 3824 "Not allowed to modify non-dynamic permission " 3825 + name); 3826 } 3827 mSettings.mPermissions.remove(name); 3828 mSettings.writeLPr(); 3829 } 3830 } 3831 } 3832 3833 private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg, 3834 BasePermission bp) { 3835 int index = pkg.requestedPermissions.indexOf(bp.name); 3836 if (index == -1) { 3837 throw new SecurityException("Package " + pkg.packageName 3838 + " has not requested permission " + bp.name); 3839 } 3840 if (!bp.isRuntime() && !bp.isDevelopment()) { 3841 throw new SecurityException("Permission " + bp.name 3842 + " is not a changeable permission type"); 3843 } 3844 } 3845 3846 @Override 3847 public void grantRuntimePermission(String packageName, String name, final int userId) { 3848 if (!sUserManager.exists(userId)) { 3849 Log.e(TAG, "No such user:" + userId); 3850 return; 3851 } 3852 3853 mContext.enforceCallingOrSelfPermission( 3854 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 3855 "grantRuntimePermission"); 3856 3857 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3858 true /* requireFullPermission */, true /* checkShell */, 3859 "grantRuntimePermission"); 3860 3861 final int uid; 3862 final SettingBase sb; 3863 3864 synchronized (mPackages) { 3865 final PackageParser.Package pkg = mPackages.get(packageName); 3866 if (pkg == null) { 3867 throw new IllegalArgumentException("Unknown package: " + packageName); 3868 } 3869 3870 final BasePermission bp = mSettings.mPermissions.get(name); 3871 if (bp == null) { 3872 throw new IllegalArgumentException("Unknown permission: " + name); 3873 } 3874 3875 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp); 3876 3877 // If a permission review is required for legacy apps we represent 3878 // their permissions as always granted runtime ones since we need 3879 // to keep the review required permission flag per user while an 3880 // install permission's state is shared across all users. 3881 if (Build.PERMISSIONS_REVIEW_REQUIRED 3882 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M 3883 && bp.isRuntime()) { 3884 return; 3885 } 3886 3887 uid = UserHandle.getUid(userId, pkg.applicationInfo.uid); 3888 sb = (SettingBase) pkg.mExtras; 3889 if (sb == null) { 3890 throw new IllegalArgumentException("Unknown package: " + packageName); 3891 } 3892 3893 final PermissionsState permissionsState = sb.getPermissionsState(); 3894 3895 final int flags = permissionsState.getPermissionFlags(name, userId); 3896 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 3897 throw new SecurityException("Cannot grant system fixed permission " 3898 + name + " for package " + packageName); 3899 } 3900 3901 if (bp.isDevelopment()) { 3902 // Development permissions must be handled specially, since they are not 3903 // normal runtime permissions. For now they apply to all users. 3904 if (permissionsState.grantInstallPermission(bp) != 3905 PermissionsState.PERMISSION_OPERATION_FAILURE) { 3906 scheduleWriteSettingsLocked(); 3907 } 3908 return; 3909 } 3910 3911 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 3912 Slog.w(TAG, "Cannot grant runtime permission to a legacy app"); 3913 return; 3914 } 3915 3916 final int result = permissionsState.grantRuntimePermission(bp, userId); 3917 switch (result) { 3918 case PermissionsState.PERMISSION_OPERATION_FAILURE: { 3919 return; 3920 } 3921 3922 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 3923 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); 3924 mHandler.post(new Runnable() { 3925 @Override 3926 public void run() { 3927 killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED); 3928 } 3929 }); 3930 } 3931 break; 3932 } 3933 3934 mOnPermissionChangeListeners.onPermissionsChanged(uid); 3935 3936 // Not critical if that is lost - app has to request again. 3937 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 3938 } 3939 3940 // Only need to do this if user is initialized. Otherwise it's a new user 3941 // and there are no processes running as the user yet and there's no need 3942 // to make an expensive call to remount processes for the changed permissions. 3943 if (READ_EXTERNAL_STORAGE.equals(name) 3944 || WRITE_EXTERNAL_STORAGE.equals(name)) { 3945 final long token = Binder.clearCallingIdentity(); 3946 try { 3947 if (sUserManager.isInitialized(userId)) { 3948 MountServiceInternal mountServiceInternal = LocalServices.getService( 3949 MountServiceInternal.class); 3950 mountServiceInternal.onExternalStoragePolicyChanged(uid, packageName); 3951 } 3952 } finally { 3953 Binder.restoreCallingIdentity(token); 3954 } 3955 } 3956 } 3957 3958 @Override 3959 public void revokeRuntimePermission(String packageName, String name, int userId) { 3960 if (!sUserManager.exists(userId)) { 3961 Log.e(TAG, "No such user:" + userId); 3962 return; 3963 } 3964 3965 mContext.enforceCallingOrSelfPermission( 3966 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 3967 "revokeRuntimePermission"); 3968 3969 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3970 true /* requireFullPermission */, true /* checkShell */, 3971 "revokeRuntimePermission"); 3972 3973 final int appId; 3974 3975 synchronized (mPackages) { 3976 final PackageParser.Package pkg = mPackages.get(packageName); 3977 if (pkg == null) { 3978 throw new IllegalArgumentException("Unknown package: " + packageName); 3979 } 3980 3981 final BasePermission bp = mSettings.mPermissions.get(name); 3982 if (bp == null) { 3983 throw new IllegalArgumentException("Unknown permission: " + name); 3984 } 3985 3986 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp); 3987 3988 // If a permission review is required for legacy apps we represent 3989 // their permissions as always granted runtime ones since we need 3990 // to keep the review required permission flag per user while an 3991 // install permission's state is shared across all users. 3992 if (Build.PERMISSIONS_REVIEW_REQUIRED 3993 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M 3994 && bp.isRuntime()) { 3995 return; 3996 } 3997 3998 SettingBase sb = (SettingBase) pkg.mExtras; 3999 if (sb == null) { 4000 throw new IllegalArgumentException("Unknown package: " + packageName); 4001 } 4002 4003 final PermissionsState permissionsState = sb.getPermissionsState(); 4004 4005 final int flags = permissionsState.getPermissionFlags(name, userId); 4006 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 4007 throw new SecurityException("Cannot revoke system fixed permission " 4008 + name + " for package " + packageName); 4009 } 4010 4011 if (bp.isDevelopment()) { 4012 // Development permissions must be handled specially, since they are not 4013 // normal runtime permissions. For now they apply to all users. 4014 if (permissionsState.revokeInstallPermission(bp) != 4015 PermissionsState.PERMISSION_OPERATION_FAILURE) { 4016 scheduleWriteSettingsLocked(); 4017 } 4018 return; 4019 } 4020 4021 if (permissionsState.revokeRuntimePermission(bp, userId) == 4022 PermissionsState.PERMISSION_OPERATION_FAILURE) { 4023 return; 4024 } 4025 4026 mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid); 4027 4028 // Critical, after this call app should never have the permission. 4029 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 4030 4031 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 4032 } 4033 4034 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED); 4035 } 4036 4037 @Override 4038 public void resetRuntimePermissions() { 4039 mContext.enforceCallingOrSelfPermission( 4040 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 4041 "revokeRuntimePermission"); 4042 4043 int callingUid = Binder.getCallingUid(); 4044 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 4045 mContext.enforceCallingOrSelfPermission( 4046 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 4047 "resetRuntimePermissions"); 4048 } 4049 4050 synchronized (mPackages) { 4051 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL); 4052 for (int userId : UserManagerService.getInstance().getUserIds()) { 4053 final int packageCount = mPackages.size(); 4054 for (int i = 0; i < packageCount; i++) { 4055 PackageParser.Package pkg = mPackages.valueAt(i); 4056 if (!(pkg.mExtras instanceof PackageSetting)) { 4057 continue; 4058 } 4059 PackageSetting ps = (PackageSetting) pkg.mExtras; 4060 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 4061 } 4062 } 4063 } 4064 } 4065 4066 @Override 4067 public int getPermissionFlags(String name, String packageName, int userId) { 4068 if (!sUserManager.exists(userId)) { 4069 return 0; 4070 } 4071 4072 enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags"); 4073 4074 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4075 true /* requireFullPermission */, false /* checkShell */, 4076 "getPermissionFlags"); 4077 4078 synchronized (mPackages) { 4079 final PackageParser.Package pkg = mPackages.get(packageName); 4080 if (pkg == null) { 4081 throw new IllegalArgumentException("Unknown package: " + packageName); 4082 } 4083 4084 final BasePermission bp = mSettings.mPermissions.get(name); 4085 if (bp == null) { 4086 throw new IllegalArgumentException("Unknown permission: " + name); 4087 } 4088 4089 SettingBase sb = (SettingBase) pkg.mExtras; 4090 if (sb == null) { 4091 throw new IllegalArgumentException("Unknown package: " + packageName); 4092 } 4093 4094 PermissionsState permissionsState = sb.getPermissionsState(); 4095 return permissionsState.getPermissionFlags(name, userId); 4096 } 4097 } 4098 4099 @Override 4100 public void updatePermissionFlags(String name, String packageName, int flagMask, 4101 int flagValues, int userId) { 4102 if (!sUserManager.exists(userId)) { 4103 return; 4104 } 4105 4106 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags"); 4107 4108 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4109 true /* requireFullPermission */, true /* checkShell */, 4110 "updatePermissionFlags"); 4111 4112 // Only the system can change these flags and nothing else. 4113 if (getCallingUid() != Process.SYSTEM_UID) { 4114 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4115 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4116 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 4117 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 4118 flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 4119 } 4120 4121 synchronized (mPackages) { 4122 final PackageParser.Package pkg = mPackages.get(packageName); 4123 if (pkg == null) { 4124 throw new IllegalArgumentException("Unknown package: " + packageName); 4125 } 4126 4127 final BasePermission bp = mSettings.mPermissions.get(name); 4128 if (bp == null) { 4129 throw new IllegalArgumentException("Unknown permission: " + name); 4130 } 4131 4132 SettingBase sb = (SettingBase) pkg.mExtras; 4133 if (sb == null) { 4134 throw new IllegalArgumentException("Unknown package: " + packageName); 4135 } 4136 4137 PermissionsState permissionsState = sb.getPermissionsState(); 4138 4139 boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null; 4140 4141 if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) { 4142 // Install and runtime permissions are stored in different places, 4143 // so figure out what permission changed and persist the change. 4144 if (permissionsState.getInstallPermissionState(name) != null) { 4145 scheduleWriteSettingsLocked(); 4146 } else if (permissionsState.getRuntimePermissionState(name, userId) != null 4147 || hadState) { 4148 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 4149 } 4150 } 4151 } 4152 } 4153 4154 /** 4155 * Update the permission flags for all packages and runtime permissions of a user in order 4156 * to allow device or profile owner to remove POLICY_FIXED. 4157 */ 4158 @Override 4159 public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) { 4160 if (!sUserManager.exists(userId)) { 4161 return; 4162 } 4163 4164 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps"); 4165 4166 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4167 true /* requireFullPermission */, true /* checkShell */, 4168 "updatePermissionFlagsForAllApps"); 4169 4170 // Only the system can change system fixed flags. 4171 if (getCallingUid() != Process.SYSTEM_UID) { 4172 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4173 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4174 } 4175 4176 synchronized (mPackages) { 4177 boolean changed = false; 4178 final int packageCount = mPackages.size(); 4179 for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) { 4180 final PackageParser.Package pkg = mPackages.valueAt(pkgIndex); 4181 SettingBase sb = (SettingBase) pkg.mExtras; 4182 if (sb == null) { 4183 continue; 4184 } 4185 PermissionsState permissionsState = sb.getPermissionsState(); 4186 changed |= permissionsState.updatePermissionFlagsForAllPermissions( 4187 userId, flagMask, flagValues); 4188 } 4189 if (changed) { 4190 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 4191 } 4192 } 4193 } 4194 4195 private void enforceGrantRevokeRuntimePermissionPermissions(String message) { 4196 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS) 4197 != PackageManager.PERMISSION_GRANTED 4198 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) 4199 != PackageManager.PERMISSION_GRANTED) { 4200 throw new SecurityException(message + " requires " 4201 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or " 4202 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS); 4203 } 4204 } 4205 4206 @Override 4207 public boolean shouldShowRequestPermissionRationale(String permissionName, 4208 String packageName, int userId) { 4209 if (UserHandle.getCallingUserId() != userId) { 4210 mContext.enforceCallingPermission( 4211 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 4212 "canShowRequestPermissionRationale for user " + userId); 4213 } 4214 4215 final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId); 4216 if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) { 4217 return false; 4218 } 4219 4220 if (checkPermission(permissionName, packageName, userId) 4221 == PackageManager.PERMISSION_GRANTED) { 4222 return false; 4223 } 4224 4225 final int flags; 4226 4227 final long identity = Binder.clearCallingIdentity(); 4228 try { 4229 flags = getPermissionFlags(permissionName, 4230 packageName, userId); 4231 } finally { 4232 Binder.restoreCallingIdentity(identity); 4233 } 4234 4235 final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 4236 | PackageManager.FLAG_PERMISSION_POLICY_FIXED 4237 | PackageManager.FLAG_PERMISSION_USER_FIXED; 4238 4239 if ((flags & fixedFlags) != 0) { 4240 return false; 4241 } 4242 4243 return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0; 4244 } 4245 4246 @Override 4247 public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 4248 mContext.enforceCallingOrSelfPermission( 4249 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS, 4250 "addOnPermissionsChangeListener"); 4251 4252 synchronized (mPackages) { 4253 mOnPermissionChangeListeners.addListenerLocked(listener); 4254 } 4255 } 4256 4257 @Override 4258 public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 4259 synchronized (mPackages) { 4260 mOnPermissionChangeListeners.removeListenerLocked(listener); 4261 } 4262 } 4263 4264 @Override 4265 public boolean isProtectedBroadcast(String actionName) { 4266 synchronized (mPackages) { 4267 if (mProtectedBroadcasts.contains(actionName)) { 4268 return true; 4269 } else if (actionName != null) { 4270 // TODO: remove these terrible hacks 4271 if (actionName.startsWith("android.net.netmon.lingerExpired") 4272 || actionName.startsWith("com.android.server.sip.SipWakeupTimer") 4273 || actionName.startsWith("com.android.internal.telephony.data-reconnect") 4274 || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) { 4275 return true; 4276 } 4277 } 4278 } 4279 return false; 4280 } 4281 4282 @Override 4283 public int checkSignatures(String pkg1, String pkg2) { 4284 synchronized (mPackages) { 4285 final PackageParser.Package p1 = mPackages.get(pkg1); 4286 final PackageParser.Package p2 = mPackages.get(pkg2); 4287 if (p1 == null || p1.mExtras == null 4288 || p2 == null || p2.mExtras == null) { 4289 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4290 } 4291 return compareSignatures(p1.mSignatures, p2.mSignatures); 4292 } 4293 } 4294 4295 @Override 4296 public int checkUidSignatures(int uid1, int uid2) { 4297 // Map to base uids. 4298 uid1 = UserHandle.getAppId(uid1); 4299 uid2 = UserHandle.getAppId(uid2); 4300 // reader 4301 synchronized (mPackages) { 4302 Signature[] s1; 4303 Signature[] s2; 4304 Object obj = mSettings.getUserIdLPr(uid1); 4305 if (obj != null) { 4306 if (obj instanceof SharedUserSetting) { 4307 s1 = ((SharedUserSetting)obj).signatures.mSignatures; 4308 } else if (obj instanceof PackageSetting) { 4309 s1 = ((PackageSetting)obj).signatures.mSignatures; 4310 } else { 4311 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4312 } 4313 } else { 4314 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4315 } 4316 obj = mSettings.getUserIdLPr(uid2); 4317 if (obj != null) { 4318 if (obj instanceof SharedUserSetting) { 4319 s2 = ((SharedUserSetting)obj).signatures.mSignatures; 4320 } else if (obj instanceof PackageSetting) { 4321 s2 = ((PackageSetting)obj).signatures.mSignatures; 4322 } else { 4323 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4324 } 4325 } else { 4326 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4327 } 4328 return compareSignatures(s1, s2); 4329 } 4330 } 4331 4332 private void killUid(int appId, int userId, String reason) { 4333 final long identity = Binder.clearCallingIdentity(); 4334 try { 4335 IActivityManager am = ActivityManagerNative.getDefault(); 4336 if (am != null) { 4337 try { 4338 am.killUid(appId, userId, reason); 4339 } catch (RemoteException e) { 4340 /* ignore - same process */ 4341 } 4342 } 4343 } finally { 4344 Binder.restoreCallingIdentity(identity); 4345 } 4346 } 4347 4348 /** 4349 * Compares two sets of signatures. Returns: 4350 * <br /> 4351 * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null, 4352 * <br /> 4353 * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null, 4354 * <br /> 4355 * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null, 4356 * <br /> 4357 * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical, 4358 * <br /> 4359 * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ. 4360 */ 4361 static int compareSignatures(Signature[] s1, Signature[] s2) { 4362 if (s1 == null) { 4363 return s2 == null 4364 ? PackageManager.SIGNATURE_NEITHER_SIGNED 4365 : PackageManager.SIGNATURE_FIRST_NOT_SIGNED; 4366 } 4367 4368 if (s2 == null) { 4369 return PackageManager.SIGNATURE_SECOND_NOT_SIGNED; 4370 } 4371 4372 if (s1.length != s2.length) { 4373 return PackageManager.SIGNATURE_NO_MATCH; 4374 } 4375 4376 // Since both signature sets are of size 1, we can compare without HashSets. 4377 if (s1.length == 1) { 4378 return s1[0].equals(s2[0]) ? 4379 PackageManager.SIGNATURE_MATCH : 4380 PackageManager.SIGNATURE_NO_MATCH; 4381 } 4382 4383 ArraySet<Signature> set1 = new ArraySet<Signature>(); 4384 for (Signature sig : s1) { 4385 set1.add(sig); 4386 } 4387 ArraySet<Signature> set2 = new ArraySet<Signature>(); 4388 for (Signature sig : s2) { 4389 set2.add(sig); 4390 } 4391 // Make sure s2 contains all signatures in s1. 4392 if (set1.equals(set2)) { 4393 return PackageManager.SIGNATURE_MATCH; 4394 } 4395 return PackageManager.SIGNATURE_NO_MATCH; 4396 } 4397 4398 /** 4399 * If the database version for this type of package (internal storage or 4400 * external storage) is less than the version where package signatures 4401 * were updated, return true. 4402 */ 4403 private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 4404 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); 4405 return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY; 4406 } 4407 4408 /** 4409 * Used for backward compatibility to make sure any packages with 4410 * certificate chains get upgraded to the new style. {@code existingSigs} 4411 * will be in the old format (since they were stored on disk from before the 4412 * system upgrade) and {@code scannedSigs} will be in the newer format. 4413 */ 4414 private int compareSignaturesCompat(PackageSignatures existingSigs, 4415 PackageParser.Package scannedPkg) { 4416 if (!isCompatSignatureUpdateNeeded(scannedPkg)) { 4417 return PackageManager.SIGNATURE_NO_MATCH; 4418 } 4419 4420 ArraySet<Signature> existingSet = new ArraySet<Signature>(); 4421 for (Signature sig : existingSigs.mSignatures) { 4422 existingSet.add(sig); 4423 } 4424 ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>(); 4425 for (Signature sig : scannedPkg.mSignatures) { 4426 try { 4427 Signature[] chainSignatures = sig.getChainSignatures(); 4428 for (Signature chainSig : chainSignatures) { 4429 scannedCompatSet.add(chainSig); 4430 } 4431 } catch (CertificateEncodingException e) { 4432 scannedCompatSet.add(sig); 4433 } 4434 } 4435 /* 4436 * Make sure the expanded scanned set contains all signatures in the 4437 * existing one. 4438 */ 4439 if (scannedCompatSet.equals(existingSet)) { 4440 // Migrate the old signatures to the new scheme. 4441 existingSigs.assignSignatures(scannedPkg.mSignatures); 4442 // The new KeySets will be re-added later in the scanning process. 4443 synchronized (mPackages) { 4444 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName); 4445 } 4446 return PackageManager.SIGNATURE_MATCH; 4447 } 4448 return PackageManager.SIGNATURE_NO_MATCH; 4449 } 4450 4451 private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 4452 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); 4453 return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER; 4454 } 4455 4456 private int compareSignaturesRecover(PackageSignatures existingSigs, 4457 PackageParser.Package scannedPkg) { 4458 if (!isRecoverSignatureUpdateNeeded(scannedPkg)) { 4459 return PackageManager.SIGNATURE_NO_MATCH; 4460 } 4461 4462 String msg = null; 4463 try { 4464 if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) { 4465 logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for " 4466 + scannedPkg.packageName); 4467 return PackageManager.SIGNATURE_MATCH; 4468 } 4469 } catch (CertificateException e) { 4470 msg = e.getMessage(); 4471 } 4472 4473 logCriticalInfo(Log.INFO, 4474 "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg); 4475 return PackageManager.SIGNATURE_NO_MATCH; 4476 } 4477 4478 @Override 4479 public List<String> getAllPackages() { 4480 synchronized (mPackages) { 4481 return new ArrayList<String>(mPackages.keySet()); 4482 } 4483 } 4484 4485 @Override 4486 public String[] getPackagesForUid(int uid) { 4487 uid = UserHandle.getAppId(uid); 4488 // reader 4489 synchronized (mPackages) { 4490 Object obj = mSettings.getUserIdLPr(uid); 4491 if (obj instanceof SharedUserSetting) { 4492 final SharedUserSetting sus = (SharedUserSetting) obj; 4493 final int N = sus.packages.size(); 4494 final String[] res = new String[N]; 4495 final Iterator<PackageSetting> it = sus.packages.iterator(); 4496 int i = 0; 4497 while (it.hasNext()) { 4498 res[i++] = it.next().name; 4499 } 4500 return res; 4501 } else if (obj instanceof PackageSetting) { 4502 final PackageSetting ps = (PackageSetting) obj; 4503 return new String[] { ps.name }; 4504 } 4505 } 4506 return null; 4507 } 4508 4509 @Override 4510 public String getNameForUid(int uid) { 4511 // reader 4512 synchronized (mPackages) { 4513 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4514 if (obj instanceof SharedUserSetting) { 4515 final SharedUserSetting sus = (SharedUserSetting) obj; 4516 return sus.name + ":" + sus.userId; 4517 } else if (obj instanceof PackageSetting) { 4518 final PackageSetting ps = (PackageSetting) obj; 4519 return ps.name; 4520 } 4521 } 4522 return null; 4523 } 4524 4525 @Override 4526 public int getUidForSharedUser(String sharedUserName) { 4527 if(sharedUserName == null) { 4528 return -1; 4529 } 4530 // reader 4531 synchronized (mPackages) { 4532 final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false); 4533 if (suid == null) { 4534 return -1; 4535 } 4536 return suid.userId; 4537 } 4538 } 4539 4540 @Override 4541 public int getFlagsForUid(int uid) { 4542 synchronized (mPackages) { 4543 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4544 if (obj instanceof SharedUserSetting) { 4545 final SharedUserSetting sus = (SharedUserSetting) obj; 4546 return sus.pkgFlags; 4547 } else if (obj instanceof PackageSetting) { 4548 final PackageSetting ps = (PackageSetting) obj; 4549 return ps.pkgFlags; 4550 } 4551 } 4552 return 0; 4553 } 4554 4555 @Override 4556 public int getPrivateFlagsForUid(int uid) { 4557 synchronized (mPackages) { 4558 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4559 if (obj instanceof SharedUserSetting) { 4560 final SharedUserSetting sus = (SharedUserSetting) obj; 4561 return sus.pkgPrivateFlags; 4562 } else if (obj instanceof PackageSetting) { 4563 final PackageSetting ps = (PackageSetting) obj; 4564 return ps.pkgPrivateFlags; 4565 } 4566 } 4567 return 0; 4568 } 4569 4570 @Override 4571 public boolean isUidPrivileged(int uid) { 4572 uid = UserHandle.getAppId(uid); 4573 // reader 4574 synchronized (mPackages) { 4575 Object obj = mSettings.getUserIdLPr(uid); 4576 if (obj instanceof SharedUserSetting) { 4577 final SharedUserSetting sus = (SharedUserSetting) obj; 4578 final Iterator<PackageSetting> it = sus.packages.iterator(); 4579 while (it.hasNext()) { 4580 if (it.next().isPrivileged()) { 4581 return true; 4582 } 4583 } 4584 } else if (obj instanceof PackageSetting) { 4585 final PackageSetting ps = (PackageSetting) obj; 4586 return ps.isPrivileged(); 4587 } 4588 } 4589 return false; 4590 } 4591 4592 @Override 4593 public String[] getAppOpPermissionPackages(String permissionName) { 4594 synchronized (mPackages) { 4595 ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName); 4596 if (pkgs == null) { 4597 return null; 4598 } 4599 return pkgs.toArray(new String[pkgs.size()]); 4600 } 4601 } 4602 4603 @Override 4604 public ResolveInfo resolveIntent(Intent intent, String resolvedType, 4605 int flags, int userId) { 4606 if (!sUserManager.exists(userId)) return null; 4607 flags = updateFlagsForResolve(flags, userId, intent); 4608 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4609 false /* requireFullPermission */, false /* checkShell */, "resolve intent"); 4610 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags, 4611 userId); 4612 final ResolveInfo bestChoice = 4613 chooseBestActivity(intent, resolvedType, flags, query, userId); 4614 4615 if (isEphemeralAllowed(intent, query, userId)) { 4616 final EphemeralResolveInfo ai = 4617 getEphemeralResolveInfo(intent, resolvedType, userId); 4618 if (ai != null) { 4619 if (DEBUG_EPHEMERAL) { 4620 Slog.v(TAG, "Returning an EphemeralResolveInfo"); 4621 } 4622 bestChoice.ephemeralInstaller = mEphemeralInstallerInfo; 4623 bestChoice.ephemeralResolveInfo = ai; 4624 } 4625 } 4626 return bestChoice; 4627 } 4628 4629 @Override 4630 public void setLastChosenActivity(Intent intent, String resolvedType, int flags, 4631 IntentFilter filter, int match, ComponentName activity) { 4632 final int userId = UserHandle.getCallingUserId(); 4633 if (DEBUG_PREFERRED) { 4634 Log.v(TAG, "setLastChosenActivity intent=" + intent 4635 + " resolvedType=" + resolvedType 4636 + " flags=" + flags 4637 + " filter=" + filter 4638 + " match=" + match 4639 + " activity=" + activity); 4640 filter.dump(new PrintStreamPrinter(System.out), " "); 4641 } 4642 intent.setComponent(null); 4643 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags, 4644 userId); 4645 // Find any earlier preferred or last chosen entries and nuke them 4646 findPreferredActivity(intent, resolvedType, 4647 flags, query, 0, false, true, false, userId); 4648 // Add the new activity as the last chosen for this filter 4649 addPreferredActivityInternal(filter, match, null, activity, false, userId, 4650 "Setting last chosen"); 4651 } 4652 4653 @Override 4654 public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) { 4655 final int userId = UserHandle.getCallingUserId(); 4656 if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent); 4657 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags, 4658 userId); 4659 return findPreferredActivity(intent, resolvedType, flags, query, 0, 4660 false, false, false, userId); 4661 } 4662 4663 4664 private boolean isEphemeralAllowed( 4665 Intent intent, List<ResolveInfo> resolvedActivites, int userId) { 4666 // Short circuit and return early if possible. 4667 if (DISABLE_EPHEMERAL_APPS) { 4668 return false; 4669 } 4670 final int callingUser = UserHandle.getCallingUserId(); 4671 if (callingUser != UserHandle.USER_SYSTEM) { 4672 return false; 4673 } 4674 if (mEphemeralResolverConnection == null) { 4675 return false; 4676 } 4677 if (intent.getComponent() != null) { 4678 return false; 4679 } 4680 if (intent.getPackage() != null) { 4681 return false; 4682 } 4683 final boolean isWebUri = hasWebURI(intent); 4684 if (!isWebUri) { 4685 return false; 4686 } 4687 // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution. 4688 synchronized (mPackages) { 4689 final int count = resolvedActivites.size(); 4690 for (int n = 0; n < count; n++) { 4691 ResolveInfo info = resolvedActivites.get(n); 4692 String packageName = info.activityInfo.packageName; 4693 PackageSetting ps = mSettings.mPackages.get(packageName); 4694 if (ps != null) { 4695 // Try to get the status from User settings first 4696 long packedStatus = getDomainVerificationStatusLPr(ps, userId); 4697 int status = (int) (packedStatus >> 32); 4698 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS 4699 || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) { 4700 if (DEBUG_EPHEMERAL) { 4701 Slog.v(TAG, "DENY ephemeral apps;" 4702 + " pkg: " + packageName + ", status: " + status); 4703 } 4704 return false; 4705 } 4706 } 4707 } 4708 } 4709 // We've exhausted all ways to deny ephemeral application; let the system look for them. 4710 return true; 4711 } 4712 4713 private EphemeralResolveInfo getEphemeralResolveInfo(Intent intent, String resolvedType, 4714 int userId) { 4715 MessageDigest digest = null; 4716 try { 4717 digest = MessageDigest.getInstance(EphemeralResolveInfo.SHA_ALGORITHM); 4718 } catch (NoSuchAlgorithmException e) { 4719 // If we can't create a digest, ignore ephemeral apps. 4720 return null; 4721 } 4722 4723 final byte[] hostBytes = intent.getData().getHost().getBytes(); 4724 final byte[] digestBytes = digest.digest(hostBytes); 4725 int shaPrefix = 4726 digestBytes[0] << 24 4727 | digestBytes[1] << 16 4728 | digestBytes[2] << 8 4729 | digestBytes[3] << 0; 4730 final List<EphemeralResolveInfo> ephemeralResolveInfoList = 4731 mEphemeralResolverConnection.getEphemeralResolveInfoList(shaPrefix); 4732 if (ephemeralResolveInfoList == null || ephemeralResolveInfoList.size() == 0) { 4733 // No hash prefix match; there are no ephemeral apps for this domain. 4734 return null; 4735 } 4736 for (int i = ephemeralResolveInfoList.size() - 1; i >= 0; --i) { 4737 EphemeralResolveInfo ephemeralApplication = ephemeralResolveInfoList.get(i); 4738 if (!Arrays.equals(digestBytes, ephemeralApplication.getDigestBytes())) { 4739 continue; 4740 } 4741 final List<IntentFilter> filters = ephemeralApplication.getFilters(); 4742 // No filters; this should never happen. 4743 if (filters.isEmpty()) { 4744 continue; 4745 } 4746 // We have a domain match; resolve the filters to see if anything matches. 4747 final EphemeralIntentResolver ephemeralResolver = new EphemeralIntentResolver(); 4748 for (int j = filters.size() - 1; j >= 0; --j) { 4749 final EphemeralResolveIntentInfo intentInfo = 4750 new EphemeralResolveIntentInfo(filters.get(j), ephemeralApplication); 4751 ephemeralResolver.addFilter(intentInfo); 4752 } 4753 List<EphemeralResolveInfo> matchedResolveInfoList = ephemeralResolver.queryIntent( 4754 intent, resolvedType, false /*defaultOnly*/, userId); 4755 if (!matchedResolveInfoList.isEmpty()) { 4756 return matchedResolveInfoList.get(0); 4757 } 4758 } 4759 // Hash or filter mis-match; no ephemeral apps for this domain. 4760 return null; 4761 } 4762 4763 private ResolveInfo chooseBestActivity(Intent intent, String resolvedType, 4764 int flags, List<ResolveInfo> query, int userId) { 4765 if (query != null) { 4766 final int N = query.size(); 4767 if (N == 1) { 4768 return query.get(0); 4769 } else if (N > 1) { 4770 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 4771 // If there is more than one activity with the same priority, 4772 // then let the user decide between them. 4773 ResolveInfo r0 = query.get(0); 4774 ResolveInfo r1 = query.get(1); 4775 if (DEBUG_INTENT_MATCHING || debug) { 4776 Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs " 4777 + r1.activityInfo.name + "=" + r1.priority); 4778 } 4779 // If the first activity has a higher priority, or a different 4780 // default, then it is always desirable to pick it. 4781 if (r0.priority != r1.priority 4782 || r0.preferredOrder != r1.preferredOrder 4783 || r0.isDefault != r1.isDefault) { 4784 return query.get(0); 4785 } 4786 // If we have saved a preference for a preferred activity for 4787 // this Intent, use that. 4788 ResolveInfo ri = findPreferredActivity(intent, resolvedType, 4789 flags, query, r0.priority, true, false, debug, userId); 4790 if (ri != null) { 4791 return ri; 4792 } 4793 ri = new ResolveInfo(mResolveInfo); 4794 ri.activityInfo = new ActivityInfo(ri.activityInfo); 4795 ri.activityInfo.applicationInfo = new ApplicationInfo( 4796 ri.activityInfo.applicationInfo); 4797 if (userId != 0) { 4798 ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId, 4799 UserHandle.getAppId(ri.activityInfo.applicationInfo.uid)); 4800 } 4801 // Make sure that the resolver is displayable in car mode 4802 if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle(); 4803 ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true); 4804 return ri; 4805 } 4806 } 4807 return null; 4808 } 4809 4810 private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType, 4811 int flags, List<ResolveInfo> query, boolean debug, int userId) { 4812 final int N = query.size(); 4813 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 4814 .get(userId); 4815 // Get the list of persistent preferred activities that handle the intent 4816 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities..."); 4817 List<PersistentPreferredActivity> pprefs = ppir != null 4818 ? ppir.queryIntent(intent, resolvedType, 4819 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 4820 : null; 4821 if (pprefs != null && pprefs.size() > 0) { 4822 final int M = pprefs.size(); 4823 for (int i=0; i<M; i++) { 4824 final PersistentPreferredActivity ppa = pprefs.get(i); 4825 if (DEBUG_PREFERRED || debug) { 4826 Slog.v(TAG, "Checking PersistentPreferredActivity ds=" 4827 + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>") 4828 + "\n component=" + ppa.mComponent); 4829 ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4830 } 4831 final ActivityInfo ai = getActivityInfo(ppa.mComponent, 4832 flags | MATCH_DISABLED_COMPONENTS, userId); 4833 if (DEBUG_PREFERRED || debug) { 4834 Slog.v(TAG, "Found persistent preferred activity:"); 4835 if (ai != null) { 4836 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4837 } else { 4838 Slog.v(TAG, " null"); 4839 } 4840 } 4841 if (ai == null) { 4842 // This previously registered persistent preferred activity 4843 // component is no longer known. Ignore it and do NOT remove it. 4844 continue; 4845 } 4846 for (int j=0; j<N; j++) { 4847 final ResolveInfo ri = query.get(j); 4848 if (!ri.activityInfo.applicationInfo.packageName 4849 .equals(ai.applicationInfo.packageName)) { 4850 continue; 4851 } 4852 if (!ri.activityInfo.name.equals(ai.name)) { 4853 continue; 4854 } 4855 // Found a persistent preference that can handle the intent. 4856 if (DEBUG_PREFERRED || debug) { 4857 Slog.v(TAG, "Returning persistent preferred activity: " + 4858 ri.activityInfo.packageName + "/" + ri.activityInfo.name); 4859 } 4860 return ri; 4861 } 4862 } 4863 } 4864 return null; 4865 } 4866 4867 // TODO: handle preferred activities missing while user has amnesia 4868 ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags, 4869 List<ResolveInfo> query, int priority, boolean always, 4870 boolean removeMatches, boolean debug, int userId) { 4871 if (!sUserManager.exists(userId)) return null; 4872 flags = updateFlagsForResolve(flags, userId, intent); 4873 // writer 4874 synchronized (mPackages) { 4875 if (intent.getSelector() != null) { 4876 intent = intent.getSelector(); 4877 } 4878 if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION); 4879 4880 // Try to find a matching persistent preferred activity. 4881 ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query, 4882 debug, userId); 4883 4884 // If a persistent preferred activity matched, use it. 4885 if (pri != null) { 4886 return pri; 4887 } 4888 4889 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 4890 // Get the list of preferred activities that handle the intent 4891 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities..."); 4892 List<PreferredActivity> prefs = pir != null 4893 ? pir.queryIntent(intent, resolvedType, 4894 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 4895 : null; 4896 if (prefs != null && prefs.size() > 0) { 4897 boolean changed = false; 4898 try { 4899 // First figure out how good the original match set is. 4900 // We will only allow preferred activities that came 4901 // from the same match quality. 4902 int match = 0; 4903 4904 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match..."); 4905 4906 final int N = query.size(); 4907 for (int j=0; j<N; j++) { 4908 final ResolveInfo ri = query.get(j); 4909 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo 4910 + ": 0x" + Integer.toHexString(match)); 4911 if (ri.match > match) { 4912 match = ri.match; 4913 } 4914 } 4915 4916 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x" 4917 + Integer.toHexString(match)); 4918 4919 match &= IntentFilter.MATCH_CATEGORY_MASK; 4920 final int M = prefs.size(); 4921 for (int i=0; i<M; i++) { 4922 final PreferredActivity pa = prefs.get(i); 4923 if (DEBUG_PREFERRED || debug) { 4924 Slog.v(TAG, "Checking PreferredActivity ds=" 4925 + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>") 4926 + "\n component=" + pa.mPref.mComponent); 4927 pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4928 } 4929 if (pa.mPref.mMatch != match) { 4930 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match " 4931 + Integer.toHexString(pa.mPref.mMatch)); 4932 continue; 4933 } 4934 // If it's not an "always" type preferred activity and that's what we're 4935 // looking for, skip it. 4936 if (always && !pa.mPref.mAlways) { 4937 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry"); 4938 continue; 4939 } 4940 final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent, 4941 flags | MATCH_DISABLED_COMPONENTS, userId); 4942 if (DEBUG_PREFERRED || debug) { 4943 Slog.v(TAG, "Found preferred activity:"); 4944 if (ai != null) { 4945 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4946 } else { 4947 Slog.v(TAG, " null"); 4948 } 4949 } 4950 if (ai == null) { 4951 // This previously registered preferred activity 4952 // component is no longer known. Most likely an update 4953 // to the app was installed and in the new version this 4954 // component no longer exists. Clean it up by removing 4955 // it from the preferred activities list, and skip it. 4956 Slog.w(TAG, "Removing dangling preferred activity: " 4957 + pa.mPref.mComponent); 4958 pir.removeFilter(pa); 4959 changed = true; 4960 continue; 4961 } 4962 for (int j=0; j<N; j++) { 4963 final ResolveInfo ri = query.get(j); 4964 if (!ri.activityInfo.applicationInfo.packageName 4965 .equals(ai.applicationInfo.packageName)) { 4966 continue; 4967 } 4968 if (!ri.activityInfo.name.equals(ai.name)) { 4969 continue; 4970 } 4971 4972 if (removeMatches) { 4973 pir.removeFilter(pa); 4974 changed = true; 4975 if (DEBUG_PREFERRED) { 4976 Slog.v(TAG, "Removing match " + pa.mPref.mComponent); 4977 } 4978 break; 4979 } 4980 4981 // Okay we found a previously set preferred or last chosen app. 4982 // If the result set is different from when this 4983 // was created, we need to clear it and re-ask the 4984 // user their preference, if we're looking for an "always" type entry. 4985 if (always && !pa.mPref.sameSet(query)) { 4986 Slog.i(TAG, "Result set changed, dropping preferred activity for " 4987 + intent + " type " + resolvedType); 4988 if (DEBUG_PREFERRED) { 4989 Slog.v(TAG, "Removing preferred activity since set changed " 4990 + pa.mPref.mComponent); 4991 } 4992 pir.removeFilter(pa); 4993 // Re-add the filter as a "last chosen" entry (!always) 4994 PreferredActivity lastChosen = new PreferredActivity( 4995 pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false); 4996 pir.addFilter(lastChosen); 4997 changed = true; 4998 return null; 4999 } 5000 5001 // Yay! Either the set matched or we're looking for the last chosen 5002 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: " 5003 + ri.activityInfo.packageName + "/" + ri.activityInfo.name); 5004 return ri; 5005 } 5006 } 5007 } finally { 5008 if (changed) { 5009 if (DEBUG_PREFERRED) { 5010 Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions"); 5011 } 5012 scheduleWritePackageRestrictionsLocked(userId); 5013 } 5014 } 5015 } 5016 } 5017 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return"); 5018 return null; 5019 } 5020 5021 /* 5022 * Returns if intent can be forwarded from the sourceUserId to the targetUserId 5023 */ 5024 @Override 5025 public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId, 5026 int targetUserId) { 5027 mContext.enforceCallingOrSelfPermission( 5028 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 5029 List<CrossProfileIntentFilter> matches = 5030 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId); 5031 if (matches != null) { 5032 int size = matches.size(); 5033 for (int i = 0; i < size; i++) { 5034 if (matches.get(i).getTargetUserId() == targetUserId) return true; 5035 } 5036 } 5037 if (hasWebURI(intent)) { 5038 // cross-profile app linking works only towards the parent. 5039 final UserInfo parent = getProfileParent(sourceUserId); 5040 synchronized(mPackages) { 5041 int flags = updateFlagsForResolve(0, parent.id, intent); 5042 CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr( 5043 intent, resolvedType, flags, sourceUserId, parent.id); 5044 return xpDomainInfo != null; 5045 } 5046 } 5047 return false; 5048 } 5049 5050 private UserInfo getProfileParent(int userId) { 5051 final long identity = Binder.clearCallingIdentity(); 5052 try { 5053 return sUserManager.getProfileParent(userId); 5054 } finally { 5055 Binder.restoreCallingIdentity(identity); 5056 } 5057 } 5058 5059 private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent, 5060 String resolvedType, int userId) { 5061 CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId); 5062 if (resolver != null) { 5063 return resolver.queryIntent(intent, resolvedType, false, userId); 5064 } 5065 return null; 5066 } 5067 5068 @Override 5069 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent, 5070 String resolvedType, int flags, int userId) { 5071 return new ParceledListSlice<>( 5072 queryIntentActivitiesInternal(intent, resolvedType, flags, userId)); 5073 } 5074 5075 private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, 5076 String resolvedType, int flags, int userId) { 5077 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5078 flags = updateFlagsForResolve(flags, userId, intent); 5079 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5080 false /* requireFullPermission */, false /* checkShell */, 5081 "query intent activities"); 5082 ComponentName comp = intent.getComponent(); 5083 if (comp == null) { 5084 if (intent.getSelector() != null) { 5085 intent = intent.getSelector(); 5086 comp = intent.getComponent(); 5087 } 5088 } 5089 5090 if (comp != null) { 5091 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5092 final ActivityInfo ai = getActivityInfo(comp, flags, userId); 5093 if (ai != null) { 5094 final ResolveInfo ri = new ResolveInfo(); 5095 ri.activityInfo = ai; 5096 list.add(ri); 5097 } 5098 return list; 5099 } 5100 5101 // reader 5102 synchronized (mPackages) { 5103 final String pkgName = intent.getPackage(); 5104 if (pkgName == null) { 5105 List<CrossProfileIntentFilter> matchingFilters = 5106 getMatchingCrossProfileIntentFilters(intent, resolvedType, userId); 5107 // Check for results that need to skip the current profile. 5108 ResolveInfo xpResolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent, 5109 resolvedType, flags, userId); 5110 if (xpResolveInfo != null) { 5111 List<ResolveInfo> result = new ArrayList<ResolveInfo>(1); 5112 result.add(xpResolveInfo); 5113 return filterIfNotSystemUser(result, userId); 5114 } 5115 5116 // Check for results in the current profile. 5117 List<ResolveInfo> result = mActivities.queryIntent( 5118 intent, resolvedType, flags, userId); 5119 result = filterIfNotSystemUser(result, userId); 5120 5121 // Check for cross profile results. 5122 boolean hasNonNegativePriorityResult = hasNonNegativePriority(result); 5123 xpResolveInfo = queryCrossProfileIntents( 5124 matchingFilters, intent, resolvedType, flags, userId, 5125 hasNonNegativePriorityResult); 5126 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) { 5127 boolean isVisibleToUser = filterIfNotSystemUser( 5128 Collections.singletonList(xpResolveInfo), userId).size() > 0; 5129 if (isVisibleToUser) { 5130 result.add(xpResolveInfo); 5131 Collections.sort(result, mResolvePrioritySorter); 5132 } 5133 } 5134 if (hasWebURI(intent)) { 5135 CrossProfileDomainInfo xpDomainInfo = null; 5136 final UserInfo parent = getProfileParent(userId); 5137 if (parent != null) { 5138 xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType, 5139 flags, userId, parent.id); 5140 } 5141 if (xpDomainInfo != null) { 5142 if (xpResolveInfo != null) { 5143 // If we didn't remove it, the cross-profile ResolveInfo would be twice 5144 // in the result. 5145 result.remove(xpResolveInfo); 5146 } 5147 if (result.size() == 0) { 5148 result.add(xpDomainInfo.resolveInfo); 5149 return result; 5150 } 5151 } else if (result.size() <= 1) { 5152 return result; 5153 } 5154 result = filterCandidatesWithDomainPreferredActivitiesLPr(intent, flags, result, 5155 xpDomainInfo, userId); 5156 Collections.sort(result, mResolvePrioritySorter); 5157 } 5158 return result; 5159 } 5160 final PackageParser.Package pkg = mPackages.get(pkgName); 5161 if (pkg != null) { 5162 return filterIfNotSystemUser( 5163 mActivities.queryIntentForPackage( 5164 intent, resolvedType, flags, pkg.activities, userId), 5165 userId); 5166 } 5167 return new ArrayList<ResolveInfo>(); 5168 } 5169 } 5170 5171 private static class CrossProfileDomainInfo { 5172 /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */ 5173 ResolveInfo resolveInfo; 5174 /* Best domain verification status of the activities found in the other profile */ 5175 int bestDomainVerificationStatus; 5176 } 5177 5178 private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent, 5179 String resolvedType, int flags, int sourceUserId, int parentUserId) { 5180 if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING, 5181 sourceUserId)) { 5182 return null; 5183 } 5184 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 5185 resolvedType, flags, parentUserId); 5186 5187 if (resultTargetUser == null || resultTargetUser.isEmpty()) { 5188 return null; 5189 } 5190 CrossProfileDomainInfo result = null; 5191 int size = resultTargetUser.size(); 5192 for (int i = 0; i < size; i++) { 5193 ResolveInfo riTargetUser = resultTargetUser.get(i); 5194 // Intent filter verification is only for filters that specify a host. So don't return 5195 // those that handle all web uris. 5196 if (riTargetUser.handleAllWebDataURI) { 5197 continue; 5198 } 5199 String packageName = riTargetUser.activityInfo.packageName; 5200 PackageSetting ps = mSettings.mPackages.get(packageName); 5201 if (ps == null) { 5202 continue; 5203 } 5204 long verificationState = getDomainVerificationStatusLPr(ps, parentUserId); 5205 int status = (int)(verificationState >> 32); 5206 if (result == null) { 5207 result = new CrossProfileDomainInfo(); 5208 result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(), 5209 sourceUserId, parentUserId); 5210 result.bestDomainVerificationStatus = status; 5211 } else { 5212 result.bestDomainVerificationStatus = bestDomainVerificationStatus(status, 5213 result.bestDomainVerificationStatus); 5214 } 5215 } 5216 // Don't consider matches with status NEVER across profiles. 5217 if (result != null && result.bestDomainVerificationStatus 5218 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5219 return null; 5220 } 5221 return result; 5222 } 5223 5224 /** 5225 * Verification statuses are ordered from the worse to the best, except for 5226 * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse. 5227 */ 5228 private int bestDomainVerificationStatus(int status1, int status2) { 5229 if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5230 return status2; 5231 } 5232 if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5233 return status1; 5234 } 5235 return (int) MathUtils.max(status1, status2); 5236 } 5237 5238 private boolean isUserEnabled(int userId) { 5239 long callingId = Binder.clearCallingIdentity(); 5240 try { 5241 UserInfo userInfo = sUserManager.getUserInfo(userId); 5242 return userInfo != null && userInfo.isEnabled(); 5243 } finally { 5244 Binder.restoreCallingIdentity(callingId); 5245 } 5246 } 5247 5248 /** 5249 * Filter out activities with systemUserOnly flag set, when current user is not System. 5250 * 5251 * @return filtered list 5252 */ 5253 private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) { 5254 if (userId == UserHandle.USER_SYSTEM) { 5255 return resolveInfos; 5256 } 5257 for (int i = resolveInfos.size() - 1; i >= 0; i--) { 5258 ResolveInfo info = resolveInfos.get(i); 5259 if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) { 5260 resolveInfos.remove(i); 5261 } 5262 } 5263 return resolveInfos; 5264 } 5265 5266 /** 5267 * @param resolveInfos list of resolve infos in descending priority order 5268 * @return if the list contains a resolve info with non-negative priority 5269 */ 5270 private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) { 5271 return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0; 5272 } 5273 5274 private static boolean hasWebURI(Intent intent) { 5275 if (intent.getData() == null) { 5276 return false; 5277 } 5278 final String scheme = intent.getScheme(); 5279 if (TextUtils.isEmpty(scheme)) { 5280 return false; 5281 } 5282 return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS); 5283 } 5284 5285 private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent, 5286 int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo, 5287 int userId) { 5288 final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0; 5289 5290 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) { 5291 Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " + 5292 candidates.size()); 5293 } 5294 5295 ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>(); 5296 ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>(); 5297 ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>(); 5298 ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>(); 5299 ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>(); 5300 ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>(); 5301 5302 synchronized (mPackages) { 5303 final int count = candidates.size(); 5304 // First, try to use linked apps. Partition the candidates into four lists: 5305 // one for the final results, one for the "do not use ever", one for "undefined status" 5306 // and finally one for "browser app type". 5307 for (int n=0; n<count; n++) { 5308 ResolveInfo info = candidates.get(n); 5309 String packageName = info.activityInfo.packageName; 5310 PackageSetting ps = mSettings.mPackages.get(packageName); 5311 if (ps != null) { 5312 // Add to the special match all list (Browser use case) 5313 if (info.handleAllWebDataURI) { 5314 matchAllList.add(info); 5315 continue; 5316 } 5317 // Try to get the status from User settings first 5318 long packedStatus = getDomainVerificationStatusLPr(ps, userId); 5319 int status = (int)(packedStatus >> 32); 5320 int linkGeneration = (int)(packedStatus & 0xFFFFFFFF); 5321 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) { 5322 if (DEBUG_DOMAIN_VERIFICATION) { 5323 Slog.i(TAG, " + always: " + info.activityInfo.packageName 5324 + " : linkgen=" + linkGeneration); 5325 } 5326 // Use link-enabled generation as preferredOrder, i.e. 5327 // prefer newly-enabled over earlier-enabled. 5328 info.preferredOrder = linkGeneration; 5329 alwaysList.add(info); 5330 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5331 if (DEBUG_DOMAIN_VERIFICATION) { 5332 Slog.i(TAG, " + never: " + info.activityInfo.packageName); 5333 } 5334 neverList.add(info); 5335 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) { 5336 if (DEBUG_DOMAIN_VERIFICATION) { 5337 Slog.i(TAG, " + always-ask: " + info.activityInfo.packageName); 5338 } 5339 alwaysAskList.add(info); 5340 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED || 5341 status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) { 5342 if (DEBUG_DOMAIN_VERIFICATION) { 5343 Slog.i(TAG, " + ask: " + info.activityInfo.packageName); 5344 } 5345 undefinedList.add(info); 5346 } 5347 } 5348 } 5349 5350 // We'll want to include browser possibilities in a few cases 5351 boolean includeBrowser = false; 5352 5353 // First try to add the "always" resolution(s) for the current user, if any 5354 if (alwaysList.size() > 0) { 5355 result.addAll(alwaysList); 5356 } else { 5357 // Add all undefined apps as we want them to appear in the disambiguation dialog. 5358 result.addAll(undefinedList); 5359 // Maybe add one for the other profile. 5360 if (xpDomainInfo != null && ( 5361 xpDomainInfo.bestDomainVerificationStatus 5362 != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) { 5363 result.add(xpDomainInfo.resolveInfo); 5364 } 5365 includeBrowser = true; 5366 } 5367 5368 // The presence of any 'always ask' alternatives means we'll also offer browsers. 5369 // If there were 'always' entries their preferred order has been set, so we also 5370 // back that off to make the alternatives equivalent 5371 if (alwaysAskList.size() > 0) { 5372 for (ResolveInfo i : result) { 5373 i.preferredOrder = 0; 5374 } 5375 result.addAll(alwaysAskList); 5376 includeBrowser = true; 5377 } 5378 5379 if (includeBrowser) { 5380 // Also add browsers (all of them or only the default one) 5381 if (DEBUG_DOMAIN_VERIFICATION) { 5382 Slog.v(TAG, " ...including browsers in candidate set"); 5383 } 5384 if ((matchFlags & MATCH_ALL) != 0) { 5385 result.addAll(matchAllList); 5386 } else { 5387 // Browser/generic handling case. If there's a default browser, go straight 5388 // to that (but only if there is no other higher-priority match). 5389 final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId); 5390 int maxMatchPrio = 0; 5391 ResolveInfo defaultBrowserMatch = null; 5392 final int numCandidates = matchAllList.size(); 5393 for (int n = 0; n < numCandidates; n++) { 5394 ResolveInfo info = matchAllList.get(n); 5395 // track the highest overall match priority... 5396 if (info.priority > maxMatchPrio) { 5397 maxMatchPrio = info.priority; 5398 } 5399 // ...and the highest-priority default browser match 5400 if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) { 5401 if (defaultBrowserMatch == null 5402 || (defaultBrowserMatch.priority < info.priority)) { 5403 if (debug) { 5404 Slog.v(TAG, "Considering default browser match " + info); 5405 } 5406 defaultBrowserMatch = info; 5407 } 5408 } 5409 } 5410 if (defaultBrowserMatch != null 5411 && defaultBrowserMatch.priority >= maxMatchPrio 5412 && !TextUtils.isEmpty(defaultBrowserPackageName)) 5413 { 5414 if (debug) { 5415 Slog.v(TAG, "Default browser match " + defaultBrowserMatch); 5416 } 5417 result.add(defaultBrowserMatch); 5418 } else { 5419 result.addAll(matchAllList); 5420 } 5421 } 5422 5423 // If there is nothing selected, add all candidates and remove the ones that the user 5424 // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state 5425 if (result.size() == 0) { 5426 result.addAll(candidates); 5427 result.removeAll(neverList); 5428 } 5429 } 5430 } 5431 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) { 5432 Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " + 5433 result.size()); 5434 for (ResolveInfo info : result) { 5435 Slog.v(TAG, " + " + info.activityInfo); 5436 } 5437 } 5438 return result; 5439 } 5440 5441 // Returns a packed value as a long: 5442 // 5443 // high 'int'-sized word: link status: undefined/ask/never/always. 5444 // low 'int'-sized word: relative priority among 'always' results. 5445 private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) { 5446 long result = ps.getDomainVerificationStatusForUser(userId); 5447 // if none available, get the master status 5448 if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 5449 if (ps.getIntentFilterVerificationInfo() != null) { 5450 result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32; 5451 } 5452 } 5453 return result; 5454 } 5455 5456 private ResolveInfo querySkipCurrentProfileIntents( 5457 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 5458 int flags, int sourceUserId) { 5459 if (matchingFilters != null) { 5460 int size = matchingFilters.size(); 5461 for (int i = 0; i < size; i ++) { 5462 CrossProfileIntentFilter filter = matchingFilters.get(i); 5463 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) { 5464 // Checking if there are activities in the target user that can handle the 5465 // intent. 5466 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent, 5467 resolvedType, flags, sourceUserId); 5468 if (resolveInfo != null) { 5469 return resolveInfo; 5470 } 5471 } 5472 } 5473 } 5474 return null; 5475 } 5476 5477 // Return matching ResolveInfo in target user if any. 5478 private ResolveInfo queryCrossProfileIntents( 5479 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 5480 int flags, int sourceUserId, boolean matchInCurrentProfile) { 5481 if (matchingFilters != null) { 5482 // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and 5483 // match the same intent. For performance reasons, it is better not to 5484 // run queryIntent twice for the same userId 5485 SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray(); 5486 int size = matchingFilters.size(); 5487 for (int i = 0; i < size; i++) { 5488 CrossProfileIntentFilter filter = matchingFilters.get(i); 5489 int targetUserId = filter.getTargetUserId(); 5490 boolean skipCurrentProfile = 5491 (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0; 5492 boolean skipCurrentProfileIfNoMatchFound = 5493 (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0; 5494 if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId) 5495 && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) { 5496 // Checking if there are activities in the target user that can handle the 5497 // intent. 5498 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent, 5499 resolvedType, flags, sourceUserId); 5500 if (resolveInfo != null) return resolveInfo; 5501 alreadyTriedUserIds.put(targetUserId, true); 5502 } 5503 } 5504 } 5505 return null; 5506 } 5507 5508 /** 5509 * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that 5510 * will forward the intent to the filter's target user. 5511 * Otherwise, returns null. 5512 */ 5513 private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent, 5514 String resolvedType, int flags, int sourceUserId) { 5515 int targetUserId = filter.getTargetUserId(); 5516 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 5517 resolvedType, flags, targetUserId); 5518 if (resultTargetUser != null && isUserEnabled(targetUserId)) { 5519 // If all the matches in the target profile are suspended, return null. 5520 for (int i = resultTargetUser.size() - 1; i >= 0; i--) { 5521 if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags 5522 & ApplicationInfo.FLAG_SUSPENDED) == 0) { 5523 return createForwardingResolveInfoUnchecked(filter, sourceUserId, 5524 targetUserId); 5525 } 5526 } 5527 } 5528 return null; 5529 } 5530 5531 private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter, 5532 int sourceUserId, int targetUserId) { 5533 ResolveInfo forwardingResolveInfo = new ResolveInfo(); 5534 long ident = Binder.clearCallingIdentity(); 5535 boolean targetIsProfile; 5536 try { 5537 targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile(); 5538 } finally { 5539 Binder.restoreCallingIdentity(ident); 5540 } 5541 String className; 5542 if (targetIsProfile) { 5543 className = FORWARD_INTENT_TO_MANAGED_PROFILE; 5544 } else { 5545 className = FORWARD_INTENT_TO_PARENT; 5546 } 5547 ComponentName forwardingActivityComponentName = new ComponentName( 5548 mAndroidApplication.packageName, className); 5549 ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0, 5550 sourceUserId); 5551 if (!targetIsProfile) { 5552 forwardingActivityInfo.showUserIcon = targetUserId; 5553 forwardingResolveInfo.noResourceId = true; 5554 } 5555 forwardingResolveInfo.activityInfo = forwardingActivityInfo; 5556 forwardingResolveInfo.priority = 0; 5557 forwardingResolveInfo.preferredOrder = 0; 5558 forwardingResolveInfo.match = 0; 5559 forwardingResolveInfo.isDefault = true; 5560 forwardingResolveInfo.filter = filter; 5561 forwardingResolveInfo.targetUserId = targetUserId; 5562 return forwardingResolveInfo; 5563 } 5564 5565 @Override 5566 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller, 5567 Intent[] specifics, String[] specificTypes, Intent intent, 5568 String resolvedType, int flags, int userId) { 5569 return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics, 5570 specificTypes, intent, resolvedType, flags, userId)); 5571 } 5572 5573 private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller, 5574 Intent[] specifics, String[] specificTypes, Intent intent, 5575 String resolvedType, int flags, int userId) { 5576 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5577 flags = updateFlagsForResolve(flags, userId, intent); 5578 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5579 false /* requireFullPermission */, false /* checkShell */, 5580 "query intent activity options"); 5581 final String resultsAction = intent.getAction(); 5582 5583 final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags 5584 | PackageManager.GET_RESOLVED_FILTER, userId); 5585 5586 if (DEBUG_INTENT_MATCHING) { 5587 Log.v(TAG, "Query " + intent + ": " + results); 5588 } 5589 5590 int specificsPos = 0; 5591 int N; 5592 5593 // todo: note that the algorithm used here is O(N^2). This 5594 // isn't a problem in our current environment, but if we start running 5595 // into situations where we have more than 5 or 10 matches then this 5596 // should probably be changed to something smarter... 5597 5598 // First we go through and resolve each of the specific items 5599 // that were supplied, taking care of removing any corresponding 5600 // duplicate items in the generic resolve list. 5601 if (specifics != null) { 5602 for (int i=0; i<specifics.length; i++) { 5603 final Intent sintent = specifics[i]; 5604 if (sintent == null) { 5605 continue; 5606 } 5607 5608 if (DEBUG_INTENT_MATCHING) { 5609 Log.v(TAG, "Specific #" + i + ": " + sintent); 5610 } 5611 5612 String action = sintent.getAction(); 5613 if (resultsAction != null && resultsAction.equals(action)) { 5614 // If this action was explicitly requested, then don't 5615 // remove things that have it. 5616 action = null; 5617 } 5618 5619 ResolveInfo ri = null; 5620 ActivityInfo ai = null; 5621 5622 ComponentName comp = sintent.getComponent(); 5623 if (comp == null) { 5624 ri = resolveIntent( 5625 sintent, 5626 specificTypes != null ? specificTypes[i] : null, 5627 flags, userId); 5628 if (ri == null) { 5629 continue; 5630 } 5631 if (ri == mResolveInfo) { 5632 // ACK! Must do something better with this. 5633 } 5634 ai = ri.activityInfo; 5635 comp = new ComponentName(ai.applicationInfo.packageName, 5636 ai.name); 5637 } else { 5638 ai = getActivityInfo(comp, flags, userId); 5639 if (ai == null) { 5640 continue; 5641 } 5642 } 5643 5644 // Look for any generic query activities that are duplicates 5645 // of this specific one, and remove them from the results. 5646 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai); 5647 N = results.size(); 5648 int j; 5649 for (j=specificsPos; j<N; j++) { 5650 ResolveInfo sri = results.get(j); 5651 if ((sri.activityInfo.name.equals(comp.getClassName()) 5652 && sri.activityInfo.applicationInfo.packageName.equals( 5653 comp.getPackageName())) 5654 || (action != null && sri.filter.matchAction(action))) { 5655 results.remove(j); 5656 if (DEBUG_INTENT_MATCHING) Log.v( 5657 TAG, "Removing duplicate item from " + j 5658 + " due to specific " + specificsPos); 5659 if (ri == null) { 5660 ri = sri; 5661 } 5662 j--; 5663 N--; 5664 } 5665 } 5666 5667 // Add this specific item to its proper place. 5668 if (ri == null) { 5669 ri = new ResolveInfo(); 5670 ri.activityInfo = ai; 5671 } 5672 results.add(specificsPos, ri); 5673 ri.specificIndex = i; 5674 specificsPos++; 5675 } 5676 } 5677 5678 // Now we go through the remaining generic results and remove any 5679 // duplicate actions that are found here. 5680 N = results.size(); 5681 for (int i=specificsPos; i<N-1; i++) { 5682 final ResolveInfo rii = results.get(i); 5683 if (rii.filter == null) { 5684 continue; 5685 } 5686 5687 // Iterate over all of the actions of this result's intent 5688 // filter... typically this should be just one. 5689 final Iterator<String> it = rii.filter.actionsIterator(); 5690 if (it == null) { 5691 continue; 5692 } 5693 while (it.hasNext()) { 5694 final String action = it.next(); 5695 if (resultsAction != null && resultsAction.equals(action)) { 5696 // If this action was explicitly requested, then don't 5697 // remove things that have it. 5698 continue; 5699 } 5700 for (int j=i+1; j<N; j++) { 5701 final ResolveInfo rij = results.get(j); 5702 if (rij.filter != null && rij.filter.hasAction(action)) { 5703 results.remove(j); 5704 if (DEBUG_INTENT_MATCHING) Log.v( 5705 TAG, "Removing duplicate item from " + j 5706 + " due to action " + action + " at " + i); 5707 j--; 5708 N--; 5709 } 5710 } 5711 } 5712 5713 // If the caller didn't request filter information, drop it now 5714 // so we don't have to marshall/unmarshall it. 5715 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 5716 rii.filter = null; 5717 } 5718 } 5719 5720 // Filter out the caller activity if so requested. 5721 if (caller != null) { 5722 N = results.size(); 5723 for (int i=0; i<N; i++) { 5724 ActivityInfo ainfo = results.get(i).activityInfo; 5725 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName) 5726 && caller.getClassName().equals(ainfo.name)) { 5727 results.remove(i); 5728 break; 5729 } 5730 } 5731 } 5732 5733 // If the caller didn't request filter information, 5734 // drop them now so we don't have to 5735 // marshall/unmarshall it. 5736 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 5737 N = results.size(); 5738 for (int i=0; i<N; i++) { 5739 results.get(i).filter = null; 5740 } 5741 } 5742 5743 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results); 5744 return results; 5745 } 5746 5747 @Override 5748 public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent, 5749 String resolvedType, int flags, int userId) { 5750 return new ParceledListSlice<>( 5751 queryIntentReceiversInternal(intent, resolvedType, flags, userId)); 5752 } 5753 5754 private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent, 5755 String resolvedType, int flags, int userId) { 5756 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5757 flags = updateFlagsForResolve(flags, userId, intent); 5758 ComponentName comp = intent.getComponent(); 5759 if (comp == null) { 5760 if (intent.getSelector() != null) { 5761 intent = intent.getSelector(); 5762 comp = intent.getComponent(); 5763 } 5764 } 5765 if (comp != null) { 5766 List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5767 ActivityInfo ai = getReceiverInfo(comp, flags, userId); 5768 if (ai != null) { 5769 ResolveInfo ri = new ResolveInfo(); 5770 ri.activityInfo = ai; 5771 list.add(ri); 5772 } 5773 return list; 5774 } 5775 5776 // reader 5777 synchronized (mPackages) { 5778 String pkgName = intent.getPackage(); 5779 if (pkgName == null) { 5780 return mReceivers.queryIntent(intent, resolvedType, flags, userId); 5781 } 5782 final PackageParser.Package pkg = mPackages.get(pkgName); 5783 if (pkg != null) { 5784 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers, 5785 userId); 5786 } 5787 return Collections.emptyList(); 5788 } 5789 } 5790 5791 @Override 5792 public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) { 5793 if (!sUserManager.exists(userId)) return null; 5794 flags = updateFlagsForResolve(flags, userId, intent); 5795 List<ResolveInfo> query = queryIntentServicesInternal(intent, resolvedType, flags, userId); 5796 if (query != null) { 5797 if (query.size() >= 1) { 5798 // If there is more than one service with the same priority, 5799 // just arbitrarily pick the first one. 5800 return query.get(0); 5801 } 5802 } 5803 return null; 5804 } 5805 5806 @Override 5807 public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent, 5808 String resolvedType, int flags, int userId) { 5809 return new ParceledListSlice<>( 5810 queryIntentServicesInternal(intent, resolvedType, flags, userId)); 5811 } 5812 5813 private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent, 5814 String resolvedType, int flags, int userId) { 5815 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5816 flags = updateFlagsForResolve(flags, userId, intent); 5817 ComponentName comp = intent.getComponent(); 5818 if (comp == null) { 5819 if (intent.getSelector() != null) { 5820 intent = intent.getSelector(); 5821 comp = intent.getComponent(); 5822 } 5823 } 5824 if (comp != null) { 5825 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5826 final ServiceInfo si = getServiceInfo(comp, flags, userId); 5827 if (si != null) { 5828 final ResolveInfo ri = new ResolveInfo(); 5829 ri.serviceInfo = si; 5830 list.add(ri); 5831 } 5832 return list; 5833 } 5834 5835 // reader 5836 synchronized (mPackages) { 5837 String pkgName = intent.getPackage(); 5838 if (pkgName == null) { 5839 return mServices.queryIntent(intent, resolvedType, flags, userId); 5840 } 5841 final PackageParser.Package pkg = mPackages.get(pkgName); 5842 if (pkg != null) { 5843 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services, 5844 userId); 5845 } 5846 return Collections.emptyList(); 5847 } 5848 } 5849 5850 @Override 5851 public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent, 5852 String resolvedType, int flags, int userId) { 5853 return new ParceledListSlice<>( 5854 queryIntentContentProvidersInternal(intent, resolvedType, flags, userId)); 5855 } 5856 5857 private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal( 5858 Intent intent, String resolvedType, int flags, int userId) { 5859 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5860 flags = updateFlagsForResolve(flags, userId, intent); 5861 ComponentName comp = intent.getComponent(); 5862 if (comp == null) { 5863 if (intent.getSelector() != null) { 5864 intent = intent.getSelector(); 5865 comp = intent.getComponent(); 5866 } 5867 } 5868 if (comp != null) { 5869 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5870 final ProviderInfo pi = getProviderInfo(comp, flags, userId); 5871 if (pi != null) { 5872 final ResolveInfo ri = new ResolveInfo(); 5873 ri.providerInfo = pi; 5874 list.add(ri); 5875 } 5876 return list; 5877 } 5878 5879 // reader 5880 synchronized (mPackages) { 5881 String pkgName = intent.getPackage(); 5882 if (pkgName == null) { 5883 return mProviders.queryIntent(intent, resolvedType, flags, userId); 5884 } 5885 final PackageParser.Package pkg = mPackages.get(pkgName); 5886 if (pkg != null) { 5887 return mProviders.queryIntentForPackage( 5888 intent, resolvedType, flags, pkg.providers, userId); 5889 } 5890 return Collections.emptyList(); 5891 } 5892 } 5893 5894 @Override 5895 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) { 5896 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 5897 flags = updateFlagsForPackage(flags, userId, null); 5898 final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0; 5899 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5900 true /* requireFullPermission */, false /* checkShell */, 5901 "get installed packages"); 5902 5903 // writer 5904 synchronized (mPackages) { 5905 ArrayList<PackageInfo> list; 5906 if (listUninstalled) { 5907 list = new ArrayList<PackageInfo>(mSettings.mPackages.size()); 5908 for (PackageSetting ps : mSettings.mPackages.values()) { 5909 PackageInfo pi; 5910 if (ps.pkg != null) { 5911 pi = generatePackageInfo(ps.pkg, flags, userId); 5912 } else { 5913 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId); 5914 } 5915 if (pi != null) { 5916 list.add(pi); 5917 } 5918 } 5919 } else { 5920 list = new ArrayList<PackageInfo>(mPackages.size()); 5921 for (PackageParser.Package p : mPackages.values()) { 5922 PackageInfo pi = generatePackageInfo(p, flags, userId); 5923 if (pi != null) { 5924 list.add(pi); 5925 } 5926 } 5927 } 5928 5929 return new ParceledListSlice<PackageInfo>(list); 5930 } 5931 } 5932 5933 private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps, 5934 String[] permissions, boolean[] tmp, int flags, int userId) { 5935 int numMatch = 0; 5936 final PermissionsState permissionsState = ps.getPermissionsState(); 5937 for (int i=0; i<permissions.length; i++) { 5938 final String permission = permissions[i]; 5939 if (permissionsState.hasPermission(permission, userId)) { 5940 tmp[i] = true; 5941 numMatch++; 5942 } else { 5943 tmp[i] = false; 5944 } 5945 } 5946 if (numMatch == 0) { 5947 return; 5948 } 5949 PackageInfo pi; 5950 if (ps.pkg != null) { 5951 pi = generatePackageInfo(ps.pkg, flags, userId); 5952 } else { 5953 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId); 5954 } 5955 // The above might return null in cases of uninstalled apps or install-state 5956 // skew across users/profiles. 5957 if (pi != null) { 5958 if ((flags&PackageManager.GET_PERMISSIONS) == 0) { 5959 if (numMatch == permissions.length) { 5960 pi.requestedPermissions = permissions; 5961 } else { 5962 pi.requestedPermissions = new String[numMatch]; 5963 numMatch = 0; 5964 for (int i=0; i<permissions.length; i++) { 5965 if (tmp[i]) { 5966 pi.requestedPermissions[numMatch] = permissions[i]; 5967 numMatch++; 5968 } 5969 } 5970 } 5971 } 5972 list.add(pi); 5973 } 5974 } 5975 5976 @Override 5977 public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions( 5978 String[] permissions, int flags, int userId) { 5979 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 5980 flags = updateFlagsForPackage(flags, userId, permissions); 5981 final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0; 5982 5983 // writer 5984 synchronized (mPackages) { 5985 ArrayList<PackageInfo> list = new ArrayList<PackageInfo>(); 5986 boolean[] tmpBools = new boolean[permissions.length]; 5987 if (listUninstalled) { 5988 for (PackageSetting ps : mSettings.mPackages.values()) { 5989 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId); 5990 } 5991 } else { 5992 for (PackageParser.Package pkg : mPackages.values()) { 5993 PackageSetting ps = (PackageSetting)pkg.mExtras; 5994 if (ps != null) { 5995 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, 5996 userId); 5997 } 5998 } 5999 } 6000 6001 return new ParceledListSlice<PackageInfo>(list); 6002 } 6003 } 6004 6005 @Override 6006 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) { 6007 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 6008 flags = updateFlagsForApplication(flags, userId, null); 6009 final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0; 6010 6011 // writer 6012 synchronized (mPackages) { 6013 ArrayList<ApplicationInfo> list; 6014 if (listUninstalled) { 6015 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size()); 6016 for (PackageSetting ps : mSettings.mPackages.values()) { 6017 ApplicationInfo ai; 6018 if (ps.pkg != null) { 6019 ai = PackageParser.generateApplicationInfo(ps.pkg, flags, 6020 ps.readUserState(userId), userId); 6021 } else { 6022 ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId); 6023 } 6024 if (ai != null) { 6025 list.add(ai); 6026 } 6027 } 6028 } else { 6029 list = new ArrayList<ApplicationInfo>(mPackages.size()); 6030 for (PackageParser.Package p : mPackages.values()) { 6031 if (p.mExtras != null) { 6032 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 6033 ((PackageSetting)p.mExtras).readUserState(userId), userId); 6034 if (ai != null) { 6035 list.add(ai); 6036 } 6037 } 6038 } 6039 } 6040 6041 return new ParceledListSlice<ApplicationInfo>(list); 6042 } 6043 } 6044 6045 @Override 6046 public ParceledListSlice<EphemeralApplicationInfo> getEphemeralApplications(int userId) { 6047 if (DISABLE_EPHEMERAL_APPS) { 6048 return null; 6049 } 6050 6051 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS, 6052 "getEphemeralApplications"); 6053 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6054 true /* requireFullPermission */, false /* checkShell */, 6055 "getEphemeralApplications"); 6056 synchronized (mPackages) { 6057 List<EphemeralApplicationInfo> ephemeralApps = mEphemeralApplicationRegistry 6058 .getEphemeralApplicationsLPw(userId); 6059 if (ephemeralApps != null) { 6060 return new ParceledListSlice<>(ephemeralApps); 6061 } 6062 } 6063 return null; 6064 } 6065 6066 @Override 6067 public boolean isEphemeralApplication(String packageName, int userId) { 6068 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6069 true /* requireFullPermission */, false /* checkShell */, 6070 "isEphemeral"); 6071 if (DISABLE_EPHEMERAL_APPS) { 6072 return false; 6073 } 6074 6075 if (!isCallerSameApp(packageName)) { 6076 return false; 6077 } 6078 synchronized (mPackages) { 6079 PackageParser.Package pkg = mPackages.get(packageName); 6080 if (pkg != null) { 6081 return pkg.applicationInfo.isEphemeralApp(); 6082 } 6083 } 6084 return false; 6085 } 6086 6087 @Override 6088 public byte[] getEphemeralApplicationCookie(String packageName, int userId) { 6089 if (DISABLE_EPHEMERAL_APPS) { 6090 return null; 6091 } 6092 6093 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6094 true /* requireFullPermission */, false /* checkShell */, 6095 "getCookie"); 6096 if (!isCallerSameApp(packageName)) { 6097 return null; 6098 } 6099 synchronized (mPackages) { 6100 return mEphemeralApplicationRegistry.getEphemeralApplicationCookieLPw( 6101 packageName, userId); 6102 } 6103 } 6104 6105 @Override 6106 public boolean setEphemeralApplicationCookie(String packageName, byte[] cookie, int userId) { 6107 if (DISABLE_EPHEMERAL_APPS) { 6108 return true; 6109 } 6110 6111 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6112 true /* requireFullPermission */, true /* checkShell */, 6113 "setCookie"); 6114 if (!isCallerSameApp(packageName)) { 6115 return false; 6116 } 6117 synchronized (mPackages) { 6118 return mEphemeralApplicationRegistry.setEphemeralApplicationCookieLPw( 6119 packageName, cookie, userId); 6120 } 6121 } 6122 6123 @Override 6124 public Bitmap getEphemeralApplicationIcon(String packageName, int userId) { 6125 if (DISABLE_EPHEMERAL_APPS) { 6126 return null; 6127 } 6128 6129 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS, 6130 "getEphemeralApplicationIcon"); 6131 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6132 true /* requireFullPermission */, false /* checkShell */, 6133 "getEphemeralApplicationIcon"); 6134 synchronized (mPackages) { 6135 return mEphemeralApplicationRegistry.getEphemeralApplicationIconLPw( 6136 packageName, userId); 6137 } 6138 } 6139 6140 private boolean isCallerSameApp(String packageName) { 6141 PackageParser.Package pkg = mPackages.get(packageName); 6142 return pkg != null 6143 && UserHandle.getAppId(Binder.getCallingUid()) == pkg.applicationInfo.uid; 6144 } 6145 6146 @Override 6147 public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) { 6148 return new ParceledListSlice<>(getPersistentApplicationsInternal(flags)); 6149 } 6150 6151 private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) { 6152 final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>(); 6153 6154 // reader 6155 synchronized (mPackages) { 6156 final Iterator<PackageParser.Package> i = mPackages.values().iterator(); 6157 final int userId = UserHandle.getCallingUserId(); 6158 while (i.hasNext()) { 6159 final PackageParser.Package p = i.next(); 6160 if (p.applicationInfo == null) continue; 6161 6162 final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0) 6163 && !p.applicationInfo.isDirectBootAware(); 6164 final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0) 6165 && p.applicationInfo.isDirectBootAware(); 6166 6167 if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0 6168 && (!mSafeMode || isSystemApp(p)) 6169 && (matchesUnaware || matchesAware)) { 6170 PackageSetting ps = mSettings.mPackages.get(p.packageName); 6171 if (ps != null) { 6172 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 6173 ps.readUserState(userId), userId); 6174 if (ai != null) { 6175 finalList.add(ai); 6176 } 6177 } 6178 } 6179 } 6180 } 6181 6182 return finalList; 6183 } 6184 6185 @Override 6186 public ProviderInfo resolveContentProvider(String name, int flags, int userId) { 6187 if (!sUserManager.exists(userId)) return null; 6188 flags = updateFlagsForComponent(flags, userId, name); 6189 // reader 6190 synchronized (mPackages) { 6191 final PackageParser.Provider provider = mProvidersByAuthority.get(name); 6192 PackageSetting ps = provider != null 6193 ? mSettings.mPackages.get(provider.owner.packageName) 6194 : null; 6195 return ps != null 6196 && mSettings.isEnabledAndMatchLPr(provider.info, flags, userId) 6197 ? PackageParser.generateProviderInfo(provider, flags, 6198 ps.readUserState(userId), userId) 6199 : null; 6200 } 6201 } 6202 6203 /** 6204 * @deprecated 6205 */ 6206 @Deprecated 6207 public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) { 6208 // reader 6209 synchronized (mPackages) { 6210 final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority 6211 .entrySet().iterator(); 6212 final int userId = UserHandle.getCallingUserId(); 6213 while (i.hasNext()) { 6214 Map.Entry<String, PackageParser.Provider> entry = i.next(); 6215 PackageParser.Provider p = entry.getValue(); 6216 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 6217 6218 if (ps != null && p.syncable 6219 && (!mSafeMode || (p.info.applicationInfo.flags 6220 &ApplicationInfo.FLAG_SYSTEM) != 0)) { 6221 ProviderInfo info = PackageParser.generateProviderInfo(p, 0, 6222 ps.readUserState(userId), userId); 6223 if (info != null) { 6224 outNames.add(entry.getKey()); 6225 outInfo.add(info); 6226 } 6227 } 6228 } 6229 } 6230 } 6231 6232 @Override 6233 public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName, 6234 int uid, int flags) { 6235 final int userId = processName != null ? UserHandle.getUserId(uid) 6236 : UserHandle.getCallingUserId(); 6237 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 6238 flags = updateFlagsForComponent(flags, userId, processName); 6239 6240 ArrayList<ProviderInfo> finalList = null; 6241 // reader 6242 synchronized (mPackages) { 6243 final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator(); 6244 while (i.hasNext()) { 6245 final PackageParser.Provider p = i.next(); 6246 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 6247 if (ps != null && p.info.authority != null 6248 && (processName == null 6249 || (p.info.processName.equals(processName) 6250 && UserHandle.isSameApp(p.info.applicationInfo.uid, uid))) 6251 && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) { 6252 if (finalList == null) { 6253 finalList = new ArrayList<ProviderInfo>(3); 6254 } 6255 ProviderInfo info = PackageParser.generateProviderInfo(p, flags, 6256 ps.readUserState(userId), userId); 6257 if (info != null) { 6258 finalList.add(info); 6259 } 6260 } 6261 } 6262 } 6263 6264 if (finalList != null) { 6265 Collections.sort(finalList, mProviderInitOrderSorter); 6266 return new ParceledListSlice<ProviderInfo>(finalList); 6267 } 6268 6269 return ParceledListSlice.emptyList(); 6270 } 6271 6272 @Override 6273 public InstrumentationInfo getInstrumentationInfo(ComponentName name, int flags) { 6274 // reader 6275 synchronized (mPackages) { 6276 final PackageParser.Instrumentation i = mInstrumentation.get(name); 6277 return PackageParser.generateInstrumentationInfo(i, flags); 6278 } 6279 } 6280 6281 @Override 6282 public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation( 6283 String targetPackage, int flags) { 6284 return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags)); 6285 } 6286 6287 private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage, 6288 int flags) { 6289 ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>(); 6290 6291 // reader 6292 synchronized (mPackages) { 6293 final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator(); 6294 while (i.hasNext()) { 6295 final PackageParser.Instrumentation p = i.next(); 6296 if (targetPackage == null 6297 || targetPackage.equals(p.info.targetPackage)) { 6298 InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p, 6299 flags); 6300 if (ii != null) { 6301 finalList.add(ii); 6302 } 6303 } 6304 } 6305 } 6306 6307 return finalList; 6308 } 6309 6310 private void createIdmapsForPackageLI(PackageParser.Package pkg) { 6311 ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName); 6312 if (overlays == null) { 6313 Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages"); 6314 return; 6315 } 6316 for (PackageParser.Package opkg : overlays.values()) { 6317 // Not much to do if idmap fails: we already logged the error 6318 // and we certainly don't want to abort installation of pkg simply 6319 // because an overlay didn't fit properly. For these reasons, 6320 // ignore the return value of createIdmapForPackagePairLI. 6321 createIdmapForPackagePairLI(pkg, opkg); 6322 } 6323 } 6324 6325 private boolean createIdmapForPackagePairLI(PackageParser.Package pkg, 6326 PackageParser.Package opkg) { 6327 if (!opkg.mTrustedOverlay) { 6328 Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " + 6329 opkg.baseCodePath + ": overlay not trusted"); 6330 return false; 6331 } 6332 ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName); 6333 if (overlaySet == null) { 6334 Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " + 6335 opkg.baseCodePath + " but target package has no known overlays"); 6336 return false; 6337 } 6338 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 6339 // TODO: generate idmap for split APKs 6340 try { 6341 mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid); 6342 } catch (InstallerException e) { 6343 Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and " 6344 + opkg.baseCodePath); 6345 return false; 6346 } 6347 PackageParser.Package[] overlayArray = 6348 overlaySet.values().toArray(new PackageParser.Package[0]); 6349 Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() { 6350 public int compare(PackageParser.Package p1, PackageParser.Package p2) { 6351 return p1.mOverlayPriority - p2.mOverlayPriority; 6352 } 6353 }; 6354 Arrays.sort(overlayArray, cmp); 6355 6356 pkg.applicationInfo.resourceDirs = new String[overlayArray.length]; 6357 int i = 0; 6358 for (PackageParser.Package p : overlayArray) { 6359 pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath; 6360 } 6361 return true; 6362 } 6363 6364 private void scanDirTracedLI(File dir, int parseFlags, int scanFlags, long currentTime) { 6365 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir"); 6366 try { 6367 scanDirLI(dir, parseFlags, scanFlags, currentTime); 6368 } finally { 6369 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6370 } 6371 } 6372 6373 private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) { 6374 final File[] files = dir.listFiles(); 6375 if (ArrayUtils.isEmpty(files)) { 6376 Log.d(TAG, "No files in app dir " + dir); 6377 return; 6378 } 6379 6380 if (DEBUG_PACKAGE_SCANNING) { 6381 Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags 6382 + " flags=0x" + Integer.toHexString(parseFlags)); 6383 } 6384 6385 for (File file : files) { 6386 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 6387 && !PackageInstallerService.isStageName(file.getName()); 6388 if (!isPackage) { 6389 // Ignore entries which are not packages 6390 continue; 6391 } 6392 try { 6393 scanPackageTracedLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK, 6394 scanFlags, currentTime, null); 6395 } catch (PackageManagerException e) { 6396 Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage()); 6397 6398 // Delete invalid userdata apps 6399 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 && 6400 e.error == PackageManager.INSTALL_FAILED_INVALID_APK) { 6401 logCriticalInfo(Log.WARN, "Deleting invalid package at " + file); 6402 removeCodePathLI(file); 6403 } 6404 } 6405 } 6406 } 6407 6408 private static File getSettingsProblemFile() { 6409 File dataDir = Environment.getDataDirectory(); 6410 File systemDir = new File(dataDir, "system"); 6411 File fname = new File(systemDir, "uiderrors.txt"); 6412 return fname; 6413 } 6414 6415 static void reportSettingsProblem(int priority, String msg) { 6416 logCriticalInfo(priority, msg); 6417 } 6418 6419 static void logCriticalInfo(int priority, String msg) { 6420 Slog.println(priority, TAG, msg); 6421 EventLogTags.writePmCriticalInfo(msg); 6422 try { 6423 File fname = getSettingsProblemFile(); 6424 FileOutputStream out = new FileOutputStream(fname, true); 6425 PrintWriter pw = new FastPrintWriter(out); 6426 SimpleDateFormat formatter = new SimpleDateFormat(); 6427 String dateString = formatter.format(new Date(System.currentTimeMillis())); 6428 pw.println(dateString + ": " + msg); 6429 pw.close(); 6430 FileUtils.setPermissions( 6431 fname.toString(), 6432 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH, 6433 -1, -1); 6434 } catch (java.io.IOException e) { 6435 } 6436 } 6437 6438 private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile, 6439 int parseFlags) throws PackageManagerException { 6440 if (ps != null 6441 && ps.codePath.equals(srcFile) 6442 && ps.timeStamp == srcFile.lastModified() 6443 && !isCompatSignatureUpdateNeeded(pkg) 6444 && !isRecoverSignatureUpdateNeeded(pkg)) { 6445 long mSigningKeySetId = ps.keySetData.getProperSigningKeySet(); 6446 KeySetManagerService ksms = mSettings.mKeySetManagerService; 6447 ArraySet<PublicKey> signingKs; 6448 synchronized (mPackages) { 6449 signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId); 6450 } 6451 if (ps.signatures.mSignatures != null 6452 && ps.signatures.mSignatures.length != 0 6453 && signingKs != null) { 6454 // Optimization: reuse the existing cached certificates 6455 // if the package appears to be unchanged. 6456 pkg.mSignatures = ps.signatures.mSignatures; 6457 pkg.mSigningKeys = signingKs; 6458 return; 6459 } 6460 6461 Slog.w(TAG, "PackageSetting for " + ps.name 6462 + " is missing signatures. Collecting certs again to recover them."); 6463 } else { 6464 Log.i(TAG, srcFile.toString() + " changed; collecting certs"); 6465 } 6466 6467 try { 6468 PackageParser.collectCertificates(pkg, parseFlags); 6469 } catch (PackageParserException e) { 6470 throw PackageManagerException.from(e); 6471 } 6472 } 6473 6474 /** 6475 * Traces a package scan. 6476 * @see #scanPackageLI(File, int, int, long, UserHandle) 6477 */ 6478 private PackageParser.Package scanPackageTracedLI(File scanFile, int parseFlags, int scanFlags, 6479 long currentTime, UserHandle user) throws PackageManagerException { 6480 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage"); 6481 try { 6482 return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user); 6483 } finally { 6484 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6485 } 6486 } 6487 6488 /** 6489 * Scans a package and returns the newly parsed package. 6490 * Returns {@code null} in case of errors and the error code is stored in mLastScanError 6491 */ 6492 private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags, 6493 long currentTime, UserHandle user) throws PackageManagerException { 6494 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile); 6495 parseFlags |= mDefParseFlags; 6496 PackageParser pp = new PackageParser(); 6497 pp.setSeparateProcesses(mSeparateProcesses); 6498 pp.setOnlyCoreApps(mOnlyCore); 6499 pp.setDisplayMetrics(mMetrics); 6500 6501 if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) { 6502 parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY; 6503 } 6504 6505 final PackageParser.Package pkg; 6506 try { 6507 pkg = pp.parsePackage(scanFile, parseFlags); 6508 } catch (PackageParserException e) { 6509 throw PackageManagerException.from(e); 6510 } 6511 6512 return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user); 6513 } 6514 6515 /** 6516 * Scans a package and returns the newly parsed package. 6517 * @throws PackageManagerException on a parse error. 6518 */ 6519 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile, 6520 int parseFlags, int scanFlags, long currentTime, UserHandle user) 6521 throws PackageManagerException { 6522 // If the package has children and this is the first dive in the function 6523 // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all 6524 // packages (parent and children) would be successfully scanned before the 6525 // actual scan since scanning mutates internal state and we want to atomically 6526 // install the package and its children. 6527 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 6528 if (pkg.childPackages != null && pkg.childPackages.size() > 0) { 6529 scanFlags |= SCAN_CHECK_ONLY; 6530 } 6531 } else { 6532 scanFlags &= ~SCAN_CHECK_ONLY; 6533 } 6534 6535 // Scan the parent 6536 PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, parseFlags, 6537 scanFlags, currentTime, user); 6538 6539 // Scan the children 6540 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 6541 for (int i = 0; i < childCount; i++) { 6542 PackageParser.Package childPackage = pkg.childPackages.get(i); 6543 scanPackageInternalLI(childPackage, scanFile, parseFlags, scanFlags, 6544 currentTime, user); 6545 } 6546 6547 6548 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 6549 return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user); 6550 } 6551 6552 return scannedPkg; 6553 } 6554 6555 /** 6556 * Scans a package and returns the newly parsed package. 6557 * @throws PackageManagerException on a parse error. 6558 */ 6559 private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile, 6560 int parseFlags, int scanFlags, long currentTime, UserHandle user) 6561 throws PackageManagerException { 6562 PackageSetting ps = null; 6563 PackageSetting updatedPkg; 6564 // reader 6565 synchronized (mPackages) { 6566 // Look to see if we already know about this package. 6567 String oldName = mSettings.mRenamedPackages.get(pkg.packageName); 6568 if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) { 6569 // This package has been renamed to its original name. Let's 6570 // use that. 6571 ps = mSettings.peekPackageLPr(oldName); 6572 } 6573 // If there was no original package, see one for the real package name. 6574 if (ps == null) { 6575 ps = mSettings.peekPackageLPr(pkg.packageName); 6576 } 6577 // Check to see if this package could be hiding/updating a system 6578 // package. Must look for it either under the original or real 6579 // package name depending on our state. 6580 updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName); 6581 if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg); 6582 6583 // If this is a package we don't know about on the system partition, we 6584 // may need to remove disabled child packages on the system partition 6585 // or may need to not add child packages if the parent apk is updated 6586 // on the data partition and no longer defines this child package. 6587 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) != 0) { 6588 // If this is a parent package for an updated system app and this system 6589 // app got an OTA update which no longer defines some of the child packages 6590 // we have to prune them from the disabled system packages. 6591 PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName); 6592 if (disabledPs != null) { 6593 final int scannedChildCount = (pkg.childPackages != null) 6594 ? pkg.childPackages.size() : 0; 6595 final int disabledChildCount = disabledPs.childPackageNames != null 6596 ? disabledPs.childPackageNames.size() : 0; 6597 for (int i = 0; i < disabledChildCount; i++) { 6598 String disabledChildPackageName = disabledPs.childPackageNames.get(i); 6599 boolean disabledPackageAvailable = false; 6600 for (int j = 0; j < scannedChildCount; j++) { 6601 PackageParser.Package childPkg = pkg.childPackages.get(j); 6602 if (childPkg.packageName.equals(disabledChildPackageName)) { 6603 disabledPackageAvailable = true; 6604 break; 6605 } 6606 } 6607 if (!disabledPackageAvailable) { 6608 mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName); 6609 } 6610 } 6611 } 6612 } 6613 } 6614 6615 boolean updatedPkgBetter = false; 6616 // First check if this is a system package that may involve an update 6617 if (updatedPkg != null && (parseFlags & PackageParser.PARSE_IS_SYSTEM) != 0) { 6618 // If new package is not located in "/system/priv-app" (e.g. due to an OTA), 6619 // it needs to drop FLAG_PRIVILEGED. 6620 if (locationIsPrivileged(scanFile)) { 6621 updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 6622 } else { 6623 updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 6624 } 6625 6626 if (ps != null && !ps.codePath.equals(scanFile)) { 6627 // The path has changed from what was last scanned... check the 6628 // version of the new path against what we have stored to determine 6629 // what to do. 6630 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath); 6631 if (pkg.mVersionCode <= ps.versionCode) { 6632 // The system package has been updated and the code path does not match 6633 // Ignore entry. Skip it. 6634 if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile 6635 + " ignored: updated version " + ps.versionCode 6636 + " better than this " + pkg.mVersionCode); 6637 if (!updatedPkg.codePath.equals(scanFile)) { 6638 Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg " 6639 + ps.name + " changing from " + updatedPkg.codePathString 6640 + " to " + scanFile); 6641 updatedPkg.codePath = scanFile; 6642 updatedPkg.codePathString = scanFile.toString(); 6643 updatedPkg.resourcePath = scanFile; 6644 updatedPkg.resourcePathString = scanFile.toString(); 6645 } 6646 updatedPkg.pkg = pkg; 6647 updatedPkg.versionCode = pkg.mVersionCode; 6648 6649 // Update the disabled system child packages to point to the package too. 6650 final int childCount = updatedPkg.childPackageNames != null 6651 ? updatedPkg.childPackageNames.size() : 0; 6652 for (int i = 0; i < childCount; i++) { 6653 String childPackageName = updatedPkg.childPackageNames.get(i); 6654 PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr( 6655 childPackageName); 6656 if (updatedChildPkg != null) { 6657 updatedChildPkg.pkg = pkg; 6658 updatedChildPkg.versionCode = pkg.mVersionCode; 6659 } 6660 } 6661 6662 throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at " 6663 + scanFile + " ignored: updated version " + ps.versionCode 6664 + " better than this " + pkg.mVersionCode); 6665 } else { 6666 // The current app on the system partition is better than 6667 // what we have updated to on the data partition; switch 6668 // back to the system partition version. 6669 // At this point, its safely assumed that package installation for 6670 // apps in system partition will go through. If not there won't be a working 6671 // version of the app 6672 // writer 6673 synchronized (mPackages) { 6674 // Just remove the loaded entries from package lists. 6675 mPackages.remove(ps.name); 6676 } 6677 6678 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 6679 + " reverting from " + ps.codePathString 6680 + ": new version " + pkg.mVersionCode 6681 + " better than installed " + ps.versionCode); 6682 6683 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 6684 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 6685 synchronized (mInstallLock) { 6686 args.cleanUpResourcesLI(); 6687 } 6688 synchronized (mPackages) { 6689 mSettings.enableSystemPackageLPw(ps.name); 6690 } 6691 updatedPkgBetter = true; 6692 } 6693 } 6694 } 6695 6696 if (updatedPkg != null) { 6697 // An updated system app will not have the PARSE_IS_SYSTEM flag set 6698 // initially 6699 parseFlags |= PackageParser.PARSE_IS_SYSTEM; 6700 6701 // An updated privileged app will not have the PARSE_IS_PRIVILEGED 6702 // flag set initially 6703 if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) { 6704 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 6705 } 6706 } 6707 6708 // Verify certificates against what was last scanned 6709 collectCertificatesLI(ps, pkg, scanFile, parseFlags); 6710 6711 /* 6712 * A new system app appeared, but we already had a non-system one of the 6713 * same name installed earlier. 6714 */ 6715 boolean shouldHideSystemApp = false; 6716 if (updatedPkg == null && ps != null 6717 && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) { 6718 /* 6719 * Check to make sure the signatures match first. If they don't, 6720 * wipe the installed application and its data. 6721 */ 6722 if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures) 6723 != PackageManager.SIGNATURE_MATCH) { 6724 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but" 6725 + " signatures don't match existing userdata copy; removing"); 6726 deletePackageLI(pkg.packageName, null, true, null, 0, null, false, null); 6727 ps = null; 6728 } else { 6729 /* 6730 * If the newly-added system app is an older version than the 6731 * already installed version, hide it. It will be scanned later 6732 * and re-added like an update. 6733 */ 6734 if (pkg.mVersionCode <= ps.versionCode) { 6735 shouldHideSystemApp = true; 6736 logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile 6737 + " but new version " + pkg.mVersionCode + " better than installed " 6738 + ps.versionCode + "; hiding system"); 6739 } else { 6740 /* 6741 * The newly found system app is a newer version that the 6742 * one previously installed. Simply remove the 6743 * already-installed application and replace it with our own 6744 * while keeping the application data. 6745 */ 6746 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 6747 + " reverting from " + ps.codePathString + ": new version " 6748 + pkg.mVersionCode + " better than installed " + ps.versionCode); 6749 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 6750 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 6751 synchronized (mInstallLock) { 6752 args.cleanUpResourcesLI(); 6753 } 6754 } 6755 } 6756 } 6757 6758 // The apk is forward locked (not public) if its code and resources 6759 // are kept in different files. (except for app in either system or 6760 // vendor path). 6761 // TODO grab this value from PackageSettings 6762 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 6763 if (ps != null && !ps.codePath.equals(ps.resourcePath)) { 6764 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 6765 } 6766 } 6767 6768 // TODO: extend to support forward-locked splits 6769 String resourcePath = null; 6770 String baseResourcePath = null; 6771 if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) { 6772 if (ps != null && ps.resourcePathString != null) { 6773 resourcePath = ps.resourcePathString; 6774 baseResourcePath = ps.resourcePathString; 6775 } else { 6776 // Should not happen at all. Just log an error. 6777 Slog.e(TAG, "Resource path not set for package " + pkg.packageName); 6778 } 6779 } else { 6780 resourcePath = pkg.codePath; 6781 baseResourcePath = pkg.baseCodePath; 6782 } 6783 6784 // Set application objects path explicitly. 6785 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 6786 pkg.setApplicationInfoCodePath(pkg.codePath); 6787 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 6788 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 6789 pkg.setApplicationInfoResourcePath(resourcePath); 6790 pkg.setApplicationInfoBaseResourcePath(baseResourcePath); 6791 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 6792 6793 // Note that we invoke the following method only if we are about to unpack an application 6794 PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags 6795 | SCAN_UPDATE_SIGNATURE, currentTime, user); 6796 6797 /* 6798 * If the system app should be overridden by a previously installed 6799 * data, hide the system app now and let the /data/app scan pick it up 6800 * again. 6801 */ 6802 if (shouldHideSystemApp) { 6803 synchronized (mPackages) { 6804 mSettings.disableSystemPackageLPw(pkg.packageName, true); 6805 } 6806 } 6807 6808 return scannedPkg; 6809 } 6810 6811 private static String fixProcessName(String defProcessName, 6812 String processName, int uid) { 6813 if (processName == null) { 6814 return defProcessName; 6815 } 6816 return processName; 6817 } 6818 6819 private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg) 6820 throws PackageManagerException { 6821 if (pkgSetting.signatures.mSignatures != null) { 6822 // Already existing package. Make sure signatures match 6823 boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures) 6824 == PackageManager.SIGNATURE_MATCH; 6825 if (!match) { 6826 match = compareSignaturesCompat(pkgSetting.signatures, pkg) 6827 == PackageManager.SIGNATURE_MATCH; 6828 } 6829 if (!match) { 6830 match = compareSignaturesRecover(pkgSetting.signatures, pkg) 6831 == PackageManager.SIGNATURE_MATCH; 6832 } 6833 if (!match) { 6834 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 6835 + pkg.packageName + " signatures do not match the " 6836 + "previously installed version; ignoring!"); 6837 } 6838 } 6839 6840 // Check for shared user signatures 6841 if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) { 6842 // Already existing package. Make sure signatures match 6843 boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 6844 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 6845 if (!match) { 6846 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg) 6847 == PackageManager.SIGNATURE_MATCH; 6848 } 6849 if (!match) { 6850 match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg) 6851 == PackageManager.SIGNATURE_MATCH; 6852 } 6853 if (!match) { 6854 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 6855 "Package " + pkg.packageName 6856 + " has no signatures that match those in shared user " 6857 + pkgSetting.sharedUser.name + "; ignoring!"); 6858 } 6859 } 6860 } 6861 6862 /** 6863 * Enforces that only the system UID or root's UID can call a method exposed 6864 * via Binder. 6865 * 6866 * @param message used as message if SecurityException is thrown 6867 * @throws SecurityException if the caller is not system or root 6868 */ 6869 private static final void enforceSystemOrRoot(String message) { 6870 final int uid = Binder.getCallingUid(); 6871 if (uid != Process.SYSTEM_UID && uid != 0) { 6872 throw new SecurityException(message); 6873 } 6874 } 6875 6876 @Override 6877 public void performFstrimIfNeeded() { 6878 enforceSystemOrRoot("Only the system can request fstrim"); 6879 6880 // Before everything else, see whether we need to fstrim. 6881 try { 6882 IMountService ms = PackageHelper.getMountService(); 6883 if (ms != null) { 6884 final boolean isUpgrade = isUpgrade(); 6885 boolean doTrim = isUpgrade; 6886 if (doTrim) { 6887 Slog.w(TAG, "Running disk maintenance immediately due to system update"); 6888 } else { 6889 final long interval = android.provider.Settings.Global.getLong( 6890 mContext.getContentResolver(), 6891 android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL, 6892 DEFAULT_MANDATORY_FSTRIM_INTERVAL); 6893 if (interval > 0) { 6894 final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance(); 6895 if (timeSinceLast > interval) { 6896 doTrim = true; 6897 Slog.w(TAG, "No disk maintenance in " + timeSinceLast 6898 + "; running immediately"); 6899 } 6900 } 6901 } 6902 if (doTrim) { 6903 if (!isFirstBoot()) { 6904 try { 6905 ActivityManagerNative.getDefault().showBootMessage( 6906 mContext.getResources().getString( 6907 R.string.android_upgrading_fstrim), true); 6908 } catch (RemoteException e) { 6909 } 6910 } 6911 ms.runMaintenance(); 6912 } 6913 } else { 6914 Slog.e(TAG, "Mount service unavailable!"); 6915 } 6916 } catch (RemoteException e) { 6917 // Can't happen; MountService is local 6918 } 6919 } 6920 6921 @Override 6922 public void extractPackagesIfNeeded() { 6923 enforceSystemOrRoot("Only the system can request package extraction"); 6924 6925 // We need to re-extract after an OTA. 6926 boolean causeUpgrade = isUpgrade(); 6927 6928 // First boot or factory reset. 6929 // Note: we also handle devices that are upgrading to N right now as if it is their 6930 // first boot, as they do not have profile data. 6931 boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade; 6932 6933 // We need to re-extract after a pruned cache, as AoT-ed files will be out of date. 6934 boolean causePrunedCache = VMRuntime.didPruneDalvikCache(); 6935 6936 if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) { 6937 return; 6938 } 6939 6940 List<PackageParser.Package> pkgs; 6941 synchronized (mPackages) { 6942 pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this); 6943 } 6944 6945 int curr = 0; 6946 int total = pkgs.size(); 6947 for (PackageParser.Package pkg : pkgs) { 6948 curr++; 6949 6950 if (DEBUG_DEXOPT) { 6951 Log.i(TAG, "Extracting app " + curr + " of " + total + ": " + pkg.packageName); 6952 } 6953 6954 if (!isFirstBoot()) { 6955 try { 6956 ActivityManagerNative.getDefault().showBootMessage( 6957 mContext.getResources().getString(R.string.android_upgrading_apk, 6958 curr, total), true); 6959 } catch (RemoteException e) { 6960 } 6961 } 6962 6963 if (PackageDexOptimizer.canOptimizePackage(pkg)) { 6964 // If the cache was pruned, any compiled odex files will likely be out of date 6965 // and would have to be patched (would be SELF_PATCHOAT, which is deprecated). 6966 // Instead, force the extraction in this case. 6967 performDexOpt(pkg.packageName, null /* instructionSet */, 6968 false /* checkProfiles */, 6969 causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT, 6970 causePrunedCache); 6971 } 6972 } 6973 } 6974 6975 @Override 6976 public void notifyPackageUse(String packageName) { 6977 synchronized (mPackages) { 6978 PackageParser.Package p = mPackages.get(packageName); 6979 if (p == null) { 6980 return; 6981 } 6982 p.mLastPackageUsageTimeInMills = System.currentTimeMillis(); 6983 } 6984 } 6985 6986 // TODO: this is not used nor needed. Delete it. 6987 @Override 6988 public boolean performDexOptIfNeeded(String packageName, String instructionSet) { 6989 return performDexOptTraced(packageName, instructionSet, false /* checkProfiles */, 6990 getFullCompilerFilter(), false /* force */); 6991 } 6992 6993 @Override 6994 public boolean performDexOpt(String packageName, String instructionSet, 6995 boolean checkProfiles, int compileReason, boolean force) { 6996 return performDexOptTraced(packageName, instructionSet, checkProfiles, 6997 getCompilerFilterForReason(compileReason), force); 6998 } 6999 7000 @Override 7001 public boolean performDexOptMode(String packageName, String instructionSet, 7002 boolean checkProfiles, String targetCompilerFilter, boolean force) { 7003 return performDexOptTraced(packageName, instructionSet, checkProfiles, 7004 targetCompilerFilter, force); 7005 } 7006 7007 private boolean performDexOptTraced(String packageName, String instructionSet, 7008 boolean checkProfiles, String targetCompilerFilter, boolean force) { 7009 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 7010 try { 7011 return performDexOptInternal(packageName, instructionSet, checkProfiles, 7012 targetCompilerFilter, force); 7013 } finally { 7014 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7015 } 7016 } 7017 7018 private boolean performDexOptInternal(String packageName, String instructionSet, 7019 boolean checkProfiles, String targetCompilerFilter, boolean force) { 7020 PackageParser.Package p; 7021 final String targetInstructionSet; 7022 synchronized (mPackages) { 7023 p = mPackages.get(packageName); 7024 if (p == null) { 7025 return false; 7026 } 7027 mPackageUsage.write(false); 7028 7029 targetInstructionSet = instructionSet != null ? instructionSet : 7030 getPrimaryInstructionSet(p.applicationInfo); 7031 } 7032 long callingId = Binder.clearCallingIdentity(); 7033 try { 7034 synchronized (mInstallLock) { 7035 final String[] instructionSets = new String[] { targetInstructionSet }; 7036 int result = performDexOptInternalWithDependenciesLI(p, instructionSets, 7037 checkProfiles, targetCompilerFilter, force); 7038 return result == PackageDexOptimizer.DEX_OPT_PERFORMED; 7039 } 7040 } finally { 7041 Binder.restoreCallingIdentity(callingId); 7042 } 7043 } 7044 7045 public ArraySet<String> getOptimizablePackages() { 7046 ArraySet<String> pkgs = new ArraySet<String>(); 7047 synchronized (mPackages) { 7048 for (PackageParser.Package p : mPackages.values()) { 7049 if (PackageDexOptimizer.canOptimizePackage(p)) { 7050 pkgs.add(p.packageName); 7051 } 7052 } 7053 } 7054 return pkgs; 7055 } 7056 7057 private int performDexOptInternalWithDependenciesLI(PackageParser.Package p, 7058 String instructionSets[], boolean checkProfiles, String targetCompilerFilter, 7059 boolean force) { 7060 // Select the dex optimizer based on the force parameter. 7061 // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to 7062 // allocate an object here. 7063 PackageDexOptimizer pdo = force 7064 ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer) 7065 : mPackageDexOptimizer; 7066 7067 // Optimize all dependencies first. Note: we ignore the return value and march on 7068 // on errors. 7069 Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p); 7070 if (!deps.isEmpty()) { 7071 for (PackageParser.Package depPackage : deps) { 7072 // TODO: Analyze and investigate if we (should) profile libraries. 7073 // Currently this will do a full compilation of the library by default. 7074 pdo.performDexOpt(depPackage, instructionSets, false /* checkProfiles */, 7075 getCompilerFilterForReason(REASON_NON_SYSTEM_LIBRARY)); 7076 } 7077 } 7078 7079 return pdo.performDexOpt(p, instructionSets, checkProfiles, targetCompilerFilter); 7080 } 7081 7082 Collection<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) { 7083 if (p.usesLibraries != null || p.usesOptionalLibraries != null) { 7084 ArrayList<PackageParser.Package> retValue = new ArrayList<>(); 7085 Set<String> collectedNames = new HashSet<>(); 7086 findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames); 7087 7088 retValue.remove(p); 7089 7090 return retValue; 7091 } else { 7092 return Collections.emptyList(); 7093 } 7094 } 7095 7096 private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p, 7097 Collection<PackageParser.Package> collected, Set<String> collectedNames) { 7098 if (!collectedNames.contains(p.packageName)) { 7099 collectedNames.add(p.packageName); 7100 collected.add(p); 7101 7102 if (p.usesLibraries != null) { 7103 findSharedNonSystemLibrariesRecursive(p.usesLibraries, collected, collectedNames); 7104 } 7105 if (p.usesOptionalLibraries != null) { 7106 findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries, collected, 7107 collectedNames); 7108 } 7109 } 7110 } 7111 7112 private void findSharedNonSystemLibrariesRecursive(Collection<String> libs, 7113 Collection<PackageParser.Package> collected, Set<String> collectedNames) { 7114 for (String libName : libs) { 7115 PackageParser.Package libPkg = findSharedNonSystemLibrary(libName); 7116 if (libPkg != null) { 7117 findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames); 7118 } 7119 } 7120 } 7121 7122 private PackageParser.Package findSharedNonSystemLibrary(String libName) { 7123 synchronized (mPackages) { 7124 PackageManagerService.SharedLibraryEntry lib = mSharedLibraries.get(libName); 7125 if (lib != null && lib.apk != null) { 7126 return mPackages.get(lib.apk); 7127 } 7128 } 7129 return null; 7130 } 7131 7132 public void shutdown() { 7133 mPackageUsage.write(true); 7134 } 7135 7136 @Override 7137 public void forceDexOpt(String packageName) { 7138 enforceSystemOrRoot("forceDexOpt"); 7139 7140 PackageParser.Package pkg; 7141 synchronized (mPackages) { 7142 pkg = mPackages.get(packageName); 7143 if (pkg == null) { 7144 throw new IllegalArgumentException("Unknown package: " + packageName); 7145 } 7146 } 7147 7148 synchronized (mInstallLock) { 7149 final String[] instructionSets = new String[] { 7150 getPrimaryInstructionSet(pkg.applicationInfo) }; 7151 7152 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 7153 7154 // Whoever is calling forceDexOpt wants a fully compiled package. 7155 // Don't use profiles since that may cause compilation to be skipped. 7156 final int res = performDexOptInternalWithDependenciesLI(pkg, instructionSets, 7157 false /* checkProfiles */, getCompilerFilterForReason(REASON_FORCED_DEXOPT), 7158 true /* force */); 7159 7160 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7161 if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) { 7162 throw new IllegalStateException("Failed to dexopt: " + res); 7163 } 7164 } 7165 } 7166 7167 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) { 7168 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) { 7169 Slog.w(TAG, "Unable to update from " + oldPkg.name 7170 + " to " + newPkg.packageName 7171 + ": old package not in system partition"); 7172 return false; 7173 } else if (mPackages.get(oldPkg.name) != null) { 7174 Slog.w(TAG, "Unable to update from " + oldPkg.name 7175 + " to " + newPkg.packageName 7176 + ": old package still exists"); 7177 return false; 7178 } 7179 return true; 7180 } 7181 7182 private boolean removeDataDirsLI(String volumeUuid, String packageName) { 7183 // TODO: triage flags as part of 26466827 7184 final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE; 7185 7186 boolean res = true; 7187 final int[] users = sUserManager.getUserIds(); 7188 for (int user : users) { 7189 try { 7190 mInstaller.destroyAppData(volumeUuid, packageName, user, flags); 7191 } catch (InstallerException e) { 7192 Slog.w(TAG, "Failed to delete data directory", e); 7193 res = false; 7194 } 7195 } 7196 return res; 7197 } 7198 7199 void removeCodePathLI(File codePath) { 7200 if (codePath.isDirectory()) { 7201 try { 7202 mInstaller.rmPackageDir(codePath.getAbsolutePath()); 7203 } catch (InstallerException e) { 7204 Slog.w(TAG, "Failed to remove code path", e); 7205 } 7206 } else { 7207 codePath.delete(); 7208 } 7209 } 7210 7211 void destroyAppDataLI(String volumeUuid, String packageName, int userId, int flags) { 7212 try { 7213 mInstaller.destroyAppData(volumeUuid, packageName, userId, flags); 7214 } catch (InstallerException e) { 7215 Slog.w(TAG, "Failed to destroy app data", e); 7216 } 7217 } 7218 7219 void restoreconAppDataLI(String volumeUuid, String packageName, int userId, int flags, 7220 int appId, String seinfo) { 7221 try { 7222 mInstaller.restoreconAppData(volumeUuid, packageName, userId, flags, appId, seinfo); 7223 } catch (InstallerException e) { 7224 Slog.e(TAG, "Failed to restorecon for " + packageName + ": " + e); 7225 } 7226 } 7227 7228 private void deleteProfilesLI(String packageName, boolean destroy) { 7229 final PackageParser.Package pkg; 7230 synchronized (mPackages) { 7231 pkg = mPackages.get(packageName); 7232 } 7233 if (pkg == null) { 7234 Slog.w(TAG, "Failed to delete profiles. No package: " + packageName); 7235 return; 7236 } 7237 deleteProfilesLI(pkg, destroy); 7238 } 7239 7240 private void deleteProfilesLI(PackageParser.Package pkg, boolean destroy) { 7241 try { 7242 if (destroy) { 7243 mInstaller.clearAppProfiles(pkg.packageName); 7244 } else { 7245 mInstaller.destroyAppProfiles(pkg.packageName); 7246 } 7247 } catch (InstallerException ex) { 7248 Log.e(TAG, "Could not delete profiles for package " + pkg.packageName); 7249 } 7250 } 7251 7252 private void deleteCodeCacheDirsLI(String volumeUuid, String packageName) { 7253 final PackageParser.Package pkg; 7254 synchronized (mPackages) { 7255 pkg = mPackages.get(packageName); 7256 } 7257 if (pkg == null) { 7258 Slog.w(TAG, "Failed to delete code cache directory. No package: " + packageName); 7259 return; 7260 } 7261 deleteCodeCacheDirsLI(pkg); 7262 } 7263 7264 private void deleteCodeCacheDirsLI(PackageParser.Package pkg) { 7265 // TODO: triage flags as part of 26466827 7266 final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE; 7267 7268 int[] users = sUserManager.getUserIds(); 7269 int res = 0; 7270 for (int user : users) { 7271 // Remove the parent code cache 7272 try { 7273 mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, user, 7274 flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 7275 } catch (InstallerException e) { 7276 Slog.w(TAG, "Failed to delete code cache directory", e); 7277 } 7278 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7279 for (int i = 0; i < childCount; i++) { 7280 PackageParser.Package childPkg = pkg.childPackages.get(i); 7281 // Remove the child code cache 7282 try { 7283 mInstaller.clearAppData(childPkg.volumeUuid, childPkg.packageName, 7284 user, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 7285 } catch (InstallerException e) { 7286 Slog.w(TAG, "Failed to delete code cache directory", e); 7287 } 7288 } 7289 } 7290 } 7291 7292 private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime, 7293 long lastUpdateTime) { 7294 // Set parent install/update time 7295 PackageSetting ps = (PackageSetting) pkg.mExtras; 7296 if (ps != null) { 7297 ps.firstInstallTime = firstInstallTime; 7298 ps.lastUpdateTime = lastUpdateTime; 7299 } 7300 // Set children install/update time 7301 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7302 for (int i = 0; i < childCount; i++) { 7303 PackageParser.Package childPkg = pkg.childPackages.get(i); 7304 ps = (PackageSetting) childPkg.mExtras; 7305 if (ps != null) { 7306 ps.firstInstallTime = firstInstallTime; 7307 ps.lastUpdateTime = lastUpdateTime; 7308 } 7309 } 7310 } 7311 7312 private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file, 7313 PackageParser.Package changingLib) { 7314 if (file.path != null) { 7315 usesLibraryFiles.add(file.path); 7316 return; 7317 } 7318 PackageParser.Package p = mPackages.get(file.apk); 7319 if (changingLib != null && changingLib.packageName.equals(file.apk)) { 7320 // If we are doing this while in the middle of updating a library apk, 7321 // then we need to make sure to use that new apk for determining the 7322 // dependencies here. (We haven't yet finished committing the new apk 7323 // to the package manager state.) 7324 if (p == null || p.packageName.equals(changingLib.packageName)) { 7325 p = changingLib; 7326 } 7327 } 7328 if (p != null) { 7329 usesLibraryFiles.addAll(p.getAllCodePaths()); 7330 } 7331 } 7332 7333 private void updateSharedLibrariesLPw(PackageParser.Package pkg, 7334 PackageParser.Package changingLib) throws PackageManagerException { 7335 if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) { 7336 final ArraySet<String> usesLibraryFiles = new ArraySet<>(); 7337 int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0; 7338 for (int i=0; i<N; i++) { 7339 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i)); 7340 if (file == null) { 7341 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, 7342 "Package " + pkg.packageName + " requires unavailable shared library " 7343 + pkg.usesLibraries.get(i) + "; failing!"); 7344 } 7345 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 7346 } 7347 N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0; 7348 for (int i=0; i<N; i++) { 7349 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i)); 7350 if (file == null) { 7351 Slog.w(TAG, "Package " + pkg.packageName 7352 + " desires unavailable shared library " 7353 + pkg.usesOptionalLibraries.get(i) + "; ignoring!"); 7354 } else { 7355 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 7356 } 7357 } 7358 N = usesLibraryFiles.size(); 7359 if (N > 0) { 7360 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]); 7361 } else { 7362 pkg.usesLibraryFiles = null; 7363 } 7364 } 7365 } 7366 7367 private static boolean hasString(List<String> list, List<String> which) { 7368 if (list == null) { 7369 return false; 7370 } 7371 for (int i=list.size()-1; i>=0; i--) { 7372 for (int j=which.size()-1; j>=0; j--) { 7373 if (which.get(j).equals(list.get(i))) { 7374 return true; 7375 } 7376 } 7377 } 7378 return false; 7379 } 7380 7381 private void updateAllSharedLibrariesLPw() { 7382 for (PackageParser.Package pkg : mPackages.values()) { 7383 try { 7384 updateSharedLibrariesLPw(pkg, null); 7385 } catch (PackageManagerException e) { 7386 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 7387 } 7388 } 7389 } 7390 7391 private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw( 7392 PackageParser.Package changingPkg) { 7393 ArrayList<PackageParser.Package> res = null; 7394 for (PackageParser.Package pkg : mPackages.values()) { 7395 if (hasString(pkg.usesLibraries, changingPkg.libraryNames) 7396 || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) { 7397 if (res == null) { 7398 res = new ArrayList<PackageParser.Package>(); 7399 } 7400 res.add(pkg); 7401 try { 7402 updateSharedLibrariesLPw(pkg, changingPkg); 7403 } catch (PackageManagerException e) { 7404 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 7405 } 7406 } 7407 } 7408 return res; 7409 } 7410 7411 /** 7412 * Derive the value of the {@code cpuAbiOverride} based on the provided 7413 * value and an optional stored value from the package settings. 7414 */ 7415 private static String deriveAbiOverride(String abiOverride, PackageSetting settings) { 7416 String cpuAbiOverride = null; 7417 7418 if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) { 7419 cpuAbiOverride = null; 7420 } else if (abiOverride != null) { 7421 cpuAbiOverride = abiOverride; 7422 } else if (settings != null) { 7423 cpuAbiOverride = settings.cpuAbiOverrideString; 7424 } 7425 7426 return cpuAbiOverride; 7427 } 7428 7429 private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg, int parseFlags, 7430 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 7431 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage"); 7432 // If the package has children and this is the first dive in the function 7433 // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see 7434 // whether all packages (parent and children) would be successfully scanned 7435 // before the actual scan since scanning mutates internal state and we want 7436 // to atomically install the package and its children. 7437 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 7438 if (pkg.childPackages != null && pkg.childPackages.size() > 0) { 7439 scanFlags |= SCAN_CHECK_ONLY; 7440 } 7441 } else { 7442 scanFlags &= ~SCAN_CHECK_ONLY; 7443 } 7444 7445 final PackageParser.Package scannedPkg; 7446 try { 7447 // Scan the parent 7448 scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags, currentTime, user); 7449 // Scan the children 7450 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7451 for (int i = 0; i < childCount; i++) { 7452 PackageParser.Package childPkg = pkg.childPackages.get(i); 7453 scanPackageLI(childPkg, parseFlags, 7454 scanFlags, currentTime, user); 7455 } 7456 } finally { 7457 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7458 } 7459 7460 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 7461 return scanPackageTracedLI(pkg, parseFlags, scanFlags, currentTime, user); 7462 } 7463 7464 return scannedPkg; 7465 } 7466 7467 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags, 7468 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 7469 boolean success = false; 7470 try { 7471 final PackageParser.Package res = scanPackageDirtyLI(pkg, parseFlags, scanFlags, 7472 currentTime, user); 7473 success = true; 7474 return res; 7475 } finally { 7476 if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) { 7477 removeDataDirsLI(pkg.volumeUuid, pkg.packageName); 7478 } 7479 } 7480 } 7481 7482 private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags, 7483 int scanFlags, long currentTime, UserHandle user) 7484 throws PackageManagerException { 7485 final File scanFile = new File(pkg.codePath); 7486 if (pkg.applicationInfo.getCodePath() == null || 7487 pkg.applicationInfo.getResourcePath() == null) { 7488 // Bail out. The resource and code paths haven't been set. 7489 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 7490 "Code and resource paths haven't been set correctly"); 7491 } 7492 7493 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 7494 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; 7495 } else { 7496 // Only allow system apps to be flagged as core apps. 7497 pkg.coreApp = false; 7498 } 7499 7500 if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) { 7501 pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 7502 } 7503 7504 if (mCustomResolverComponentName != null && 7505 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) { 7506 setUpCustomResolverActivity(pkg); 7507 } 7508 7509 if (pkg.packageName.equals("android")) { 7510 synchronized (mPackages) { 7511 if (mAndroidApplication != null) { 7512 Slog.w(TAG, "*************************************************"); 7513 Slog.w(TAG, "Core android package being redefined. Skipping."); 7514 Slog.w(TAG, " file=" + scanFile); 7515 Slog.w(TAG, "*************************************************"); 7516 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 7517 "Core android package being redefined. Skipping."); 7518 } 7519 7520 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 7521 // Set up information for our fall-back user intent resolution activity. 7522 mPlatformPackage = pkg; 7523 pkg.mVersionCode = mSdkVersion; 7524 mAndroidApplication = pkg.applicationInfo; 7525 7526 if (!mResolverReplaced) { 7527 mResolveActivity.applicationInfo = mAndroidApplication; 7528 mResolveActivity.name = ResolverActivity.class.getName(); 7529 mResolveActivity.packageName = mAndroidApplication.packageName; 7530 mResolveActivity.processName = "system:ui"; 7531 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 7532 mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER; 7533 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS; 7534 mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert; 7535 mResolveActivity.exported = true; 7536 mResolveActivity.enabled = true; 7537 mResolveInfo.activityInfo = mResolveActivity; 7538 mResolveInfo.priority = 0; 7539 mResolveInfo.preferredOrder = 0; 7540 mResolveInfo.match = 0; 7541 mResolveComponentName = new ComponentName( 7542 mAndroidApplication.packageName, mResolveActivity.name); 7543 } 7544 } 7545 } 7546 } 7547 7548 if (DEBUG_PACKAGE_SCANNING) { 7549 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 7550 Log.d(TAG, "Scanning package " + pkg.packageName); 7551 } 7552 7553 synchronized (mPackages) { 7554 if (mPackages.containsKey(pkg.packageName) 7555 || mSharedLibraries.containsKey(pkg.packageName)) { 7556 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 7557 "Application package " + pkg.packageName 7558 + " already installed. Skipping duplicate."); 7559 } 7560 7561 // If we're only installing presumed-existing packages, require that the 7562 // scanned APK is both already known and at the path previously established 7563 // for it. Previously unknown packages we pick up normally, but if we have an 7564 // a priori expectation about this package's install presence, enforce it. 7565 // With a singular exception for new system packages. When an OTA contains 7566 // a new system package, we allow the codepath to change from a system location 7567 // to the user-installed location. If we don't allow this change, any newer, 7568 // user-installed version of the application will be ignored. 7569 if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) { 7570 if (mExpectingBetter.containsKey(pkg.packageName)) { 7571 logCriticalInfo(Log.WARN, 7572 "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName); 7573 } else { 7574 PackageSetting known = mSettings.peekPackageLPr(pkg.packageName); 7575 if (known != null) { 7576 if (DEBUG_PACKAGE_SCANNING) { 7577 Log.d(TAG, "Examining " + pkg.codePath 7578 + " and requiring known paths " + known.codePathString 7579 + " & " + known.resourcePathString); 7580 } 7581 if (!pkg.applicationInfo.getCodePath().equals(known.codePathString) 7582 || !pkg.applicationInfo.getResourcePath().equals( 7583 known.resourcePathString)) { 7584 throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED, 7585 "Application package " + pkg.packageName 7586 + " found at " + pkg.applicationInfo.getCodePath() 7587 + " but expected at " + known.codePathString 7588 + "; ignoring."); 7589 } 7590 } 7591 } 7592 } 7593 } 7594 7595 // Initialize package source and resource directories 7596 File destCodeFile = new File(pkg.applicationInfo.getCodePath()); 7597 File destResourceFile = new File(pkg.applicationInfo.getResourcePath()); 7598 7599 SharedUserSetting suid = null; 7600 PackageSetting pkgSetting = null; 7601 7602 if (!isSystemApp(pkg)) { 7603 // Only system apps can use these features. 7604 pkg.mOriginalPackages = null; 7605 pkg.mRealPackage = null; 7606 pkg.mAdoptPermissions = null; 7607 } 7608 7609 // Getting the package setting may have a side-effect, so if we 7610 // are only checking if scan would succeed, stash a copy of the 7611 // old setting to restore at the end. 7612 PackageSetting nonMutatedPs = null; 7613 7614 // writer 7615 synchronized (mPackages) { 7616 if (pkg.mSharedUserId != null) { 7617 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, true); 7618 if (suid == null) { 7619 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 7620 "Creating application package " + pkg.packageName 7621 + " for shared user failed"); 7622 } 7623 if (DEBUG_PACKAGE_SCANNING) { 7624 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 7625 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId 7626 + "): packages=" + suid.packages); 7627 } 7628 } 7629 7630 // Check if we are renaming from an original package name. 7631 PackageSetting origPackage = null; 7632 String realName = null; 7633 if (pkg.mOriginalPackages != null) { 7634 // This package may need to be renamed to a previously 7635 // installed name. Let's check on that... 7636 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage); 7637 if (pkg.mOriginalPackages.contains(renamed)) { 7638 // This package had originally been installed as the 7639 // original name, and we have already taken care of 7640 // transitioning to the new one. Just update the new 7641 // one to continue using the old name. 7642 realName = pkg.mRealPackage; 7643 if (!pkg.packageName.equals(renamed)) { 7644 // Callers into this function may have already taken 7645 // care of renaming the package; only do it here if 7646 // it is not already done. 7647 pkg.setPackageName(renamed); 7648 } 7649 7650 } else { 7651 for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) { 7652 if ((origPackage = mSettings.peekPackageLPr( 7653 pkg.mOriginalPackages.get(i))) != null) { 7654 // We do have the package already installed under its 7655 // original name... should we use it? 7656 if (!verifyPackageUpdateLPr(origPackage, pkg)) { 7657 // New package is not compatible with original. 7658 origPackage = null; 7659 continue; 7660 } else if (origPackage.sharedUser != null) { 7661 // Make sure uid is compatible between packages. 7662 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) { 7663 Slog.w(TAG, "Unable to migrate data from " + origPackage.name 7664 + " to " + pkg.packageName + ": old uid " 7665 + origPackage.sharedUser.name 7666 + " differs from " + pkg.mSharedUserId); 7667 origPackage = null; 7668 continue; 7669 } 7670 } else { 7671 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package " 7672 + pkg.packageName + " to old name " + origPackage.name); 7673 } 7674 break; 7675 } 7676 } 7677 } 7678 } 7679 7680 if (mTransferedPackages.contains(pkg.packageName)) { 7681 Slog.w(TAG, "Package " + pkg.packageName 7682 + " was transferred to another, but its .apk remains"); 7683 } 7684 7685 // See comments in nonMutatedPs declaration 7686 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 7687 PackageSetting foundPs = mSettings.peekPackageLPr(pkg.packageName); 7688 if (foundPs != null) { 7689 nonMutatedPs = new PackageSetting(foundPs); 7690 } 7691 } 7692 7693 // Just create the setting, don't add it yet. For already existing packages 7694 // the PkgSetting exists already and doesn't have to be created. 7695 pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile, 7696 destResourceFile, pkg.applicationInfo.nativeLibraryRootDir, 7697 pkg.applicationInfo.primaryCpuAbi, 7698 pkg.applicationInfo.secondaryCpuAbi, 7699 pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, 7700 user, false); 7701 if (pkgSetting == null) { 7702 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 7703 "Creating application package " + pkg.packageName + " failed"); 7704 } 7705 7706 if (pkgSetting.origPackage != null) { 7707 // If we are first transitioning from an original package, 7708 // fix up the new package's name now. We need to do this after 7709 // looking up the package under its new name, so getPackageLP 7710 // can take care of fiddling things correctly. 7711 pkg.setPackageName(origPackage.name); 7712 7713 // File a report about this. 7714 String msg = "New package " + pkgSetting.realName 7715 + " renamed to replace old package " + pkgSetting.name; 7716 reportSettingsProblem(Log.WARN, msg); 7717 7718 // Make a note of it. 7719 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 7720 mTransferedPackages.add(origPackage.name); 7721 } 7722 7723 // No longer need to retain this. 7724 pkgSetting.origPackage = null; 7725 } 7726 7727 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) { 7728 // Make a note of it. 7729 mTransferedPackages.add(pkg.packageName); 7730 } 7731 7732 if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) { 7733 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 7734 } 7735 7736 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 7737 // Check all shared libraries and map to their actual file path. 7738 // We only do this here for apps not on a system dir, because those 7739 // are the only ones that can fail an install due to this. We 7740 // will take care of the system apps by updating all of their 7741 // library paths after the scan is done. 7742 updateSharedLibrariesLPw(pkg, null); 7743 } 7744 7745 if (mFoundPolicyFile) { 7746 SELinuxMMAC.assignSeinfoValue(pkg); 7747 } 7748 7749 pkg.applicationInfo.uid = pkgSetting.appId; 7750 pkg.mExtras = pkgSetting; 7751 if (shouldCheckUpgradeKeySetLP(pkgSetting, scanFlags)) { 7752 if (checkUpgradeKeySetLP(pkgSetting, pkg)) { 7753 // We just determined the app is signed correctly, so bring 7754 // over the latest parsed certs. 7755 pkgSetting.signatures.mSignatures = pkg.mSignatures; 7756 } else { 7757 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 7758 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 7759 "Package " + pkg.packageName + " upgrade keys do not match the " 7760 + "previously installed version"); 7761 } else { 7762 pkgSetting.signatures.mSignatures = pkg.mSignatures; 7763 String msg = "System package " + pkg.packageName 7764 + " signature changed; retaining data."; 7765 reportSettingsProblem(Log.WARN, msg); 7766 } 7767 } 7768 } else { 7769 try { 7770 verifySignaturesLP(pkgSetting, pkg); 7771 // We just determined the app is signed correctly, so bring 7772 // over the latest parsed certs. 7773 pkgSetting.signatures.mSignatures = pkg.mSignatures; 7774 } catch (PackageManagerException e) { 7775 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 7776 throw e; 7777 } 7778 // The signature has changed, but this package is in the system 7779 // image... let's recover! 7780 pkgSetting.signatures.mSignatures = pkg.mSignatures; 7781 // However... if this package is part of a shared user, but it 7782 // doesn't match the signature of the shared user, let's fail. 7783 // What this means is that you can't change the signatures 7784 // associated with an overall shared user, which doesn't seem all 7785 // that unreasonable. 7786 if (pkgSetting.sharedUser != null) { 7787 if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 7788 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { 7789 throw new PackageManagerException( 7790 INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES, 7791 "Signature mismatch for shared user: " 7792 + pkgSetting.sharedUser); 7793 } 7794 } 7795 // File a report about this. 7796 String msg = "System package " + pkg.packageName 7797 + " signature changed; retaining data."; 7798 reportSettingsProblem(Log.WARN, msg); 7799 } 7800 } 7801 // Verify that this new package doesn't have any content providers 7802 // that conflict with existing packages. Only do this if the 7803 // package isn't already installed, since we don't want to break 7804 // things that are installed. 7805 if ((scanFlags & SCAN_NEW_INSTALL) != 0) { 7806 final int N = pkg.providers.size(); 7807 int i; 7808 for (i=0; i<N; i++) { 7809 PackageParser.Provider p = pkg.providers.get(i); 7810 if (p.info.authority != null) { 7811 String names[] = p.info.authority.split(";"); 7812 for (int j = 0; j < names.length; j++) { 7813 if (mProvidersByAuthority.containsKey(names[j])) { 7814 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 7815 final String otherPackageName = 7816 ((other != null && other.getComponentName() != null) ? 7817 other.getComponentName().getPackageName() : "?"); 7818 throw new PackageManagerException( 7819 INSTALL_FAILED_CONFLICTING_PROVIDER, 7820 "Can't install because provider name " + names[j] 7821 + " (in package " + pkg.applicationInfo.packageName 7822 + ") is already used by " + otherPackageName); 7823 } 7824 } 7825 } 7826 } 7827 } 7828 7829 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) { 7830 // This package wants to adopt ownership of permissions from 7831 // another package. 7832 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) { 7833 final String origName = pkg.mAdoptPermissions.get(i); 7834 final PackageSetting orig = mSettings.peekPackageLPr(origName); 7835 if (orig != null) { 7836 if (verifyPackageUpdateLPr(orig, pkg)) { 7837 Slog.i(TAG, "Adopting permissions from " + origName + " to " 7838 + pkg.packageName); 7839 mSettings.transferPermissionsLPw(origName, pkg.packageName); 7840 } 7841 } 7842 } 7843 } 7844 } 7845 7846 final String pkgName = pkg.packageName; 7847 7848 final long scanFileTime = scanFile.lastModified(); 7849 final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0; 7850 pkg.applicationInfo.processName = fixProcessName( 7851 pkg.applicationInfo.packageName, 7852 pkg.applicationInfo.processName, 7853 pkg.applicationInfo.uid); 7854 7855 if (pkg != mPlatformPackage) { 7856 // Get all of our default paths setup 7857 pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM); 7858 } 7859 7860 final String path = scanFile.getPath(); 7861 final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting); 7862 7863 if ((scanFlags & SCAN_NEW_INSTALL) == 0) { 7864 derivePackageAbi(pkg, scanFile, cpuAbiOverride, true /* extract libs */); 7865 7866 // Some system apps still use directory structure for native libraries 7867 // in which case we might end up not detecting abi solely based on apk 7868 // structure. Try to detect abi based on directory structure. 7869 if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() && 7870 pkg.applicationInfo.primaryCpuAbi == null) { 7871 setBundledAppAbisAndRoots(pkg, pkgSetting); 7872 setNativeLibraryPaths(pkg); 7873 } 7874 7875 } else { 7876 if ((scanFlags & SCAN_MOVE) != 0) { 7877 // We haven't run dex-opt for this move (since we've moved the compiled output too) 7878 // but we already have this packages package info in the PackageSetting. We just 7879 // use that and derive the native library path based on the new codepath. 7880 pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString; 7881 pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString; 7882 } 7883 7884 // Set native library paths again. For moves, the path will be updated based on the 7885 // ABIs we've determined above. For non-moves, the path will be updated based on the 7886 // ABIs we determined during compilation, but the path will depend on the final 7887 // package path (after the rename away from the stage path). 7888 setNativeLibraryPaths(pkg); 7889 } 7890 7891 // This is a special case for the "system" package, where the ABI is 7892 // dictated by the zygote configuration (and init.rc). We should keep track 7893 // of this ABI so that we can deal with "normal" applications that run under 7894 // the same UID correctly. 7895 if (mPlatformPackage == pkg) { 7896 pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ? 7897 Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]; 7898 } 7899 7900 // If there's a mismatch between the abi-override in the package setting 7901 // and the abiOverride specified for the install. Warn about this because we 7902 // would've already compiled the app without taking the package setting into 7903 // account. 7904 if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) { 7905 if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) { 7906 Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride + 7907 " for package " + pkg.packageName); 7908 } 7909 } 7910 7911 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 7912 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 7913 pkgSetting.cpuAbiOverrideString = cpuAbiOverride; 7914 7915 // Copy the derived override back to the parsed package, so that we can 7916 // update the package settings accordingly. 7917 pkg.cpuAbiOverride = cpuAbiOverride; 7918 7919 if (DEBUG_ABI_SELECTION) { 7920 Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName 7921 + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa=" 7922 + pkg.applicationInfo.nativeLibraryRootRequiresIsa); 7923 } 7924 7925 // Push the derived path down into PackageSettings so we know what to 7926 // clean up at uninstall time. 7927 pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir; 7928 7929 if (DEBUG_ABI_SELECTION) { 7930 Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" + 7931 " primary=" + pkg.applicationInfo.primaryCpuAbi + 7932 " secondary=" + pkg.applicationInfo.secondaryCpuAbi); 7933 } 7934 7935 if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) { 7936 // We don't do this here during boot because we can do it all 7937 // at once after scanning all existing packages. 7938 // 7939 // We also do this *before* we perform dexopt on this package, so that 7940 // we can avoid redundant dexopts, and also to make sure we've got the 7941 // code and package path correct. 7942 adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, 7943 pkg, true /* boot complete */); 7944 } 7945 7946 if (mFactoryTest && pkg.requestedPermissions.contains( 7947 android.Manifest.permission.FACTORY_TEST)) { 7948 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST; 7949 } 7950 7951 ArrayList<PackageParser.Package> clientLibPkgs = null; 7952 7953 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 7954 if (nonMutatedPs != null) { 7955 synchronized (mPackages) { 7956 mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs); 7957 } 7958 } 7959 return pkg; 7960 } 7961 7962 // Only privileged apps and updated privileged apps can add child packages. 7963 if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) { 7964 if ((parseFlags & PARSE_IS_PRIVILEGED) == 0) { 7965 throw new PackageManagerException("Only privileged apps and updated " 7966 + "privileged apps can add child packages. Ignoring package " 7967 + pkg.packageName); 7968 } 7969 final int childCount = pkg.childPackages.size(); 7970 for (int i = 0; i < childCount; i++) { 7971 PackageParser.Package childPkg = pkg.childPackages.get(i); 7972 if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName, 7973 childPkg.packageName)) { 7974 throw new PackageManagerException("Cannot override a child package of " 7975 + "another disabled system app. Ignoring package " + pkg.packageName); 7976 } 7977 } 7978 } 7979 7980 // writer 7981 synchronized (mPackages) { 7982 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7983 // Only system apps can add new shared libraries. 7984 if (pkg.libraryNames != null) { 7985 for (int i=0; i<pkg.libraryNames.size(); i++) { 7986 String name = pkg.libraryNames.get(i); 7987 boolean allowed = false; 7988 if (pkg.isUpdatedSystemApp()) { 7989 // New library entries can only be added through the 7990 // system image. This is important to get rid of a lot 7991 // of nasty edge cases: for example if we allowed a non- 7992 // system update of the app to add a library, then uninstalling 7993 // the update would make the library go away, and assumptions 7994 // we made such as through app install filtering would now 7995 // have allowed apps on the device which aren't compatible 7996 // with it. Better to just have the restriction here, be 7997 // conservative, and create many fewer cases that can negatively 7998 // impact the user experience. 7999 final PackageSetting sysPs = mSettings 8000 .getDisabledSystemPkgLPr(pkg.packageName); 8001 if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) { 8002 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) { 8003 if (name.equals(sysPs.pkg.libraryNames.get(j))) { 8004 allowed = true; 8005 break; 8006 } 8007 } 8008 } 8009 } else { 8010 allowed = true; 8011 } 8012 if (allowed) { 8013 if (!mSharedLibraries.containsKey(name)) { 8014 mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName)); 8015 } else if (!name.equals(pkg.packageName)) { 8016 Slog.w(TAG, "Package " + pkg.packageName + " library " 8017 + name + " already exists; skipping"); 8018 } 8019 } else { 8020 Slog.w(TAG, "Package " + pkg.packageName + " declares lib " 8021 + name + " that is not declared on system image; skipping"); 8022 } 8023 } 8024 if ((scanFlags & SCAN_BOOTING) == 0) { 8025 // If we are not booting, we need to update any applications 8026 // that are clients of our shared library. If we are booting, 8027 // this will all be done once the scan is complete. 8028 clientLibPkgs = updateAllSharedLibrariesLPw(pkg); 8029 } 8030 } 8031 } 8032 } 8033 8034 // Request the ActivityManager to kill the process(only for existing packages) 8035 // so that we do not end up in a confused state while the user is still using the older 8036 // version of the application while the new one gets installed. 8037 final boolean isReplacing = (scanFlags & SCAN_REPLACING) != 0; 8038 final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0; 8039 if (killApp) { 8040 if (isReplacing) { 8041 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "killApplication"); 8042 8043 killApplication(pkg.applicationInfo.packageName, 8044 pkg.applicationInfo.uid, "replace pkg"); 8045 8046 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 8047 } 8048 } 8049 8050 // Also need to kill any apps that are dependent on the library. 8051 if (clientLibPkgs != null) { 8052 for (int i=0; i<clientLibPkgs.size(); i++) { 8053 PackageParser.Package clientPkg = clientLibPkgs.get(i); 8054 killApplication(clientPkg.applicationInfo.packageName, 8055 clientPkg.applicationInfo.uid, "update lib"); 8056 } 8057 } 8058 8059 // Make sure we're not adding any bogus keyset info 8060 KeySetManagerService ksms = mSettings.mKeySetManagerService; 8061 ksms.assertScannedPackageValid(pkg); 8062 8063 // writer 8064 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 8065 8066 boolean createIdmapFailed = false; 8067 synchronized (mPackages) { 8068 // We don't expect installation to fail beyond this point 8069 8070 // Add the new setting to mSettings 8071 mSettings.insertPackageSettingLPw(pkgSetting, pkg); 8072 // Add the new setting to mPackages 8073 mPackages.put(pkg.applicationInfo.packageName, pkg); 8074 // Make sure we don't accidentally delete its data. 8075 final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator(); 8076 while (iter.hasNext()) { 8077 PackageCleanItem item = iter.next(); 8078 if (pkgName.equals(item.packageName)) { 8079 iter.remove(); 8080 } 8081 } 8082 8083 // Take care of first install / last update times. 8084 if (currentTime != 0) { 8085 if (pkgSetting.firstInstallTime == 0) { 8086 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime; 8087 } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) { 8088 pkgSetting.lastUpdateTime = currentTime; 8089 } 8090 } else if (pkgSetting.firstInstallTime == 0) { 8091 // We need *something*. Take time time stamp of the file. 8092 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime; 8093 } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) { 8094 if (scanFileTime != pkgSetting.timeStamp) { 8095 // A package on the system image has changed; consider this 8096 // to be an update. 8097 pkgSetting.lastUpdateTime = scanFileTime; 8098 } 8099 } 8100 8101 // Add the package's KeySets to the global KeySetManagerService 8102 ksms.addScannedPackageLPw(pkg); 8103 8104 int N = pkg.providers.size(); 8105 StringBuilder r = null; 8106 int i; 8107 for (i=0; i<N; i++) { 8108 PackageParser.Provider p = pkg.providers.get(i); 8109 p.info.processName = fixProcessName(pkg.applicationInfo.processName, 8110 p.info.processName, pkg.applicationInfo.uid); 8111 mProviders.addProvider(p); 8112 p.syncable = p.info.isSyncable; 8113 if (p.info.authority != null) { 8114 String names[] = p.info.authority.split(";"); 8115 p.info.authority = null; 8116 for (int j = 0; j < names.length; j++) { 8117 if (j == 1 && p.syncable) { 8118 // We only want the first authority for a provider to possibly be 8119 // syncable, so if we already added this provider using a different 8120 // authority clear the syncable flag. We copy the provider before 8121 // changing it because the mProviders object contains a reference 8122 // to a provider that we don't want to change. 8123 // Only do this for the second authority since the resulting provider 8124 // object can be the same for all future authorities for this provider. 8125 p = new PackageParser.Provider(p); 8126 p.syncable = false; 8127 } 8128 if (!mProvidersByAuthority.containsKey(names[j])) { 8129 mProvidersByAuthority.put(names[j], p); 8130 if (p.info.authority == null) { 8131 p.info.authority = names[j]; 8132 } else { 8133 p.info.authority = p.info.authority + ";" + names[j]; 8134 } 8135 if (DEBUG_PACKAGE_SCANNING) { 8136 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 8137 Log.d(TAG, "Registered content provider: " + names[j] 8138 + ", className = " + p.info.name + ", isSyncable = " 8139 + p.info.isSyncable); 8140 } 8141 } else { 8142 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 8143 Slog.w(TAG, "Skipping provider name " + names[j] + 8144 " (in package " + pkg.applicationInfo.packageName + 8145 "): name already used by " 8146 + ((other != null && other.getComponentName() != null) 8147 ? other.getComponentName().getPackageName() : "?")); 8148 } 8149 } 8150 } 8151 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8152 if (r == null) { 8153 r = new StringBuilder(256); 8154 } else { 8155 r.append(' '); 8156 } 8157 r.append(p.info.name); 8158 } 8159 } 8160 if (r != null) { 8161 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r); 8162 } 8163 8164 N = pkg.services.size(); 8165 r = null; 8166 for (i=0; i<N; i++) { 8167 PackageParser.Service s = pkg.services.get(i); 8168 s.info.processName = fixProcessName(pkg.applicationInfo.processName, 8169 s.info.processName, pkg.applicationInfo.uid); 8170 mServices.addService(s); 8171 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8172 if (r == null) { 8173 r = new StringBuilder(256); 8174 } else { 8175 r.append(' '); 8176 } 8177 r.append(s.info.name); 8178 } 8179 } 8180 if (r != null) { 8181 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r); 8182 } 8183 8184 N = pkg.receivers.size(); 8185 r = null; 8186 for (i=0; i<N; i++) { 8187 PackageParser.Activity a = pkg.receivers.get(i); 8188 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 8189 a.info.processName, pkg.applicationInfo.uid); 8190 mReceivers.addActivity(a, "receiver"); 8191 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8192 if (r == null) { 8193 r = new StringBuilder(256); 8194 } else { 8195 r.append(' '); 8196 } 8197 r.append(a.info.name); 8198 } 8199 } 8200 if (r != null) { 8201 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r); 8202 } 8203 8204 N = pkg.activities.size(); 8205 r = null; 8206 for (i=0; i<N; i++) { 8207 PackageParser.Activity a = pkg.activities.get(i); 8208 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 8209 a.info.processName, pkg.applicationInfo.uid); 8210 mActivities.addActivity(a, "activity"); 8211 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8212 if (r == null) { 8213 r = new StringBuilder(256); 8214 } else { 8215 r.append(' '); 8216 } 8217 r.append(a.info.name); 8218 } 8219 } 8220 if (r != null) { 8221 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r); 8222 } 8223 8224 N = pkg.permissionGroups.size(); 8225 r = null; 8226 for (i=0; i<N; i++) { 8227 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i); 8228 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name); 8229 if (cur == null) { 8230 mPermissionGroups.put(pg.info.name, pg); 8231 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8232 if (r == null) { 8233 r = new StringBuilder(256); 8234 } else { 8235 r.append(' '); 8236 } 8237 r.append(pg.info.name); 8238 } 8239 } else { 8240 Slog.w(TAG, "Permission group " + pg.info.name + " from package " 8241 + pg.info.packageName + " ignored: original from " 8242 + cur.info.packageName); 8243 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8244 if (r == null) { 8245 r = new StringBuilder(256); 8246 } else { 8247 r.append(' '); 8248 } 8249 r.append("DUP:"); 8250 r.append(pg.info.name); 8251 } 8252 } 8253 } 8254 if (r != null) { 8255 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permission Groups: " + r); 8256 } 8257 8258 N = pkg.permissions.size(); 8259 r = null; 8260 for (i=0; i<N; i++) { 8261 PackageParser.Permission p = pkg.permissions.get(i); 8262 8263 // Assume by default that we did not install this permission into the system. 8264 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED; 8265 8266 // Now that permission groups have a special meaning, we ignore permission 8267 // groups for legacy apps to prevent unexpected behavior. In particular, 8268 // permissions for one app being granted to someone just becase they happen 8269 // to be in a group defined by another app (before this had no implications). 8270 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) { 8271 p.group = mPermissionGroups.get(p.info.group); 8272 // Warn for a permission in an unknown group. 8273 if (p.info.group != null && p.group == null) { 8274 Slog.w(TAG, "Permission " + p.info.name + " from package " 8275 + p.info.packageName + " in an unknown group " + p.info.group); 8276 } 8277 } 8278 8279 ArrayMap<String, BasePermission> permissionMap = 8280 p.tree ? mSettings.mPermissionTrees 8281 : mSettings.mPermissions; 8282 BasePermission bp = permissionMap.get(p.info.name); 8283 8284 // Allow system apps to redefine non-system permissions 8285 if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) { 8286 final boolean currentOwnerIsSystem = (bp.perm != null 8287 && isSystemApp(bp.perm.owner)); 8288 if (isSystemApp(p.owner)) { 8289 if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) { 8290 // It's a built-in permission and no owner, take ownership now 8291 bp.packageSetting = pkgSetting; 8292 bp.perm = p; 8293 bp.uid = pkg.applicationInfo.uid; 8294 bp.sourcePackage = p.info.packageName; 8295 p.info.flags |= PermissionInfo.FLAG_INSTALLED; 8296 } else if (!currentOwnerIsSystem) { 8297 String msg = "New decl " + p.owner + " of permission " 8298 + p.info.name + " is system; overriding " + bp.sourcePackage; 8299 reportSettingsProblem(Log.WARN, msg); 8300 bp = null; 8301 } 8302 } 8303 } 8304 8305 if (bp == null) { 8306 bp = new BasePermission(p.info.name, p.info.packageName, 8307 BasePermission.TYPE_NORMAL); 8308 permissionMap.put(p.info.name, bp); 8309 } 8310 8311 if (bp.perm == null) { 8312 if (bp.sourcePackage == null 8313 || bp.sourcePackage.equals(p.info.packageName)) { 8314 BasePermission tree = findPermissionTreeLP(p.info.name); 8315 if (tree == null 8316 || tree.sourcePackage.equals(p.info.packageName)) { 8317 bp.packageSetting = pkgSetting; 8318 bp.perm = p; 8319 bp.uid = pkg.applicationInfo.uid; 8320 bp.sourcePackage = p.info.packageName; 8321 p.info.flags |= PermissionInfo.FLAG_INSTALLED; 8322 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8323 if (r == null) { 8324 r = new StringBuilder(256); 8325 } else { 8326 r.append(' '); 8327 } 8328 r.append(p.info.name); 8329 } 8330 } else { 8331 Slog.w(TAG, "Permission " + p.info.name + " from package " 8332 + p.info.packageName + " ignored: base tree " 8333 + tree.name + " is from package " 8334 + tree.sourcePackage); 8335 } 8336 } else { 8337 Slog.w(TAG, "Permission " + p.info.name + " from package " 8338 + p.info.packageName + " ignored: original from " 8339 + bp.sourcePackage); 8340 } 8341 } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8342 if (r == null) { 8343 r = new StringBuilder(256); 8344 } else { 8345 r.append(' '); 8346 } 8347 r.append("DUP:"); 8348 r.append(p.info.name); 8349 } 8350 if (bp.perm == p) { 8351 bp.protectionLevel = p.info.protectionLevel; 8352 } 8353 } 8354 8355 if (r != null) { 8356 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permissions: " + r); 8357 } 8358 8359 N = pkg.instrumentation.size(); 8360 r = null; 8361 for (i=0; i<N; i++) { 8362 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 8363 a.info.packageName = pkg.applicationInfo.packageName; 8364 a.info.sourceDir = pkg.applicationInfo.sourceDir; 8365 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir; 8366 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs; 8367 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs; 8368 a.info.dataDir = pkg.applicationInfo.dataDir; 8369 a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir; 8370 a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir; 8371 8372 // TODO: Update instrumentation.nativeLibraryDir as well ? Does it 8373 // need other information about the application, like the ABI and what not ? 8374 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir; 8375 mInstrumentation.put(a.getComponentName(), a); 8376 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8377 if (r == null) { 8378 r = new StringBuilder(256); 8379 } else { 8380 r.append(' '); 8381 } 8382 r.append(a.info.name); 8383 } 8384 } 8385 if (r != null) { 8386 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r); 8387 } 8388 8389 if (pkg.protectedBroadcasts != null) { 8390 N = pkg.protectedBroadcasts.size(); 8391 for (i=0; i<N; i++) { 8392 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i)); 8393 } 8394 } 8395 8396 pkgSetting.setTimeStamp(scanFileTime); 8397 8398 // Create idmap files for pairs of (packages, overlay packages). 8399 // Note: "android", ie framework-res.apk, is handled by native layers. 8400 if (pkg.mOverlayTarget != null) { 8401 // This is an overlay package. 8402 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) { 8403 if (!mOverlays.containsKey(pkg.mOverlayTarget)) { 8404 mOverlays.put(pkg.mOverlayTarget, 8405 new ArrayMap<String, PackageParser.Package>()); 8406 } 8407 ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget); 8408 map.put(pkg.packageName, pkg); 8409 PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget); 8410 if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) { 8411 createIdmapFailed = true; 8412 } 8413 } 8414 } else if (mOverlays.containsKey(pkg.packageName) && 8415 !pkg.packageName.equals("android")) { 8416 // This is a regular package, with one or more known overlay packages. 8417 createIdmapsForPackageLI(pkg); 8418 } 8419 } 8420 8421 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 8422 8423 if (createIdmapFailed) { 8424 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 8425 "scanPackageLI failed to createIdmap"); 8426 } 8427 return pkg; 8428 } 8429 8430 /** 8431 * Derive the ABI of a non-system package located at {@code scanFile}. This information 8432 * is derived purely on the basis of the contents of {@code scanFile} and 8433 * {@code cpuAbiOverride}. 8434 * 8435 * If {@code extractLibs} is true, native libraries are extracted from the app if required. 8436 */ 8437 private void derivePackageAbi(PackageParser.Package pkg, File scanFile, 8438 String cpuAbiOverride, boolean extractLibs) 8439 throws PackageManagerException { 8440 // TODO: We can probably be smarter about this stuff. For installed apps, 8441 // we can calculate this information at install time once and for all. For 8442 // system apps, we can probably assume that this information doesn't change 8443 // after the first boot scan. As things stand, we do lots of unnecessary work. 8444 8445 // Give ourselves some initial paths; we'll come back for another 8446 // pass once we've determined ABI below. 8447 setNativeLibraryPaths(pkg); 8448 8449 // We would never need to extract libs for forward-locked and external packages, 8450 // since the container service will do it for us. We shouldn't attempt to 8451 // extract libs from system app when it was not updated. 8452 if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() || 8453 (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) { 8454 extractLibs = false; 8455 } 8456 8457 final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir; 8458 final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa; 8459 8460 NativeLibraryHelper.Handle handle = null; 8461 try { 8462 handle = NativeLibraryHelper.Handle.create(pkg); 8463 // TODO(multiArch): This can be null for apps that didn't go through the 8464 // usual installation process. We can calculate it again, like we 8465 // do during install time. 8466 // 8467 // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally 8468 // unnecessary. 8469 final File nativeLibraryRoot = new File(nativeLibraryRootStr); 8470 8471 // Null out the abis so that they can be recalculated. 8472 pkg.applicationInfo.primaryCpuAbi = null; 8473 pkg.applicationInfo.secondaryCpuAbi = null; 8474 if (isMultiArch(pkg.applicationInfo)) { 8475 // Warn if we've set an abiOverride for multi-lib packages.. 8476 // By definition, we need to copy both 32 and 64 bit libraries for 8477 // such packages. 8478 if (pkg.cpuAbiOverride != null 8479 && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) { 8480 Slog.w(TAG, "Ignoring abiOverride for multi arch application."); 8481 } 8482 8483 int abi32 = PackageManager.NO_NATIVE_LIBRARIES; 8484 int abi64 = PackageManager.NO_NATIVE_LIBRARIES; 8485 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) { 8486 if (extractLibs) { 8487 abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 8488 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS, 8489 useIsaSpecificSubdirs); 8490 } else { 8491 abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS); 8492 } 8493 } 8494 8495 maybeThrowExceptionForMultiArchCopy( 8496 "Error unpackaging 32 bit native libs for multiarch app.", abi32); 8497 8498 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) { 8499 if (extractLibs) { 8500 abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 8501 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS, 8502 useIsaSpecificSubdirs); 8503 } else { 8504 abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS); 8505 } 8506 } 8507 8508 maybeThrowExceptionForMultiArchCopy( 8509 "Error unpackaging 64 bit native libs for multiarch app.", abi64); 8510 8511 if (abi64 >= 0) { 8512 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64]; 8513 } 8514 8515 if (abi32 >= 0) { 8516 final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32]; 8517 if (abi64 >= 0) { 8518 if (cpuAbiOverride == null && pkg.use32bitAbi) { 8519 pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi; 8520 pkg.applicationInfo.primaryCpuAbi = abi; 8521 } else { 8522 pkg.applicationInfo.secondaryCpuAbi = abi; 8523 } 8524 } else { 8525 pkg.applicationInfo.primaryCpuAbi = abi; 8526 } 8527 } 8528 8529 } else { 8530 String[] abiList = (cpuAbiOverride != null) ? 8531 new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS; 8532 8533 // Enable gross and lame hacks for apps that are built with old 8534 // SDK tools. We must scan their APKs for renderscript bitcode and 8535 // not launch them if it's present. Don't bother checking on devices 8536 // that don't have 64 bit support. 8537 boolean needsRenderScriptOverride = false; 8538 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null && 8539 NativeLibraryHelper.hasRenderscriptBitcode(handle)) { 8540 abiList = Build.SUPPORTED_32_BIT_ABIS; 8541 needsRenderScriptOverride = true; 8542 } 8543 8544 final int copyRet; 8545 if (extractLibs) { 8546 copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 8547 nativeLibraryRoot, abiList, useIsaSpecificSubdirs); 8548 } else { 8549 copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList); 8550 } 8551 8552 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { 8553 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, 8554 "Error unpackaging native libs for app, errorCode=" + copyRet); 8555 } 8556 8557 if (copyRet >= 0) { 8558 pkg.applicationInfo.primaryCpuAbi = abiList[copyRet]; 8559 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) { 8560 pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride; 8561 } else if (needsRenderScriptOverride) { 8562 pkg.applicationInfo.primaryCpuAbi = abiList[0]; 8563 } 8564 } 8565 } catch (IOException ioe) { 8566 Slog.e(TAG, "Unable to get canonical file " + ioe.toString()); 8567 } finally { 8568 IoUtils.closeQuietly(handle); 8569 } 8570 8571 // Now that we've calculated the ABIs and determined if it's an internal app, 8572 // we will go ahead and populate the nativeLibraryPath. 8573 setNativeLibraryPaths(pkg); 8574 } 8575 8576 /** 8577 * Adjusts ABIs for a set of packages belonging to a shared user so that they all match. 8578 * i.e, so that all packages can be run inside a single process if required. 8579 * 8580 * Optionally, callers can pass in a parsed package via {@code newPackage} in which case 8581 * this function will either try and make the ABI for all packages in {@code packagesForUser} 8582 * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match 8583 * the ABI selected for {@code packagesForUser}. This variant is used when installing or 8584 * updating a package that belongs to a shared user. 8585 * 8586 * NOTE: We currently only match for the primary CPU abi string. Matching the secondary 8587 * adds unnecessary complexity. 8588 */ 8589 private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser, 8590 PackageParser.Package scannedPackage, boolean bootComplete) { 8591 String requiredInstructionSet = null; 8592 if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) { 8593 requiredInstructionSet = VMRuntime.getInstructionSet( 8594 scannedPackage.applicationInfo.primaryCpuAbi); 8595 } 8596 8597 PackageSetting requirer = null; 8598 for (PackageSetting ps : packagesForUser) { 8599 // If packagesForUser contains scannedPackage, we skip it. This will happen 8600 // when scannedPackage is an update of an existing package. Without this check, 8601 // we will never be able to change the ABI of any package belonging to a shared 8602 // user, even if it's compatible with other packages. 8603 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 8604 if (ps.primaryCpuAbiString == null) { 8605 continue; 8606 } 8607 8608 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString); 8609 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) { 8610 // We have a mismatch between instruction sets (say arm vs arm64) warn about 8611 // this but there's not much we can do. 8612 String errorMessage = "Instruction set mismatch, " 8613 + ((requirer == null) ? "[caller]" : requirer) 8614 + " requires " + requiredInstructionSet + " whereas " + ps 8615 + " requires " + instructionSet; 8616 Slog.w(TAG, errorMessage); 8617 } 8618 8619 if (requiredInstructionSet == null) { 8620 requiredInstructionSet = instructionSet; 8621 requirer = ps; 8622 } 8623 } 8624 } 8625 8626 if (requiredInstructionSet != null) { 8627 String adjustedAbi; 8628 if (requirer != null) { 8629 // requirer != null implies that either scannedPackage was null or that scannedPackage 8630 // did not require an ABI, in which case we have to adjust scannedPackage to match 8631 // the ABI of the set (which is the same as requirer's ABI) 8632 adjustedAbi = requirer.primaryCpuAbiString; 8633 if (scannedPackage != null) { 8634 scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi; 8635 } 8636 } else { 8637 // requirer == null implies that we're updating all ABIs in the set to 8638 // match scannedPackage. 8639 adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi; 8640 } 8641 8642 for (PackageSetting ps : packagesForUser) { 8643 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 8644 if (ps.primaryCpuAbiString != null) { 8645 continue; 8646 } 8647 8648 ps.primaryCpuAbiString = adjustedAbi; 8649 if (ps.pkg != null && ps.pkg.applicationInfo != null && 8650 !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) { 8651 ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi; 8652 Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi 8653 + " (requirer=" 8654 + (requirer == null ? "null" : requirer.pkg.packageName) 8655 + ", scannedPackage=" 8656 + (scannedPackage != null ? scannedPackage.packageName : "null") 8657 + ")"); 8658 try { 8659 mInstaller.rmdex(ps.codePathString, 8660 getDexCodeInstructionSet(getPreferredInstructionSet())); 8661 } catch (InstallerException ignored) { 8662 } 8663 } 8664 } 8665 } 8666 } 8667 } 8668 8669 private void setUpCustomResolverActivity(PackageParser.Package pkg) { 8670 synchronized (mPackages) { 8671 mResolverReplaced = true; 8672 // Set up information for custom user intent resolution activity. 8673 mResolveActivity.applicationInfo = pkg.applicationInfo; 8674 mResolveActivity.name = mCustomResolverComponentName.getClassName(); 8675 mResolveActivity.packageName = pkg.applicationInfo.packageName; 8676 mResolveActivity.processName = pkg.applicationInfo.packageName; 8677 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 8678 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS | 8679 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 8680 mResolveActivity.theme = 0; 8681 mResolveActivity.exported = true; 8682 mResolveActivity.enabled = true; 8683 mResolveInfo.activityInfo = mResolveActivity; 8684 mResolveInfo.priority = 0; 8685 mResolveInfo.preferredOrder = 0; 8686 mResolveInfo.match = 0; 8687 mResolveComponentName = mCustomResolverComponentName; 8688 Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " + 8689 mResolveComponentName); 8690 } 8691 } 8692 8693 private void setUpEphemeralInstallerActivityLP(ComponentName installerComponent) { 8694 final PackageParser.Package pkg = mPackages.get(installerComponent.getPackageName()); 8695 8696 // Set up information for ephemeral installer activity 8697 mEphemeralInstallerActivity.applicationInfo = pkg.applicationInfo; 8698 mEphemeralInstallerActivity.name = mEphemeralInstallerComponent.getClassName(); 8699 mEphemeralInstallerActivity.packageName = pkg.applicationInfo.packageName; 8700 mEphemeralInstallerActivity.processName = pkg.applicationInfo.packageName; 8701 mEphemeralInstallerActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 8702 mEphemeralInstallerActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS | 8703 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 8704 mEphemeralInstallerActivity.theme = 0; 8705 mEphemeralInstallerActivity.exported = true; 8706 mEphemeralInstallerActivity.enabled = true; 8707 mEphemeralInstallerInfo.activityInfo = mEphemeralInstallerActivity; 8708 mEphemeralInstallerInfo.priority = 0; 8709 mEphemeralInstallerInfo.preferredOrder = 0; 8710 mEphemeralInstallerInfo.match = 0; 8711 8712 if (DEBUG_EPHEMERAL) { 8713 Slog.d(TAG, "Set ephemeral installer activity: " + mEphemeralInstallerComponent); 8714 } 8715 } 8716 8717 private static String calculateBundledApkRoot(final String codePathString) { 8718 final File codePath = new File(codePathString); 8719 final File codeRoot; 8720 if (FileUtils.contains(Environment.getRootDirectory(), codePath)) { 8721 codeRoot = Environment.getRootDirectory(); 8722 } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) { 8723 codeRoot = Environment.getOemDirectory(); 8724 } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) { 8725 codeRoot = Environment.getVendorDirectory(); 8726 } else { 8727 // Unrecognized code path; take its top real segment as the apk root: 8728 // e.g. /something/app/blah.apk => /something 8729 try { 8730 File f = codePath.getCanonicalFile(); 8731 File parent = f.getParentFile(); // non-null because codePath is a file 8732 File tmp; 8733 while ((tmp = parent.getParentFile()) != null) { 8734 f = parent; 8735 parent = tmp; 8736 } 8737 codeRoot = f; 8738 Slog.w(TAG, "Unrecognized code path " 8739 + codePath + " - using " + codeRoot); 8740 } catch (IOException e) { 8741 // Can't canonicalize the code path -- shenanigans? 8742 Slog.w(TAG, "Can't canonicalize code path " + codePath); 8743 return Environment.getRootDirectory().getPath(); 8744 } 8745 } 8746 return codeRoot.getPath(); 8747 } 8748 8749 /** 8750 * Derive and set the location of native libraries for the given package, 8751 * which varies depending on where and how the package was installed. 8752 */ 8753 private void setNativeLibraryPaths(PackageParser.Package pkg) { 8754 final ApplicationInfo info = pkg.applicationInfo; 8755 final String codePath = pkg.codePath; 8756 final File codeFile = new File(codePath); 8757 final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp(); 8758 final boolean asecApp = info.isForwardLocked() || info.isExternalAsec(); 8759 8760 info.nativeLibraryRootDir = null; 8761 info.nativeLibraryRootRequiresIsa = false; 8762 info.nativeLibraryDir = null; 8763 info.secondaryNativeLibraryDir = null; 8764 8765 if (isApkFile(codeFile)) { 8766 // Monolithic install 8767 if (bundledApp) { 8768 // If "/system/lib64/apkname" exists, assume that is the per-package 8769 // native library directory to use; otherwise use "/system/lib/apkname". 8770 final String apkRoot = calculateBundledApkRoot(info.sourceDir); 8771 final boolean is64Bit = VMRuntime.is64BitInstructionSet( 8772 getPrimaryInstructionSet(info)); 8773 8774 // This is a bundled system app so choose the path based on the ABI. 8775 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this 8776 // is just the default path. 8777 final String apkName = deriveCodePathName(codePath); 8778 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME; 8779 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir, 8780 apkName).getAbsolutePath(); 8781 8782 if (info.secondaryCpuAbi != null) { 8783 final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME; 8784 info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot), 8785 secondaryLibDir, apkName).getAbsolutePath(); 8786 } 8787 } else if (asecApp) { 8788 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME) 8789 .getAbsolutePath(); 8790 } else { 8791 final String apkName = deriveCodePathName(codePath); 8792 info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName) 8793 .getAbsolutePath(); 8794 } 8795 8796 info.nativeLibraryRootRequiresIsa = false; 8797 info.nativeLibraryDir = info.nativeLibraryRootDir; 8798 } else { 8799 // Cluster install 8800 info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath(); 8801 info.nativeLibraryRootRequiresIsa = true; 8802 8803 info.nativeLibraryDir = new File(info.nativeLibraryRootDir, 8804 getPrimaryInstructionSet(info)).getAbsolutePath(); 8805 8806 if (info.secondaryCpuAbi != null) { 8807 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir, 8808 VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath(); 8809 } 8810 } 8811 } 8812 8813 /** 8814 * Calculate the abis and roots for a bundled app. These can uniquely 8815 * be determined from the contents of the system partition, i.e whether 8816 * it contains 64 or 32 bit shared libraries etc. We do not validate any 8817 * of this information, and instead assume that the system was built 8818 * sensibly. 8819 */ 8820 private void setBundledAppAbisAndRoots(PackageParser.Package pkg, 8821 PackageSetting pkgSetting) { 8822 final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath()); 8823 8824 // If "/system/lib64/apkname" exists, assume that is the per-package 8825 // native library directory to use; otherwise use "/system/lib/apkname". 8826 final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir); 8827 setBundledAppAbi(pkg, apkRoot, apkName); 8828 // pkgSetting might be null during rescan following uninstall of updates 8829 // to a bundled app, so accommodate that possibility. The settings in 8830 // that case will be established later from the parsed package. 8831 // 8832 // If the settings aren't null, sync them up with what we've just derived. 8833 // note that apkRoot isn't stored in the package settings. 8834 if (pkgSetting != null) { 8835 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 8836 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 8837 } 8838 } 8839 8840 /** 8841 * Deduces the ABI of a bundled app and sets the relevant fields on the 8842 * parsed pkg object. 8843 * 8844 * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem} 8845 * under which system libraries are installed. 8846 * @param apkName the name of the installed package. 8847 */ 8848 private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) { 8849 final File codeFile = new File(pkg.codePath); 8850 8851 final boolean has64BitLibs; 8852 final boolean has32BitLibs; 8853 if (isApkFile(codeFile)) { 8854 // Monolithic install 8855 has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists(); 8856 has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists(); 8857 } else { 8858 // Cluster install 8859 final File rootDir = new File(codeFile, LIB_DIR_NAME); 8860 if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS) 8861 && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) { 8862 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]); 8863 has64BitLibs = (new File(rootDir, isa)).exists(); 8864 } else { 8865 has64BitLibs = false; 8866 } 8867 if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS) 8868 && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) { 8869 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]); 8870 has32BitLibs = (new File(rootDir, isa)).exists(); 8871 } else { 8872 has32BitLibs = false; 8873 } 8874 } 8875 8876 if (has64BitLibs && !has32BitLibs) { 8877 // The package has 64 bit libs, but not 32 bit libs. Its primary 8878 // ABI should be 64 bit. We can safely assume here that the bundled 8879 // native libraries correspond to the most preferred ABI in the list. 8880 8881 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 8882 pkg.applicationInfo.secondaryCpuAbi = null; 8883 } else if (has32BitLibs && !has64BitLibs) { 8884 // The package has 32 bit libs but not 64 bit libs. Its primary 8885 // ABI should be 32 bit. 8886 8887 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 8888 pkg.applicationInfo.secondaryCpuAbi = null; 8889 } else if (has32BitLibs && has64BitLibs) { 8890 // The application has both 64 and 32 bit bundled libraries. We check 8891 // here that the app declares multiArch support, and warn if it doesn't. 8892 // 8893 // We will be lenient here and record both ABIs. The primary will be the 8894 // ABI that's higher on the list, i.e, a device that's configured to prefer 8895 // 64 bit apps will see a 64 bit primary ABI, 8896 8897 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) { 8898 Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch."); 8899 } 8900 8901 if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) { 8902 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 8903 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 8904 } else { 8905 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 8906 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 8907 } 8908 } else { 8909 pkg.applicationInfo.primaryCpuAbi = null; 8910 pkg.applicationInfo.secondaryCpuAbi = null; 8911 } 8912 } 8913 8914 private void killPackage(PackageParser.Package pkg, String reason) { 8915 // Kill the parent package 8916 killApplication(pkg.packageName, pkg.applicationInfo.uid, reason); 8917 // Kill the child packages 8918 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8919 for (int i = 0; i < childCount; i++) { 8920 PackageParser.Package childPkg = pkg.childPackages.get(i); 8921 killApplication(childPkg.packageName, childPkg.applicationInfo.uid, reason); 8922 } 8923 } 8924 8925 private void killApplication(String pkgName, int appId, String reason) { 8926 // Request the ActivityManager to kill the process(only for existing packages) 8927 // so that we do not end up in a confused state while the user is still using the older 8928 // version of the application while the new one gets installed. 8929 IActivityManager am = ActivityManagerNative.getDefault(); 8930 if (am != null) { 8931 try { 8932 am.killApplicationWithAppId(pkgName, appId, reason); 8933 } catch (RemoteException e) { 8934 } 8935 } 8936 } 8937 8938 private void removePackageLI(PackageParser.Package pkg, boolean chatty) { 8939 // Remove the parent package setting 8940 PackageSetting ps = (PackageSetting) pkg.mExtras; 8941 if (ps != null) { 8942 removePackageLI(ps, chatty); 8943 } 8944 // Remove the child package setting 8945 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8946 for (int i = 0; i < childCount; i++) { 8947 PackageParser.Package childPkg = pkg.childPackages.get(i); 8948 ps = (PackageSetting) childPkg.mExtras; 8949 if (ps != null) { 8950 removePackageLI(ps, chatty); 8951 } 8952 } 8953 } 8954 8955 void removePackageLI(PackageSetting ps, boolean chatty) { 8956 if (DEBUG_INSTALL) { 8957 if (chatty) 8958 Log.d(TAG, "Removing package " + ps.name); 8959 } 8960 8961 // writer 8962 synchronized (mPackages) { 8963 mPackages.remove(ps.name); 8964 final PackageParser.Package pkg = ps.pkg; 8965 if (pkg != null) { 8966 cleanPackageDataStructuresLILPw(pkg, chatty); 8967 } 8968 } 8969 } 8970 8971 void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) { 8972 if (DEBUG_INSTALL) { 8973 if (chatty) 8974 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName); 8975 } 8976 8977 // writer 8978 synchronized (mPackages) { 8979 // Remove the parent package 8980 mPackages.remove(pkg.applicationInfo.packageName); 8981 cleanPackageDataStructuresLILPw(pkg, chatty); 8982 8983 // Remove the child packages 8984 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8985 for (int i = 0; i < childCount; i++) { 8986 PackageParser.Package childPkg = pkg.childPackages.get(i); 8987 mPackages.remove(childPkg.applicationInfo.packageName); 8988 cleanPackageDataStructuresLILPw(childPkg, chatty); 8989 } 8990 } 8991 } 8992 8993 void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) { 8994 int N = pkg.providers.size(); 8995 StringBuilder r = null; 8996 int i; 8997 for (i=0; i<N; i++) { 8998 PackageParser.Provider p = pkg.providers.get(i); 8999 mProviders.removeProvider(p); 9000 if (p.info.authority == null) { 9001 9002 /* There was another ContentProvider with this authority when 9003 * this app was installed so this authority is null, 9004 * Ignore it as we don't have to unregister the provider. 9005 */ 9006 continue; 9007 } 9008 String names[] = p.info.authority.split(";"); 9009 for (int j = 0; j < names.length; j++) { 9010 if (mProvidersByAuthority.get(names[j]) == p) { 9011 mProvidersByAuthority.remove(names[j]); 9012 if (DEBUG_REMOVE) { 9013 if (chatty) 9014 Log.d(TAG, "Unregistered content provider: " + names[j] 9015 + ", className = " + p.info.name + ", isSyncable = " 9016 + p.info.isSyncable); 9017 } 9018 } 9019 } 9020 if (DEBUG_REMOVE && chatty) { 9021 if (r == null) { 9022 r = new StringBuilder(256); 9023 } else { 9024 r.append(' '); 9025 } 9026 r.append(p.info.name); 9027 } 9028 } 9029 if (r != null) { 9030 if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r); 9031 } 9032 9033 N = pkg.services.size(); 9034 r = null; 9035 for (i=0; i<N; i++) { 9036 PackageParser.Service s = pkg.services.get(i); 9037 mServices.removeService(s); 9038 if (chatty) { 9039 if (r == null) { 9040 r = new StringBuilder(256); 9041 } else { 9042 r.append(' '); 9043 } 9044 r.append(s.info.name); 9045 } 9046 } 9047 if (r != null) { 9048 if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r); 9049 } 9050 9051 N = pkg.receivers.size(); 9052 r = null; 9053 for (i=0; i<N; i++) { 9054 PackageParser.Activity a = pkg.receivers.get(i); 9055 mReceivers.removeActivity(a, "receiver"); 9056 if (DEBUG_REMOVE && chatty) { 9057 if (r == null) { 9058 r = new StringBuilder(256); 9059 } else { 9060 r.append(' '); 9061 } 9062 r.append(a.info.name); 9063 } 9064 } 9065 if (r != null) { 9066 if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r); 9067 } 9068 9069 N = pkg.activities.size(); 9070 r = null; 9071 for (i=0; i<N; i++) { 9072 PackageParser.Activity a = pkg.activities.get(i); 9073 mActivities.removeActivity(a, "activity"); 9074 if (DEBUG_REMOVE && chatty) { 9075 if (r == null) { 9076 r = new StringBuilder(256); 9077 } else { 9078 r.append(' '); 9079 } 9080 r.append(a.info.name); 9081 } 9082 } 9083 if (r != null) { 9084 if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r); 9085 } 9086 9087 N = pkg.permissions.size(); 9088 r = null; 9089 for (i=0; i<N; i++) { 9090 PackageParser.Permission p = pkg.permissions.get(i); 9091 BasePermission bp = mSettings.mPermissions.get(p.info.name); 9092 if (bp == null) { 9093 bp = mSettings.mPermissionTrees.get(p.info.name); 9094 } 9095 if (bp != null && bp.perm == p) { 9096 bp.perm = null; 9097 if (DEBUG_REMOVE && chatty) { 9098 if (r == null) { 9099 r = new StringBuilder(256); 9100 } else { 9101 r.append(' '); 9102 } 9103 r.append(p.info.name); 9104 } 9105 } 9106 if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 9107 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name); 9108 if (appOpPkgs != null) { 9109 appOpPkgs.remove(pkg.packageName); 9110 } 9111 } 9112 } 9113 if (r != null) { 9114 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 9115 } 9116 9117 N = pkg.requestedPermissions.size(); 9118 r = null; 9119 for (i=0; i<N; i++) { 9120 String perm = pkg.requestedPermissions.get(i); 9121 BasePermission bp = mSettings.mPermissions.get(perm); 9122 if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 9123 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm); 9124 if (appOpPkgs != null) { 9125 appOpPkgs.remove(pkg.packageName); 9126 if (appOpPkgs.isEmpty()) { 9127 mAppOpPermissionPackages.remove(perm); 9128 } 9129 } 9130 } 9131 } 9132 if (r != null) { 9133 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 9134 } 9135 9136 N = pkg.instrumentation.size(); 9137 r = null; 9138 for (i=0; i<N; i++) { 9139 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 9140 mInstrumentation.remove(a.getComponentName()); 9141 if (DEBUG_REMOVE && chatty) { 9142 if (r == null) { 9143 r = new StringBuilder(256); 9144 } else { 9145 r.append(' '); 9146 } 9147 r.append(a.info.name); 9148 } 9149 } 9150 if (r != null) { 9151 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r); 9152 } 9153 9154 r = null; 9155 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9156 // Only system apps can hold shared libraries. 9157 if (pkg.libraryNames != null) { 9158 for (i=0; i<pkg.libraryNames.size(); i++) { 9159 String name = pkg.libraryNames.get(i); 9160 SharedLibraryEntry cur = mSharedLibraries.get(name); 9161 if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) { 9162 mSharedLibraries.remove(name); 9163 if (DEBUG_REMOVE && chatty) { 9164 if (r == null) { 9165 r = new StringBuilder(256); 9166 } else { 9167 r.append(' '); 9168 } 9169 r.append(name); 9170 } 9171 } 9172 } 9173 } 9174 } 9175 if (r != null) { 9176 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r); 9177 } 9178 } 9179 9180 private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) { 9181 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) { 9182 if (pkgInfo.permissions.get(i).info.name.equals(perm)) { 9183 return true; 9184 } 9185 } 9186 return false; 9187 } 9188 9189 static final int UPDATE_PERMISSIONS_ALL = 1<<0; 9190 static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1; 9191 static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2; 9192 9193 private void updatePermissionsLPw(PackageParser.Package pkg, int flags) { 9194 // Update the parent permissions 9195 updatePermissionsLPw(pkg.packageName, pkg, flags); 9196 // Update the child permissions 9197 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 9198 for (int i = 0; i < childCount; i++) { 9199 PackageParser.Package childPkg = pkg.childPackages.get(i); 9200 updatePermissionsLPw(childPkg.packageName, childPkg, flags); 9201 } 9202 } 9203 9204 private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo, 9205 int flags) { 9206 final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null; 9207 updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags); 9208 } 9209 9210 private void updatePermissionsLPw(String changingPkg, 9211 PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) { 9212 // Make sure there are no dangling permission trees. 9213 Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator(); 9214 while (it.hasNext()) { 9215 final BasePermission bp = it.next(); 9216 if (bp.packageSetting == null) { 9217 // We may not yet have parsed the package, so just see if 9218 // we still know about its settings. 9219 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 9220 } 9221 if (bp.packageSetting == null) { 9222 Slog.w(TAG, "Removing dangling permission tree: " + bp.name 9223 + " from package " + bp.sourcePackage); 9224 it.remove(); 9225 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 9226 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 9227 Slog.i(TAG, "Removing old permission tree: " + bp.name 9228 + " from package " + bp.sourcePackage); 9229 flags |= UPDATE_PERMISSIONS_ALL; 9230 it.remove(); 9231 } 9232 } 9233 } 9234 9235 // Make sure all dynamic permissions have been assigned to a package, 9236 // and make sure there are no dangling permissions. 9237 it = mSettings.mPermissions.values().iterator(); 9238 while (it.hasNext()) { 9239 final BasePermission bp = it.next(); 9240 if (bp.type == BasePermission.TYPE_DYNAMIC) { 9241 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name=" 9242 + bp.name + " pkg=" + bp.sourcePackage 9243 + " info=" + bp.pendingInfo); 9244 if (bp.packageSetting == null && bp.pendingInfo != null) { 9245 final BasePermission tree = findPermissionTreeLP(bp.name); 9246 if (tree != null && tree.perm != null) { 9247 bp.packageSetting = tree.packageSetting; 9248 bp.perm = new PackageParser.Permission(tree.perm.owner, 9249 new PermissionInfo(bp.pendingInfo)); 9250 bp.perm.info.packageName = tree.perm.info.packageName; 9251 bp.perm.info.name = bp.name; 9252 bp.uid = tree.uid; 9253 } 9254 } 9255 } 9256 if (bp.packageSetting == null) { 9257 // We may not yet have parsed the package, so just see if 9258 // we still know about its settings. 9259 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 9260 } 9261 if (bp.packageSetting == null) { 9262 Slog.w(TAG, "Removing dangling permission: " + bp.name 9263 + " from package " + bp.sourcePackage); 9264 it.remove(); 9265 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 9266 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 9267 Slog.i(TAG, "Removing old permission: " + bp.name 9268 + " from package " + bp.sourcePackage); 9269 flags |= UPDATE_PERMISSIONS_ALL; 9270 it.remove(); 9271 } 9272 } 9273 } 9274 9275 // Now update the permissions for all packages, in particular 9276 // replace the granted permissions of the system packages. 9277 if ((flags&UPDATE_PERMISSIONS_ALL) != 0) { 9278 for (PackageParser.Package pkg : mPackages.values()) { 9279 if (pkg != pkgInfo) { 9280 // Only replace for packages on requested volume 9281 final String volumeUuid = getVolumeUuidForPackage(pkg); 9282 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0) 9283 && Objects.equals(replaceVolumeUuid, volumeUuid); 9284 grantPermissionsLPw(pkg, replace, changingPkg); 9285 } 9286 } 9287 } 9288 9289 if (pkgInfo != null) { 9290 // Only replace for packages on requested volume 9291 final String volumeUuid = getVolumeUuidForPackage(pkgInfo); 9292 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0) 9293 && Objects.equals(replaceVolumeUuid, volumeUuid); 9294 grantPermissionsLPw(pkgInfo, replace, changingPkg); 9295 } 9296 } 9297 9298 private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace, 9299 String packageOfInterest) { 9300 // IMPORTANT: There are two types of permissions: install and runtime. 9301 // Install time permissions are granted when the app is installed to 9302 // all device users and users added in the future. Runtime permissions 9303 // are granted at runtime explicitly to specific users. Normal and signature 9304 // protected permissions are install time permissions. Dangerous permissions 9305 // are install permissions if the app's target SDK is Lollipop MR1 or older, 9306 // otherwise they are runtime permissions. This function does not manage 9307 // runtime permissions except for the case an app targeting Lollipop MR1 9308 // being upgraded to target a newer SDK, in which case dangerous permissions 9309 // are transformed from install time to runtime ones. 9310 9311 final PackageSetting ps = (PackageSetting) pkg.mExtras; 9312 if (ps == null) { 9313 return; 9314 } 9315 9316 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions"); 9317 9318 PermissionsState permissionsState = ps.getPermissionsState(); 9319 PermissionsState origPermissions = permissionsState; 9320 9321 final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); 9322 9323 boolean runtimePermissionsRevoked = false; 9324 int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY; 9325 9326 boolean changedInstallPermission = false; 9327 9328 if (replace) { 9329 ps.installPermissionsFixed = false; 9330 if (!ps.isSharedUser()) { 9331 origPermissions = new PermissionsState(permissionsState); 9332 permissionsState.reset(); 9333 } else { 9334 // We need to know only about runtime permission changes since the 9335 // calling code always writes the install permissions state but 9336 // the runtime ones are written only if changed. The only cases of 9337 // changed runtime permissions here are promotion of an install to 9338 // runtime and revocation of a runtime from a shared user. 9339 changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw( 9340 ps.sharedUser, UserManagerService.getInstance().getUserIds()); 9341 if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) { 9342 runtimePermissionsRevoked = true; 9343 } 9344 } 9345 } 9346 9347 permissionsState.setGlobalGids(mGlobalGids); 9348 9349 final int N = pkg.requestedPermissions.size(); 9350 for (int i=0; i<N; i++) { 9351 final String name = pkg.requestedPermissions.get(i); 9352 final BasePermission bp = mSettings.mPermissions.get(name); 9353 9354 if (DEBUG_INSTALL) { 9355 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp); 9356 } 9357 9358 if (bp == null || bp.packageSetting == null) { 9359 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 9360 Slog.w(TAG, "Unknown permission " + name 9361 + " in package " + pkg.packageName); 9362 } 9363 continue; 9364 } 9365 9366 final String perm = bp.name; 9367 boolean allowedSig = false; 9368 int grant = GRANT_DENIED; 9369 9370 // Keep track of app op permissions. 9371 if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 9372 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name); 9373 if (pkgs == null) { 9374 pkgs = new ArraySet<>(); 9375 mAppOpPermissionPackages.put(bp.name, pkgs); 9376 } 9377 pkgs.add(pkg.packageName); 9378 } 9379 9380 final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; 9381 final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion 9382 >= Build.VERSION_CODES.M; 9383 switch (level) { 9384 case PermissionInfo.PROTECTION_NORMAL: { 9385 // For all apps normal permissions are install time ones. 9386 grant = GRANT_INSTALL; 9387 } break; 9388 9389 case PermissionInfo.PROTECTION_DANGEROUS: { 9390 // If a permission review is required for legacy apps we represent 9391 // their permissions as always granted runtime ones since we need 9392 // to keep the review required permission flag per user while an 9393 // install permission's state is shared across all users. 9394 if (!appSupportsRuntimePermissions && !Build.PERMISSIONS_REVIEW_REQUIRED) { 9395 // For legacy apps dangerous permissions are install time ones. 9396 grant = GRANT_INSTALL; 9397 } else if (origPermissions.hasInstallPermission(bp.name)) { 9398 // For legacy apps that became modern, install becomes runtime. 9399 grant = GRANT_UPGRADE; 9400 } else if (mPromoteSystemApps 9401 && isSystemApp(ps) 9402 && mExistingSystemPackages.contains(ps.name)) { 9403 // For legacy system apps, install becomes runtime. 9404 // We cannot check hasInstallPermission() for system apps since those 9405 // permissions were granted implicitly and not persisted pre-M. 9406 grant = GRANT_UPGRADE; 9407 } else { 9408 // For modern apps keep runtime permissions unchanged. 9409 grant = GRANT_RUNTIME; 9410 } 9411 } break; 9412 9413 case PermissionInfo.PROTECTION_SIGNATURE: { 9414 // For all apps signature permissions are install time ones. 9415 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions); 9416 if (allowedSig) { 9417 grant = GRANT_INSTALL; 9418 } 9419 } break; 9420 } 9421 9422 if (DEBUG_INSTALL) { 9423 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm); 9424 } 9425 9426 if (grant != GRANT_DENIED) { 9427 if (!isSystemApp(ps) && ps.installPermissionsFixed) { 9428 // If this is an existing, non-system package, then 9429 // we can't add any new permissions to it. 9430 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) { 9431 // Except... if this is a permission that was added 9432 // to the platform (note: need to only do this when 9433 // updating the platform). 9434 if (!isNewPlatformPermissionForPackage(perm, pkg)) { 9435 grant = GRANT_DENIED; 9436 } 9437 } 9438 } 9439 9440 switch (grant) { 9441 case GRANT_INSTALL: { 9442 // Revoke this as runtime permission to handle the case of 9443 // a runtime permission being downgraded to an install one. Also in permission review mode we keep dangerous permissions for legacy apps 9444 for (int userId : UserManagerService.getInstance().getUserIds()) { 9445 if (origPermissions.getRuntimePermissionState( 9446 bp.name, userId) != null) { 9447 // Revoke the runtime permission and clear the flags. 9448 origPermissions.revokeRuntimePermission(bp, userId); 9449 origPermissions.updatePermissionFlags(bp, userId, 9450 PackageManager.MASK_PERMISSION_FLAGS, 0); 9451 // If we revoked a permission permission, we have to write. 9452 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 9453 changedRuntimePermissionUserIds, userId); 9454 } 9455 } 9456 // Grant an install permission. 9457 if (permissionsState.grantInstallPermission(bp) != 9458 PermissionsState.PERMISSION_OPERATION_FAILURE) { 9459 changedInstallPermission = true; 9460 } 9461 } break; 9462 9463 case GRANT_RUNTIME: { 9464 // Grant previously granted runtime permissions. 9465 for (int userId : UserManagerService.getInstance().getUserIds()) { 9466 PermissionState permissionState = origPermissions 9467 .getRuntimePermissionState(bp.name, userId); 9468 int flags = permissionState != null 9469 ? permissionState.getFlags() : 0; 9470 if (origPermissions.hasRuntimePermission(bp.name, userId)) { 9471 if (permissionsState.grantRuntimePermission(bp, userId) == 9472 PermissionsState.PERMISSION_OPERATION_FAILURE) { 9473 // If we cannot put the permission as it was, we have to write. 9474 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 9475 changedRuntimePermissionUserIds, userId); 9476 } 9477 // If the app supports runtime permissions no need for a review. 9478 if (Build.PERMISSIONS_REVIEW_REQUIRED 9479 && appSupportsRuntimePermissions 9480 && (flags & PackageManager 9481 .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) { 9482 flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 9483 // Since we changed the flags, we have to write. 9484 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 9485 changedRuntimePermissionUserIds, userId); 9486 } 9487 } else if (Build.PERMISSIONS_REVIEW_REQUIRED 9488 && !appSupportsRuntimePermissions) { 9489 // For legacy apps that need a permission review, every new 9490 // runtime permission is granted but it is pending a review. 9491 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) { 9492 permissionsState.grantRuntimePermission(bp, userId); 9493 flags |= FLAG_PERMISSION_REVIEW_REQUIRED; 9494 // We changed the permission and flags, hence have to write. 9495 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 9496 changedRuntimePermissionUserIds, userId); 9497 } 9498 } 9499 // Propagate the permission flags. 9500 permissionsState.updatePermissionFlags(bp, userId, flags, flags); 9501 } 9502 } break; 9503 9504 case GRANT_UPGRADE: { 9505 // Grant runtime permissions for a previously held install permission. 9506 PermissionState permissionState = origPermissions 9507 .getInstallPermissionState(bp.name); 9508 final int flags = permissionState != null ? permissionState.getFlags() : 0; 9509 9510 if (origPermissions.revokeInstallPermission(bp) 9511 != PermissionsState.PERMISSION_OPERATION_FAILURE) { 9512 // We will be transferring the permission flags, so clear them. 9513 origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL, 9514 PackageManager.MASK_PERMISSION_FLAGS, 0); 9515 changedInstallPermission = true; 9516 } 9517 9518 // If the permission is not to be promoted to runtime we ignore it and 9519 // also its other flags as they are not applicable to install permissions. 9520 if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) { 9521 for (int userId : currentUserIds) { 9522 if (permissionsState.grantRuntimePermission(bp, userId) != 9523 PermissionsState.PERMISSION_OPERATION_FAILURE) { 9524 // Transfer the permission flags. 9525 permissionsState.updatePermissionFlags(bp, userId, 9526 flags, flags); 9527 // If we granted the permission, we have to write. 9528 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 9529 changedRuntimePermissionUserIds, userId); 9530 } 9531 } 9532 } 9533 } break; 9534 9535 default: { 9536 if (packageOfInterest == null 9537 || packageOfInterest.equals(pkg.packageName)) { 9538 Slog.w(TAG, "Not granting permission " + perm 9539 + " to package " + pkg.packageName 9540 + " because it was previously installed without"); 9541 } 9542 } break; 9543 } 9544 } else { 9545 if (permissionsState.revokeInstallPermission(bp) != 9546 PermissionsState.PERMISSION_OPERATION_FAILURE) { 9547 // Also drop the permission flags. 9548 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 9549 PackageManager.MASK_PERMISSION_FLAGS, 0); 9550 changedInstallPermission = true; 9551 Slog.i(TAG, "Un-granting permission " + perm 9552 + " from package " + pkg.packageName 9553 + " (protectionLevel=" + bp.protectionLevel 9554 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 9555 + ")"); 9556 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) { 9557 // Don't print warning for app op permissions, since it is fine for them 9558 // not to be granted, there is a UI for the user to decide. 9559 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 9560 Slog.w(TAG, "Not granting permission " + perm 9561 + " to package " + pkg.packageName 9562 + " (protectionLevel=" + bp.protectionLevel 9563 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 9564 + ")"); 9565 } 9566 } 9567 } 9568 } 9569 9570 if ((changedInstallPermission || replace) && !ps.installPermissionsFixed && 9571 !isSystemApp(ps) || isUpdatedSystemApp(ps)){ 9572 // This is the first that we have heard about this package, so the 9573 // permissions we have now selected are fixed until explicitly 9574 // changed. 9575 ps.installPermissionsFixed = true; 9576 } 9577 9578 // Persist the runtime permissions state for users with changes. If permissions 9579 // were revoked because no app in the shared user declares them we have to 9580 // write synchronously to avoid losing runtime permissions state. 9581 for (int userId : changedRuntimePermissionUserIds) { 9582 mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked); 9583 } 9584 9585 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 9586 } 9587 9588 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) { 9589 boolean allowed = false; 9590 final int NP = PackageParser.NEW_PERMISSIONS.length; 9591 for (int ip=0; ip<NP; ip++) { 9592 final PackageParser.NewPermissionInfo npi 9593 = PackageParser.NEW_PERMISSIONS[ip]; 9594 if (npi.name.equals(perm) 9595 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) { 9596 allowed = true; 9597 Log.i(TAG, "Auto-granting " + perm + " to old pkg " 9598 + pkg.packageName); 9599 break; 9600 } 9601 } 9602 return allowed; 9603 } 9604 9605 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg, 9606 BasePermission bp, PermissionsState origPermissions) { 9607 boolean allowed; 9608 allowed = (compareSignatures( 9609 bp.packageSetting.signatures.mSignatures, pkg.mSignatures) 9610 == PackageManager.SIGNATURE_MATCH) 9611 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures) 9612 == PackageManager.SIGNATURE_MATCH); 9613 if (!allowed && (bp.protectionLevel 9614 & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) { 9615 if (isSystemApp(pkg)) { 9616 // For updated system applications, a system permission 9617 // is granted only if it had been defined by the original application. 9618 if (pkg.isUpdatedSystemApp()) { 9619 final PackageSetting sysPs = mSettings 9620 .getDisabledSystemPkgLPr(pkg.packageName); 9621 if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) { 9622 // If the original was granted this permission, we take 9623 // that grant decision as read and propagate it to the 9624 // update. 9625 if (sysPs.isPrivileged()) { 9626 allowed = true; 9627 } 9628 } else { 9629 // The system apk may have been updated with an older 9630 // version of the one on the data partition, but which 9631 // granted a new system permission that it didn't have 9632 // before. In this case we do want to allow the app to 9633 // now get the new permission if the ancestral apk is 9634 // privileged to get it. 9635 if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) { 9636 for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) { 9637 if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) { 9638 allowed = true; 9639 break; 9640 } 9641 } 9642 } 9643 // Also if a privileged parent package on the system image or any of 9644 // its children requested a privileged permission, the updated child 9645 // packages can also get the permission. 9646 if (pkg.parentPackage != null) { 9647 final PackageSetting disabledSysParentPs = mSettings 9648 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName); 9649 if (disabledSysParentPs != null && disabledSysParentPs.pkg != null 9650 && disabledSysParentPs.isPrivileged()) { 9651 if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) { 9652 allowed = true; 9653 } else if (disabledSysParentPs.pkg.childPackages != null) { 9654 final int count = disabledSysParentPs.pkg.childPackages.size(); 9655 for (int i = 0; i < count; i++) { 9656 PackageParser.Package disabledSysChildPkg = 9657 disabledSysParentPs.pkg.childPackages.get(i); 9658 if (isPackageRequestingPermission(disabledSysChildPkg, 9659 perm)) { 9660 allowed = true; 9661 break; 9662 } 9663 } 9664 } 9665 } 9666 } 9667 } 9668 } else { 9669 allowed = isPrivilegedApp(pkg); 9670 } 9671 } 9672 } 9673 if (!allowed) { 9674 if (!allowed && (bp.protectionLevel 9675 & PermissionInfo.PROTECTION_FLAG_PRE23) != 0 9676 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 9677 // If this was a previously normal/dangerous permission that got moved 9678 // to a system permission as part of the runtime permission redesign, then 9679 // we still want to blindly grant it to old apps. 9680 allowed = true; 9681 } 9682 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0 9683 && pkg.packageName.equals(mRequiredInstallerPackage)) { 9684 // If this permission is to be granted to the system installer and 9685 // this app is an installer, then it gets the permission. 9686 allowed = true; 9687 } 9688 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0 9689 && pkg.packageName.equals(mRequiredVerifierPackage)) { 9690 // If this permission is to be granted to the system verifier and 9691 // this app is a verifier, then it gets the permission. 9692 allowed = true; 9693 } 9694 if (!allowed && (bp.protectionLevel 9695 & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0 9696 && isSystemApp(pkg)) { 9697 // Any pre-installed system app is allowed to get this permission. 9698 allowed = true; 9699 } 9700 if (!allowed && (bp.protectionLevel 9701 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) { 9702 // For development permissions, a development permission 9703 // is granted only if it was already granted. 9704 allowed = origPermissions.hasInstallPermission(perm); 9705 } 9706 } 9707 return allowed; 9708 } 9709 9710 private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) { 9711 final int permCount = pkg.requestedPermissions.size(); 9712 for (int j = 0; j < permCount; j++) { 9713 String requestedPermission = pkg.requestedPermissions.get(j); 9714 if (permission.equals(requestedPermission)) { 9715 return true; 9716 } 9717 } 9718 return false; 9719 } 9720 9721 final class ActivityIntentResolver 9722 extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> { 9723 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 9724 boolean defaultOnly, int userId) { 9725 if (!sUserManager.exists(userId)) return null; 9726 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 9727 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 9728 } 9729 9730 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 9731 int userId) { 9732 if (!sUserManager.exists(userId)) return null; 9733 mFlags = flags; 9734 return super.queryIntent(intent, resolvedType, 9735 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 9736 } 9737 9738 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 9739 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) { 9740 if (!sUserManager.exists(userId)) return null; 9741 if (packageActivities == null) { 9742 return null; 9743 } 9744 mFlags = flags; 9745 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 9746 final int N = packageActivities.size(); 9747 ArrayList<PackageParser.ActivityIntentInfo[]> listCut = 9748 new ArrayList<PackageParser.ActivityIntentInfo[]>(N); 9749 9750 ArrayList<PackageParser.ActivityIntentInfo> intentFilters; 9751 for (int i = 0; i < N; ++i) { 9752 intentFilters = packageActivities.get(i).intents; 9753 if (intentFilters != null && intentFilters.size() > 0) { 9754 PackageParser.ActivityIntentInfo[] array = 9755 new PackageParser.ActivityIntentInfo[intentFilters.size()]; 9756 intentFilters.toArray(array); 9757 listCut.add(array); 9758 } 9759 } 9760 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 9761 } 9762 9763 public final void addActivity(PackageParser.Activity a, String type) { 9764 final boolean systemApp = a.info.applicationInfo.isSystemApp(); 9765 mActivities.put(a.getComponentName(), a); 9766 if (DEBUG_SHOW_INFO) 9767 Log.v( 9768 TAG, " " + type + " " + 9769 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":"); 9770 if (DEBUG_SHOW_INFO) 9771 Log.v(TAG, " Class=" + a.info.name); 9772 final int NI = a.intents.size(); 9773 for (int j=0; j<NI; j++) { 9774 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 9775 if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) { 9776 intent.setPriority(0); 9777 Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity " 9778 + a.className + " with priority > 0, forcing to 0"); 9779 } 9780 if (DEBUG_SHOW_INFO) { 9781 Log.v(TAG, " IntentFilter:"); 9782 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 9783 } 9784 if (!intent.debugCheck()) { 9785 Log.w(TAG, "==> For Activity " + a.info.name); 9786 } 9787 addFilter(intent); 9788 } 9789 } 9790 9791 public final void removeActivity(PackageParser.Activity a, String type) { 9792 mActivities.remove(a.getComponentName()); 9793 if (DEBUG_SHOW_INFO) { 9794 Log.v(TAG, " " + type + " " 9795 + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel 9796 : a.info.name) + ":"); 9797 Log.v(TAG, " Class=" + a.info.name); 9798 } 9799 final int NI = a.intents.size(); 9800 for (int j=0; j<NI; j++) { 9801 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 9802 if (DEBUG_SHOW_INFO) { 9803 Log.v(TAG, " IntentFilter:"); 9804 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 9805 } 9806 removeFilter(intent); 9807 } 9808 } 9809 9810 @Override 9811 protected boolean allowFilterResult( 9812 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) { 9813 ActivityInfo filterAi = filter.activity.info; 9814 for (int i=dest.size()-1; i>=0; i--) { 9815 ActivityInfo destAi = dest.get(i).activityInfo; 9816 if (destAi.name == filterAi.name 9817 && destAi.packageName == filterAi.packageName) { 9818 return false; 9819 } 9820 } 9821 return true; 9822 } 9823 9824 @Override 9825 protected ActivityIntentInfo[] newArray(int size) { 9826 return new ActivityIntentInfo[size]; 9827 } 9828 9829 @Override 9830 protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) { 9831 if (!sUserManager.exists(userId)) return true; 9832 PackageParser.Package p = filter.activity.owner; 9833 if (p != null) { 9834 PackageSetting ps = (PackageSetting)p.mExtras; 9835 if (ps != null) { 9836 // System apps are never considered stopped for purposes of 9837 // filtering, because there may be no way for the user to 9838 // actually re-launch them. 9839 return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0 9840 && ps.getStopped(userId); 9841 } 9842 } 9843 return false; 9844 } 9845 9846 @Override 9847 protected boolean isPackageForFilter(String packageName, 9848 PackageParser.ActivityIntentInfo info) { 9849 return packageName.equals(info.activity.owner.packageName); 9850 } 9851 9852 @Override 9853 protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info, 9854 int match, int userId) { 9855 if (!sUserManager.exists(userId)) return null; 9856 if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) { 9857 return null; 9858 } 9859 final PackageParser.Activity activity = info.activity; 9860 PackageSetting ps = (PackageSetting) activity.owner.mExtras; 9861 if (ps == null) { 9862 return null; 9863 } 9864 ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags, 9865 ps.readUserState(userId), userId); 9866 if (ai == null) { 9867 return null; 9868 } 9869 final ResolveInfo res = new ResolveInfo(); 9870 res.activityInfo = ai; 9871 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 9872 res.filter = info; 9873 } 9874 if (info != null) { 9875 res.handleAllWebDataURI = info.handleAllWebDataURI(); 9876 } 9877 res.priority = info.getPriority(); 9878 res.preferredOrder = activity.owner.mPreferredOrder; 9879 //System.out.println("Result: " + res.activityInfo.className + 9880 // " = " + res.priority); 9881 res.match = match; 9882 res.isDefault = info.hasDefault; 9883 res.labelRes = info.labelRes; 9884 res.nonLocalizedLabel = info.nonLocalizedLabel; 9885 if (userNeedsBadging(userId)) { 9886 res.noResourceId = true; 9887 } else { 9888 res.icon = info.icon; 9889 } 9890 res.iconResourceId = info.icon; 9891 res.system = res.activityInfo.applicationInfo.isSystemApp(); 9892 return res; 9893 } 9894 9895 @Override 9896 protected void sortResults(List<ResolveInfo> results) { 9897 Collections.sort(results, mResolvePrioritySorter); 9898 } 9899 9900 @Override 9901 protected void dumpFilter(PrintWriter out, String prefix, 9902 PackageParser.ActivityIntentInfo filter) { 9903 out.print(prefix); out.print( 9904 Integer.toHexString(System.identityHashCode(filter.activity))); 9905 out.print(' '); 9906 filter.activity.printComponentShortName(out); 9907 out.print(" filter "); 9908 out.println(Integer.toHexString(System.identityHashCode(filter))); 9909 } 9910 9911 @Override 9912 protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) { 9913 return filter.activity; 9914 } 9915 9916 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 9917 PackageParser.Activity activity = (PackageParser.Activity)label; 9918 out.print(prefix); out.print( 9919 Integer.toHexString(System.identityHashCode(activity))); 9920 out.print(' '); 9921 activity.printComponentShortName(out); 9922 if (count > 1) { 9923 out.print(" ("); out.print(count); out.print(" filters)"); 9924 } 9925 out.println(); 9926 } 9927 9928// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 9929// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 9930// final List<ResolveInfo> retList = Lists.newArrayList(); 9931// while (i.hasNext()) { 9932// final ResolveInfo resolveInfo = i.next(); 9933// if (isEnabledLP(resolveInfo.activityInfo)) { 9934// retList.add(resolveInfo); 9935// } 9936// } 9937// return retList; 9938// } 9939 9940 // Keys are String (activity class name), values are Activity. 9941 private final ArrayMap<ComponentName, PackageParser.Activity> mActivities 9942 = new ArrayMap<ComponentName, PackageParser.Activity>(); 9943 private int mFlags; 9944 } 9945 9946 private final class ServiceIntentResolver 9947 extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> { 9948 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 9949 boolean defaultOnly, int userId) { 9950 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 9951 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 9952 } 9953 9954 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 9955 int userId) { 9956 if (!sUserManager.exists(userId)) return null; 9957 mFlags = flags; 9958 return super.queryIntent(intent, resolvedType, 9959 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 9960 } 9961 9962 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 9963 int flags, ArrayList<PackageParser.Service> packageServices, int userId) { 9964 if (!sUserManager.exists(userId)) return null; 9965 if (packageServices == null) { 9966 return null; 9967 } 9968 mFlags = flags; 9969 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 9970 final int N = packageServices.size(); 9971 ArrayList<PackageParser.ServiceIntentInfo[]> listCut = 9972 new ArrayList<PackageParser.ServiceIntentInfo[]>(N); 9973 9974 ArrayList<PackageParser.ServiceIntentInfo> intentFilters; 9975 for (int i = 0; i < N; ++i) { 9976 intentFilters = packageServices.get(i).intents; 9977 if (intentFilters != null && intentFilters.size() > 0) { 9978 PackageParser.ServiceIntentInfo[] array = 9979 new PackageParser.ServiceIntentInfo[intentFilters.size()]; 9980 intentFilters.toArray(array); 9981 listCut.add(array); 9982 } 9983 } 9984 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 9985 } 9986 9987 public final void addService(PackageParser.Service s) { 9988 mServices.put(s.getComponentName(), s); 9989 if (DEBUG_SHOW_INFO) { 9990 Log.v(TAG, " " 9991 + (s.info.nonLocalizedLabel != null 9992 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 9993 Log.v(TAG, " Class=" + s.info.name); 9994 } 9995 final int NI = s.intents.size(); 9996 int j; 9997 for (j=0; j<NI; j++) { 9998 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 9999 if (DEBUG_SHOW_INFO) { 10000 Log.v(TAG, " IntentFilter:"); 10001 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10002 } 10003 if (!intent.debugCheck()) { 10004 Log.w(TAG, "==> For Service " + s.info.name); 10005 } 10006 addFilter(intent); 10007 } 10008 } 10009 10010 public final void removeService(PackageParser.Service s) { 10011 mServices.remove(s.getComponentName()); 10012 if (DEBUG_SHOW_INFO) { 10013 Log.v(TAG, " " + (s.info.nonLocalizedLabel != null 10014 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 10015 Log.v(TAG, " Class=" + s.info.name); 10016 } 10017 final int NI = s.intents.size(); 10018 int j; 10019 for (j=0; j<NI; j++) { 10020 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 10021 if (DEBUG_SHOW_INFO) { 10022 Log.v(TAG, " IntentFilter:"); 10023 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10024 } 10025 removeFilter(intent); 10026 } 10027 } 10028 10029 @Override 10030 protected boolean allowFilterResult( 10031 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) { 10032 ServiceInfo filterSi = filter.service.info; 10033 for (int i=dest.size()-1; i>=0; i--) { 10034 ServiceInfo destAi = dest.get(i).serviceInfo; 10035 if (destAi.name == filterSi.name 10036 && destAi.packageName == filterSi.packageName) { 10037 return false; 10038 } 10039 } 10040 return true; 10041 } 10042 10043 @Override 10044 protected PackageParser.ServiceIntentInfo[] newArray(int size) { 10045 return new PackageParser.ServiceIntentInfo[size]; 10046 } 10047 10048 @Override 10049 protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) { 10050 if (!sUserManager.exists(userId)) return true; 10051 PackageParser.Package p = filter.service.owner; 10052 if (p != null) { 10053 PackageSetting ps = (PackageSetting)p.mExtras; 10054 if (ps != null) { 10055 // System apps are never considered stopped for purposes of 10056 // filtering, because there may be no way for the user to 10057 // actually re-launch them. 10058 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 10059 && ps.getStopped(userId); 10060 } 10061 } 10062 return false; 10063 } 10064 10065 @Override 10066 protected boolean isPackageForFilter(String packageName, 10067 PackageParser.ServiceIntentInfo info) { 10068 return packageName.equals(info.service.owner.packageName); 10069 } 10070 10071 @Override 10072 protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter, 10073 int match, int userId) { 10074 if (!sUserManager.exists(userId)) return null; 10075 final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter; 10076 if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) { 10077 return null; 10078 } 10079 final PackageParser.Service service = info.service; 10080 PackageSetting ps = (PackageSetting) service.owner.mExtras; 10081 if (ps == null) { 10082 return null; 10083 } 10084 ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags, 10085 ps.readUserState(userId), userId); 10086 if (si == null) { 10087 return null; 10088 } 10089 final ResolveInfo res = new ResolveInfo(); 10090 res.serviceInfo = si; 10091 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 10092 res.filter = filter; 10093 } 10094 res.priority = info.getPriority(); 10095 res.preferredOrder = service.owner.mPreferredOrder; 10096 res.match = match; 10097 res.isDefault = info.hasDefault; 10098 res.labelRes = info.labelRes; 10099 res.nonLocalizedLabel = info.nonLocalizedLabel; 10100 res.icon = info.icon; 10101 res.system = res.serviceInfo.applicationInfo.isSystemApp(); 10102 return res; 10103 } 10104 10105 @Override 10106 protected void sortResults(List<ResolveInfo> results) { 10107 Collections.sort(results, mResolvePrioritySorter); 10108 } 10109 10110 @Override 10111 protected void dumpFilter(PrintWriter out, String prefix, 10112 PackageParser.ServiceIntentInfo filter) { 10113 out.print(prefix); out.print( 10114 Integer.toHexString(System.identityHashCode(filter.service))); 10115 out.print(' '); 10116 filter.service.printComponentShortName(out); 10117 out.print(" filter "); 10118 out.println(Integer.toHexString(System.identityHashCode(filter))); 10119 } 10120 10121 @Override 10122 protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) { 10123 return filter.service; 10124 } 10125 10126 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 10127 PackageParser.Service service = (PackageParser.Service)label; 10128 out.print(prefix); out.print( 10129 Integer.toHexString(System.identityHashCode(service))); 10130 out.print(' '); 10131 service.printComponentShortName(out); 10132 if (count > 1) { 10133 out.print(" ("); out.print(count); out.print(" filters)"); 10134 } 10135 out.println(); 10136 } 10137 10138// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 10139// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 10140// final List<ResolveInfo> retList = Lists.newArrayList(); 10141// while (i.hasNext()) { 10142// final ResolveInfo resolveInfo = (ResolveInfo) i; 10143// if (isEnabledLP(resolveInfo.serviceInfo)) { 10144// retList.add(resolveInfo); 10145// } 10146// } 10147// return retList; 10148// } 10149 10150 // Keys are String (activity class name), values are Activity. 10151 private final ArrayMap<ComponentName, PackageParser.Service> mServices 10152 = new ArrayMap<ComponentName, PackageParser.Service>(); 10153 private int mFlags; 10154 }; 10155 10156 private final class ProviderIntentResolver 10157 extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> { 10158 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 10159 boolean defaultOnly, int userId) { 10160 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 10161 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 10162 } 10163 10164 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 10165 int userId) { 10166 if (!sUserManager.exists(userId)) 10167 return null; 10168 mFlags = flags; 10169 return super.queryIntent(intent, resolvedType, 10170 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 10171 } 10172 10173 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 10174 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) { 10175 if (!sUserManager.exists(userId)) 10176 return null; 10177 if (packageProviders == null) { 10178 return null; 10179 } 10180 mFlags = flags; 10181 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; 10182 final int N = packageProviders.size(); 10183 ArrayList<PackageParser.ProviderIntentInfo[]> listCut = 10184 new ArrayList<PackageParser.ProviderIntentInfo[]>(N); 10185 10186 ArrayList<PackageParser.ProviderIntentInfo> intentFilters; 10187 for (int i = 0; i < N; ++i) { 10188 intentFilters = packageProviders.get(i).intents; 10189 if (intentFilters != null && intentFilters.size() > 0) { 10190 PackageParser.ProviderIntentInfo[] array = 10191 new PackageParser.ProviderIntentInfo[intentFilters.size()]; 10192 intentFilters.toArray(array); 10193 listCut.add(array); 10194 } 10195 } 10196 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 10197 } 10198 10199 public final void addProvider(PackageParser.Provider p) { 10200 if (mProviders.containsKey(p.getComponentName())) { 10201 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring"); 10202 return; 10203 } 10204 10205 mProviders.put(p.getComponentName(), p); 10206 if (DEBUG_SHOW_INFO) { 10207 Log.v(TAG, " " 10208 + (p.info.nonLocalizedLabel != null 10209 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 10210 Log.v(TAG, " Class=" + p.info.name); 10211 } 10212 final int NI = p.intents.size(); 10213 int j; 10214 for (j = 0; j < NI; j++) { 10215 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 10216 if (DEBUG_SHOW_INFO) { 10217 Log.v(TAG, " IntentFilter:"); 10218 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10219 } 10220 if (!intent.debugCheck()) { 10221 Log.w(TAG, "==> For Provider " + p.info.name); 10222 } 10223 addFilter(intent); 10224 } 10225 } 10226 10227 public final void removeProvider(PackageParser.Provider p) { 10228 mProviders.remove(p.getComponentName()); 10229 if (DEBUG_SHOW_INFO) { 10230 Log.v(TAG, " " + (p.info.nonLocalizedLabel != null 10231 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 10232 Log.v(TAG, " Class=" + p.info.name); 10233 } 10234 final int NI = p.intents.size(); 10235 int j; 10236 for (j = 0; j < NI; j++) { 10237 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 10238 if (DEBUG_SHOW_INFO) { 10239 Log.v(TAG, " IntentFilter:"); 10240 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10241 } 10242 removeFilter(intent); 10243 } 10244 } 10245 10246 @Override 10247 protected boolean allowFilterResult( 10248 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) { 10249 ProviderInfo filterPi = filter.provider.info; 10250 for (int i = dest.size() - 1; i >= 0; i--) { 10251 ProviderInfo destPi = dest.get(i).providerInfo; 10252 if (destPi.name == filterPi.name 10253 && destPi.packageName == filterPi.packageName) { 10254 return false; 10255 } 10256 } 10257 return true; 10258 } 10259 10260 @Override 10261 protected PackageParser.ProviderIntentInfo[] newArray(int size) { 10262 return new PackageParser.ProviderIntentInfo[size]; 10263 } 10264 10265 @Override 10266 protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) { 10267 if (!sUserManager.exists(userId)) 10268 return true; 10269 PackageParser.Package p = filter.provider.owner; 10270 if (p != null) { 10271 PackageSetting ps = (PackageSetting) p.mExtras; 10272 if (ps != null) { 10273 // System apps are never considered stopped for purposes of 10274 // filtering, because there may be no way for the user to 10275 // actually re-launch them. 10276 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 10277 && ps.getStopped(userId); 10278 } 10279 } 10280 return false; 10281 } 10282 10283 @Override 10284 protected boolean isPackageForFilter(String packageName, 10285 PackageParser.ProviderIntentInfo info) { 10286 return packageName.equals(info.provider.owner.packageName); 10287 } 10288 10289 @Override 10290 protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter, 10291 int match, int userId) { 10292 if (!sUserManager.exists(userId)) 10293 return null; 10294 final PackageParser.ProviderIntentInfo info = filter; 10295 if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) { 10296 return null; 10297 } 10298 final PackageParser.Provider provider = info.provider; 10299 PackageSetting ps = (PackageSetting) provider.owner.mExtras; 10300 if (ps == null) { 10301 return null; 10302 } 10303 ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags, 10304 ps.readUserState(userId), userId); 10305 if (pi == null) { 10306 return null; 10307 } 10308 final ResolveInfo res = new ResolveInfo(); 10309 res.providerInfo = pi; 10310 if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) { 10311 res.filter = filter; 10312 } 10313 res.priority = info.getPriority(); 10314 res.preferredOrder = provider.owner.mPreferredOrder; 10315 res.match = match; 10316 res.isDefault = info.hasDefault; 10317 res.labelRes = info.labelRes; 10318 res.nonLocalizedLabel = info.nonLocalizedLabel; 10319 res.icon = info.icon; 10320 res.system = res.providerInfo.applicationInfo.isSystemApp(); 10321 return res; 10322 } 10323 10324 @Override 10325 protected void sortResults(List<ResolveInfo> results) { 10326 Collections.sort(results, mResolvePrioritySorter); 10327 } 10328 10329 @Override 10330 protected void dumpFilter(PrintWriter out, String prefix, 10331 PackageParser.ProviderIntentInfo filter) { 10332 out.print(prefix); 10333 out.print( 10334 Integer.toHexString(System.identityHashCode(filter.provider))); 10335 out.print(' '); 10336 filter.provider.printComponentShortName(out); 10337 out.print(" filter "); 10338 out.println(Integer.toHexString(System.identityHashCode(filter))); 10339 } 10340 10341 @Override 10342 protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) { 10343 return filter.provider; 10344 } 10345 10346 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 10347 PackageParser.Provider provider = (PackageParser.Provider)label; 10348 out.print(prefix); out.print( 10349 Integer.toHexString(System.identityHashCode(provider))); 10350 out.print(' '); 10351 provider.printComponentShortName(out); 10352 if (count > 1) { 10353 out.print(" ("); out.print(count); out.print(" filters)"); 10354 } 10355 out.println(); 10356 } 10357 10358 private final ArrayMap<ComponentName, PackageParser.Provider> mProviders 10359 = new ArrayMap<ComponentName, PackageParser.Provider>(); 10360 private int mFlags; 10361 } 10362 10363 private static final class EphemeralIntentResolver 10364 extends IntentResolver<EphemeralResolveIntentInfo, EphemeralResolveInfo> { 10365 @Override 10366 protected EphemeralResolveIntentInfo[] newArray(int size) { 10367 return new EphemeralResolveIntentInfo[size]; 10368 } 10369 10370 @Override 10371 protected boolean isPackageForFilter(String packageName, EphemeralResolveIntentInfo info) { 10372 return true; 10373 } 10374 10375 @Override 10376 protected EphemeralResolveInfo newResult(EphemeralResolveIntentInfo info, int match, 10377 int userId) { 10378 if (!sUserManager.exists(userId)) { 10379 return null; 10380 } 10381 return info.getEphemeralResolveInfo(); 10382 } 10383 } 10384 10385 private static final Comparator<ResolveInfo> mResolvePrioritySorter = 10386 new Comparator<ResolveInfo>() { 10387 public int compare(ResolveInfo r1, ResolveInfo r2) { 10388 int v1 = r1.priority; 10389 int v2 = r2.priority; 10390 //System.out.println("Comparing: q1=" + q1 + " q2=" + q2); 10391 if (v1 != v2) { 10392 return (v1 > v2) ? -1 : 1; 10393 } 10394 v1 = r1.preferredOrder; 10395 v2 = r2.preferredOrder; 10396 if (v1 != v2) { 10397 return (v1 > v2) ? -1 : 1; 10398 } 10399 if (r1.isDefault != r2.isDefault) { 10400 return r1.isDefault ? -1 : 1; 10401 } 10402 v1 = r1.match; 10403 v2 = r2.match; 10404 //System.out.println("Comparing: m1=" + m1 + " m2=" + m2); 10405 if (v1 != v2) { 10406 return (v1 > v2) ? -1 : 1; 10407 } 10408 if (r1.system != r2.system) { 10409 return r1.system ? -1 : 1; 10410 } 10411 if (r1.activityInfo != null) { 10412 return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName); 10413 } 10414 if (r1.serviceInfo != null) { 10415 return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName); 10416 } 10417 if (r1.providerInfo != null) { 10418 return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName); 10419 } 10420 return 0; 10421 } 10422 }; 10423 10424 private static final Comparator<ProviderInfo> mProviderInitOrderSorter = 10425 new Comparator<ProviderInfo>() { 10426 public int compare(ProviderInfo p1, ProviderInfo p2) { 10427 final int v1 = p1.initOrder; 10428 final int v2 = p2.initOrder; 10429 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0); 10430 } 10431 }; 10432 10433 final void sendPackageBroadcast(final String action, final String pkg, final Bundle extras, 10434 final int flags, final String targetPkg, final IIntentReceiver finishedReceiver, 10435 final int[] userIds) { 10436 mHandler.post(new Runnable() { 10437 @Override 10438 public void run() { 10439 try { 10440 final IActivityManager am = ActivityManagerNative.getDefault(); 10441 if (am == null) return; 10442 final int[] resolvedUserIds; 10443 if (userIds == null) { 10444 resolvedUserIds = am.getRunningUserIds(); 10445 } else { 10446 resolvedUserIds = userIds; 10447 } 10448 for (int id : resolvedUserIds) { 10449 final Intent intent = new Intent(action, 10450 pkg != null ? Uri.fromParts("package", pkg, null) : null); 10451 if (extras != null) { 10452 intent.putExtras(extras); 10453 } 10454 if (targetPkg != null) { 10455 intent.setPackage(targetPkg); 10456 } 10457 // Modify the UID when posting to other users 10458 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); 10459 if (uid > 0 && UserHandle.getUserId(uid) != id) { 10460 uid = UserHandle.getUid(id, UserHandle.getAppId(uid)); 10461 intent.putExtra(Intent.EXTRA_UID, uid); 10462 } 10463 intent.putExtra(Intent.EXTRA_USER_HANDLE, id); 10464 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags); 10465 if (DEBUG_BROADCASTS) { 10466 RuntimeException here = new RuntimeException("here"); 10467 here.fillInStackTrace(); 10468 Slog.d(TAG, "Sending to user " + id + ": " 10469 + intent.toShortString(false, true, false, false) 10470 + " " + intent.getExtras(), here); 10471 } 10472 am.broadcastIntent(null, intent, null, finishedReceiver, 10473 0, null, null, null, android.app.AppOpsManager.OP_NONE, 10474 null, finishedReceiver != null, false, id); 10475 } 10476 } catch (RemoteException ex) { 10477 } 10478 } 10479 }); 10480 } 10481 10482 /** 10483 * Check if the external storage media is available. This is true if there 10484 * is a mounted external storage medium or if the external storage is 10485 * emulated. 10486 */ 10487 private boolean isExternalMediaAvailable() { 10488 return mMediaMounted || Environment.isExternalStorageEmulated(); 10489 } 10490 10491 @Override 10492 public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) { 10493 // writer 10494 synchronized (mPackages) { 10495 if (!isExternalMediaAvailable()) { 10496 // If the external storage is no longer mounted at this point, 10497 // the caller may not have been able to delete all of this 10498 // packages files and can not delete any more. Bail. 10499 return null; 10500 } 10501 final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned; 10502 if (lastPackage != null) { 10503 pkgs.remove(lastPackage); 10504 } 10505 if (pkgs.size() > 0) { 10506 return pkgs.get(0); 10507 } 10508 } 10509 return null; 10510 } 10511 10512 void schedulePackageCleaning(String packageName, int userId, boolean andCode) { 10513 final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE, 10514 userId, andCode ? 1 : 0, packageName); 10515 if (mSystemReady) { 10516 msg.sendToTarget(); 10517 } else { 10518 if (mPostSystemReadyMessages == null) { 10519 mPostSystemReadyMessages = new ArrayList<>(); 10520 } 10521 mPostSystemReadyMessages.add(msg); 10522 } 10523 } 10524 10525 void startCleaningPackages() { 10526 // reader 10527 if (!isExternalMediaAvailable()) { 10528 return; 10529 } 10530 synchronized (mPackages) { 10531 if (mSettings.mPackagesToBeCleaned.isEmpty()) { 10532 return; 10533 } 10534 } 10535 Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE); 10536 intent.setComponent(DEFAULT_CONTAINER_COMPONENT); 10537 IActivityManager am = ActivityManagerNative.getDefault(); 10538 if (am != null) { 10539 try { 10540 am.startService(null, intent, null, mContext.getOpPackageName(), 10541 UserHandle.USER_SYSTEM); 10542 } catch (RemoteException e) { 10543 } 10544 } 10545 } 10546 10547 @Override 10548 public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer, 10549 int installFlags, String installerPackageName, int userId) { 10550 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null); 10551 10552 final int callingUid = Binder.getCallingUid(); 10553 enforceCrossUserPermission(callingUid, userId, 10554 true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser"); 10555 10556 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 10557 try { 10558 if (observer != null) { 10559 observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null); 10560 } 10561 } catch (RemoteException re) { 10562 } 10563 return; 10564 } 10565 10566 if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) { 10567 installFlags |= PackageManager.INSTALL_FROM_ADB; 10568 10569 } else { 10570 // Caller holds INSTALL_PACKAGES permission, so we're less strict 10571 // about installerPackageName. 10572 10573 installFlags &= ~PackageManager.INSTALL_FROM_ADB; 10574 installFlags &= ~PackageManager.INSTALL_ALL_USERS; 10575 } 10576 10577 UserHandle user; 10578 if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) { 10579 user = UserHandle.ALL; 10580 } else { 10581 user = new UserHandle(userId); 10582 } 10583 10584 // Only system components can circumvent runtime permissions when installing. 10585 if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0 10586 && mContext.checkCallingOrSelfPermission(Manifest.permission 10587 .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) { 10588 throw new SecurityException("You need the " 10589 + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission " 10590 + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag"); 10591 } 10592 10593 final File originFile = new File(originPath); 10594 final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile); 10595 10596 final Message msg = mHandler.obtainMessage(INIT_COPY); 10597 final VerificationInfo verificationInfo = new VerificationInfo( 10598 null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid); 10599 final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer, 10600 installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user, 10601 null /*packageAbiOverride*/, null /*grantedPermissions*/); 10602 params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params)); 10603 msg.obj = params; 10604 10605 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser", 10606 System.identityHashCode(msg.obj)); 10607 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 10608 System.identityHashCode(msg.obj)); 10609 10610 mHandler.sendMessage(msg); 10611 } 10612 10613 void installStage(String packageName, File stagedDir, String stagedCid, 10614 IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams, 10615 String installerPackageName, int installerUid, UserHandle user) { 10616 if (DEBUG_EPHEMERAL) { 10617 if ((sessionParams.installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) { 10618 Slog.d(TAG, "Ephemeral install of " + packageName); 10619 } 10620 } 10621 final VerificationInfo verificationInfo = new VerificationInfo( 10622 sessionParams.originatingUri, sessionParams.referrerUri, 10623 sessionParams.originatingUid, installerUid); 10624 10625 final OriginInfo origin; 10626 if (stagedDir != null) { 10627 origin = OriginInfo.fromStagedFile(stagedDir); 10628 } else { 10629 origin = OriginInfo.fromStagedContainer(stagedCid); 10630 } 10631 10632 final Message msg = mHandler.obtainMessage(INIT_COPY); 10633 final InstallParams params = new InstallParams(origin, null, observer, 10634 sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid, 10635 verificationInfo, user, sessionParams.abiOverride, 10636 sessionParams.grantedRuntimePermissions); 10637 params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params)); 10638 msg.obj = params; 10639 10640 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage", 10641 System.identityHashCode(msg.obj)); 10642 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 10643 System.identityHashCode(msg.obj)); 10644 10645 mHandler.sendMessage(msg); 10646 } 10647 10648 private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, 10649 int userId) { 10650 final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting); 10651 sendPackageAddedForUser(packageName, isSystem, pkgSetting.appId, userId); 10652 } 10653 10654 private void sendPackageAddedForUser(String packageName, boolean isSystem, 10655 int appId, int userId) { 10656 Bundle extras = new Bundle(1); 10657 extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, appId)); 10658 10659 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 10660 packageName, extras, 0, null, null, new int[] {userId}); 10661 try { 10662 IActivityManager am = ActivityManagerNative.getDefault(); 10663 if (isSystem && am.isUserRunning(userId, 0)) { 10664 // The just-installed/enabled app is bundled on the system, so presumed 10665 // to be able to run automatically without needing an explicit launch. 10666 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one. 10667 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED) 10668 .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES) 10669 .setPackage(packageName); 10670 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null, 10671 android.app.AppOpsManager.OP_NONE, null, false, false, userId); 10672 } 10673 } catch (RemoteException e) { 10674 // shouldn't happen 10675 Slog.w(TAG, "Unable to bootstrap installed package", e); 10676 } 10677 } 10678 10679 @Override 10680 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, 10681 int userId) { 10682 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 10683 PackageSetting pkgSetting; 10684 final int uid = Binder.getCallingUid(); 10685 enforceCrossUserPermission(uid, userId, 10686 true /* requireFullPermission */, true /* checkShell */, 10687 "setApplicationHiddenSetting for user " + userId); 10688 10689 if (hidden && isPackageDeviceAdmin(packageName, userId)) { 10690 Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin"); 10691 return false; 10692 } 10693 10694 long callingId = Binder.clearCallingIdentity(); 10695 try { 10696 boolean sendAdded = false; 10697 boolean sendRemoved = false; 10698 // writer 10699 synchronized (mPackages) { 10700 pkgSetting = mSettings.mPackages.get(packageName); 10701 if (pkgSetting == null) { 10702 return false; 10703 } 10704 if (pkgSetting.getHidden(userId) != hidden) { 10705 pkgSetting.setHidden(hidden, userId); 10706 mSettings.writePackageRestrictionsLPr(userId); 10707 if (hidden) { 10708 sendRemoved = true; 10709 } else { 10710 sendAdded = true; 10711 } 10712 } 10713 } 10714 if (sendAdded) { 10715 sendPackageAddedForUser(packageName, pkgSetting, userId); 10716 return true; 10717 } 10718 if (sendRemoved) { 10719 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId), 10720 "hiding pkg"); 10721 sendApplicationHiddenForUser(packageName, pkgSetting, userId); 10722 return true; 10723 } 10724 } finally { 10725 Binder.restoreCallingIdentity(callingId); 10726 } 10727 return false; 10728 } 10729 10730 private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting, 10731 int userId) { 10732 final PackageRemovedInfo info = new PackageRemovedInfo(); 10733 info.removedPackage = packageName; 10734 info.removedUsers = new int[] {userId}; 10735 info.uid = UserHandle.getUid(userId, pkgSetting.appId); 10736 info.sendPackageRemovedBroadcasts(true /*killApp*/); 10737 } 10738 10739 private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) { 10740 if (pkgList.length > 0) { 10741 Bundle extras = new Bundle(1); 10742 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 10743 10744 sendPackageBroadcast( 10745 suspended ? Intent.ACTION_PACKAGES_SUSPENDED 10746 : Intent.ACTION_PACKAGES_UNSUSPENDED, 10747 null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null, 10748 new int[] {userId}); 10749 } 10750 } 10751 10752 /** 10753 * Returns true if application is not found or there was an error. Otherwise it returns 10754 * the hidden state of the package for the given user. 10755 */ 10756 @Override 10757 public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) { 10758 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 10759 enforceCrossUserPermission(Binder.getCallingUid(), userId, 10760 true /* requireFullPermission */, false /* checkShell */, 10761 "getApplicationHidden for user " + userId); 10762 PackageSetting pkgSetting; 10763 long callingId = Binder.clearCallingIdentity(); 10764 try { 10765 // writer 10766 synchronized (mPackages) { 10767 pkgSetting = mSettings.mPackages.get(packageName); 10768 if (pkgSetting == null) { 10769 return true; 10770 } 10771 return pkgSetting.getHidden(userId); 10772 } 10773 } finally { 10774 Binder.restoreCallingIdentity(callingId); 10775 } 10776 } 10777 10778 /** 10779 * @hide 10780 */ 10781 @Override 10782 public int installExistingPackageAsUser(String packageName, int userId) { 10783 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, 10784 null); 10785 PackageSetting pkgSetting; 10786 final int uid = Binder.getCallingUid(); 10787 enforceCrossUserPermission(uid, userId, 10788 true /* requireFullPermission */, true /* checkShell */, 10789 "installExistingPackage for user " + userId); 10790 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 10791 return PackageManager.INSTALL_FAILED_USER_RESTRICTED; 10792 } 10793 10794 long callingId = Binder.clearCallingIdentity(); 10795 try { 10796 boolean installed = false; 10797 10798 // writer 10799 synchronized (mPackages) { 10800 pkgSetting = mSettings.mPackages.get(packageName); 10801 if (pkgSetting == null) { 10802 return PackageManager.INSTALL_FAILED_INVALID_URI; 10803 } 10804 if (!pkgSetting.getInstalled(userId)) { 10805 pkgSetting.setInstalled(true, userId); 10806 pkgSetting.setHidden(false, userId); 10807 mSettings.writePackageRestrictionsLPr(userId); 10808 installed = true; 10809 } 10810 } 10811 10812 if (installed) { 10813 if (pkgSetting.pkg != null) { 10814 prepareAppDataAfterInstall(pkgSetting.pkg); 10815 } 10816 sendPackageAddedForUser(packageName, pkgSetting, userId); 10817 } 10818 } finally { 10819 Binder.restoreCallingIdentity(callingId); 10820 } 10821 10822 return PackageManager.INSTALL_SUCCEEDED; 10823 } 10824 10825 boolean isUserRestricted(int userId, String restrictionKey) { 10826 Bundle restrictions = sUserManager.getUserRestrictions(userId); 10827 if (restrictions.getBoolean(restrictionKey, false)) { 10828 Log.w(TAG, "User is restricted: " + restrictionKey); 10829 return true; 10830 } 10831 return false; 10832 } 10833 10834 @Override 10835 public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended, 10836 int userId) { 10837 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 10838 enforceCrossUserPermission(Binder.getCallingUid(), userId, 10839 true /* requireFullPermission */, true /* checkShell */, 10840 "setPackagesSuspended for user " + userId); 10841 10842 if (ArrayUtils.isEmpty(packageNames)) { 10843 return packageNames; 10844 } 10845 10846 // List of package names for whom the suspended state has changed. 10847 List<String> changedPackages = new ArrayList<>(packageNames.length); 10848 // List of package names for whom the suspended state is not set as requested in this 10849 // method. 10850 List<String> unactionedPackages = new ArrayList<>(packageNames.length); 10851 for (int i = 0; i < packageNames.length; i++) { 10852 String packageName = packageNames[i]; 10853 long callingId = Binder.clearCallingIdentity(); 10854 try { 10855 boolean changed = false; 10856 final int appId; 10857 synchronized (mPackages) { 10858 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName); 10859 if (pkgSetting == null) { 10860 Slog.w(TAG, "Could not find package setting for package \"" + packageName 10861 + "\". Skipping suspending/un-suspending."); 10862 unactionedPackages.add(packageName); 10863 continue; 10864 } 10865 appId = pkgSetting.appId; 10866 if (pkgSetting.getSuspended(userId) != suspended) { 10867 if (!canSuspendPackageForUserLocked(packageName, userId)) { 10868 unactionedPackages.add(packageName); 10869 continue; 10870 } 10871 pkgSetting.setSuspended(suspended, userId); 10872 mSettings.writePackageRestrictionsLPr(userId); 10873 changed = true; 10874 changedPackages.add(packageName); 10875 } 10876 } 10877 10878 if (changed && suspended) { 10879 killApplication(packageName, UserHandle.getUid(userId, appId), 10880 "suspending package"); 10881 } 10882 } finally { 10883 Binder.restoreCallingIdentity(callingId); 10884 } 10885 } 10886 10887 if (!changedPackages.isEmpty()) { 10888 sendPackagesSuspendedForUser(changedPackages.toArray( 10889 new String[changedPackages.size()]), userId, suspended); 10890 } 10891 10892 return unactionedPackages.toArray(new String[unactionedPackages.size()]); 10893 } 10894 10895 @Override 10896 public boolean isPackageSuspendedForUser(String packageName, int userId) { 10897 enforceCrossUserPermission(Binder.getCallingUid(), userId, 10898 true /* requireFullPermission */, false /* checkShell */, 10899 "isPackageSuspendedForUser for user " + userId); 10900 synchronized (mPackages) { 10901 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName); 10902 return pkgSetting != null && pkgSetting.getSuspended(userId); 10903 } 10904 } 10905 10906 /** 10907 * TODO: cache and disallow blocking the active dialer. 10908 * 10909 * @see also DefaultPermissionGrantPolicy#grantDefaultSystemHandlerPermissions 10910 */ 10911 private boolean canSuspendPackageForUserLocked(String packageName, int userId) { 10912 if (isPackageDeviceAdmin(packageName, userId)) { 10913 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 10914 + "\": has an active device admin"); 10915 return false; 10916 } 10917 10918 String activeLauncherPackageName = getActiveLauncherPackageName(userId); 10919 if (packageName.equals(activeLauncherPackageName)) { 10920 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 10921 + "\": contains the active launcher"); 10922 return false; 10923 } 10924 10925 if (packageName.equals(mRequiredInstallerPackage)) { 10926 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 10927 + "\": required for package installation"); 10928 return false; 10929 } 10930 10931 if (packageName.equals(mRequiredVerifierPackage)) { 10932 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 10933 + "\": required for package verification"); 10934 return false; 10935 } 10936 10937 final PackageParser.Package pkg = mPackages.get(packageName); 10938 if (pkg != null && isPrivilegedApp(pkg)) { 10939 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 10940 + "\": is a privileged app"); 10941 return false; 10942 } 10943 10944 return true; 10945 } 10946 10947 private String getActiveLauncherPackageName(int userId) { 10948 Intent intent = new Intent(Intent.ACTION_MAIN); 10949 intent.addCategory(Intent.CATEGORY_HOME); 10950 ResolveInfo resolveInfo = resolveIntent( 10951 intent, 10952 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 10953 PackageManager.MATCH_DEFAULT_ONLY, 10954 userId); 10955 10956 return resolveInfo == null ? null : resolveInfo.activityInfo.packageName; 10957 } 10958 10959 @Override 10960 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException { 10961 mContext.enforceCallingOrSelfPermission( 10962 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 10963 "Only package verification agents can verify applications"); 10964 10965 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 10966 final PackageVerificationResponse response = new PackageVerificationResponse( 10967 verificationCode, Binder.getCallingUid()); 10968 msg.arg1 = id; 10969 msg.obj = response; 10970 mHandler.sendMessage(msg); 10971 } 10972 10973 @Override 10974 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, 10975 long millisecondsToDelay) { 10976 mContext.enforceCallingOrSelfPermission( 10977 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 10978 "Only package verification agents can extend verification timeouts"); 10979 10980 final PackageVerificationState state = mPendingVerification.get(id); 10981 final PackageVerificationResponse response = new PackageVerificationResponse( 10982 verificationCodeAtTimeout, Binder.getCallingUid()); 10983 10984 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) { 10985 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT; 10986 } 10987 if (millisecondsToDelay < 0) { 10988 millisecondsToDelay = 0; 10989 } 10990 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW) 10991 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) { 10992 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT; 10993 } 10994 10995 if ((state != null) && !state.timeoutExtended()) { 10996 state.extendTimeout(); 10997 10998 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 10999 msg.arg1 = id; 11000 msg.obj = response; 11001 mHandler.sendMessageDelayed(msg, millisecondsToDelay); 11002 } 11003 } 11004 11005 private void broadcastPackageVerified(int verificationId, Uri packageUri, 11006 int verificationCode, UserHandle user) { 11007 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED); 11008 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE); 11009 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 11010 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 11011 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode); 11012 11013 mContext.sendBroadcastAsUser(intent, user, 11014 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT); 11015 } 11016 11017 private ComponentName matchComponentForVerifier(String packageName, 11018 List<ResolveInfo> receivers) { 11019 ActivityInfo targetReceiver = null; 11020 11021 final int NR = receivers.size(); 11022 for (int i = 0; i < NR; i++) { 11023 final ResolveInfo info = receivers.get(i); 11024 if (info.activityInfo == null) { 11025 continue; 11026 } 11027 11028 if (packageName.equals(info.activityInfo.packageName)) { 11029 targetReceiver = info.activityInfo; 11030 break; 11031 } 11032 } 11033 11034 if (targetReceiver == null) { 11035 return null; 11036 } 11037 11038 return new ComponentName(targetReceiver.packageName, targetReceiver.name); 11039 } 11040 11041 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo, 11042 List<ResolveInfo> receivers, final PackageVerificationState verificationState) { 11043 if (pkgInfo.verifiers.length == 0) { 11044 return null; 11045 } 11046 11047 final int N = pkgInfo.verifiers.length; 11048 final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1); 11049 for (int i = 0; i < N; i++) { 11050 final VerifierInfo verifierInfo = pkgInfo.verifiers[i]; 11051 11052 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName, 11053 receivers); 11054 if (comp == null) { 11055 continue; 11056 } 11057 11058 final int verifierUid = getUidForVerifier(verifierInfo); 11059 if (verifierUid == -1) { 11060 continue; 11061 } 11062 11063 if (DEBUG_VERIFY) { 11064 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName 11065 + " with the correct signature"); 11066 } 11067 sufficientVerifiers.add(comp); 11068 verificationState.addSufficientVerifier(verifierUid); 11069 } 11070 11071 return sufficientVerifiers; 11072 } 11073 11074 private int getUidForVerifier(VerifierInfo verifierInfo) { 11075 synchronized (mPackages) { 11076 final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName); 11077 if (pkg == null) { 11078 return -1; 11079 } else if (pkg.mSignatures.length != 1) { 11080 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 11081 + " has more than one signature; ignoring"); 11082 return -1; 11083 } 11084 11085 /* 11086 * If the public key of the package's signature does not match 11087 * our expected public key, then this is a different package and 11088 * we should skip. 11089 */ 11090 11091 final byte[] expectedPublicKey; 11092 try { 11093 final Signature verifierSig = pkg.mSignatures[0]; 11094 final PublicKey publicKey = verifierSig.getPublicKey(); 11095 expectedPublicKey = publicKey.getEncoded(); 11096 } catch (CertificateException e) { 11097 return -1; 11098 } 11099 11100 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded(); 11101 11102 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) { 11103 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 11104 + " does not have the expected public key; ignoring"); 11105 return -1; 11106 } 11107 11108 return pkg.applicationInfo.uid; 11109 } 11110 } 11111 11112 @Override 11113 public void finishPackageInstall(int token) { 11114 enforceSystemOrRoot("Only the system is allowed to finish installs"); 11115 11116 if (DEBUG_INSTALL) { 11117 Slog.v(TAG, "BM finishing package install for " + token); 11118 } 11119 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token); 11120 11121 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 11122 mHandler.sendMessage(msg); 11123 } 11124 11125 /** 11126 * Get the verification agent timeout. 11127 * 11128 * @return verification timeout in milliseconds 11129 */ 11130 private long getVerificationTimeout() { 11131 return android.provider.Settings.Global.getLong(mContext.getContentResolver(), 11132 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT, 11133 DEFAULT_VERIFICATION_TIMEOUT); 11134 } 11135 11136 /** 11137 * Get the default verification agent response code. 11138 * 11139 * @return default verification response code 11140 */ 11141 private int getDefaultVerificationResponse() { 11142 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 11143 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE, 11144 DEFAULT_VERIFICATION_RESPONSE); 11145 } 11146 11147 /** 11148 * Check whether or not package verification has been enabled. 11149 * 11150 * @return true if verification should be performed 11151 */ 11152 private boolean isVerificationEnabled(int userId, int installFlags) { 11153 if (!DEFAULT_VERIFY_ENABLE) { 11154 return false; 11155 } 11156 // Ephemeral apps don't get the full verification treatment 11157 if ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) { 11158 if (DEBUG_EPHEMERAL) { 11159 Slog.d(TAG, "INSTALL_EPHEMERAL so skipping verification"); 11160 } 11161 return false; 11162 } 11163 11164 boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS); 11165 11166 // Check if installing from ADB 11167 if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) { 11168 // Do not run verification in a test harness environment 11169 if (ActivityManager.isRunningInTestHarness()) { 11170 return false; 11171 } 11172 if (ensureVerifyAppsEnabled) { 11173 return true; 11174 } 11175 // Check if the developer does not want package verification for ADB installs 11176 if (android.provider.Settings.Global.getInt(mContext.getContentResolver(), 11177 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) { 11178 return false; 11179 } 11180 } 11181 11182 if (ensureVerifyAppsEnabled) { 11183 return true; 11184 } 11185 11186 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 11187 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1; 11188 } 11189 11190 @Override 11191 public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains) 11192 throws RemoteException { 11193 mContext.enforceCallingOrSelfPermission( 11194 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 11195 "Only intentfilter verification agents can verify applications"); 11196 11197 final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED); 11198 final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse( 11199 Binder.getCallingUid(), verificationCode, failedDomains); 11200 msg.arg1 = id; 11201 msg.obj = response; 11202 mHandler.sendMessage(msg); 11203 } 11204 11205 @Override 11206 public int getIntentVerificationStatus(String packageName, int userId) { 11207 synchronized (mPackages) { 11208 return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 11209 } 11210 } 11211 11212 @Override 11213 public boolean updateIntentVerificationStatus(String packageName, int status, int userId) { 11214 mContext.enforceCallingOrSelfPermission( 11215 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 11216 11217 boolean result = false; 11218 synchronized (mPackages) { 11219 result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId); 11220 } 11221 if (result) { 11222 scheduleWritePackageRestrictionsLocked(userId); 11223 } 11224 return result; 11225 } 11226 11227 @Override 11228 public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications( 11229 String packageName) { 11230 synchronized (mPackages) { 11231 return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName)); 11232 } 11233 } 11234 11235 @Override 11236 public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) { 11237 if (TextUtils.isEmpty(packageName)) { 11238 return ParceledListSlice.emptyList(); 11239 } 11240 synchronized (mPackages) { 11241 PackageParser.Package pkg = mPackages.get(packageName); 11242 if (pkg == null || pkg.activities == null) { 11243 return ParceledListSlice.emptyList(); 11244 } 11245 final int count = pkg.activities.size(); 11246 ArrayList<IntentFilter> result = new ArrayList<>(); 11247 for (int n=0; n<count; n++) { 11248 PackageParser.Activity activity = pkg.activities.get(n); 11249 if (activity.intents != null && activity.intents.size() > 0) { 11250 result.addAll(activity.intents); 11251 } 11252 } 11253 return new ParceledListSlice<>(result); 11254 } 11255 } 11256 11257 @Override 11258 public boolean setDefaultBrowserPackageName(String packageName, int userId) { 11259 mContext.enforceCallingOrSelfPermission( 11260 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 11261 11262 synchronized (mPackages) { 11263 boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId); 11264 if (packageName != null) { 11265 result |= updateIntentVerificationStatus(packageName, 11266 PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, 11267 userId); 11268 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr( 11269 packageName, userId); 11270 } 11271 return result; 11272 } 11273 } 11274 11275 @Override 11276 public String getDefaultBrowserPackageName(int userId) { 11277 synchronized (mPackages) { 11278 return mSettings.getDefaultBrowserPackageNameLPw(userId); 11279 } 11280 } 11281 11282 /** 11283 * Get the "allow unknown sources" setting. 11284 * 11285 * @return the current "allow unknown sources" setting 11286 */ 11287 private int getUnknownSourcesSettings() { 11288 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 11289 android.provider.Settings.Global.INSTALL_NON_MARKET_APPS, 11290 -1); 11291 } 11292 11293 @Override 11294 public void setInstallerPackageName(String targetPackage, String installerPackageName) { 11295 final int uid = Binder.getCallingUid(); 11296 // writer 11297 synchronized (mPackages) { 11298 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage); 11299 if (targetPackageSetting == null) { 11300 throw new IllegalArgumentException("Unknown target package: " + targetPackage); 11301 } 11302 11303 PackageSetting installerPackageSetting; 11304 if (installerPackageName != null) { 11305 installerPackageSetting = mSettings.mPackages.get(installerPackageName); 11306 if (installerPackageSetting == null) { 11307 throw new IllegalArgumentException("Unknown installer package: " 11308 + installerPackageName); 11309 } 11310 } else { 11311 installerPackageSetting = null; 11312 } 11313 11314 Signature[] callerSignature; 11315 Object obj = mSettings.getUserIdLPr(uid); 11316 if (obj != null) { 11317 if (obj instanceof SharedUserSetting) { 11318 callerSignature = ((SharedUserSetting)obj).signatures.mSignatures; 11319 } else if (obj instanceof PackageSetting) { 11320 callerSignature = ((PackageSetting)obj).signatures.mSignatures; 11321 } else { 11322 throw new SecurityException("Bad object " + obj + " for uid " + uid); 11323 } 11324 } else { 11325 throw new SecurityException("Unknown calling UID: " + uid); 11326 } 11327 11328 // Verify: can't set installerPackageName to a package that is 11329 // not signed with the same cert as the caller. 11330 if (installerPackageSetting != null) { 11331 if (compareSignatures(callerSignature, 11332 installerPackageSetting.signatures.mSignatures) 11333 != PackageManager.SIGNATURE_MATCH) { 11334 throw new SecurityException( 11335 "Caller does not have same cert as new installer package " 11336 + installerPackageName); 11337 } 11338 } 11339 11340 // Verify: if target already has an installer package, it must 11341 // be signed with the same cert as the caller. 11342 if (targetPackageSetting.installerPackageName != null) { 11343 PackageSetting setting = mSettings.mPackages.get( 11344 targetPackageSetting.installerPackageName); 11345 // If the currently set package isn't valid, then it's always 11346 // okay to change it. 11347 if (setting != null) { 11348 if (compareSignatures(callerSignature, 11349 setting.signatures.mSignatures) 11350 != PackageManager.SIGNATURE_MATCH) { 11351 throw new SecurityException( 11352 "Caller does not have same cert as old installer package " 11353 + targetPackageSetting.installerPackageName); 11354 } 11355 } 11356 } 11357 11358 // Okay! 11359 targetPackageSetting.installerPackageName = installerPackageName; 11360 scheduleWriteSettingsLocked(); 11361 } 11362 } 11363 11364 private void processPendingInstall(final InstallArgs args, final int currentStatus) { 11365 // Queue up an async operation since the package installation may take a little while. 11366 mHandler.post(new Runnable() { 11367 public void run() { 11368 mHandler.removeCallbacks(this); 11369 // Result object to be returned 11370 PackageInstalledInfo res = new PackageInstalledInfo(); 11371 res.setReturnCode(currentStatus); 11372 res.uid = -1; 11373 res.pkg = null; 11374 res.removedInfo = null; 11375 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 11376 args.doPreInstall(res.returnCode); 11377 synchronized (mInstallLock) { 11378 installPackageTracedLI(args, res); 11379 } 11380 args.doPostInstall(res.returnCode, res.uid); 11381 } 11382 11383 // A restore should be performed at this point if (a) the install 11384 // succeeded, (b) the operation is not an update, and (c) the new 11385 // package has not opted out of backup participation. 11386 final boolean update = res.removedInfo != null 11387 && res.removedInfo.removedPackage != null; 11388 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags; 11389 boolean doRestore = !update 11390 && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0); 11391 11392 // Set up the post-install work request bookkeeping. This will be used 11393 // and cleaned up by the post-install event handling regardless of whether 11394 // there's a restore pass performed. Token values are >= 1. 11395 int token; 11396 if (mNextInstallToken < 0) mNextInstallToken = 1; 11397 token = mNextInstallToken++; 11398 11399 PostInstallData data = new PostInstallData(args, res); 11400 mRunningInstalls.put(token, data); 11401 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token); 11402 11403 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) { 11404 // Pass responsibility to the Backup Manager. It will perform a 11405 // restore if appropriate, then pass responsibility back to the 11406 // Package Manager to run the post-install observer callbacks 11407 // and broadcasts. 11408 IBackupManager bm = IBackupManager.Stub.asInterface( 11409 ServiceManager.getService(Context.BACKUP_SERVICE)); 11410 if (bm != null) { 11411 if (DEBUG_INSTALL) Log.v(TAG, "token " + token 11412 + " to BM for possible restore"); 11413 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token); 11414 try { 11415 // TODO: http://b/22388012 11416 if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) { 11417 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token); 11418 } else { 11419 doRestore = false; 11420 } 11421 } catch (RemoteException e) { 11422 // can't happen; the backup manager is local 11423 } catch (Exception e) { 11424 Slog.e(TAG, "Exception trying to enqueue restore", e); 11425 doRestore = false; 11426 } 11427 } else { 11428 Slog.e(TAG, "Backup Manager not found!"); 11429 doRestore = false; 11430 } 11431 } 11432 11433 if (!doRestore) { 11434 // No restore possible, or the Backup Manager was mysteriously not 11435 // available -- just fire the post-install work request directly. 11436 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token); 11437 11438 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token); 11439 11440 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 11441 mHandler.sendMessage(msg); 11442 } 11443 } 11444 }); 11445 } 11446 11447 private abstract class HandlerParams { 11448 private static final int MAX_RETRIES = 4; 11449 11450 /** 11451 * Number of times startCopy() has been attempted and had a non-fatal 11452 * error. 11453 */ 11454 private int mRetries = 0; 11455 11456 /** User handle for the user requesting the information or installation. */ 11457 private final UserHandle mUser; 11458 String traceMethod; 11459 int traceCookie; 11460 11461 HandlerParams(UserHandle user) { 11462 mUser = user; 11463 } 11464 11465 UserHandle getUser() { 11466 return mUser; 11467 } 11468 11469 HandlerParams setTraceMethod(String traceMethod) { 11470 this.traceMethod = traceMethod; 11471 return this; 11472 } 11473 11474 HandlerParams setTraceCookie(int traceCookie) { 11475 this.traceCookie = traceCookie; 11476 return this; 11477 } 11478 11479 final boolean startCopy() { 11480 boolean res; 11481 try { 11482 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this); 11483 11484 if (++mRetries > MAX_RETRIES) { 11485 Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up"); 11486 mHandler.sendEmptyMessage(MCS_GIVE_UP); 11487 handleServiceError(); 11488 return false; 11489 } else { 11490 handleStartCopy(); 11491 res = true; 11492 } 11493 } catch (RemoteException e) { 11494 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT"); 11495 mHandler.sendEmptyMessage(MCS_RECONNECT); 11496 res = false; 11497 } 11498 handleReturnCode(); 11499 return res; 11500 } 11501 11502 final void serviceError() { 11503 if (DEBUG_INSTALL) Slog.i(TAG, "serviceError"); 11504 handleServiceError(); 11505 handleReturnCode(); 11506 } 11507 11508 abstract void handleStartCopy() throws RemoteException; 11509 abstract void handleServiceError(); 11510 abstract void handleReturnCode(); 11511 } 11512 11513 class MeasureParams extends HandlerParams { 11514 private final PackageStats mStats; 11515 private boolean mSuccess; 11516 11517 private final IPackageStatsObserver mObserver; 11518 11519 public MeasureParams(PackageStats stats, IPackageStatsObserver observer) { 11520 super(new UserHandle(stats.userHandle)); 11521 mObserver = observer; 11522 mStats = stats; 11523 } 11524 11525 @Override 11526 public String toString() { 11527 return "MeasureParams{" 11528 + Integer.toHexString(System.identityHashCode(this)) 11529 + " " + mStats.packageName + "}"; 11530 } 11531 11532 @Override 11533 void handleStartCopy() throws RemoteException { 11534 synchronized (mInstallLock) { 11535 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats); 11536 } 11537 11538 if (mSuccess) { 11539 final boolean mounted; 11540 if (Environment.isExternalStorageEmulated()) { 11541 mounted = true; 11542 } else { 11543 final String status = Environment.getExternalStorageState(); 11544 mounted = (Environment.MEDIA_MOUNTED.equals(status) 11545 || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status)); 11546 } 11547 11548 if (mounted) { 11549 final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle); 11550 11551 mStats.externalCacheSize = calculateDirectorySize(mContainerService, 11552 userEnv.buildExternalStorageAppCacheDirs(mStats.packageName)); 11553 11554 mStats.externalDataSize = calculateDirectorySize(mContainerService, 11555 userEnv.buildExternalStorageAppDataDirs(mStats.packageName)); 11556 11557 // Always subtract cache size, since it's a subdirectory 11558 mStats.externalDataSize -= mStats.externalCacheSize; 11559 11560 mStats.externalMediaSize = calculateDirectorySize(mContainerService, 11561 userEnv.buildExternalStorageAppMediaDirs(mStats.packageName)); 11562 11563 mStats.externalObbSize = calculateDirectorySize(mContainerService, 11564 userEnv.buildExternalStorageAppObbDirs(mStats.packageName)); 11565 } 11566 } 11567 } 11568 11569 @Override 11570 void handleReturnCode() { 11571 if (mObserver != null) { 11572 try { 11573 mObserver.onGetStatsCompleted(mStats, mSuccess); 11574 } catch (RemoteException e) { 11575 Slog.i(TAG, "Observer no longer exists."); 11576 } 11577 } 11578 } 11579 11580 @Override 11581 void handleServiceError() { 11582 Slog.e(TAG, "Could not measure application " + mStats.packageName 11583 + " external storage"); 11584 } 11585 } 11586 11587 private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths) 11588 throws RemoteException { 11589 long result = 0; 11590 for (File path : paths) { 11591 result += mcs.calculateDirectorySize(path.getAbsolutePath()); 11592 } 11593 return result; 11594 } 11595 11596 private static void clearDirectory(IMediaContainerService mcs, File[] paths) { 11597 for (File path : paths) { 11598 try { 11599 mcs.clearDirectory(path.getAbsolutePath()); 11600 } catch (RemoteException e) { 11601 } 11602 } 11603 } 11604 11605 static class OriginInfo { 11606 /** 11607 * Location where install is coming from, before it has been 11608 * copied/renamed into place. This could be a single monolithic APK 11609 * file, or a cluster directory. This location may be untrusted. 11610 */ 11611 final File file; 11612 final String cid; 11613 11614 /** 11615 * Flag indicating that {@link #file} or {@link #cid} has already been 11616 * staged, meaning downstream users don't need to defensively copy the 11617 * contents. 11618 */ 11619 final boolean staged; 11620 11621 /** 11622 * Flag indicating that {@link #file} or {@link #cid} is an already 11623 * installed app that is being moved. 11624 */ 11625 final boolean existing; 11626 11627 final String resolvedPath; 11628 final File resolvedFile; 11629 11630 static OriginInfo fromNothing() { 11631 return new OriginInfo(null, null, false, false); 11632 } 11633 11634 static OriginInfo fromUntrustedFile(File file) { 11635 return new OriginInfo(file, null, false, false); 11636 } 11637 11638 static OriginInfo fromExistingFile(File file) { 11639 return new OriginInfo(file, null, false, true); 11640 } 11641 11642 static OriginInfo fromStagedFile(File file) { 11643 return new OriginInfo(file, null, true, false); 11644 } 11645 11646 static OriginInfo fromStagedContainer(String cid) { 11647 return new OriginInfo(null, cid, true, false); 11648 } 11649 11650 private OriginInfo(File file, String cid, boolean staged, boolean existing) { 11651 this.file = file; 11652 this.cid = cid; 11653 this.staged = staged; 11654 this.existing = existing; 11655 11656 if (cid != null) { 11657 resolvedPath = PackageHelper.getSdDir(cid); 11658 resolvedFile = new File(resolvedPath); 11659 } else if (file != null) { 11660 resolvedPath = file.getAbsolutePath(); 11661 resolvedFile = file; 11662 } else { 11663 resolvedPath = null; 11664 resolvedFile = null; 11665 } 11666 } 11667 } 11668 11669 static class MoveInfo { 11670 final int moveId; 11671 final String fromUuid; 11672 final String toUuid; 11673 final String packageName; 11674 final String dataAppName; 11675 final int appId; 11676 final String seinfo; 11677 final int targetSdkVersion; 11678 11679 public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName, 11680 String dataAppName, int appId, String seinfo, int targetSdkVersion) { 11681 this.moveId = moveId; 11682 this.fromUuid = fromUuid; 11683 this.toUuid = toUuid; 11684 this.packageName = packageName; 11685 this.dataAppName = dataAppName; 11686 this.appId = appId; 11687 this.seinfo = seinfo; 11688 this.targetSdkVersion = targetSdkVersion; 11689 } 11690 } 11691 11692 static class VerificationInfo { 11693 /** A constant used to indicate that a uid value is not present. */ 11694 public static final int NO_UID = -1; 11695 11696 /** URI referencing where the package was downloaded from. */ 11697 final Uri originatingUri; 11698 11699 /** HTTP referrer URI associated with the originatingURI. */ 11700 final Uri referrer; 11701 11702 /** UID of the application that the install request originated from. */ 11703 final int originatingUid; 11704 11705 /** UID of application requesting the install */ 11706 final int installerUid; 11707 11708 VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) { 11709 this.originatingUri = originatingUri; 11710 this.referrer = referrer; 11711 this.originatingUid = originatingUid; 11712 this.installerUid = installerUid; 11713 } 11714 } 11715 11716 class InstallParams extends HandlerParams { 11717 final OriginInfo origin; 11718 final MoveInfo move; 11719 final IPackageInstallObserver2 observer; 11720 int installFlags; 11721 final String installerPackageName; 11722 final String volumeUuid; 11723 private InstallArgs mArgs; 11724 private int mRet; 11725 final String packageAbiOverride; 11726 final String[] grantedRuntimePermissions; 11727 final VerificationInfo verificationInfo; 11728 11729 InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 11730 int installFlags, String installerPackageName, String volumeUuid, 11731 VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride, 11732 String[] grantedPermissions) { 11733 super(user); 11734 this.origin = origin; 11735 this.move = move; 11736 this.observer = observer; 11737 this.installFlags = installFlags; 11738 this.installerPackageName = installerPackageName; 11739 this.volumeUuid = volumeUuid; 11740 this.verificationInfo = verificationInfo; 11741 this.packageAbiOverride = packageAbiOverride; 11742 this.grantedRuntimePermissions = grantedPermissions; 11743 } 11744 11745 @Override 11746 public String toString() { 11747 return "InstallParams{" + Integer.toHexString(System.identityHashCode(this)) 11748 + " file=" + origin.file + " cid=" + origin.cid + "}"; 11749 } 11750 11751 private int installLocationPolicy(PackageInfoLite pkgLite) { 11752 String packageName = pkgLite.packageName; 11753 int installLocation = pkgLite.installLocation; 11754 boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 11755 // reader 11756 synchronized (mPackages) { 11757 // Currently installed package which the new package is attempting to replace or 11758 // null if no such package is installed. 11759 PackageParser.Package installedPkg = mPackages.get(packageName); 11760 // Package which currently owns the data which the new package will own if installed. 11761 // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg 11762 // will be null whereas dataOwnerPkg will contain information about the package 11763 // which was uninstalled while keeping its data. 11764 PackageParser.Package dataOwnerPkg = installedPkg; 11765 if (dataOwnerPkg == null) { 11766 PackageSetting ps = mSettings.mPackages.get(packageName); 11767 if (ps != null) { 11768 dataOwnerPkg = ps.pkg; 11769 } 11770 } 11771 11772 if (dataOwnerPkg != null) { 11773 // If installed, the package will get access to data left on the device by its 11774 // predecessor. As a security measure, this is permited only if this is not a 11775 // version downgrade or if the predecessor package is marked as debuggable and 11776 // a downgrade is explicitly requested. 11777 if (((dataOwnerPkg.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) 11778 || ((installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) == 0)) { 11779 try { 11780 checkDowngrade(dataOwnerPkg, pkgLite); 11781 } catch (PackageManagerException e) { 11782 Slog.w(TAG, "Downgrade detected: " + e.getMessage()); 11783 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE; 11784 } 11785 } 11786 } 11787 11788 if (installedPkg != null) { 11789 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 11790 // Check for updated system application. 11791 if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11792 if (onSd) { 11793 Slog.w(TAG, "Cannot install update to system app on sdcard"); 11794 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION; 11795 } 11796 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 11797 } else { 11798 if (onSd) { 11799 // Install flag overrides everything. 11800 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 11801 } 11802 // If current upgrade specifies particular preference 11803 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) { 11804 // Application explicitly specified internal. 11805 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 11806 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) { 11807 // App explictly prefers external. Let policy decide 11808 } else { 11809 // Prefer previous location 11810 if (isExternal(installedPkg)) { 11811 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 11812 } 11813 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 11814 } 11815 } 11816 } else { 11817 // Invalid install. Return error code 11818 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS; 11819 } 11820 } 11821 } 11822 // All the special cases have been taken care of. 11823 // Return result based on recommended install location. 11824 if (onSd) { 11825 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 11826 } 11827 return pkgLite.recommendedInstallLocation; 11828 } 11829 11830 /* 11831 * Invoke remote method to get package information and install 11832 * location values. Override install location based on default 11833 * policy if needed and then create install arguments based 11834 * on the install location. 11835 */ 11836 public void handleStartCopy() throws RemoteException { 11837 int ret = PackageManager.INSTALL_SUCCEEDED; 11838 11839 // If we're already staged, we've firmly committed to an install location 11840 if (origin.staged) { 11841 if (origin.file != null) { 11842 installFlags |= PackageManager.INSTALL_INTERNAL; 11843 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 11844 } else if (origin.cid != null) { 11845 installFlags |= PackageManager.INSTALL_EXTERNAL; 11846 installFlags &= ~PackageManager.INSTALL_INTERNAL; 11847 } else { 11848 throw new IllegalStateException("Invalid stage location"); 11849 } 11850 } 11851 11852 final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 11853 final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0; 11854 final boolean ephemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; 11855 PackageInfoLite pkgLite = null; 11856 11857 if (onInt && onSd) { 11858 // Check if both bits are set. 11859 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external"); 11860 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 11861 } else if (onSd && ephemeral) { 11862 Slog.w(TAG, "Conflicting flags specified for installing ephemeral on external"); 11863 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 11864 } else { 11865 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags, 11866 packageAbiOverride); 11867 11868 if (DEBUG_EPHEMERAL && ephemeral) { 11869 Slog.v(TAG, "pkgLite for install: " + pkgLite); 11870 } 11871 11872 /* 11873 * If we have too little free space, try to free cache 11874 * before giving up. 11875 */ 11876 if (!origin.staged && pkgLite.recommendedInstallLocation 11877 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 11878 // TODO: focus freeing disk space on the target device 11879 final StorageManager storage = StorageManager.from(mContext); 11880 final long lowThreshold = storage.getStorageLowBytes( 11881 Environment.getDataDirectory()); 11882 11883 final long sizeBytes = mContainerService.calculateInstalledSize( 11884 origin.resolvedPath, isForwardLocked(), packageAbiOverride); 11885 11886 try { 11887 mInstaller.freeCache(null, sizeBytes + lowThreshold); 11888 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, 11889 installFlags, packageAbiOverride); 11890 } catch (InstallerException e) { 11891 Slog.w(TAG, "Failed to free cache", e); 11892 } 11893 11894 /* 11895 * The cache free must have deleted the file we 11896 * downloaded to install. 11897 * 11898 * TODO: fix the "freeCache" call to not delete 11899 * the file we care about. 11900 */ 11901 if (pkgLite.recommendedInstallLocation 11902 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 11903 pkgLite.recommendedInstallLocation 11904 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE; 11905 } 11906 } 11907 } 11908 11909 if (ret == PackageManager.INSTALL_SUCCEEDED) { 11910 int loc = pkgLite.recommendedInstallLocation; 11911 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) { 11912 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 11913 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) { 11914 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 11915 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 11916 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 11917 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) { 11918 ret = PackageManager.INSTALL_FAILED_INVALID_APK; 11919 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 11920 ret = PackageManager.INSTALL_FAILED_INVALID_URI; 11921 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) { 11922 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE; 11923 } else { 11924 // Override with defaults if needed. 11925 loc = installLocationPolicy(pkgLite); 11926 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) { 11927 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 11928 } else if (!onSd && !onInt) { 11929 // Override install location with flags 11930 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) { 11931 // Set the flag to install on external media. 11932 installFlags |= PackageManager.INSTALL_EXTERNAL; 11933 installFlags &= ~PackageManager.INSTALL_INTERNAL; 11934 } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) { 11935 if (DEBUG_EPHEMERAL) { 11936 Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag"); 11937 } 11938 installFlags |= PackageManager.INSTALL_EPHEMERAL; 11939 installFlags &= ~(PackageManager.INSTALL_EXTERNAL 11940 |PackageManager.INSTALL_INTERNAL); 11941 } else { 11942 // Make sure the flag for installing on external 11943 // media is unset 11944 installFlags |= PackageManager.INSTALL_INTERNAL; 11945 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 11946 } 11947 } 11948 } 11949 } 11950 11951 final InstallArgs args = createInstallArgs(this); 11952 mArgs = args; 11953 11954 if (ret == PackageManager.INSTALL_SUCCEEDED) { 11955 // TODO: http://b/22976637 11956 // Apps installed for "all" users use the device owner to verify the app 11957 UserHandle verifierUser = getUser(); 11958 if (verifierUser == UserHandle.ALL) { 11959 verifierUser = UserHandle.SYSTEM; 11960 } 11961 11962 /* 11963 * Determine if we have any installed package verifiers. If we 11964 * do, then we'll defer to them to verify the packages. 11965 */ 11966 final int requiredUid = mRequiredVerifierPackage == null ? -1 11967 : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 11968 verifierUser.getIdentifier()); 11969 if (!origin.existing && requiredUid != -1 11970 && isVerificationEnabled(verifierUser.getIdentifier(), installFlags)) { 11971 final Intent verification = new Intent( 11972 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 11973 verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 11974 verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)), 11975 PACKAGE_MIME_TYPE); 11976 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 11977 11978 // Query all live verifiers based on current user state 11979 final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification, 11980 PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier()); 11981 11982 if (DEBUG_VERIFY) { 11983 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent " 11984 + verification.toString() + " with " + pkgLite.verifiers.length 11985 + " optional verifiers"); 11986 } 11987 11988 final int verificationId = mPendingVerificationToken++; 11989 11990 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 11991 11992 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE, 11993 installerPackageName); 11994 11995 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, 11996 installFlags); 11997 11998 verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME, 11999 pkgLite.packageName); 12000 12001 verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE, 12002 pkgLite.versionCode); 12003 12004 if (verificationInfo != null) { 12005 if (verificationInfo.originatingUri != null) { 12006 verification.putExtra(Intent.EXTRA_ORIGINATING_URI, 12007 verificationInfo.originatingUri); 12008 } 12009 if (verificationInfo.referrer != null) { 12010 verification.putExtra(Intent.EXTRA_REFERRER, 12011 verificationInfo.referrer); 12012 } 12013 if (verificationInfo.originatingUid >= 0) { 12014 verification.putExtra(Intent.EXTRA_ORIGINATING_UID, 12015 verificationInfo.originatingUid); 12016 } 12017 if (verificationInfo.installerUid >= 0) { 12018 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID, 12019 verificationInfo.installerUid); 12020 } 12021 } 12022 12023 final PackageVerificationState verificationState = new PackageVerificationState( 12024 requiredUid, args); 12025 12026 mPendingVerification.append(verificationId, verificationState); 12027 12028 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite, 12029 receivers, verificationState); 12030 12031 /* 12032 * If any sufficient verifiers were listed in the package 12033 * manifest, attempt to ask them. 12034 */ 12035 if (sufficientVerifiers != null) { 12036 final int N = sufficientVerifiers.size(); 12037 if (N == 0) { 12038 Slog.i(TAG, "Additional verifiers required, but none installed."); 12039 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 12040 } else { 12041 for (int i = 0; i < N; i++) { 12042 final ComponentName verifierComponent = sufficientVerifiers.get(i); 12043 12044 final Intent sufficientIntent = new Intent(verification); 12045 sufficientIntent.setComponent(verifierComponent); 12046 mContext.sendBroadcastAsUser(sufficientIntent, verifierUser); 12047 } 12048 } 12049 } 12050 12051 final ComponentName requiredVerifierComponent = matchComponentForVerifier( 12052 mRequiredVerifierPackage, receivers); 12053 if (ret == PackageManager.INSTALL_SUCCEEDED 12054 && mRequiredVerifierPackage != null) { 12055 Trace.asyncTraceBegin( 12056 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 12057 /* 12058 * Send the intent to the required verification agent, 12059 * but only start the verification timeout after the 12060 * target BroadcastReceivers have run. 12061 */ 12062 verification.setComponent(requiredVerifierComponent); 12063 mContext.sendOrderedBroadcastAsUser(verification, verifierUser, 12064 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 12065 new BroadcastReceiver() { 12066 @Override 12067 public void onReceive(Context context, Intent intent) { 12068 final Message msg = mHandler 12069 .obtainMessage(CHECK_PENDING_VERIFICATION); 12070 msg.arg1 = verificationId; 12071 mHandler.sendMessageDelayed(msg, getVerificationTimeout()); 12072 } 12073 }, null, 0, null, null); 12074 12075 /* 12076 * We don't want the copy to proceed until verification 12077 * succeeds, so null out this field. 12078 */ 12079 mArgs = null; 12080 } 12081 } else { 12082 /* 12083 * No package verification is enabled, so immediately start 12084 * the remote call to initiate copy using temporary file. 12085 */ 12086 ret = args.copyApk(mContainerService, true); 12087 } 12088 } 12089 12090 mRet = ret; 12091 } 12092 12093 @Override 12094 void handleReturnCode() { 12095 // If mArgs is null, then MCS couldn't be reached. When it 12096 // reconnects, it will try again to install. At that point, this 12097 // will succeed. 12098 if (mArgs != null) { 12099 processPendingInstall(mArgs, mRet); 12100 } 12101 } 12102 12103 @Override 12104 void handleServiceError() { 12105 mArgs = createInstallArgs(this); 12106 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 12107 } 12108 12109 public boolean isForwardLocked() { 12110 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 12111 } 12112 } 12113 12114 /** 12115 * Used during creation of InstallArgs 12116 * 12117 * @param installFlags package installation flags 12118 * @return true if should be installed on external storage 12119 */ 12120 private static boolean installOnExternalAsec(int installFlags) { 12121 if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) { 12122 return false; 12123 } 12124 if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) { 12125 return true; 12126 } 12127 return false; 12128 } 12129 12130 /** 12131 * Used during creation of InstallArgs 12132 * 12133 * @param installFlags package installation flags 12134 * @return true if should be installed as forward locked 12135 */ 12136 private static boolean installForwardLocked(int installFlags) { 12137 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 12138 } 12139 12140 private InstallArgs createInstallArgs(InstallParams params) { 12141 if (params.move != null) { 12142 return new MoveInstallArgs(params); 12143 } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) { 12144 return new AsecInstallArgs(params); 12145 } else { 12146 return new FileInstallArgs(params); 12147 } 12148 } 12149 12150 /** 12151 * Create args that describe an existing installed package. Typically used 12152 * when cleaning up old installs, or used as a move source. 12153 */ 12154 private InstallArgs createInstallArgsForExisting(int installFlags, String codePath, 12155 String resourcePath, String[] instructionSets) { 12156 final boolean isInAsec; 12157 if (installOnExternalAsec(installFlags)) { 12158 /* Apps on SD card are always in ASEC containers. */ 12159 isInAsec = true; 12160 } else if (installForwardLocked(installFlags) 12161 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) { 12162 /* 12163 * Forward-locked apps are only in ASEC containers if they're the 12164 * new style 12165 */ 12166 isInAsec = true; 12167 } else { 12168 isInAsec = false; 12169 } 12170 12171 if (isInAsec) { 12172 return new AsecInstallArgs(codePath, instructionSets, 12173 installOnExternalAsec(installFlags), installForwardLocked(installFlags)); 12174 } else { 12175 return new FileInstallArgs(codePath, resourcePath, instructionSets); 12176 } 12177 } 12178 12179 static abstract class InstallArgs { 12180 /** @see InstallParams#origin */ 12181 final OriginInfo origin; 12182 /** @see InstallParams#move */ 12183 final MoveInfo move; 12184 12185 final IPackageInstallObserver2 observer; 12186 // Always refers to PackageManager flags only 12187 final int installFlags; 12188 final String installerPackageName; 12189 final String volumeUuid; 12190 final UserHandle user; 12191 final String abiOverride; 12192 final String[] installGrantPermissions; 12193 /** If non-null, drop an async trace when the install completes */ 12194 final String traceMethod; 12195 final int traceCookie; 12196 12197 // The list of instruction sets supported by this app. This is currently 12198 // only used during the rmdex() phase to clean up resources. We can get rid of this 12199 // if we move dex files under the common app path. 12200 /* nullable */ String[] instructionSets; 12201 12202 InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 12203 int installFlags, String installerPackageName, String volumeUuid, 12204 UserHandle user, String[] instructionSets, 12205 String abiOverride, String[] installGrantPermissions, 12206 String traceMethod, int traceCookie) { 12207 this.origin = origin; 12208 this.move = move; 12209 this.installFlags = installFlags; 12210 this.observer = observer; 12211 this.installerPackageName = installerPackageName; 12212 this.volumeUuid = volumeUuid; 12213 this.user = user; 12214 this.instructionSets = instructionSets; 12215 this.abiOverride = abiOverride; 12216 this.installGrantPermissions = installGrantPermissions; 12217 this.traceMethod = traceMethod; 12218 this.traceCookie = traceCookie; 12219 } 12220 12221 abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException; 12222 abstract int doPreInstall(int status); 12223 12224 /** 12225 * Rename package into final resting place. All paths on the given 12226 * scanned package should be updated to reflect the rename. 12227 */ 12228 abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath); 12229 abstract int doPostInstall(int status, int uid); 12230 12231 /** @see PackageSettingBase#codePathString */ 12232 abstract String getCodePath(); 12233 /** @see PackageSettingBase#resourcePathString */ 12234 abstract String getResourcePath(); 12235 12236 // Need installer lock especially for dex file removal. 12237 abstract void cleanUpResourcesLI(); 12238 abstract boolean doPostDeleteLI(boolean delete); 12239 12240 /** 12241 * Called before the source arguments are copied. This is used mostly 12242 * for MoveParams when it needs to read the source file to put it in the 12243 * destination. 12244 */ 12245 int doPreCopy() { 12246 return PackageManager.INSTALL_SUCCEEDED; 12247 } 12248 12249 /** 12250 * Called after the source arguments are copied. This is used mostly for 12251 * MoveParams when it needs to read the source file to put it in the 12252 * destination. 12253 * 12254 * @return 12255 */ 12256 int doPostCopy(int uid) { 12257 return PackageManager.INSTALL_SUCCEEDED; 12258 } 12259 12260 protected boolean isFwdLocked() { 12261 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 12262 } 12263 12264 protected boolean isExternalAsec() { 12265 return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 12266 } 12267 12268 protected boolean isEphemeral() { 12269 return (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; 12270 } 12271 12272 UserHandle getUser() { 12273 return user; 12274 } 12275 } 12276 12277 private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) { 12278 if (!allCodePaths.isEmpty()) { 12279 if (instructionSets == null) { 12280 throw new IllegalStateException("instructionSet == null"); 12281 } 12282 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); 12283 for (String codePath : allCodePaths) { 12284 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 12285 try { 12286 mInstaller.rmdex(codePath, dexCodeInstructionSet); 12287 } catch (InstallerException ignored) { 12288 } 12289 } 12290 } 12291 } 12292 } 12293 12294 /** 12295 * Logic to handle installation of non-ASEC applications, including copying 12296 * and renaming logic. 12297 */ 12298 class FileInstallArgs extends InstallArgs { 12299 private File codeFile; 12300 private File resourceFile; 12301 12302 // Example topology: 12303 // /data/app/com.example/base.apk 12304 // /data/app/com.example/split_foo.apk 12305 // /data/app/com.example/lib/arm/libfoo.so 12306 // /data/app/com.example/lib/arm64/libfoo.so 12307 // /data/app/com.example/dalvik/arm/base.apk@classes.dex 12308 12309 /** New install */ 12310 FileInstallArgs(InstallParams params) { 12311 super(params.origin, params.move, params.observer, params.installFlags, 12312 params.installerPackageName, params.volumeUuid, 12313 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 12314 params.grantedRuntimePermissions, 12315 params.traceMethod, params.traceCookie); 12316 if (isFwdLocked()) { 12317 throw new IllegalArgumentException("Forward locking only supported in ASEC"); 12318 } 12319 } 12320 12321 /** Existing install */ 12322 FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) { 12323 super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets, 12324 null, null, null, 0); 12325 this.codeFile = (codePath != null) ? new File(codePath) : null; 12326 this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null; 12327 } 12328 12329 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 12330 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk"); 12331 try { 12332 return doCopyApk(imcs, temp); 12333 } finally { 12334 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 12335 } 12336 } 12337 12338 private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 12339 if (origin.staged) { 12340 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy"); 12341 codeFile = origin.file; 12342 resourceFile = origin.file; 12343 return PackageManager.INSTALL_SUCCEEDED; 12344 } 12345 12346 try { 12347 final boolean isEphemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; 12348 final File tempDir = 12349 mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral); 12350 codeFile = tempDir; 12351 resourceFile = tempDir; 12352 } catch (IOException e) { 12353 Slog.w(TAG, "Failed to create copy file: " + e); 12354 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 12355 } 12356 12357 final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() { 12358 @Override 12359 public ParcelFileDescriptor open(String name, int mode) throws RemoteException { 12360 if (!FileUtils.isValidExtFilename(name)) { 12361 throw new IllegalArgumentException("Invalid filename: " + name); 12362 } 12363 try { 12364 final File file = new File(codeFile, name); 12365 final FileDescriptor fd = Os.open(file.getAbsolutePath(), 12366 O_RDWR | O_CREAT, 0644); 12367 Os.chmod(file.getAbsolutePath(), 0644); 12368 return new ParcelFileDescriptor(fd); 12369 } catch (ErrnoException e) { 12370 throw new RemoteException("Failed to open: " + e.getMessage()); 12371 } 12372 } 12373 }; 12374 12375 int ret = PackageManager.INSTALL_SUCCEEDED; 12376 ret = imcs.copyPackage(origin.file.getAbsolutePath(), target); 12377 if (ret != PackageManager.INSTALL_SUCCEEDED) { 12378 Slog.e(TAG, "Failed to copy package"); 12379 return ret; 12380 } 12381 12382 final File libraryRoot = new File(codeFile, LIB_DIR_NAME); 12383 NativeLibraryHelper.Handle handle = null; 12384 try { 12385 handle = NativeLibraryHelper.Handle.create(codeFile); 12386 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot, 12387 abiOverride); 12388 } catch (IOException e) { 12389 Slog.e(TAG, "Copying native libraries failed", e); 12390 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 12391 } finally { 12392 IoUtils.closeQuietly(handle); 12393 } 12394 12395 return ret; 12396 } 12397 12398 int doPreInstall(int status) { 12399 if (status != PackageManager.INSTALL_SUCCEEDED) { 12400 cleanUp(); 12401 } 12402 return status; 12403 } 12404 12405 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 12406 if (status != PackageManager.INSTALL_SUCCEEDED) { 12407 cleanUp(); 12408 return false; 12409 } 12410 12411 final File targetDir = codeFile.getParentFile(); 12412 final File beforeCodeFile = codeFile; 12413 final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName); 12414 12415 if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile); 12416 try { 12417 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath()); 12418 } catch (ErrnoException e) { 12419 Slog.w(TAG, "Failed to rename", e); 12420 return false; 12421 } 12422 12423 if (!SELinux.restoreconRecursive(afterCodeFile)) { 12424 Slog.w(TAG, "Failed to restorecon"); 12425 return false; 12426 } 12427 12428 // Reflect the rename internally 12429 codeFile = afterCodeFile; 12430 resourceFile = afterCodeFile; 12431 12432 // Reflect the rename in scanned details 12433 pkg.setCodePath(afterCodeFile.getAbsolutePath()); 12434 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile, 12435 afterCodeFile, pkg.baseCodePath)); 12436 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile, 12437 afterCodeFile, pkg.splitCodePaths)); 12438 12439 // Reflect the rename in app info 12440 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 12441 pkg.setApplicationInfoCodePath(pkg.codePath); 12442 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 12443 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 12444 pkg.setApplicationInfoResourcePath(pkg.codePath); 12445 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 12446 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 12447 12448 return true; 12449 } 12450 12451 int doPostInstall(int status, int uid) { 12452 if (status != PackageManager.INSTALL_SUCCEEDED) { 12453 cleanUp(); 12454 } 12455 return status; 12456 } 12457 12458 @Override 12459 String getCodePath() { 12460 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 12461 } 12462 12463 @Override 12464 String getResourcePath() { 12465 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 12466 } 12467 12468 private boolean cleanUp() { 12469 if (codeFile == null || !codeFile.exists()) { 12470 return false; 12471 } 12472 12473 removeCodePathLI(codeFile); 12474 12475 if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) { 12476 resourceFile.delete(); 12477 } 12478 12479 return true; 12480 } 12481 12482 void cleanUpResourcesLI() { 12483 // Try enumerating all code paths before deleting 12484 List<String> allCodePaths = Collections.EMPTY_LIST; 12485 if (codeFile != null && codeFile.exists()) { 12486 try { 12487 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 12488 allCodePaths = pkg.getAllCodePaths(); 12489 } catch (PackageParserException e) { 12490 // Ignored; we tried our best 12491 } 12492 } 12493 12494 cleanUp(); 12495 removeDexFiles(allCodePaths, instructionSets); 12496 } 12497 12498 boolean doPostDeleteLI(boolean delete) { 12499 // XXX err, shouldn't we respect the delete flag? 12500 cleanUpResourcesLI(); 12501 return true; 12502 } 12503 } 12504 12505 private boolean isAsecExternal(String cid) { 12506 final String asecPath = PackageHelper.getSdFilesystem(cid); 12507 return !asecPath.startsWith(mAsecInternalPath); 12508 } 12509 12510 private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws 12511 PackageManagerException { 12512 if (copyRet < 0) { 12513 if (copyRet != PackageManager.NO_NATIVE_LIBRARIES && 12514 copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) { 12515 throw new PackageManagerException(copyRet, message); 12516 } 12517 } 12518 } 12519 12520 /** 12521 * Extract the MountService "container ID" from the full code path of an 12522 * .apk. 12523 */ 12524 static String cidFromCodePath(String fullCodePath) { 12525 int eidx = fullCodePath.lastIndexOf("/"); 12526 String subStr1 = fullCodePath.substring(0, eidx); 12527 int sidx = subStr1.lastIndexOf("/"); 12528 return subStr1.substring(sidx+1, eidx); 12529 } 12530 12531 /** 12532 * Logic to handle installation of ASEC applications, including copying and 12533 * renaming logic. 12534 */ 12535 class AsecInstallArgs extends InstallArgs { 12536 static final String RES_FILE_NAME = "pkg.apk"; 12537 static final String PUBLIC_RES_FILE_NAME = "res.zip"; 12538 12539 String cid; 12540 String packagePath; 12541 String resourcePath; 12542 12543 /** New install */ 12544 AsecInstallArgs(InstallParams params) { 12545 super(params.origin, params.move, params.observer, params.installFlags, 12546 params.installerPackageName, params.volumeUuid, 12547 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 12548 params.grantedRuntimePermissions, 12549 params.traceMethod, params.traceCookie); 12550 } 12551 12552 /** Existing install */ 12553 AsecInstallArgs(String fullCodePath, String[] instructionSets, 12554 boolean isExternal, boolean isForwardLocked) { 12555 super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0) 12556 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, 12557 instructionSets, null, null, null, 0); 12558 // Hackily pretend we're still looking at a full code path 12559 if (!fullCodePath.endsWith(RES_FILE_NAME)) { 12560 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath(); 12561 } 12562 12563 // Extract cid from fullCodePath 12564 int eidx = fullCodePath.lastIndexOf("/"); 12565 String subStr1 = fullCodePath.substring(0, eidx); 12566 int sidx = subStr1.lastIndexOf("/"); 12567 cid = subStr1.substring(sidx+1, eidx); 12568 setMountPath(subStr1); 12569 } 12570 12571 AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) { 12572 super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0) 12573 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, 12574 instructionSets, null, null, null, 0); 12575 this.cid = cid; 12576 setMountPath(PackageHelper.getSdDir(cid)); 12577 } 12578 12579 void createCopyFile() { 12580 cid = mInstallerService.allocateExternalStageCidLegacy(); 12581 } 12582 12583 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 12584 if (origin.staged && origin.cid != null) { 12585 if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy"); 12586 cid = origin.cid; 12587 setMountPath(PackageHelper.getSdDir(cid)); 12588 return PackageManager.INSTALL_SUCCEEDED; 12589 } 12590 12591 if (temp) { 12592 createCopyFile(); 12593 } else { 12594 /* 12595 * Pre-emptively destroy the container since it's destroyed if 12596 * copying fails due to it existing anyway. 12597 */ 12598 PackageHelper.destroySdDir(cid); 12599 } 12600 12601 final String newMountPath = imcs.copyPackageToContainer( 12602 origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(), 12603 isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */)); 12604 12605 if (newMountPath != null) { 12606 setMountPath(newMountPath); 12607 return PackageManager.INSTALL_SUCCEEDED; 12608 } else { 12609 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 12610 } 12611 } 12612 12613 @Override 12614 String getCodePath() { 12615 return packagePath; 12616 } 12617 12618 @Override 12619 String getResourcePath() { 12620 return resourcePath; 12621 } 12622 12623 int doPreInstall(int status) { 12624 if (status != PackageManager.INSTALL_SUCCEEDED) { 12625 // Destroy container 12626 PackageHelper.destroySdDir(cid); 12627 } else { 12628 boolean mounted = PackageHelper.isContainerMounted(cid); 12629 if (!mounted) { 12630 String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(), 12631 Process.SYSTEM_UID); 12632 if (newMountPath != null) { 12633 setMountPath(newMountPath); 12634 } else { 12635 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 12636 } 12637 } 12638 } 12639 return status; 12640 } 12641 12642 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 12643 String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME); 12644 String newMountPath = null; 12645 if (PackageHelper.isContainerMounted(cid)) { 12646 // Unmount the container 12647 if (!PackageHelper.unMountSdDir(cid)) { 12648 Slog.i(TAG, "Failed to unmount " + cid + " before renaming"); 12649 return false; 12650 } 12651 } 12652 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 12653 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId + 12654 " which might be stale. Will try to clean up."); 12655 // Clean up the stale container and proceed to recreate. 12656 if (!PackageHelper.destroySdDir(newCacheId)) { 12657 Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId); 12658 return false; 12659 } 12660 // Successfully cleaned up stale container. Try to rename again. 12661 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 12662 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId 12663 + " inspite of cleaning it up."); 12664 return false; 12665 } 12666 } 12667 if (!PackageHelper.isContainerMounted(newCacheId)) { 12668 Slog.w(TAG, "Mounting container " + newCacheId); 12669 newMountPath = PackageHelper.mountSdDir(newCacheId, 12670 getEncryptKey(), Process.SYSTEM_UID); 12671 } else { 12672 newMountPath = PackageHelper.getSdDir(newCacheId); 12673 } 12674 if (newMountPath == null) { 12675 Slog.w(TAG, "Failed to get cache path for " + newCacheId); 12676 return false; 12677 } 12678 Log.i(TAG, "Succesfully renamed " + cid + 12679 " to " + newCacheId + 12680 " at new path: " + newMountPath); 12681 cid = newCacheId; 12682 12683 final File beforeCodeFile = new File(packagePath); 12684 setMountPath(newMountPath); 12685 final File afterCodeFile = new File(packagePath); 12686 12687 // Reflect the rename in scanned details 12688 pkg.setCodePath(afterCodeFile.getAbsolutePath()); 12689 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile, 12690 afterCodeFile, pkg.baseCodePath)); 12691 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile, 12692 afterCodeFile, pkg.splitCodePaths)); 12693 12694 // Reflect the rename in app info 12695 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 12696 pkg.setApplicationInfoCodePath(pkg.codePath); 12697 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 12698 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 12699 pkg.setApplicationInfoResourcePath(pkg.codePath); 12700 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 12701 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 12702 12703 return true; 12704 } 12705 12706 private void setMountPath(String mountPath) { 12707 final File mountFile = new File(mountPath); 12708 12709 final File monolithicFile = new File(mountFile, RES_FILE_NAME); 12710 if (monolithicFile.exists()) { 12711 packagePath = monolithicFile.getAbsolutePath(); 12712 if (isFwdLocked()) { 12713 resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath(); 12714 } else { 12715 resourcePath = packagePath; 12716 } 12717 } else { 12718 packagePath = mountFile.getAbsolutePath(); 12719 resourcePath = packagePath; 12720 } 12721 } 12722 12723 int doPostInstall(int status, int uid) { 12724 if (status != PackageManager.INSTALL_SUCCEEDED) { 12725 cleanUp(); 12726 } else { 12727 final int groupOwner; 12728 final String protectedFile; 12729 if (isFwdLocked()) { 12730 groupOwner = UserHandle.getSharedAppGid(uid); 12731 protectedFile = RES_FILE_NAME; 12732 } else { 12733 groupOwner = -1; 12734 protectedFile = null; 12735 } 12736 12737 if (uid < Process.FIRST_APPLICATION_UID 12738 || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) { 12739 Slog.e(TAG, "Failed to finalize " + cid); 12740 PackageHelper.destroySdDir(cid); 12741 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 12742 } 12743 12744 boolean mounted = PackageHelper.isContainerMounted(cid); 12745 if (!mounted) { 12746 PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid()); 12747 } 12748 } 12749 return status; 12750 } 12751 12752 private void cleanUp() { 12753 if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp"); 12754 12755 // Destroy secure container 12756 PackageHelper.destroySdDir(cid); 12757 } 12758 12759 private List<String> getAllCodePaths() { 12760 final File codeFile = new File(getCodePath()); 12761 if (codeFile != null && codeFile.exists()) { 12762 try { 12763 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 12764 return pkg.getAllCodePaths(); 12765 } catch (PackageParserException e) { 12766 // Ignored; we tried our best 12767 } 12768 } 12769 return Collections.EMPTY_LIST; 12770 } 12771 12772 void cleanUpResourcesLI() { 12773 // Enumerate all code paths before deleting 12774 cleanUpResourcesLI(getAllCodePaths()); 12775 } 12776 12777 private void cleanUpResourcesLI(List<String> allCodePaths) { 12778 cleanUp(); 12779 removeDexFiles(allCodePaths, instructionSets); 12780 } 12781 12782 String getPackageName() { 12783 return getAsecPackageName(cid); 12784 } 12785 12786 boolean doPostDeleteLI(boolean delete) { 12787 if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete); 12788 final List<String> allCodePaths = getAllCodePaths(); 12789 boolean mounted = PackageHelper.isContainerMounted(cid); 12790 if (mounted) { 12791 // Unmount first 12792 if (PackageHelper.unMountSdDir(cid)) { 12793 mounted = false; 12794 } 12795 } 12796 if (!mounted && delete) { 12797 cleanUpResourcesLI(allCodePaths); 12798 } 12799 return !mounted; 12800 } 12801 12802 @Override 12803 int doPreCopy() { 12804 if (isFwdLocked()) { 12805 if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE, 12806 MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) { 12807 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 12808 } 12809 } 12810 12811 return PackageManager.INSTALL_SUCCEEDED; 12812 } 12813 12814 @Override 12815 int doPostCopy(int uid) { 12816 if (isFwdLocked()) { 12817 if (uid < Process.FIRST_APPLICATION_UID 12818 || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid), 12819 RES_FILE_NAME)) { 12820 Slog.e(TAG, "Failed to finalize " + cid); 12821 PackageHelper.destroySdDir(cid); 12822 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 12823 } 12824 } 12825 12826 return PackageManager.INSTALL_SUCCEEDED; 12827 } 12828 } 12829 12830 /** 12831 * Logic to handle movement of existing installed applications. 12832 */ 12833 class MoveInstallArgs extends InstallArgs { 12834 private File codeFile; 12835 private File resourceFile; 12836 12837 /** New install */ 12838 MoveInstallArgs(InstallParams params) { 12839 super(params.origin, params.move, params.observer, params.installFlags, 12840 params.installerPackageName, params.volumeUuid, 12841 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 12842 params.grantedRuntimePermissions, 12843 params.traceMethod, params.traceCookie); 12844 } 12845 12846 int copyApk(IMediaContainerService imcs, boolean temp) { 12847 if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from " 12848 + move.fromUuid + " to " + move.toUuid); 12849 synchronized (mInstaller) { 12850 try { 12851 mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName, 12852 move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion); 12853 } catch (InstallerException e) { 12854 Slog.w(TAG, "Failed to move app", e); 12855 return PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 12856 } 12857 } 12858 12859 codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName); 12860 resourceFile = codeFile; 12861 if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile); 12862 12863 return PackageManager.INSTALL_SUCCEEDED; 12864 } 12865 12866 int doPreInstall(int status) { 12867 if (status != PackageManager.INSTALL_SUCCEEDED) { 12868 cleanUp(move.toUuid); 12869 } 12870 return status; 12871 } 12872 12873 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 12874 if (status != PackageManager.INSTALL_SUCCEEDED) { 12875 cleanUp(move.toUuid); 12876 return false; 12877 } 12878 12879 // Reflect the move in app info 12880 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 12881 pkg.setApplicationInfoCodePath(pkg.codePath); 12882 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 12883 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 12884 pkg.setApplicationInfoResourcePath(pkg.codePath); 12885 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 12886 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 12887 12888 return true; 12889 } 12890 12891 int doPostInstall(int status, int uid) { 12892 if (status == PackageManager.INSTALL_SUCCEEDED) { 12893 cleanUp(move.fromUuid); 12894 } else { 12895 cleanUp(move.toUuid); 12896 } 12897 return status; 12898 } 12899 12900 @Override 12901 String getCodePath() { 12902 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 12903 } 12904 12905 @Override 12906 String getResourcePath() { 12907 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 12908 } 12909 12910 private boolean cleanUp(String volumeUuid) { 12911 final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid), 12912 move.dataAppName); 12913 Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid); 12914 synchronized (mInstallLock) { 12915 // Clean up both app data and code 12916 removeDataDirsLI(volumeUuid, move.packageName); 12917 removeCodePathLI(codeFile); 12918 } 12919 return true; 12920 } 12921 12922 void cleanUpResourcesLI() { 12923 throw new UnsupportedOperationException(); 12924 } 12925 12926 boolean doPostDeleteLI(boolean delete) { 12927 throw new UnsupportedOperationException(); 12928 } 12929 } 12930 12931 static String getAsecPackageName(String packageCid) { 12932 int idx = packageCid.lastIndexOf("-"); 12933 if (idx == -1) { 12934 return packageCid; 12935 } 12936 return packageCid.substring(0, idx); 12937 } 12938 12939 // Utility method used to create code paths based on package name and available index. 12940 private static String getNextCodePath(String oldCodePath, String prefix, String suffix) { 12941 String idxStr = ""; 12942 int idx = 1; 12943 // Fall back to default value of idx=1 if prefix is not 12944 // part of oldCodePath 12945 if (oldCodePath != null) { 12946 String subStr = oldCodePath; 12947 // Drop the suffix right away 12948 if (suffix != null && subStr.endsWith(suffix)) { 12949 subStr = subStr.substring(0, subStr.length() - suffix.length()); 12950 } 12951 // If oldCodePath already contains prefix find out the 12952 // ending index to either increment or decrement. 12953 int sidx = subStr.lastIndexOf(prefix); 12954 if (sidx != -1) { 12955 subStr = subStr.substring(sidx + prefix.length()); 12956 if (subStr != null) { 12957 if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) { 12958 subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length()); 12959 } 12960 try { 12961 idx = Integer.parseInt(subStr); 12962 if (idx <= 1) { 12963 idx++; 12964 } else { 12965 idx--; 12966 } 12967 } catch(NumberFormatException e) { 12968 } 12969 } 12970 } 12971 } 12972 idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx); 12973 return prefix + idxStr; 12974 } 12975 12976 private File getNextCodePath(File targetDir, String packageName) { 12977 int suffix = 1; 12978 File result; 12979 do { 12980 result = new File(targetDir, packageName + "-" + suffix); 12981 suffix++; 12982 } while (result.exists()); 12983 return result; 12984 } 12985 12986 // Utility method that returns the relative package path with respect 12987 // to the installation directory. Like say for /data/data/com.test-1.apk 12988 // string com.test-1 is returned. 12989 static String deriveCodePathName(String codePath) { 12990 if (codePath == null) { 12991 return null; 12992 } 12993 final File codeFile = new File(codePath); 12994 final String name = codeFile.getName(); 12995 if (codeFile.isDirectory()) { 12996 return name; 12997 } else if (name.endsWith(".apk") || name.endsWith(".tmp")) { 12998 final int lastDot = name.lastIndexOf('.'); 12999 return name.substring(0, lastDot); 13000 } else { 13001 Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK"); 13002 return null; 13003 } 13004 } 13005 13006 static class PackageInstalledInfo { 13007 String name; 13008 int uid; 13009 // The set of users that originally had this package installed. 13010 int[] origUsers; 13011 // The set of users that now have this package installed. 13012 int[] newUsers; 13013 PackageParser.Package pkg; 13014 int returnCode; 13015 String returnMsg; 13016 PackageRemovedInfo removedInfo; 13017 ArrayMap<String, PackageInstalledInfo> addedChildPackages; 13018 13019 public void setError(int code, String msg) { 13020 setReturnCode(code); 13021 setReturnMessage(msg); 13022 Slog.w(TAG, msg); 13023 } 13024 13025 public void setError(String msg, PackageParserException e) { 13026 setReturnCode(e.error); 13027 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e)); 13028 Slog.w(TAG, msg, e); 13029 } 13030 13031 public void setError(String msg, PackageManagerException e) { 13032 returnCode = e.error; 13033 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e)); 13034 Slog.w(TAG, msg, e); 13035 } 13036 13037 public void setReturnCode(int returnCode) { 13038 this.returnCode = returnCode; 13039 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0; 13040 for (int i = 0; i < childCount; i++) { 13041 addedChildPackages.valueAt(i).returnCode = returnCode; 13042 } 13043 } 13044 13045 private void setReturnMessage(String returnMsg) { 13046 this.returnMsg = returnMsg; 13047 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0; 13048 for (int i = 0; i < childCount; i++) { 13049 addedChildPackages.valueAt(i).returnMsg = returnMsg; 13050 } 13051 } 13052 13053 // In some error cases we want to convey more info back to the observer 13054 String origPackage; 13055 String origPermission; 13056 } 13057 13058 /* 13059 * Install a non-existing package. 13060 */ 13061 private void installNewPackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, 13062 UserHandle user, String installerPackageName, String volumeUuid, 13063 PackageInstalledInfo res) { 13064 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage"); 13065 13066 // Remember this for later, in case we need to rollback this install 13067 String pkgName = pkg.packageName; 13068 13069 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg); 13070 13071 synchronized(mPackages) { 13072 if (mSettings.mRenamedPackages.containsKey(pkgName)) { 13073 // A package with the same name is already installed, though 13074 // it has been renamed to an older name. The package we 13075 // are trying to install should be installed as an update to 13076 // the existing one, but that has not been requested, so bail. 13077 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 13078 + " without first uninstalling package running as " 13079 + mSettings.mRenamedPackages.get(pkgName)); 13080 return; 13081 } 13082 if (mPackages.containsKey(pkgName)) { 13083 // Don't allow installation over an existing package with the same name. 13084 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 13085 + " without first uninstalling."); 13086 return; 13087 } 13088 } 13089 13090 try { 13091 PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags, 13092 System.currentTimeMillis(), user); 13093 13094 updateSettingsLI(newPackage, installerPackageName, null, res, user); 13095 13096 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 13097 prepareAppDataAfterInstall(newPackage); 13098 13099 } else { 13100 // Remove package from internal structures, but keep around any 13101 // data that might have already existed 13102 deletePackageLI(pkgName, UserHandle.ALL, false, null, 13103 PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null); 13104 } 13105 } catch (PackageManagerException e) { 13106 res.setError("Package couldn't be installed in " + pkg.codePath, e); 13107 } 13108 13109 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13110 } 13111 13112 private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) { 13113 // Can't rotate keys during boot or if sharedUser. 13114 if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null 13115 || !oldPs.keySetData.isUsingUpgradeKeySets()) { 13116 return false; 13117 } 13118 // app is using upgradeKeySets; make sure all are valid 13119 KeySetManagerService ksms = mSettings.mKeySetManagerService; 13120 long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets(); 13121 for (int i = 0; i < upgradeKeySets.length; i++) { 13122 if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) { 13123 Slog.wtf(TAG, "Package " 13124 + (oldPs.name != null ? oldPs.name : "<null>") 13125 + " contains upgrade-key-set reference to unknown key-set: " 13126 + upgradeKeySets[i] 13127 + " reverting to signatures check."); 13128 return false; 13129 } 13130 } 13131 return true; 13132 } 13133 13134 private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) { 13135 // Upgrade keysets are being used. Determine if new package has a superset of the 13136 // required keys. 13137 long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets(); 13138 KeySetManagerService ksms = mSettings.mKeySetManagerService; 13139 for (int i = 0; i < upgradeKeySets.length; i++) { 13140 Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]); 13141 if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) { 13142 return true; 13143 } 13144 } 13145 return false; 13146 } 13147 13148 private void replacePackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, 13149 UserHandle user, String installerPackageName, PackageInstalledInfo res) { 13150 final boolean isEphemeral = (parseFlags & PackageParser.PARSE_IS_EPHEMERAL) != 0; 13151 13152 final PackageParser.Package oldPackage; 13153 final String pkgName = pkg.packageName; 13154 final int[] allUsers; 13155 final boolean weFroze; 13156 13157 // First find the old package info and check signatures 13158 synchronized(mPackages) { 13159 oldPackage = mPackages.get(pkgName); 13160 final boolean oldIsEphemeral = oldPackage.applicationInfo.isEphemeralApp(); 13161 if (isEphemeral && !oldIsEphemeral) { 13162 // can't downgrade from full to ephemeral 13163 Slog.w(TAG, "Can't replace app with ephemeral: " + pkgName); 13164 res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID); 13165 return; 13166 } 13167 if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage); 13168 final PackageSetting ps = mSettings.mPackages.get(pkgName); 13169 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { 13170 if (!checkUpgradeKeySetLP(ps, pkg)) { 13171 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 13172 "New package not signed by keys specified by upgrade-keysets: " 13173 + pkgName); 13174 return; 13175 } 13176 } else { 13177 // default to original signature matching 13178 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures) 13179 != PackageManager.SIGNATURE_MATCH) { 13180 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 13181 "New package has a different signature: " + pkgName); 13182 return; 13183 } 13184 } 13185 13186 // In case of rollback, remember per-user/profile install state 13187 allUsers = sUserManager.getUserIds(); 13188 13189 // Mark the app as frozen to prevent launching during the upgrade 13190 // process, and then kill all running instances 13191 if (!ps.frozen) { 13192 ps.frozen = true; 13193 weFroze = true; 13194 } else { 13195 weFroze = false; 13196 } 13197 } 13198 13199 try { 13200 replacePackageDirtyLI(pkg, oldPackage, parseFlags, scanFlags, user, allUsers, 13201 installerPackageName, res); 13202 } finally { 13203 // Regardless of success or failure of upgrade steps above, always 13204 // unfreeze the package if we froze it 13205 if (weFroze) { 13206 unfreezePackage(pkgName); 13207 } 13208 } 13209 } 13210 13211 private void replacePackageDirtyLI(PackageParser.Package pkg, PackageParser.Package oldPackage, 13212 int parseFlags, int scanFlags, UserHandle user, int[] allUsers, 13213 String installerPackageName, PackageInstalledInfo res) { 13214 // Update what is removed 13215 res.removedInfo = new PackageRemovedInfo(); 13216 res.removedInfo.uid = oldPackage.applicationInfo.uid; 13217 res.removedInfo.removedPackage = oldPackage.packageName; 13218 res.removedInfo.isUpdate = true; 13219 final int childCount = (oldPackage.childPackages != null) 13220 ? oldPackage.childPackages.size() : 0; 13221 for (int i = 0; i < childCount; i++) { 13222 boolean childPackageUpdated = false; 13223 PackageParser.Package childPkg = oldPackage.childPackages.get(i); 13224 if (res.addedChildPackages != null) { 13225 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName); 13226 if (childRes != null) { 13227 childRes.removedInfo.uid = childPkg.applicationInfo.uid; 13228 childRes.removedInfo.removedPackage = childPkg.packageName; 13229 childRes.removedInfo.isUpdate = true; 13230 childPackageUpdated = true; 13231 } 13232 } 13233 if (!childPackageUpdated) { 13234 PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(); 13235 childRemovedRes.removedPackage = childPkg.packageName; 13236 childRemovedRes.isUpdate = false; 13237 childRemovedRes.dataRemoved = true; 13238 synchronized (mPackages) { 13239 PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName); 13240 if (childPs != null) { 13241 childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true); 13242 } 13243 } 13244 if (res.removedInfo.removedChildPackages == null) { 13245 res.removedInfo.removedChildPackages = new ArrayMap<>(); 13246 } 13247 res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes); 13248 } 13249 } 13250 13251 boolean sysPkg = (isSystemApp(oldPackage)); 13252 if (sysPkg) { 13253 replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags, 13254 user, allUsers, installerPackageName, res); 13255 } else { 13256 replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags, 13257 user, allUsers, installerPackageName, res); 13258 } 13259 } 13260 13261 public List<String> getPreviousCodePaths(String packageName) { 13262 final PackageSetting ps = mSettings.mPackages.get(packageName); 13263 final List<String> result = new ArrayList<String>(); 13264 if (ps != null && ps.oldCodePaths != null) { 13265 result.addAll(ps.oldCodePaths); 13266 } 13267 return result; 13268 } 13269 13270 private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage, 13271 PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, 13272 int[] allUsers, String installerPackageName, PackageInstalledInfo res) { 13273 if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old=" 13274 + deletedPackage); 13275 13276 String pkgName = deletedPackage.packageName; 13277 boolean deletedPkg = true; 13278 boolean addedPkg = false; 13279 boolean updatedSettings = false; 13280 final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0; 13281 final int deleteFlags = PackageManager.DELETE_KEEP_DATA 13282 | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP); 13283 13284 final long origUpdateTime = (pkg.mExtras != null) 13285 ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0; 13286 13287 // First delete the existing package while retaining the data directory 13288 if (!deletePackageLI(pkgName, null, true, allUsers, deleteFlags, 13289 res.removedInfo, true, pkg)) { 13290 // If the existing package wasn't successfully deleted 13291 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI"); 13292 deletedPkg = false; 13293 } else { 13294 // Successfully deleted the old package; proceed with replace. 13295 13296 // If deleted package lived in a container, give users a chance to 13297 // relinquish resources before killing. 13298 if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) { 13299 if (DEBUG_INSTALL) { 13300 Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE"); 13301 } 13302 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid }; 13303 final ArrayList<String> pkgList = new ArrayList<String>(1); 13304 pkgList.add(deletedPackage.applicationInfo.packageName); 13305 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null); 13306 } 13307 13308 deleteCodeCacheDirsLI(pkg); 13309 deleteProfilesLI(pkg, /*destroy*/ false); 13310 13311 try { 13312 final PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags, 13313 scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user); 13314 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user); 13315 13316 // Update the in-memory copy of the previous code paths. 13317 PackageSetting ps = mSettings.mPackages.get(pkgName); 13318 if (!killApp) { 13319 if (ps.oldCodePaths == null) { 13320 ps.oldCodePaths = new ArraySet<>(); 13321 } 13322 Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath); 13323 if (deletedPackage.splitCodePaths != null) { 13324 Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths); 13325 } 13326 } else { 13327 ps.oldCodePaths = null; 13328 } 13329 if (ps.childPackageNames != null) { 13330 for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) { 13331 final String childPkgName = ps.childPackageNames.get(i); 13332 final PackageSetting childPs = mSettings.mPackages.get(childPkgName); 13333 childPs.oldCodePaths = ps.oldCodePaths; 13334 } 13335 } 13336 prepareAppDataAfterInstall(newPackage); 13337 addedPkg = true; 13338 } catch (PackageManagerException e) { 13339 res.setError("Package couldn't be installed in " + pkg.codePath, e); 13340 } 13341 } 13342 13343 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 13344 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName); 13345 13346 // Revert all internal state mutations and added folders for the failed install 13347 if (addedPkg) { 13348 deletePackageLI(pkgName, null, true, allUsers, deleteFlags, 13349 res.removedInfo, true, null); 13350 } 13351 13352 // Restore the old package 13353 if (deletedPkg) { 13354 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage); 13355 File restoreFile = new File(deletedPackage.codePath); 13356 // Parse old package 13357 boolean oldExternal = isExternal(deletedPackage); 13358 int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY | 13359 (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) | 13360 (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0); 13361 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME; 13362 try { 13363 scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, 13364 null); 13365 } catch (PackageManagerException e) { 13366 Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: " 13367 + e.getMessage()); 13368 return; 13369 } 13370 13371 synchronized (mPackages) { 13372 // Ensure the installer package name up to date 13373 setInstallerPackageNameLPw(deletedPackage, installerPackageName); 13374 13375 // Update permissions for restored package 13376 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL); 13377 13378 mSettings.writeLPr(); 13379 } 13380 13381 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade"); 13382 } 13383 } else { 13384 synchronized (mPackages) { 13385 PackageSetting ps = mSettings.peekPackageLPr(pkg.packageName); 13386 if (ps != null) { 13387 res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null; 13388 if (res.removedInfo.removedChildPackages != null) { 13389 final int childCount = res.removedInfo.removedChildPackages.size(); 13390 // Iterate in reverse as we may modify the collection 13391 for (int i = childCount - 1; i >= 0; i--) { 13392 String childPackageName = res.removedInfo.removedChildPackages.keyAt(i); 13393 if (res.addedChildPackages.containsKey(childPackageName)) { 13394 res.removedInfo.removedChildPackages.removeAt(i); 13395 } else { 13396 PackageRemovedInfo childInfo = res.removedInfo 13397 .removedChildPackages.valueAt(i); 13398 childInfo.removedForAllUsers = mPackages.get( 13399 childInfo.removedPackage) == null; 13400 } 13401 } 13402 } 13403 } 13404 } 13405 } 13406 } 13407 13408 private void replaceSystemPackageLI(PackageParser.Package deletedPackage, 13409 PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, 13410 int[] allUsers, String installerPackageName, PackageInstalledInfo res) { 13411 if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg 13412 + ", old=" + deletedPackage); 13413 13414 final boolean disabledSystem; 13415 13416 // Set the system/privileged flags as needed 13417 parseFlags |= PackageParser.PARSE_IS_SYSTEM; 13418 if ((deletedPackage.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) 13419 != 0) { 13420 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 13421 } 13422 13423 // Kill package processes including services, providers, etc. 13424 killPackage(deletedPackage, "replace sys pkg"); 13425 13426 // Remove existing system package 13427 removePackageLI(deletedPackage, true); 13428 13429 disabledSystem = disableSystemPackageLPw(deletedPackage, pkg); 13430 if (!disabledSystem) { 13431 // We didn't need to disable the .apk as a current system package, 13432 // which means we are replacing another update that is already 13433 // installed. We need to make sure to delete the older one's .apk. 13434 res.removedInfo.args = createInstallArgsForExisting(0, 13435 deletedPackage.applicationInfo.getCodePath(), 13436 deletedPackage.applicationInfo.getResourcePath(), 13437 getAppDexInstructionSets(deletedPackage.applicationInfo)); 13438 } else { 13439 res.removedInfo.args = null; 13440 } 13441 13442 // Successfully disabled the old package. Now proceed with re-installation 13443 deleteCodeCacheDirsLI(pkg); 13444 deleteProfilesLI(pkg, /*destroy*/ false); 13445 13446 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 13447 pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP, 13448 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP); 13449 13450 PackageParser.Package newPackage = null; 13451 try { 13452 // Add the package to the internal data structures 13453 newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags, 0, user); 13454 13455 // Set the update and install times 13456 PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras; 13457 setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime, 13458 System.currentTimeMillis()); 13459 13460 // Check for shared user id changes 13461 String invalidPackageName = getParentOrChildPackageChangedSharedUser( 13462 deletedPackage, newPackage); 13463 if (invalidPackageName != null) { 13464 res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 13465 "Forbidding shared user change from " + deletedPkgSetting.sharedUser 13466 + " to " + invalidPackageName); 13467 } 13468 13469 // Update the package dynamic state if succeeded 13470 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 13471 // Now that the install succeeded make sure we remove data 13472 // directories for any child package the update removed. 13473 final int deletedChildCount = (deletedPackage.childPackages != null) 13474 ? deletedPackage.childPackages.size() : 0; 13475 final int newChildCount = (newPackage.childPackages != null) 13476 ? newPackage.childPackages.size() : 0; 13477 for (int i = 0; i < deletedChildCount; i++) { 13478 PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i); 13479 boolean childPackageDeleted = true; 13480 for (int j = 0; j < newChildCount; j++) { 13481 PackageParser.Package newChildPkg = newPackage.childPackages.get(j); 13482 if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) { 13483 childPackageDeleted = false; 13484 break; 13485 } 13486 } 13487 if (childPackageDeleted) { 13488 PackageSetting ps = mSettings.getDisabledSystemPkgLPr( 13489 deletedChildPkg.packageName); 13490 if (ps != null && res.removedInfo.removedChildPackages != null) { 13491 PackageRemovedInfo removedChildRes = res.removedInfo 13492 .removedChildPackages.get(deletedChildPkg.packageName); 13493 removePackageDataLI(ps, allUsers, removedChildRes, 0, false); 13494 removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null; 13495 } 13496 } 13497 } 13498 13499 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user); 13500 prepareAppDataAfterInstall(newPackage); 13501 } 13502 } catch (PackageManagerException e) { 13503 res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR); 13504 res.setError("Package couldn't be installed in " + pkg.codePath, e); 13505 } 13506 13507 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 13508 // Re installation failed. Restore old information 13509 // Remove new pkg information 13510 if (newPackage != null) { 13511 removeInstalledPackageLI(newPackage, true); 13512 } 13513 // Add back the old system package 13514 try { 13515 scanPackageTracedLI(deletedPackage, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user); 13516 } catch (PackageManagerException e) { 13517 Slog.e(TAG, "Failed to restore original package: " + e.getMessage()); 13518 } 13519 13520 synchronized (mPackages) { 13521 if (disabledSystem) { 13522 enableSystemPackageLPw(deletedPackage); 13523 } 13524 13525 // Ensure the installer package name up to date 13526 setInstallerPackageNameLPw(deletedPackage, installerPackageName); 13527 13528 // Update permissions for restored package 13529 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL); 13530 13531 mSettings.writeLPr(); 13532 } 13533 13534 Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName 13535 + " after failed upgrade"); 13536 } 13537 } 13538 13539 /** 13540 * Checks whether the parent or any of the child packages have a change shared 13541 * user. For a package to be a valid update the shred users of the parent and 13542 * the children should match. We may later support changing child shared users. 13543 * @param oldPkg The updated package. 13544 * @param newPkg The update package. 13545 * @return The shared user that change between the versions. 13546 */ 13547 private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg, 13548 PackageParser.Package newPkg) { 13549 // Check parent shared user 13550 if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) { 13551 return newPkg.packageName; 13552 } 13553 // Check child shared users 13554 final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0; 13555 final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0; 13556 for (int i = 0; i < newChildCount; i++) { 13557 PackageParser.Package newChildPkg = newPkg.childPackages.get(i); 13558 // If this child was present, did it have the same shared user? 13559 for (int j = 0; j < oldChildCount; j++) { 13560 PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j); 13561 if (newChildPkg.packageName.equals(oldChildPkg.packageName) 13562 && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) { 13563 return newChildPkg.packageName; 13564 } 13565 } 13566 } 13567 return null; 13568 } 13569 13570 private void removeNativeBinariesLI(PackageSetting ps) { 13571 // Remove the lib path for the parent package 13572 if (ps != null) { 13573 NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString); 13574 // Remove the lib path for the child packages 13575 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0; 13576 for (int i = 0; i < childCount; i++) { 13577 PackageSetting childPs = null; 13578 synchronized (mPackages) { 13579 childPs = mSettings.peekPackageLPr(ps.childPackageNames.get(i)); 13580 } 13581 if (childPs != null) { 13582 NativeLibraryHelper.removeNativeBinariesLI(childPs 13583 .legacyNativeLibraryPathString); 13584 } 13585 } 13586 } 13587 } 13588 13589 private void enableSystemPackageLPw(PackageParser.Package pkg) { 13590 // Enable the parent package 13591 mSettings.enableSystemPackageLPw(pkg.packageName); 13592 // Enable the child packages 13593 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 13594 for (int i = 0; i < childCount; i++) { 13595 PackageParser.Package childPkg = pkg.childPackages.get(i); 13596 mSettings.enableSystemPackageLPw(childPkg.packageName); 13597 } 13598 } 13599 13600 private boolean disableSystemPackageLPw(PackageParser.Package oldPkg, 13601 PackageParser.Package newPkg) { 13602 // Disable the parent package (parent always replaced) 13603 boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true); 13604 // Disable the child packages 13605 final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0; 13606 for (int i = 0; i < childCount; i++) { 13607 PackageParser.Package childPkg = oldPkg.childPackages.get(i); 13608 final boolean replace = newPkg.hasChildPackage(childPkg.packageName); 13609 disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace); 13610 } 13611 return disabled; 13612 } 13613 13614 private void setInstallerPackageNameLPw(PackageParser.Package pkg, 13615 String installerPackageName) { 13616 // Enable the parent package 13617 mSettings.setInstallerPackageName(pkg.packageName, installerPackageName); 13618 // Enable the child packages 13619 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 13620 for (int i = 0; i < childCount; i++) { 13621 PackageParser.Package childPkg = pkg.childPackages.get(i); 13622 mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName); 13623 } 13624 } 13625 13626 private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) { 13627 // Collect all used permissions in the UID 13628 ArraySet<String> usedPermissions = new ArraySet<>(); 13629 final int packageCount = su.packages.size(); 13630 for (int i = 0; i < packageCount; i++) { 13631 PackageSetting ps = su.packages.valueAt(i); 13632 if (ps.pkg == null) { 13633 continue; 13634 } 13635 final int requestedPermCount = ps.pkg.requestedPermissions.size(); 13636 for (int j = 0; j < requestedPermCount; j++) { 13637 String permission = ps.pkg.requestedPermissions.get(j); 13638 BasePermission bp = mSettings.mPermissions.get(permission); 13639 if (bp != null) { 13640 usedPermissions.add(permission); 13641 } 13642 } 13643 } 13644 13645 PermissionsState permissionsState = su.getPermissionsState(); 13646 // Prune install permissions 13647 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates(); 13648 final int installPermCount = installPermStates.size(); 13649 for (int i = installPermCount - 1; i >= 0; i--) { 13650 PermissionState permissionState = installPermStates.get(i); 13651 if (!usedPermissions.contains(permissionState.getName())) { 13652 BasePermission bp = mSettings.mPermissions.get(permissionState.getName()); 13653 if (bp != null) { 13654 permissionsState.revokeInstallPermission(bp); 13655 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 13656 PackageManager.MASK_PERMISSION_FLAGS, 0); 13657 } 13658 } 13659 } 13660 13661 int[] runtimePermissionChangedUserIds = EmptyArray.INT; 13662 13663 // Prune runtime permissions 13664 for (int userId : allUserIds) { 13665 List<PermissionState> runtimePermStates = permissionsState 13666 .getRuntimePermissionStates(userId); 13667 final int runtimePermCount = runtimePermStates.size(); 13668 for (int i = runtimePermCount - 1; i >= 0; i--) { 13669 PermissionState permissionState = runtimePermStates.get(i); 13670 if (!usedPermissions.contains(permissionState.getName())) { 13671 BasePermission bp = mSettings.mPermissions.get(permissionState.getName()); 13672 if (bp != null) { 13673 permissionsState.revokeRuntimePermission(bp, userId); 13674 permissionsState.updatePermissionFlags(bp, userId, 13675 PackageManager.MASK_PERMISSION_FLAGS, 0); 13676 runtimePermissionChangedUserIds = ArrayUtils.appendInt( 13677 runtimePermissionChangedUserIds, userId); 13678 } 13679 } 13680 } 13681 } 13682 13683 return runtimePermissionChangedUserIds; 13684 } 13685 13686 private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, 13687 int[] allUsers, PackageInstalledInfo res, UserHandle user) { 13688 // Update the parent package setting 13689 updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers, 13690 res, user); 13691 // Update the child packages setting 13692 final int childCount = (newPackage.childPackages != null) 13693 ? newPackage.childPackages.size() : 0; 13694 for (int i = 0; i < childCount; i++) { 13695 PackageParser.Package childPackage = newPackage.childPackages.get(i); 13696 PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName); 13697 updateSettingsInternalLI(childPackage, installerPackageName, allUsers, 13698 childRes.origUsers, childRes, user); 13699 } 13700 } 13701 13702 private void updateSettingsInternalLI(PackageParser.Package newPackage, 13703 String installerPackageName, int[] allUsers, int[] installedForUsers, 13704 PackageInstalledInfo res, UserHandle user) { 13705 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 13706 13707 String pkgName = newPackage.packageName; 13708 synchronized (mPackages) { 13709 //write settings. the installStatus will be incomplete at this stage. 13710 //note that the new package setting would have already been 13711 //added to mPackages. It hasn't been persisted yet. 13712 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE); 13713 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings"); 13714 mSettings.writeLPr(); 13715 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13716 } 13717 13718 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath); 13719 synchronized (mPackages) { 13720 updatePermissionsLPw(newPackage.packageName, newPackage, 13721 UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0 13722 ? UPDATE_PERMISSIONS_ALL : 0)); 13723 // For system-bundled packages, we assume that installing an upgraded version 13724 // of the package implies that the user actually wants to run that new code, 13725 // so we enable the package. 13726 PackageSetting ps = mSettings.mPackages.get(pkgName); 13727 final int userId = user.getIdentifier(); 13728 if (ps != null) { 13729 if (isSystemApp(newPackage)) { 13730 if (DEBUG_INSTALL) { 13731 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName); 13732 } 13733 // Enable system package for requested users 13734 if (res.origUsers != null) { 13735 for (int origUserId : res.origUsers) { 13736 if (userId == UserHandle.USER_ALL || userId == origUserId) { 13737 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 13738 origUserId, installerPackageName); 13739 } 13740 } 13741 } 13742 // Also convey the prior install/uninstall state 13743 if (allUsers != null && installedForUsers != null) { 13744 for (int currentUserId : allUsers) { 13745 final boolean installed = ArrayUtils.contains( 13746 installedForUsers, currentUserId); 13747 if (DEBUG_INSTALL) { 13748 Slog.d(TAG, " user " + currentUserId + " => " + installed); 13749 } 13750 ps.setInstalled(installed, currentUserId); 13751 } 13752 // these install state changes will be persisted in the 13753 // upcoming call to mSettings.writeLPr(). 13754 } 13755 } 13756 // It's implied that when a user requests installation, they want the app to be 13757 // installed and enabled. 13758 if (userId != UserHandle.USER_ALL) { 13759 ps.setInstalled(true, userId); 13760 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName); 13761 } 13762 } 13763 res.name = pkgName; 13764 res.uid = newPackage.applicationInfo.uid; 13765 res.pkg = newPackage; 13766 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE); 13767 mSettings.setInstallerPackageName(pkgName, installerPackageName); 13768 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 13769 //to update install status 13770 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings"); 13771 mSettings.writeLPr(); 13772 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13773 } 13774 13775 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13776 } 13777 13778 private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) { 13779 try { 13780 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage"); 13781 installPackageLI(args, res); 13782 } finally { 13783 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13784 } 13785 } 13786 13787 private void installPackageLI(InstallArgs args, PackageInstalledInfo res) { 13788 final int installFlags = args.installFlags; 13789 final String installerPackageName = args.installerPackageName; 13790 final String volumeUuid = args.volumeUuid; 13791 final File tmpPackageFile = new File(args.getCodePath()); 13792 final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0); 13793 final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) 13794 || (args.volumeUuid != null)); 13795 final boolean ephemeral = ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0); 13796 boolean replace = false; 13797 int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE; 13798 if (args.move != null) { 13799 // moving a complete application; perform an initial scan on the new install location 13800 scanFlags |= SCAN_INITIAL; 13801 } 13802 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) { 13803 scanFlags |= SCAN_DONT_KILL_APP; 13804 } 13805 13806 // Result object to be returned 13807 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 13808 13809 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile); 13810 13811 // Sanity check 13812 if (ephemeral && (forwardLocked || onExternal)) { 13813 Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked 13814 + " external=" + onExternal); 13815 res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID); 13816 return; 13817 } 13818 13819 // Retrieve PackageSettings and parse package 13820 final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY 13821 | PackageParser.PARSE_ENFORCE_CODE 13822 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) 13823 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0) 13824 | (ephemeral ? PackageParser.PARSE_IS_EPHEMERAL : 0); 13825 PackageParser pp = new PackageParser(); 13826 pp.setSeparateProcesses(mSeparateProcesses); 13827 pp.setDisplayMetrics(mMetrics); 13828 13829 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage"); 13830 final PackageParser.Package pkg; 13831 try { 13832 pkg = pp.parsePackage(tmpPackageFile, parseFlags); 13833 } catch (PackageParserException e) { 13834 res.setError("Failed parse during installPackageLI", e); 13835 return; 13836 } finally { 13837 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13838 } 13839 13840 // If we are installing a clustered package add results for the children 13841 if (pkg.childPackages != null) { 13842 synchronized (mPackages) { 13843 final int childCount = pkg.childPackages.size(); 13844 for (int i = 0; i < childCount; i++) { 13845 PackageParser.Package childPkg = pkg.childPackages.get(i); 13846 PackageInstalledInfo childRes = new PackageInstalledInfo(); 13847 childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 13848 childRes.pkg = childPkg; 13849 childRes.name = childPkg.packageName; 13850 PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName); 13851 if (childPs != null) { 13852 childRes.origUsers = childPs.queryInstalledUsers( 13853 sUserManager.getUserIds(), true); 13854 } 13855 if ((mPackages.containsKey(childPkg.packageName))) { 13856 childRes.removedInfo = new PackageRemovedInfo(); 13857 childRes.removedInfo.removedPackage = childPkg.packageName; 13858 } 13859 if (res.addedChildPackages == null) { 13860 res.addedChildPackages = new ArrayMap<>(); 13861 } 13862 res.addedChildPackages.put(childPkg.packageName, childRes); 13863 } 13864 } 13865 } 13866 13867 // If package doesn't declare API override, mark that we have an install 13868 // time CPU ABI override. 13869 if (TextUtils.isEmpty(pkg.cpuAbiOverride)) { 13870 pkg.cpuAbiOverride = args.abiOverride; 13871 } 13872 13873 String pkgName = res.name = pkg.packageName; 13874 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) { 13875 if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) { 13876 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI"); 13877 return; 13878 } 13879 } 13880 13881 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates"); 13882 try { 13883 PackageParser.collectCertificates(pkg, parseFlags); 13884 } catch (PackageParserException e) { 13885 res.setError("Failed collect during installPackageLI", e); 13886 return; 13887 } finally { 13888 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13889 } 13890 13891 // Get rid of all references to package scan path via parser. 13892 pp = null; 13893 String oldCodePath = null; 13894 boolean systemApp = false; 13895 synchronized (mPackages) { 13896 // Check if installing already existing package 13897 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 13898 String oldName = mSettings.mRenamedPackages.get(pkgName); 13899 if (pkg.mOriginalPackages != null 13900 && pkg.mOriginalPackages.contains(oldName) 13901 && mPackages.containsKey(oldName)) { 13902 // This package is derived from an original package, 13903 // and this device has been updating from that original 13904 // name. We must continue using the original name, so 13905 // rename the new package here. 13906 pkg.setPackageName(oldName); 13907 pkgName = pkg.packageName; 13908 replace = true; 13909 if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName=" 13910 + oldName + " pkgName=" + pkgName); 13911 } else if (mPackages.containsKey(pkgName)) { 13912 // This package, under its official name, already exists 13913 // on the device; we should replace it. 13914 replace = true; 13915 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName); 13916 } 13917 13918 // Child packages are installed through the parent package 13919 if (pkg.parentPackage != null) { 13920 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME, 13921 "Package " + pkg.packageName + " is child of package " 13922 + pkg.parentPackage.parentPackage + ". Child packages " 13923 + "can be updated only through the parent package."); 13924 return; 13925 } 13926 13927 if (replace) { 13928 // Prevent apps opting out from runtime permissions 13929 PackageParser.Package oldPackage = mPackages.get(pkgName); 13930 final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion; 13931 final int newTargetSdk = pkg.applicationInfo.targetSdkVersion; 13932 if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1 13933 && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) { 13934 res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE, 13935 "Package " + pkg.packageName + " new target SDK " + newTargetSdk 13936 + " doesn't support runtime permissions but the old" 13937 + " target SDK " + oldTargetSdk + " does."); 13938 return; 13939 } 13940 13941 // Prevent installing of child packages 13942 if (oldPackage.parentPackage != null) { 13943 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME, 13944 "Package " + pkg.packageName + " is child of package " 13945 + oldPackage.parentPackage + ". Child packages " 13946 + "can be updated only through the parent package."); 13947 return; 13948 } 13949 } 13950 } 13951 13952 PackageSetting ps = mSettings.mPackages.get(pkgName); 13953 if (ps != null) { 13954 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps); 13955 13956 // Quick sanity check that we're signed correctly if updating; 13957 // we'll check this again later when scanning, but we want to 13958 // bail early here before tripping over redefined permissions. 13959 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { 13960 if (!checkUpgradeKeySetLP(ps, pkg)) { 13961 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 13962 + pkg.packageName + " upgrade keys do not match the " 13963 + "previously installed version"); 13964 return; 13965 } 13966 } else { 13967 try { 13968 verifySignaturesLP(ps, pkg); 13969 } catch (PackageManagerException e) { 13970 res.setError(e.error, e.getMessage()); 13971 return; 13972 } 13973 } 13974 13975 oldCodePath = mSettings.mPackages.get(pkgName).codePathString; 13976 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 13977 systemApp = (ps.pkg.applicationInfo.flags & 13978 ApplicationInfo.FLAG_SYSTEM) != 0; 13979 } 13980 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 13981 } 13982 13983 // Check whether the newly-scanned package wants to define an already-defined perm 13984 int N = pkg.permissions.size(); 13985 for (int i = N-1; i >= 0; i--) { 13986 PackageParser.Permission perm = pkg.permissions.get(i); 13987 BasePermission bp = mSettings.mPermissions.get(perm.info.name); 13988 if (bp != null) { 13989 // If the defining package is signed with our cert, it's okay. This 13990 // also includes the "updating the same package" case, of course. 13991 // "updating same package" could also involve key-rotation. 13992 final boolean sigsOk; 13993 if (bp.sourcePackage.equals(pkg.packageName) 13994 && (bp.packageSetting instanceof PackageSetting) 13995 && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting, 13996 scanFlags))) { 13997 sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg); 13998 } else { 13999 sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures, 14000 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 14001 } 14002 if (!sigsOk) { 14003 // If the owning package is the system itself, we log but allow 14004 // install to proceed; we fail the install on all other permission 14005 // redefinitions. 14006 if (!bp.sourcePackage.equals("android")) { 14007 res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package " 14008 + pkg.packageName + " attempting to redeclare permission " 14009 + perm.info.name + " already owned by " + bp.sourcePackage); 14010 res.origPermission = perm.info.name; 14011 res.origPackage = bp.sourcePackage; 14012 return; 14013 } else { 14014 Slog.w(TAG, "Package " + pkg.packageName 14015 + " attempting to redeclare system permission " 14016 + perm.info.name + "; ignoring new declaration"); 14017 pkg.permissions.remove(i); 14018 } 14019 } 14020 } 14021 } 14022 } 14023 14024 if (systemApp) { 14025 if (onExternal) { 14026 // Abort update; system app can't be replaced with app on sdcard 14027 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION, 14028 "Cannot install updates to system apps on sdcard"); 14029 return; 14030 } else if (ephemeral) { 14031 // Abort update; system app can't be replaced with an ephemeral app 14032 res.setError(INSTALL_FAILED_EPHEMERAL_INVALID, 14033 "Cannot update a system app with an ephemeral app"); 14034 return; 14035 } 14036 } 14037 14038 if (args.move != null) { 14039 // We did an in-place move, so dex is ready to roll 14040 scanFlags |= SCAN_NO_DEX; 14041 scanFlags |= SCAN_MOVE; 14042 14043 synchronized (mPackages) { 14044 final PackageSetting ps = mSettings.mPackages.get(pkgName); 14045 if (ps == null) { 14046 res.setError(INSTALL_FAILED_INTERNAL_ERROR, 14047 "Missing settings for moved package " + pkgName); 14048 } 14049 14050 // We moved the entire application as-is, so bring over the 14051 // previously derived ABI information. 14052 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString; 14053 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString; 14054 } 14055 14056 } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) { 14057 // Enable SCAN_NO_DEX flag to skip dexopt at a later stage 14058 scanFlags |= SCAN_NO_DEX; 14059 14060 try { 14061 String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ? 14062 args.abiOverride : pkg.cpuAbiOverride); 14063 derivePackageAbi(pkg, new File(pkg.codePath), abiOverride, 14064 true /* extract libs */); 14065 } catch (PackageManagerException pme) { 14066 Slog.e(TAG, "Error deriving application ABI", pme); 14067 res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI"); 14068 return; 14069 } 14070 14071 14072 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 14073 // Do not run PackageDexOptimizer through the local performDexOpt 14074 // method because `pkg` is not in `mPackages` yet. 14075 int result = mPackageDexOptimizer.performDexOpt(pkg, null /* instructionSets */, 14076 false /* checkProfiles */, getCompilerFilterForReason(REASON_INSTALL)); 14077 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14078 if (result == PackageDexOptimizer.DEX_OPT_FAILED) { 14079 String msg = "Extracking package failed for " + pkgName; 14080 res.setError(INSTALL_FAILED_DEXOPT, msg); 14081 return; 14082 } 14083 } 14084 14085 if (!args.doRename(res.returnCode, pkg, oldCodePath)) { 14086 res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename"); 14087 return; 14088 } 14089 14090 startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg); 14091 14092 if (replace) { 14093 replacePackageLI(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user, 14094 installerPackageName, res); 14095 } else { 14096 installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES, 14097 args.user, installerPackageName, volumeUuid, res); 14098 } 14099 synchronized (mPackages) { 14100 final PackageSetting ps = mSettings.mPackages.get(pkgName); 14101 if (ps != null) { 14102 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 14103 } 14104 14105 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 14106 for (int i = 0; i < childCount; i++) { 14107 PackageParser.Package childPkg = pkg.childPackages.get(i); 14108 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName); 14109 PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName); 14110 if (childPs != null) { 14111 childRes.newUsers = childPs.queryInstalledUsers( 14112 sUserManager.getUserIds(), true); 14113 } 14114 } 14115 } 14116 } 14117 14118 private void startIntentFilterVerifications(int userId, boolean replacing, 14119 PackageParser.Package pkg) { 14120 if (mIntentFilterVerifierComponent == null) { 14121 Slog.w(TAG, "No IntentFilter verification will not be done as " 14122 + "there is no IntentFilterVerifier available!"); 14123 return; 14124 } 14125 14126 final int verifierUid = getPackageUid( 14127 mIntentFilterVerifierComponent.getPackageName(), 14128 MATCH_DEBUG_TRIAGED_MISSING, 14129 (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId); 14130 14131 Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 14132 msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid); 14133 mHandler.sendMessage(msg); 14134 14135 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 14136 for (int i = 0; i < childCount; i++) { 14137 PackageParser.Package childPkg = pkg.childPackages.get(i); 14138 msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 14139 msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid); 14140 mHandler.sendMessage(msg); 14141 } 14142 } 14143 14144 private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing, 14145 PackageParser.Package pkg) { 14146 int size = pkg.activities.size(); 14147 if (size == 0) { 14148 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 14149 "No activity, so no need to verify any IntentFilter!"); 14150 return; 14151 } 14152 14153 final boolean hasDomainURLs = hasDomainURLs(pkg); 14154 if (!hasDomainURLs) { 14155 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 14156 "No domain URLs, so no need to verify any IntentFilter!"); 14157 return; 14158 } 14159 14160 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId 14161 + " if any IntentFilter from the " + size 14162 + " Activities needs verification ..."); 14163 14164 int count = 0; 14165 final String packageName = pkg.packageName; 14166 14167 synchronized (mPackages) { 14168 // If this is a new install and we see that we've already run verification for this 14169 // package, we have nothing to do: it means the state was restored from backup. 14170 if (!replacing) { 14171 IntentFilterVerificationInfo ivi = 14172 mSettings.getIntentFilterVerificationLPr(packageName); 14173 if (ivi != null) { 14174 if (DEBUG_DOMAIN_VERIFICATION) { 14175 Slog.i(TAG, "Package " + packageName+ " already verified: status=" 14176 + ivi.getStatusString()); 14177 } 14178 return; 14179 } 14180 } 14181 14182 // If any filters need to be verified, then all need to be. 14183 boolean needToVerify = false; 14184 for (PackageParser.Activity a : pkg.activities) { 14185 for (ActivityIntentInfo filter : a.intents) { 14186 if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) { 14187 if (DEBUG_DOMAIN_VERIFICATION) { 14188 Slog.d(TAG, "Intent filter needs verification, so processing all filters"); 14189 } 14190 needToVerify = true; 14191 break; 14192 } 14193 } 14194 } 14195 14196 if (needToVerify) { 14197 final int verificationId = mIntentFilterVerificationToken++; 14198 for (PackageParser.Activity a : pkg.activities) { 14199 for (ActivityIntentInfo filter : a.intents) { 14200 if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) { 14201 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 14202 "Verification needed for IntentFilter:" + filter.toString()); 14203 mIntentFilterVerifier.addOneIntentFilterVerification( 14204 verifierUid, userId, verificationId, filter, packageName); 14205 count++; 14206 } 14207 } 14208 } 14209 } 14210 } 14211 14212 if (count > 0) { 14213 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count 14214 + " IntentFilter verification" + (count > 1 ? "s" : "") 14215 + " for userId:" + userId); 14216 mIntentFilterVerifier.startVerifications(userId); 14217 } else { 14218 if (DEBUG_DOMAIN_VERIFICATION) { 14219 Slog.d(TAG, "No filters or not all autoVerify for " + packageName); 14220 } 14221 } 14222 } 14223 14224 private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) { 14225 final ComponentName cn = filter.activity.getComponentName(); 14226 final String packageName = cn.getPackageName(); 14227 14228 IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr( 14229 packageName); 14230 if (ivi == null) { 14231 return true; 14232 } 14233 int status = ivi.getStatus(); 14234 switch (status) { 14235 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 14236 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 14237 return true; 14238 14239 default: 14240 // Nothing to do 14241 return false; 14242 } 14243 } 14244 14245 private static boolean isMultiArch(ApplicationInfo info) { 14246 return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0; 14247 } 14248 14249 private static boolean isExternal(PackageParser.Package pkg) { 14250 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 14251 } 14252 14253 private static boolean isExternal(PackageSetting ps) { 14254 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 14255 } 14256 14257 private static boolean isEphemeral(PackageParser.Package pkg) { 14258 return pkg.applicationInfo.isEphemeralApp(); 14259 } 14260 14261 private static boolean isEphemeral(PackageSetting ps) { 14262 return ps.pkg != null && isEphemeral(ps.pkg); 14263 } 14264 14265 private static boolean isSystemApp(PackageParser.Package pkg) { 14266 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 14267 } 14268 14269 private static boolean isPrivilegedApp(PackageParser.Package pkg) { 14270 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; 14271 } 14272 14273 private static boolean hasDomainURLs(PackageParser.Package pkg) { 14274 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0; 14275 } 14276 14277 private static boolean isSystemApp(PackageSetting ps) { 14278 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0; 14279 } 14280 14281 private static boolean isUpdatedSystemApp(PackageSetting ps) { 14282 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; 14283 } 14284 14285 private int packageFlagsToInstallFlags(PackageSetting ps) { 14286 int installFlags = 0; 14287 if (isEphemeral(ps)) { 14288 installFlags |= PackageManager.INSTALL_EPHEMERAL; 14289 } 14290 if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) { 14291 // This existing package was an external ASEC install when we have 14292 // the external flag without a UUID 14293 installFlags |= PackageManager.INSTALL_EXTERNAL; 14294 } 14295 if (ps.isForwardLocked()) { 14296 installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 14297 } 14298 return installFlags; 14299 } 14300 14301 private String getVolumeUuidForPackage(PackageParser.Package pkg) { 14302 if (isExternal(pkg)) { 14303 if (TextUtils.isEmpty(pkg.volumeUuid)) { 14304 return StorageManager.UUID_PRIMARY_PHYSICAL; 14305 } else { 14306 return pkg.volumeUuid; 14307 } 14308 } else { 14309 return StorageManager.UUID_PRIVATE_INTERNAL; 14310 } 14311 } 14312 14313 private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) { 14314 if (isExternal(pkg)) { 14315 if (TextUtils.isEmpty(pkg.volumeUuid)) { 14316 return mSettings.getExternalVersion(); 14317 } else { 14318 return mSettings.findOrCreateVersion(pkg.volumeUuid); 14319 } 14320 } else { 14321 return mSettings.getInternalVersion(); 14322 } 14323 } 14324 14325 private void deleteTempPackageFiles() { 14326 final FilenameFilter filter = new FilenameFilter() { 14327 public boolean accept(File dir, String name) { 14328 return name.startsWith("vmdl") && name.endsWith(".tmp"); 14329 } 14330 }; 14331 for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) { 14332 file.delete(); 14333 } 14334 } 14335 14336 @Override 14337 public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId, 14338 int flags) { 14339 deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId, 14340 flags); 14341 } 14342 14343 @Override 14344 public void deletePackage(final String packageName, 14345 final IPackageDeleteObserver2 observer, final int userId, final int flags) { 14346 mContext.enforceCallingOrSelfPermission( 14347 android.Manifest.permission.DELETE_PACKAGES, null); 14348 Preconditions.checkNotNull(packageName); 14349 Preconditions.checkNotNull(observer); 14350 final int uid = Binder.getCallingUid(); 14351 final boolean deleteAllUsers = (flags & PackageManager.DELETE_ALL_USERS) != 0; 14352 final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId }; 14353 if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) { 14354 mContext.enforceCallingOrSelfPermission( 14355 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 14356 "deletePackage for user " + userId); 14357 } 14358 14359 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) { 14360 try { 14361 observer.onPackageDeleted(packageName, 14362 PackageManager.DELETE_FAILED_USER_RESTRICTED, null); 14363 } catch (RemoteException re) { 14364 } 14365 return; 14366 } 14367 14368 if (!deleteAllUsers && getBlockUninstallForUser(packageName, userId)) { 14369 try { 14370 observer.onPackageDeleted(packageName, 14371 PackageManager.DELETE_FAILED_OWNER_BLOCKED, null); 14372 } catch (RemoteException re) { 14373 } 14374 return; 14375 } 14376 14377 if (DEBUG_REMOVE) { 14378 Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId 14379 + " deleteAllUsers: " + deleteAllUsers ); 14380 } 14381 // Queue up an async operation since the package deletion may take a little while. 14382 mHandler.post(new Runnable() { 14383 public void run() { 14384 mHandler.removeCallbacks(this); 14385 int returnCode; 14386 if (!deleteAllUsers) { 14387 returnCode = deletePackageX(packageName, userId, flags); 14388 } else { 14389 int[] blockUninstallUserIds = getBlockUninstallForUsers(packageName, users); 14390 // If nobody is blocking uninstall, proceed with delete for all users 14391 if (ArrayUtils.isEmpty(blockUninstallUserIds)) { 14392 returnCode = deletePackageX(packageName, userId, flags); 14393 } else { 14394 // Otherwise uninstall individually for users with blockUninstalls=false 14395 final int userFlags = flags & ~PackageManager.DELETE_ALL_USERS; 14396 for (int userId : users) { 14397 if (!ArrayUtils.contains(blockUninstallUserIds, userId)) { 14398 returnCode = deletePackageX(packageName, userId, userFlags); 14399 if (returnCode != PackageManager.DELETE_SUCCEEDED) { 14400 Slog.w(TAG, "Package delete failed for user " + userId 14401 + ", returnCode " + returnCode); 14402 } 14403 } 14404 } 14405 // The app has only been marked uninstalled for certain users. 14406 // We still need to report that delete was blocked 14407 returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED; 14408 } 14409 } 14410 try { 14411 observer.onPackageDeleted(packageName, returnCode, null); 14412 } catch (RemoteException e) { 14413 Log.i(TAG, "Observer no longer exists."); 14414 } //end catch 14415 } //end run 14416 }); 14417 } 14418 14419 private int[] getBlockUninstallForUsers(String packageName, int[] userIds) { 14420 int[] result = EMPTY_INT_ARRAY; 14421 for (int userId : userIds) { 14422 if (getBlockUninstallForUser(packageName, userId)) { 14423 result = ArrayUtils.appendInt(result, userId); 14424 } 14425 } 14426 return result; 14427 } 14428 14429 @Override 14430 public boolean isPackageDeviceAdminOnAnyUser(String packageName) { 14431 return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL); 14432 } 14433 14434 private boolean isPackageDeviceAdmin(String packageName, int userId) { 14435 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface( 14436 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); 14437 try { 14438 if (dpm != null) { 14439 final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent( 14440 /* callingUserOnly =*/ false); 14441 final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null 14442 : deviceOwnerComponentName.getPackageName(); 14443 // Does the package contains the device owner? 14444 // TODO Do we have to do it even if userId != UserHandle.USER_ALL? Otherwise, 14445 // this check is probably not needed, since DO should be registered as a device 14446 // admin on some user too. (Original bug for this: b/17657954) 14447 if (packageName.equals(deviceOwnerPackageName)) { 14448 return true; 14449 } 14450 // Does it contain a device admin for any user? 14451 int[] users; 14452 if (userId == UserHandle.USER_ALL) { 14453 users = sUserManager.getUserIds(); 14454 } else { 14455 users = new int[]{userId}; 14456 } 14457 for (int i = 0; i < users.length; ++i) { 14458 if (dpm.packageHasActiveAdmins(packageName, users[i])) { 14459 return true; 14460 } 14461 } 14462 } 14463 } catch (RemoteException e) { 14464 } 14465 return false; 14466 } 14467 14468 private boolean shouldKeepUninstalledPackageLPr(String packageName) { 14469 return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName); 14470 } 14471 14472 /** 14473 * This method is an internal method that could be get invoked either 14474 * to delete an installed package or to clean up a failed installation. 14475 * After deleting an installed package, a broadcast is sent to notify any 14476 * listeners that the package has been installed. For cleaning up a failed 14477 * installation, the broadcast is not necessary since the package's 14478 * installation wouldn't have sent the initial broadcast either 14479 * The key steps in deleting a package are 14480 * deleting the package information in internal structures like mPackages, 14481 * deleting the packages base directories through installd 14482 * updating mSettings to reflect current status 14483 * persisting settings for later use 14484 * sending a broadcast if necessary 14485 */ 14486 private int deletePackageX(String packageName, int userId, int flags) { 14487 final PackageRemovedInfo info = new PackageRemovedInfo(); 14488 final boolean res; 14489 14490 final UserHandle removeForUser = (flags & PackageManager.DELETE_ALL_USERS) != 0 14491 ? UserHandle.ALL : new UserHandle(userId); 14492 14493 if (isPackageDeviceAdmin(packageName, removeForUser.getIdentifier())) { 14494 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin"); 14495 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER; 14496 } 14497 14498 PackageSetting uninstalledPs = null; 14499 14500 // for the uninstall-updates case and restricted profiles, remember the per- 14501 // user handle installed state 14502 int[] allUsers; 14503 synchronized (mPackages) { 14504 uninstalledPs = mSettings.mPackages.get(packageName); 14505 if (uninstalledPs == null) { 14506 Slog.w(TAG, "Not removing non-existent package " + packageName); 14507 return PackageManager.DELETE_FAILED_INTERNAL_ERROR; 14508 } 14509 allUsers = sUserManager.getUserIds(); 14510 info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true); 14511 } 14512 14513 synchronized (mInstallLock) { 14514 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId); 14515 res = deletePackageLI(packageName, removeForUser, true, allUsers, 14516 flags | REMOVE_CHATTY, info, true, null); 14517 deleteProfilesLI(packageName, /*destroy*/ true); 14518 synchronized (mPackages) { 14519 if (res) { 14520 mEphemeralApplicationRegistry.onPackageUninstalledLPw(uninstalledPs.pkg); 14521 } 14522 } 14523 } 14524 14525 if (res) { 14526 final boolean killApp = (flags & PackageManager.INSTALL_DONT_KILL_APP) == 0; 14527 info.sendPackageRemovedBroadcasts(killApp); 14528 info.sendSystemPackageUpdatedBroadcasts(); 14529 info.sendSystemPackageAppearedBroadcasts(); 14530 } 14531 // Force a gc here. 14532 Runtime.getRuntime().gc(); 14533 // Delete the resources here after sending the broadcast to let 14534 // other processes clean up before deleting resources. 14535 if (info.args != null) { 14536 synchronized (mInstallLock) { 14537 info.args.doPostDeleteLI(true); 14538 } 14539 } 14540 14541 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR; 14542 } 14543 14544 class PackageRemovedInfo { 14545 String removedPackage; 14546 int uid = -1; 14547 int removedAppId = -1; 14548 int[] origUsers; 14549 int[] removedUsers = null; 14550 boolean isRemovedPackageSystemUpdate = false; 14551 boolean isUpdate; 14552 boolean dataRemoved; 14553 boolean removedForAllUsers; 14554 // Clean up resources deleted packages. 14555 InstallArgs args = null; 14556 ArrayMap<String, PackageRemovedInfo> removedChildPackages; 14557 ArrayMap<String, PackageInstalledInfo> appearedChildPackages; 14558 14559 void sendPackageRemovedBroadcasts(boolean killApp) { 14560 sendPackageRemovedBroadcastInternal(killApp); 14561 final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0; 14562 for (int i = 0; i < childCount; i++) { 14563 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i); 14564 childInfo.sendPackageRemovedBroadcastInternal(killApp); 14565 } 14566 } 14567 14568 void sendSystemPackageUpdatedBroadcasts() { 14569 if (isRemovedPackageSystemUpdate) { 14570 sendSystemPackageUpdatedBroadcastsInternal(); 14571 final int childCount = (removedChildPackages != null) 14572 ? removedChildPackages.size() : 0; 14573 for (int i = 0; i < childCount; i++) { 14574 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i); 14575 if (childInfo.isRemovedPackageSystemUpdate) { 14576 childInfo.sendSystemPackageUpdatedBroadcastsInternal(); 14577 } 14578 } 14579 } 14580 } 14581 14582 void sendSystemPackageAppearedBroadcasts() { 14583 final int packageCount = (appearedChildPackages != null) 14584 ? appearedChildPackages.size() : 0; 14585 for (int i = 0; i < packageCount; i++) { 14586 PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i); 14587 for (int userId : installedInfo.newUsers) { 14588 sendPackageAddedForUser(installedInfo.name, true, 14589 UserHandle.getAppId(installedInfo.uid), userId); 14590 } 14591 } 14592 } 14593 14594 private void sendSystemPackageUpdatedBroadcastsInternal() { 14595 Bundle extras = new Bundle(2); 14596 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 14597 extras.putBoolean(Intent.EXTRA_REPLACING, true); 14598 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, removedPackage, 14599 extras, 0, null, null, null); 14600 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, removedPackage, 14601 extras, 0, null, null, null); 14602 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null, 14603 null, 0, removedPackage, null, null); 14604 } 14605 14606 private void sendPackageRemovedBroadcastInternal(boolean killApp) { 14607 Bundle extras = new Bundle(2); 14608 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 14609 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved); 14610 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp); 14611 if (isUpdate || isRemovedPackageSystemUpdate) { 14612 extras.putBoolean(Intent.EXTRA_REPLACING, true); 14613 } 14614 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers); 14615 if (removedPackage != null) { 14616 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, 14617 extras, 0, null, null, removedUsers); 14618 if (dataRemoved && !isRemovedPackageSystemUpdate) { 14619 sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, 14620 removedPackage, extras, 0, null, null, removedUsers); 14621 } 14622 } 14623 if (removedAppId >= 0) { 14624 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, 0, null, null, 14625 removedUsers); 14626 } 14627 } 14628 } 14629 14630 /* 14631 * This method deletes the package from internal data structures. If the DONT_DELETE_DATA 14632 * flag is not set, the data directory is removed as well. 14633 * make sure this flag is set for partially installed apps. If not its meaningless to 14634 * delete a partially installed application. 14635 */ 14636 private void removePackageDataLI(PackageSetting ps, int[] allUserHandles, 14637 PackageRemovedInfo outInfo, int flags, boolean writeSettings) { 14638 String packageName = ps.name; 14639 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps); 14640 removePackageLI(ps, (flags&REMOVE_CHATTY) != 0); 14641 // Retrieve object to delete permissions for shared user later on 14642 final PackageSetting deletedPs; 14643 // reader 14644 synchronized (mPackages) { 14645 deletedPs = mSettings.mPackages.get(packageName); 14646 if (outInfo != null) { 14647 outInfo.removedPackage = packageName; 14648 outInfo.removedUsers = deletedPs != null 14649 ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true) 14650 : null; 14651 } 14652 } 14653 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 14654 removeDataDirsLI(ps.volumeUuid, packageName); 14655 if (outInfo != null) { 14656 outInfo.dataRemoved = true; 14657 } 14658 schedulePackageCleaning(packageName, UserHandle.USER_ALL, true); 14659 } 14660 // writer 14661 synchronized (mPackages) { 14662 if (deletedPs != null) { 14663 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 14664 clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL); 14665 clearDefaultBrowserIfNeeded(packageName); 14666 if (outInfo != null) { 14667 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName); 14668 outInfo.removedAppId = mSettings.removePackageLPw(packageName); 14669 } 14670 updatePermissionsLPw(deletedPs.name, null, 0); 14671 if (deletedPs.sharedUser != null) { 14672 // Remove permissions associated with package. Since runtime 14673 // permissions are per user we have to kill the removed package 14674 // or packages running under the shared user of the removed 14675 // package if revoking the permissions requested only by the removed 14676 // package is successful and this causes a change in gids. 14677 for (int userId : UserManagerService.getInstance().getUserIds()) { 14678 final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs, 14679 userId); 14680 if (userIdToKill == UserHandle.USER_ALL 14681 || userIdToKill >= UserHandle.USER_SYSTEM) { 14682 // If gids changed for this user, kill all affected packages. 14683 mHandler.post(new Runnable() { 14684 @Override 14685 public void run() { 14686 // This has to happen with no lock held. 14687 killApplication(deletedPs.name, deletedPs.appId, 14688 KILL_APP_REASON_GIDS_CHANGED); 14689 } 14690 }); 14691 break; 14692 } 14693 } 14694 } 14695 clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL); 14696 } 14697 // make sure to preserve per-user disabled state if this removal was just 14698 // a downgrade of a system app to the factory package 14699 if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) { 14700 if (DEBUG_REMOVE) { 14701 Slog.d(TAG, "Propagating install state across downgrade"); 14702 } 14703 for (int userId : allUserHandles) { 14704 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId); 14705 if (DEBUG_REMOVE) { 14706 Slog.d(TAG, " user " + userId + " => " + installed); 14707 } 14708 ps.setInstalled(installed, userId); 14709 } 14710 } 14711 } 14712 // can downgrade to reader 14713 if (writeSettings) { 14714 // Save settings now 14715 mSettings.writeLPr(); 14716 } 14717 } 14718 if (outInfo != null) { 14719 // A user ID was deleted here. Go through all users and remove it 14720 // from KeyStore. 14721 removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId); 14722 } 14723 } 14724 14725 static boolean locationIsPrivileged(File path) { 14726 try { 14727 final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app") 14728 .getCanonicalPath(); 14729 return path.getCanonicalPath().startsWith(privilegedAppDir); 14730 } catch (IOException e) { 14731 Slog.e(TAG, "Unable to access code path " + path); 14732 } 14733 return false; 14734 } 14735 14736 /* 14737 * Tries to delete system package. 14738 */ 14739 private boolean deleteSystemPackageLI(PackageParser.Package deletedPkg, 14740 PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo, 14741 boolean writeSettings) { 14742 if (deletedPs.parentPackageName != null) { 14743 Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName); 14744 return false; 14745 } 14746 14747 final boolean applyUserRestrictions 14748 = (allUserHandles != null) && (outInfo.origUsers != null); 14749 final PackageSetting disabledPs; 14750 // Confirm if the system package has been updated 14751 // An updated system app can be deleted. This will also have to restore 14752 // the system pkg from system partition 14753 // reader 14754 synchronized (mPackages) { 14755 disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name); 14756 } 14757 14758 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName 14759 + " disabledPs=" + disabledPs); 14760 14761 if (disabledPs == null) { 14762 Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName); 14763 return false; 14764 } else if (DEBUG_REMOVE) { 14765 Slog.d(TAG, "Deleting system pkg from data partition"); 14766 } 14767 14768 if (DEBUG_REMOVE) { 14769 if (applyUserRestrictions) { 14770 Slog.d(TAG, "Remembering install states:"); 14771 for (int userId : allUserHandles) { 14772 final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId); 14773 Slog.d(TAG, " u=" + userId + " inst=" + finstalled); 14774 } 14775 } 14776 } 14777 14778 // Delete the updated package 14779 outInfo.isRemovedPackageSystemUpdate = true; 14780 if (outInfo.removedChildPackages != null) { 14781 final int childCount = (deletedPs.childPackageNames != null) 14782 ? deletedPs.childPackageNames.size() : 0; 14783 for (int i = 0; i < childCount; i++) { 14784 String childPackageName = deletedPs.childPackageNames.get(i); 14785 if (disabledPs.childPackageNames != null && disabledPs.childPackageNames 14786 .contains(childPackageName)) { 14787 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get( 14788 childPackageName); 14789 if (childInfo != null) { 14790 childInfo.isRemovedPackageSystemUpdate = true; 14791 } 14792 } 14793 } 14794 } 14795 14796 if (disabledPs.versionCode < deletedPs.versionCode) { 14797 // Delete data for downgrades 14798 flags &= ~PackageManager.DELETE_KEEP_DATA; 14799 } else { 14800 // Preserve data by setting flag 14801 flags |= PackageManager.DELETE_KEEP_DATA; 14802 } 14803 14804 boolean ret = deleteInstalledPackageLI(deletedPs, true, flags, allUserHandles, 14805 outInfo, writeSettings, disabledPs.pkg); 14806 if (!ret) { 14807 return false; 14808 } 14809 14810 // writer 14811 synchronized (mPackages) { 14812 // Reinstate the old system package 14813 enableSystemPackageLPw(disabledPs.pkg); 14814 // Remove any native libraries from the upgraded package. 14815 removeNativeBinariesLI(deletedPs); 14816 } 14817 14818 // Install the system package 14819 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs); 14820 int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM; 14821 if (locationIsPrivileged(disabledPs.codePath)) { 14822 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 14823 } 14824 14825 final PackageParser.Package newPkg; 14826 try { 14827 newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null); 14828 } catch (PackageManagerException e) { 14829 Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": " 14830 + e.getMessage()); 14831 return false; 14832 } 14833 14834 prepareAppDataAfterInstall(newPkg); 14835 14836 // writer 14837 synchronized (mPackages) { 14838 PackageSetting ps = mSettings.mPackages.get(newPkg.packageName); 14839 14840 // Propagate the permissions state as we do not want to drop on the floor 14841 // runtime permissions. The update permissions method below will take 14842 // care of removing obsolete permissions and grant install permissions. 14843 ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState()); 14844 updatePermissionsLPw(newPkg.packageName, newPkg, 14845 UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG); 14846 14847 if (applyUserRestrictions) { 14848 if (DEBUG_REMOVE) { 14849 Slog.d(TAG, "Propagating install state across reinstall"); 14850 } 14851 for (int userId : allUserHandles) { 14852 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId); 14853 if (DEBUG_REMOVE) { 14854 Slog.d(TAG, " user " + userId + " => " + installed); 14855 } 14856 ps.setInstalled(installed, userId); 14857 14858 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 14859 } 14860 // Regardless of writeSettings we need to ensure that this restriction 14861 // state propagation is persisted 14862 mSettings.writeAllUsersPackageRestrictionsLPr(); 14863 } 14864 // can downgrade to reader here 14865 if (writeSettings) { 14866 mSettings.writeLPr(); 14867 } 14868 } 14869 return true; 14870 } 14871 14872 private boolean deleteInstalledPackageLI(PackageSetting ps, 14873 boolean deleteCodeAndResources, int flags, int[] allUserHandles, 14874 PackageRemovedInfo outInfo, boolean writeSettings, 14875 PackageParser.Package replacingPackage) { 14876 synchronized (mPackages) { 14877 if (outInfo != null) { 14878 outInfo.uid = ps.appId; 14879 } 14880 14881 if (outInfo != null && outInfo.removedChildPackages != null) { 14882 final int childCount = (ps.childPackageNames != null) 14883 ? ps.childPackageNames.size() : 0; 14884 for (int i = 0; i < childCount; i++) { 14885 String childPackageName = ps.childPackageNames.get(i); 14886 PackageSetting childPs = mSettings.mPackages.get(childPackageName); 14887 if (childPs == null) { 14888 return false; 14889 } 14890 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get( 14891 childPackageName); 14892 if (childInfo != null) { 14893 childInfo.uid = childPs.appId; 14894 } 14895 } 14896 } 14897 } 14898 14899 // Delete package data from internal structures and also remove data if flag is set 14900 removePackageDataLI(ps, allUserHandles, outInfo, flags, writeSettings); 14901 14902 // Delete the child packages data 14903 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0; 14904 for (int i = 0; i < childCount; i++) { 14905 PackageSetting childPs; 14906 synchronized (mPackages) { 14907 childPs = mSettings.peekPackageLPr(ps.childPackageNames.get(i)); 14908 } 14909 if (childPs != null) { 14910 PackageRemovedInfo childOutInfo = (outInfo != null 14911 && outInfo.removedChildPackages != null) 14912 ? outInfo.removedChildPackages.get(childPs.name) : null; 14913 final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0 14914 && (replacingPackage != null 14915 && !replacingPackage.hasChildPackage(childPs.name)) 14916 ? flags & ~DELETE_KEEP_DATA : flags; 14917 removePackageDataLI(childPs, allUserHandles, childOutInfo, 14918 deleteFlags, writeSettings); 14919 } 14920 } 14921 14922 // Delete application code and resources only for parent packages 14923 if (ps.parentPackageName == null) { 14924 if (deleteCodeAndResources && (outInfo != null)) { 14925 outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 14926 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 14927 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args); 14928 } 14929 } 14930 14931 return true; 14932 } 14933 14934 @Override 14935 public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall, 14936 int userId) { 14937 mContext.enforceCallingOrSelfPermission( 14938 android.Manifest.permission.DELETE_PACKAGES, null); 14939 synchronized (mPackages) { 14940 PackageSetting ps = mSettings.mPackages.get(packageName); 14941 if (ps == null) { 14942 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName); 14943 return false; 14944 } 14945 if (!ps.getInstalled(userId)) { 14946 // Can't block uninstall for an app that is not installed or enabled. 14947 Log.i(TAG, "Package not installed in set block uninstall " + packageName); 14948 return false; 14949 } 14950 ps.setBlockUninstall(blockUninstall, userId); 14951 mSettings.writePackageRestrictionsLPr(userId); 14952 } 14953 return true; 14954 } 14955 14956 @Override 14957 public boolean getBlockUninstallForUser(String packageName, int userId) { 14958 synchronized (mPackages) { 14959 PackageSetting ps = mSettings.mPackages.get(packageName); 14960 if (ps == null) { 14961 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName); 14962 return false; 14963 } 14964 return ps.getBlockUninstall(userId); 14965 } 14966 } 14967 14968 @Override 14969 public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) { 14970 int callingUid = Binder.getCallingUid(); 14971 if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) { 14972 throw new SecurityException( 14973 "setRequiredForSystemUser can only be run by the system or root"); 14974 } 14975 synchronized (mPackages) { 14976 PackageSetting ps = mSettings.mPackages.get(packageName); 14977 if (ps == null) { 14978 Log.w(TAG, "Package doesn't exist: " + packageName); 14979 return false; 14980 } 14981 if (systemUserApp) { 14982 ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER; 14983 } else { 14984 ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER; 14985 } 14986 mSettings.writeLPr(); 14987 } 14988 return true; 14989 } 14990 14991 /* 14992 * This method handles package deletion in general 14993 */ 14994 private boolean deletePackageLI(String packageName, UserHandle user, 14995 boolean deleteCodeAndResources, int[] allUserHandles, int flags, 14996 PackageRemovedInfo outInfo, boolean writeSettings, 14997 PackageParser.Package replacingPackage) { 14998 if (packageName == null) { 14999 Slog.w(TAG, "Attempt to delete null packageName."); 15000 return false; 15001 } 15002 15003 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user); 15004 15005 PackageSetting ps; 15006 15007 synchronized (mPackages) { 15008 ps = mSettings.mPackages.get(packageName); 15009 if (ps == null) { 15010 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 15011 return false; 15012 } 15013 15014 if (ps.parentPackageName != null && (!isSystemApp(ps) 15015 || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) { 15016 if (DEBUG_REMOVE) { 15017 Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:" 15018 + ((user == null) ? UserHandle.USER_ALL : user)); 15019 } 15020 final int removedUserId = (user != null) ? user.getIdentifier() 15021 : UserHandle.USER_ALL; 15022 if (!clearPackageStateForUser(ps, removedUserId, outInfo)) { 15023 return false; 15024 } 15025 markPackageUninstalledForUserLPw(ps, user); 15026 scheduleWritePackageRestrictionsLocked(user); 15027 return true; 15028 } 15029 } 15030 15031 if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null 15032 && user.getIdentifier() != UserHandle.USER_ALL)) { 15033 // The caller is asking that the package only be deleted for a single 15034 // user. To do this, we just mark its uninstalled state and delete 15035 // its data. If this is a system app, we only allow this to happen if 15036 // they have set the special DELETE_SYSTEM_APP which requests different 15037 // semantics than normal for uninstalling system apps. 15038 markPackageUninstalledForUserLPw(ps, user); 15039 15040 if (!isSystemApp(ps)) { 15041 // Do not uninstall the APK if an app should be cached 15042 boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName); 15043 if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) { 15044 // Other user still have this package installed, so all 15045 // we need to do is clear this user's data and save that 15046 // it is uninstalled. 15047 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users"); 15048 if (!clearPackageStateForUser(ps, user.getIdentifier(), outInfo)) { 15049 return false; 15050 } 15051 scheduleWritePackageRestrictionsLocked(user); 15052 return true; 15053 } else { 15054 // We need to set it back to 'installed' so the uninstall 15055 // broadcasts will be sent correctly. 15056 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete"); 15057 ps.setInstalled(true, user.getIdentifier()); 15058 } 15059 } else { 15060 // This is a system app, so we assume that the 15061 // other users still have this package installed, so all 15062 // we need to do is clear this user's data and save that 15063 // it is uninstalled. 15064 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app"); 15065 if (!clearPackageStateForUser(ps, user.getIdentifier(), outInfo)) { 15066 return false; 15067 } 15068 scheduleWritePackageRestrictionsLocked(user); 15069 return true; 15070 } 15071 } 15072 15073 // If we are deleting a composite package for all users, keep track 15074 // of result for each child. 15075 if (ps.childPackageNames != null && outInfo != null) { 15076 synchronized (mPackages) { 15077 final int childCount = ps.childPackageNames.size(); 15078 outInfo.removedChildPackages = new ArrayMap<>(childCount); 15079 for (int i = 0; i < childCount; i++) { 15080 String childPackageName = ps.childPackageNames.get(i); 15081 PackageRemovedInfo childInfo = new PackageRemovedInfo(); 15082 childInfo.removedPackage = childPackageName; 15083 outInfo.removedChildPackages.put(childPackageName, childInfo); 15084 PackageSetting childPs = mSettings.peekPackageLPr(childPackageName); 15085 if (childPs != null) { 15086 childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true); 15087 } 15088 } 15089 } 15090 } 15091 15092 boolean ret = false; 15093 if (isSystemApp(ps)) { 15094 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name); 15095 // When an updated system application is deleted we delete the existing resources 15096 // as well and fall back to existing code in system partition 15097 ret = deleteSystemPackageLI(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings); 15098 } else { 15099 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name); 15100 // Kill application pre-emptively especially for apps on sd. 15101 final boolean killApp = (flags & PackageManager.DELETE_DONT_KILL_APP) == 0; 15102 if (killApp) { 15103 killApplication(packageName, ps.appId, "uninstall pkg"); 15104 } 15105 ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags, allUserHandles, 15106 outInfo, writeSettings, replacingPackage); 15107 } 15108 15109 // Take a note whether we deleted the package for all users 15110 if (outInfo != null) { 15111 outInfo.removedForAllUsers = mPackages.get(ps.name) == null; 15112 if (outInfo.removedChildPackages != null) { 15113 synchronized (mPackages) { 15114 final int childCount = outInfo.removedChildPackages.size(); 15115 for (int i = 0; i < childCount; i++) { 15116 PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i); 15117 if (childInfo != null) { 15118 childInfo.removedForAllUsers = mPackages.get( 15119 childInfo.removedPackage) == null; 15120 } 15121 } 15122 } 15123 } 15124 // If we uninstalled an update to a system app there may be some 15125 // child packages that appeared as they are declared in the system 15126 // app but were not declared in the update. 15127 if (isSystemApp(ps)) { 15128 synchronized (mPackages) { 15129 PackageSetting updatedPs = mSettings.peekPackageLPr(ps.name); 15130 final int childCount = (updatedPs.childPackageNames != null) 15131 ? updatedPs.childPackageNames.size() : 0; 15132 for (int i = 0; i < childCount; i++) { 15133 String childPackageName = updatedPs.childPackageNames.get(i); 15134 if (outInfo.removedChildPackages == null 15135 || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) { 15136 PackageSetting childPs = mSettings.peekPackageLPr(childPackageName); 15137 if (childPs == null) { 15138 continue; 15139 } 15140 PackageInstalledInfo installRes = new PackageInstalledInfo(); 15141 installRes.name = childPackageName; 15142 installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true); 15143 installRes.pkg = mPackages.get(childPackageName); 15144 installRes.uid = childPs.pkg.applicationInfo.uid; 15145 if (outInfo.appearedChildPackages == null) { 15146 outInfo.appearedChildPackages = new ArrayMap<>(); 15147 } 15148 outInfo.appearedChildPackages.put(childPackageName, installRes); 15149 } 15150 } 15151 } 15152 } 15153 } 15154 15155 return ret; 15156 } 15157 15158 private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) { 15159 final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL) 15160 ? sUserManager.getUserIds() : new int[] {user.getIdentifier()}; 15161 for (int nextUserId : userIds) { 15162 if (DEBUG_REMOVE) { 15163 Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId); 15164 } 15165 ps.setUserState(nextUserId, COMPONENT_ENABLED_STATE_DEFAULT, 15166 false /*installed*/, true /*stopped*/, true /*notLaunched*/, 15167 false /*hidden*/, false /*suspended*/, null, null, null, 15168 false /*blockUninstall*/, 15169 ps.readUserState(nextUserId).domainVerificationStatus, 0); 15170 } 15171 } 15172 15173 private boolean clearPackageStateForUser(PackageSetting ps, int userId, 15174 PackageRemovedInfo outInfo) { 15175 final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() 15176 : new int[] {userId}; 15177 for (int nextUserId : userIds) { 15178 if (DEBUG_REMOVE) { 15179 Slog.d(TAG, "Updating package:" + ps.name + " install state for user:" 15180 + nextUserId); 15181 } 15182 final int flags = StorageManager.FLAG_STORAGE_CE| StorageManager.FLAG_STORAGE_DE; 15183 try { 15184 mInstaller.destroyAppData(ps.volumeUuid, ps.name, nextUserId, flags); 15185 } catch (InstallerException e) { 15186 Slog.w(TAG, "Couldn't remove cache files for package " + ps.name, e); 15187 return false; 15188 } 15189 removeKeystoreDataIfNeeded(nextUserId, ps.appId); 15190 schedulePackageCleaning(ps.name, nextUserId, false); 15191 synchronized (mPackages) { 15192 if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) { 15193 scheduleWritePackageRestrictionsLocked(nextUserId); 15194 } 15195 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId); 15196 } 15197 } 15198 15199 if (outInfo != null) { 15200 outInfo.removedPackage = ps.name; 15201 outInfo.removedAppId = ps.appId; 15202 outInfo.removedUsers = userIds; 15203 } 15204 15205 return true; 15206 } 15207 15208 private final class ClearStorageConnection implements ServiceConnection { 15209 IMediaContainerService mContainerService; 15210 15211 @Override 15212 public void onServiceConnected(ComponentName name, IBinder service) { 15213 synchronized (this) { 15214 mContainerService = IMediaContainerService.Stub.asInterface(service); 15215 notifyAll(); 15216 } 15217 } 15218 15219 @Override 15220 public void onServiceDisconnected(ComponentName name) { 15221 } 15222 } 15223 15224 private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) { 15225 final boolean mounted; 15226 if (Environment.isExternalStorageEmulated()) { 15227 mounted = true; 15228 } else { 15229 final String status = Environment.getExternalStorageState(); 15230 15231 mounted = status.equals(Environment.MEDIA_MOUNTED) 15232 || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY); 15233 } 15234 15235 if (!mounted) { 15236 return; 15237 } 15238 15239 final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 15240 int[] users; 15241 if (userId == UserHandle.USER_ALL) { 15242 users = sUserManager.getUserIds(); 15243 } else { 15244 users = new int[] { userId }; 15245 } 15246 final ClearStorageConnection conn = new ClearStorageConnection(); 15247 if (mContext.bindServiceAsUser( 15248 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) { 15249 try { 15250 for (int curUser : users) { 15251 long timeout = SystemClock.uptimeMillis() + 5000; 15252 synchronized (conn) { 15253 long now = SystemClock.uptimeMillis(); 15254 while (conn.mContainerService == null && now < timeout) { 15255 try { 15256 conn.wait(timeout - now); 15257 } catch (InterruptedException e) { 15258 } 15259 } 15260 } 15261 if (conn.mContainerService == null) { 15262 return; 15263 } 15264 15265 final UserEnvironment userEnv = new UserEnvironment(curUser); 15266 clearDirectory(conn.mContainerService, 15267 userEnv.buildExternalStorageAppCacheDirs(packageName)); 15268 if (allData) { 15269 clearDirectory(conn.mContainerService, 15270 userEnv.buildExternalStorageAppDataDirs(packageName)); 15271 clearDirectory(conn.mContainerService, 15272 userEnv.buildExternalStorageAppMediaDirs(packageName)); 15273 } 15274 } 15275 } finally { 15276 mContext.unbindService(conn); 15277 } 15278 } 15279 } 15280 15281 @Override 15282 public void clearApplicationProfileData(String packageName) { 15283 enforceSystemOrRoot("Only the system can clear all profile data"); 15284 try { 15285 mInstaller.clearAppProfiles(packageName); 15286 } catch (InstallerException ex) { 15287 Log.e(TAG, "Could not clear profile data of package " + packageName); 15288 } 15289 } 15290 15291 @Override 15292 public void clearApplicationUserData(final String packageName, 15293 final IPackageDataObserver observer, final int userId) { 15294 mContext.enforceCallingOrSelfPermission( 15295 android.Manifest.permission.CLEAR_APP_USER_DATA, null); 15296 15297 enforceCrossUserPermission(Binder.getCallingUid(), userId, 15298 true /* requireFullPermission */, false /* checkShell */, "clear application data"); 15299 15300 final DevicePolicyManagerInternal dpmi = LocalServices 15301 .getService(DevicePolicyManagerInternal.class); 15302 if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) { 15303 throw new SecurityException("Cannot clear data for a device owner or a profile owner"); 15304 } 15305 // Queue up an async operation since the package deletion may take a little while. 15306 mHandler.post(new Runnable() { 15307 public void run() { 15308 mHandler.removeCallbacks(this); 15309 final boolean succeeded; 15310 synchronized (mInstallLock) { 15311 succeeded = clearApplicationUserDataLI(packageName, userId); 15312 } 15313 clearExternalStorageDataSync(packageName, userId, true); 15314 if (succeeded) { 15315 // invoke DeviceStorageMonitor's update method to clear any notifications 15316 DeviceStorageMonitorInternal dsm = LocalServices 15317 .getService(DeviceStorageMonitorInternal.class); 15318 if (dsm != null) { 15319 dsm.checkMemory(); 15320 } 15321 } 15322 if(observer != null) { 15323 try { 15324 observer.onRemoveCompleted(packageName, succeeded); 15325 } catch (RemoteException e) { 15326 Log.i(TAG, "Observer no longer exists."); 15327 } 15328 } //end if observer 15329 } //end run 15330 }); 15331 } 15332 15333 private boolean clearApplicationUserDataLI(String packageName, int userId) { 15334 if (packageName == null) { 15335 Slog.w(TAG, "Attempt to delete null packageName."); 15336 return false; 15337 } 15338 15339 // Try finding details about the requested package 15340 PackageParser.Package pkg; 15341 synchronized (mPackages) { 15342 pkg = mPackages.get(packageName); 15343 if (pkg == null) { 15344 final PackageSetting ps = mSettings.mPackages.get(packageName); 15345 if (ps != null) { 15346 pkg = ps.pkg; 15347 } 15348 } 15349 15350 if (pkg == null) { 15351 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 15352 return false; 15353 } 15354 15355 PackageSetting ps = (PackageSetting) pkg.mExtras; 15356 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 15357 } 15358 15359 // Always delete data directories for package, even if we found no other 15360 // record of app. This helps users recover from UID mismatches without 15361 // resorting to a full data wipe. 15362 // TODO: triage flags as part of 26466827 15363 final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE; 15364 try { 15365 mInstaller.clearAppData(pkg.volumeUuid, packageName, userId, flags); 15366 } catch (InstallerException e) { 15367 Slog.w(TAG, "Couldn't remove cache files for package " + packageName, e); 15368 return false; 15369 } 15370 15371 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); 15372 removeKeystoreDataIfNeeded(userId, appId); 15373 15374 // Create a native library symlink only if we have native libraries 15375 // and if the native libraries are 32 bit libraries. We do not provide 15376 // this symlink for 64 bit libraries. 15377 if (pkg.applicationInfo.primaryCpuAbi != null && 15378 !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) { 15379 final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir; 15380 try { 15381 mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName, 15382 nativeLibPath, userId); 15383 } catch (InstallerException e) { 15384 Slog.w(TAG, "Failed linking native library dir", e); 15385 return false; 15386 } 15387 } 15388 15389 return true; 15390 } 15391 15392 /** 15393 * Reverts user permission state changes (permissions and flags) in 15394 * all packages for a given user. 15395 * 15396 * @param userId The device user for which to do a reset. 15397 */ 15398 private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) { 15399 final int packageCount = mPackages.size(); 15400 for (int i = 0; i < packageCount; i++) { 15401 PackageParser.Package pkg = mPackages.valueAt(i); 15402 PackageSetting ps = (PackageSetting) pkg.mExtras; 15403 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 15404 } 15405 } 15406 15407 /** 15408 * Reverts user permission state changes (permissions and flags). 15409 * 15410 * @param ps The package for which to reset. 15411 * @param userId The device user for which to do a reset. 15412 */ 15413 private void resetUserChangesToRuntimePermissionsAndFlagsLPw( 15414 final PackageSetting ps, final int userId) { 15415 if (ps.pkg == null) { 15416 return; 15417 } 15418 15419 // These are flags that can change base on user actions. 15420 final int userSettableMask = FLAG_PERMISSION_USER_SET 15421 | FLAG_PERMISSION_USER_FIXED 15422 | FLAG_PERMISSION_REVOKE_ON_UPGRADE 15423 | FLAG_PERMISSION_REVIEW_REQUIRED; 15424 15425 final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED 15426 | FLAG_PERMISSION_POLICY_FIXED; 15427 15428 boolean writeInstallPermissions = false; 15429 boolean writeRuntimePermissions = false; 15430 15431 final int permissionCount = ps.pkg.requestedPermissions.size(); 15432 for (int i = 0; i < permissionCount; i++) { 15433 String permission = ps.pkg.requestedPermissions.get(i); 15434 15435 BasePermission bp = mSettings.mPermissions.get(permission); 15436 if (bp == null) { 15437 continue; 15438 } 15439 15440 // If shared user we just reset the state to which only this app contributed. 15441 if (ps.sharedUser != null) { 15442 boolean used = false; 15443 final int packageCount = ps.sharedUser.packages.size(); 15444 for (int j = 0; j < packageCount; j++) { 15445 PackageSetting pkg = ps.sharedUser.packages.valueAt(j); 15446 if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName) 15447 && pkg.pkg.requestedPermissions.contains(permission)) { 15448 used = true; 15449 break; 15450 } 15451 } 15452 if (used) { 15453 continue; 15454 } 15455 } 15456 15457 PermissionsState permissionsState = ps.getPermissionsState(); 15458 15459 final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId); 15460 15461 // Always clear the user settable flags. 15462 final boolean hasInstallState = permissionsState.getInstallPermissionState( 15463 bp.name) != null; 15464 // If permission review is enabled and this is a legacy app, mark the 15465 // permission as requiring a review as this is the initial state. 15466 int flags = 0; 15467 if (Build.PERMISSIONS_REVIEW_REQUIRED 15468 && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 15469 flags |= FLAG_PERMISSION_REVIEW_REQUIRED; 15470 } 15471 if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) { 15472 if (hasInstallState) { 15473 writeInstallPermissions = true; 15474 } else { 15475 writeRuntimePermissions = true; 15476 } 15477 } 15478 15479 // Below is only runtime permission handling. 15480 if (!bp.isRuntime()) { 15481 continue; 15482 } 15483 15484 // Never clobber system or policy. 15485 if ((oldFlags & policyOrSystemFlags) != 0) { 15486 continue; 15487 } 15488 15489 // If this permission was granted by default, make sure it is. 15490 if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) { 15491 if (permissionsState.grantRuntimePermission(bp, userId) 15492 != PERMISSION_OPERATION_FAILURE) { 15493 writeRuntimePermissions = true; 15494 } 15495 // If permission review is enabled the permissions for a legacy apps 15496 // are represented as constantly granted runtime ones, so don't revoke. 15497 } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) { 15498 // Otherwise, reset the permission. 15499 final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId); 15500 switch (revokeResult) { 15501 case PERMISSION_OPERATION_SUCCESS: { 15502 writeRuntimePermissions = true; 15503 } break; 15504 15505 case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 15506 writeRuntimePermissions = true; 15507 final int appId = ps.appId; 15508 mHandler.post(new Runnable() { 15509 @Override 15510 public void run() { 15511 killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED); 15512 } 15513 }); 15514 } break; 15515 } 15516 } 15517 } 15518 15519 // Synchronously write as we are taking permissions away. 15520 if (writeRuntimePermissions) { 15521 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 15522 } 15523 15524 // Synchronously write as we are taking permissions away. 15525 if (writeInstallPermissions) { 15526 mSettings.writeLPr(); 15527 } 15528 } 15529 15530 /** 15531 * Remove entries from the keystore daemon. Will only remove it if the 15532 * {@code appId} is valid. 15533 */ 15534 private static void removeKeystoreDataIfNeeded(int userId, int appId) { 15535 if (appId < 0) { 15536 return; 15537 } 15538 15539 final KeyStore keyStore = KeyStore.getInstance(); 15540 if (keyStore != null) { 15541 if (userId == UserHandle.USER_ALL) { 15542 for (final int individual : sUserManager.getUserIds()) { 15543 keyStore.clearUid(UserHandle.getUid(individual, appId)); 15544 } 15545 } else { 15546 keyStore.clearUid(UserHandle.getUid(userId, appId)); 15547 } 15548 } else { 15549 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId); 15550 } 15551 } 15552 15553 @Override 15554 public void deleteApplicationCacheFiles(final String packageName, 15555 final IPackageDataObserver observer) { 15556 mContext.enforceCallingOrSelfPermission( 15557 android.Manifest.permission.DELETE_CACHE_FILES, null); 15558 // Queue up an async operation since the package deletion may take a little while. 15559 final int userId = UserHandle.getCallingUserId(); 15560 mHandler.post(new Runnable() { 15561 public void run() { 15562 mHandler.removeCallbacks(this); 15563 final boolean succeded; 15564 synchronized (mInstallLock) { 15565 succeded = deleteApplicationCacheFilesLI(packageName, userId); 15566 } 15567 clearExternalStorageDataSync(packageName, userId, false); 15568 if (observer != null) { 15569 try { 15570 observer.onRemoveCompleted(packageName, succeded); 15571 } catch (RemoteException e) { 15572 Log.i(TAG, "Observer no longer exists."); 15573 } 15574 } //end if observer 15575 } //end run 15576 }); 15577 } 15578 15579 private boolean deleteApplicationCacheFilesLI(String packageName, int userId) { 15580 if (packageName == null) { 15581 Slog.w(TAG, "Attempt to delete null packageName."); 15582 return false; 15583 } 15584 PackageParser.Package p; 15585 synchronized (mPackages) { 15586 p = mPackages.get(packageName); 15587 } 15588 if (p == null) { 15589 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 15590 return false; 15591 } 15592 final ApplicationInfo applicationInfo = p.applicationInfo; 15593 if (applicationInfo == null) { 15594 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 15595 return false; 15596 } 15597 // TODO: triage flags as part of 26466827 15598 final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE; 15599 try { 15600 mInstaller.clearAppData(p.volumeUuid, packageName, userId, 15601 flags | Installer.FLAG_CLEAR_CACHE_ONLY); 15602 } catch (InstallerException e) { 15603 Slog.w(TAG, "Couldn't remove cache files for package " 15604 + packageName + " u" + userId, e); 15605 return false; 15606 } 15607 return true; 15608 } 15609 15610 @Override 15611 public void getPackageSizeInfo(final String packageName, int userHandle, 15612 final IPackageStatsObserver observer) { 15613 mContext.enforceCallingOrSelfPermission( 15614 android.Manifest.permission.GET_PACKAGE_SIZE, null); 15615 if (packageName == null) { 15616 throw new IllegalArgumentException("Attempt to get size of null packageName"); 15617 } 15618 15619 PackageStats stats = new PackageStats(packageName, userHandle); 15620 15621 /* 15622 * Queue up an async operation since the package measurement may take a 15623 * little while. 15624 */ 15625 Message msg = mHandler.obtainMessage(INIT_COPY); 15626 msg.obj = new MeasureParams(stats, observer); 15627 mHandler.sendMessage(msg); 15628 } 15629 15630 private boolean getPackageSizeInfoLI(String packageName, int userHandle, 15631 PackageStats pStats) { 15632 if (packageName == null) { 15633 Slog.w(TAG, "Attempt to get size of null packageName."); 15634 return false; 15635 } 15636 PackageParser.Package p; 15637 boolean dataOnly = false; 15638 String libDirRoot = null; 15639 String asecPath = null; 15640 PackageSetting ps = null; 15641 synchronized (mPackages) { 15642 p = mPackages.get(packageName); 15643 ps = mSettings.mPackages.get(packageName); 15644 if(p == null) { 15645 dataOnly = true; 15646 if((ps == null) || (ps.pkg == null)) { 15647 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 15648 return false; 15649 } 15650 p = ps.pkg; 15651 } 15652 if (ps != null) { 15653 libDirRoot = ps.legacyNativeLibraryPathString; 15654 } 15655 if (p != null && (p.isForwardLocked() || p.applicationInfo.isExternalAsec())) { 15656 final long token = Binder.clearCallingIdentity(); 15657 try { 15658 String secureContainerId = cidFromCodePath(p.applicationInfo.getBaseCodePath()); 15659 if (secureContainerId != null) { 15660 asecPath = PackageHelper.getSdFilesystem(secureContainerId); 15661 } 15662 } finally { 15663 Binder.restoreCallingIdentity(token); 15664 } 15665 } 15666 } 15667 String publicSrcDir = null; 15668 if(!dataOnly) { 15669 final ApplicationInfo applicationInfo = p.applicationInfo; 15670 if (applicationInfo == null) { 15671 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 15672 return false; 15673 } 15674 if (p.isForwardLocked()) { 15675 publicSrcDir = applicationInfo.getBaseResourcePath(); 15676 } 15677 } 15678 // TODO: extend to measure size of split APKs 15679 // TODO(multiArch): Extend getSizeInfo to look at the full subdirectory tree, 15680 // not just the first level. 15681 // TODO(multiArch): Extend getSizeInfo to look at *all* instruction sets, not 15682 // just the primary. 15683 String[] dexCodeInstructionSets = getDexCodeInstructionSets(getAppDexInstructionSets(ps)); 15684 15685 String apkPath; 15686 File packageDir = new File(p.codePath); 15687 15688 if (packageDir.isDirectory() && p.canHaveOatDir()) { 15689 apkPath = packageDir.getAbsolutePath(); 15690 // If libDirRoot is inside a package dir, set it to null to avoid it being counted twice 15691 if (libDirRoot != null && libDirRoot.startsWith(apkPath)) { 15692 libDirRoot = null; 15693 } 15694 } else { 15695 apkPath = p.baseCodePath; 15696 } 15697 15698 // TODO: triage flags as part of 26466827 15699 final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE; 15700 try { 15701 mInstaller.getAppSize(p.volumeUuid, packageName, userHandle, flags, apkPath, 15702 libDirRoot, publicSrcDir, asecPath, dexCodeInstructionSets, pStats); 15703 } catch (InstallerException e) { 15704 return false; 15705 } 15706 15707 // Fix-up for forward-locked applications in ASEC containers. 15708 if (!isExternal(p)) { 15709 pStats.codeSize += pStats.externalCodeSize; 15710 pStats.externalCodeSize = 0L; 15711 } 15712 15713 return true; 15714 } 15715 15716 private int getUidTargetSdkVersionLockedLPr(int uid) { 15717 Object obj = mSettings.getUserIdLPr(uid); 15718 if (obj instanceof SharedUserSetting) { 15719 final SharedUserSetting sus = (SharedUserSetting) obj; 15720 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT; 15721 final Iterator<PackageSetting> it = sus.packages.iterator(); 15722 while (it.hasNext()) { 15723 final PackageSetting ps = it.next(); 15724 if (ps.pkg != null) { 15725 int v = ps.pkg.applicationInfo.targetSdkVersion; 15726 if (v < vers) vers = v; 15727 } 15728 } 15729 return vers; 15730 } else if (obj instanceof PackageSetting) { 15731 final PackageSetting ps = (PackageSetting) obj; 15732 if (ps.pkg != null) { 15733 return ps.pkg.applicationInfo.targetSdkVersion; 15734 } 15735 } 15736 return Build.VERSION_CODES.CUR_DEVELOPMENT; 15737 } 15738 15739 @Override 15740 public void addPreferredActivity(IntentFilter filter, int match, 15741 ComponentName[] set, ComponentName activity, int userId) { 15742 addPreferredActivityInternal(filter, match, set, activity, true, userId, 15743 "Adding preferred"); 15744 } 15745 15746 private void addPreferredActivityInternal(IntentFilter filter, int match, 15747 ComponentName[] set, ComponentName activity, boolean always, int userId, 15748 String opname) { 15749 // writer 15750 int callingUid = Binder.getCallingUid(); 15751 enforceCrossUserPermission(callingUid, userId, 15752 true /* requireFullPermission */, false /* checkShell */, "add preferred activity"); 15753 if (filter.countActions() == 0) { 15754 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 15755 return; 15756 } 15757 synchronized (mPackages) { 15758 if (mContext.checkCallingOrSelfPermission( 15759 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 15760 != PackageManager.PERMISSION_GRANTED) { 15761 if (getUidTargetSdkVersionLockedLPr(callingUid) 15762 < Build.VERSION_CODES.FROYO) { 15763 Slog.w(TAG, "Ignoring addPreferredActivity() from uid " 15764 + callingUid); 15765 return; 15766 } 15767 mContext.enforceCallingOrSelfPermission( 15768 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 15769 } 15770 15771 PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId); 15772 Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user " 15773 + userId + ":"); 15774 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 15775 pir.addFilter(new PreferredActivity(filter, match, set, activity, always)); 15776 scheduleWritePackageRestrictionsLocked(userId); 15777 } 15778 } 15779 15780 @Override 15781 public void replacePreferredActivity(IntentFilter filter, int match, 15782 ComponentName[] set, ComponentName activity, int userId) { 15783 if (filter.countActions() != 1) { 15784 throw new IllegalArgumentException( 15785 "replacePreferredActivity expects filter to have only 1 action."); 15786 } 15787 if (filter.countDataAuthorities() != 0 15788 || filter.countDataPaths() != 0 15789 || filter.countDataSchemes() > 1 15790 || filter.countDataTypes() != 0) { 15791 throw new IllegalArgumentException( 15792 "replacePreferredActivity expects filter to have no data authorities, " + 15793 "paths, or types; and at most one scheme."); 15794 } 15795 15796 final int callingUid = Binder.getCallingUid(); 15797 enforceCrossUserPermission(callingUid, userId, 15798 true /* requireFullPermission */, false /* checkShell */, 15799 "replace preferred activity"); 15800 synchronized (mPackages) { 15801 if (mContext.checkCallingOrSelfPermission( 15802 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 15803 != PackageManager.PERMISSION_GRANTED) { 15804 if (getUidTargetSdkVersionLockedLPr(callingUid) 15805 < Build.VERSION_CODES.FROYO) { 15806 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid " 15807 + Binder.getCallingUid()); 15808 return; 15809 } 15810 mContext.enforceCallingOrSelfPermission( 15811 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 15812 } 15813 15814 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 15815 if (pir != null) { 15816 // Get all of the existing entries that exactly match this filter. 15817 ArrayList<PreferredActivity> existing = pir.findFilters(filter); 15818 if (existing != null && existing.size() == 1) { 15819 PreferredActivity cur = existing.get(0); 15820 if (DEBUG_PREFERRED) { 15821 Slog.i(TAG, "Checking replace of preferred:"); 15822 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 15823 if (!cur.mPref.mAlways) { 15824 Slog.i(TAG, " -- CUR; not mAlways!"); 15825 } else { 15826 Slog.i(TAG, " -- CUR: mMatch=" + cur.mPref.mMatch); 15827 Slog.i(TAG, " -- CUR: mSet=" 15828 + Arrays.toString(cur.mPref.mSetComponents)); 15829 Slog.i(TAG, " -- CUR: mComponent=" + cur.mPref.mShortComponent); 15830 Slog.i(TAG, " -- NEW: mMatch=" 15831 + (match&IntentFilter.MATCH_CATEGORY_MASK)); 15832 Slog.i(TAG, " -- CUR: mSet=" + Arrays.toString(set)); 15833 Slog.i(TAG, " -- CUR: mComponent=" + activity.flattenToShortString()); 15834 } 15835 } 15836 if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity) 15837 && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK) 15838 && cur.mPref.sameSet(set)) { 15839 // Setting the preferred activity to what it happens to be already 15840 if (DEBUG_PREFERRED) { 15841 Slog.i(TAG, "Replacing with same preferred activity " 15842 + cur.mPref.mShortComponent + " for user " 15843 + userId + ":"); 15844 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 15845 } 15846 return; 15847 } 15848 } 15849 15850 if (existing != null) { 15851 if (DEBUG_PREFERRED) { 15852 Slog.i(TAG, existing.size() + " existing preferred matches for:"); 15853 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 15854 } 15855 for (int i = 0; i < existing.size(); i++) { 15856 PreferredActivity pa = existing.get(i); 15857 if (DEBUG_PREFERRED) { 15858 Slog.i(TAG, "Removing existing preferred activity " 15859 + pa.mPref.mComponent + ":"); 15860 pa.dump(new LogPrinter(Log.INFO, TAG), " "); 15861 } 15862 pir.removeFilter(pa); 15863 } 15864 } 15865 } 15866 addPreferredActivityInternal(filter, match, set, activity, true, userId, 15867 "Replacing preferred"); 15868 } 15869 } 15870 15871 @Override 15872 public void clearPackagePreferredActivities(String packageName) { 15873 final int uid = Binder.getCallingUid(); 15874 // writer 15875 synchronized (mPackages) { 15876 PackageParser.Package pkg = mPackages.get(packageName); 15877 if (pkg == null || pkg.applicationInfo.uid != uid) { 15878 if (mContext.checkCallingOrSelfPermission( 15879 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 15880 != PackageManager.PERMISSION_GRANTED) { 15881 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid()) 15882 < Build.VERSION_CODES.FROYO) { 15883 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid " 15884 + Binder.getCallingUid()); 15885 return; 15886 } 15887 mContext.enforceCallingOrSelfPermission( 15888 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 15889 } 15890 } 15891 15892 int user = UserHandle.getCallingUserId(); 15893 if (clearPackagePreferredActivitiesLPw(packageName, user)) { 15894 scheduleWritePackageRestrictionsLocked(user); 15895 } 15896 } 15897 } 15898 15899 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 15900 boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) { 15901 ArrayList<PreferredActivity> removed = null; 15902 boolean changed = false; 15903 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 15904 final int thisUserId = mSettings.mPreferredActivities.keyAt(i); 15905 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 15906 if (userId != UserHandle.USER_ALL && userId != thisUserId) { 15907 continue; 15908 } 15909 Iterator<PreferredActivity> it = pir.filterIterator(); 15910 while (it.hasNext()) { 15911 PreferredActivity pa = it.next(); 15912 // Mark entry for removal only if it matches the package name 15913 // and the entry is of type "always". 15914 if (packageName == null || 15915 (pa.mPref.mComponent.getPackageName().equals(packageName) 15916 && pa.mPref.mAlways)) { 15917 if (removed == null) { 15918 removed = new ArrayList<PreferredActivity>(); 15919 } 15920 removed.add(pa); 15921 } 15922 } 15923 if (removed != null) { 15924 for (int j=0; j<removed.size(); j++) { 15925 PreferredActivity pa = removed.get(j); 15926 pir.removeFilter(pa); 15927 } 15928 changed = true; 15929 } 15930 } 15931 return changed; 15932 } 15933 15934 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 15935 private void clearIntentFilterVerificationsLPw(int userId) { 15936 final int packageCount = mPackages.size(); 15937 for (int i = 0; i < packageCount; i++) { 15938 PackageParser.Package pkg = mPackages.valueAt(i); 15939 clearIntentFilterVerificationsLPw(pkg.packageName, userId); 15940 } 15941 } 15942 15943 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 15944 void clearIntentFilterVerificationsLPw(String packageName, int userId) { 15945 if (userId == UserHandle.USER_ALL) { 15946 if (mSettings.removeIntentFilterVerificationLPw(packageName, 15947 sUserManager.getUserIds())) { 15948 for (int oneUserId : sUserManager.getUserIds()) { 15949 scheduleWritePackageRestrictionsLocked(oneUserId); 15950 } 15951 } 15952 } else { 15953 if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) { 15954 scheduleWritePackageRestrictionsLocked(userId); 15955 } 15956 } 15957 } 15958 15959 void clearDefaultBrowserIfNeeded(String packageName) { 15960 for (int oneUserId : sUserManager.getUserIds()) { 15961 String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId); 15962 if (TextUtils.isEmpty(defaultBrowserPackageName)) continue; 15963 if (packageName.equals(defaultBrowserPackageName)) { 15964 setDefaultBrowserPackageName(null, oneUserId); 15965 } 15966 } 15967 } 15968 15969 @Override 15970 public void resetApplicationPreferences(int userId) { 15971 mContext.enforceCallingOrSelfPermission( 15972 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 15973 // writer 15974 synchronized (mPackages) { 15975 final long identity = Binder.clearCallingIdentity(); 15976 try { 15977 clearPackagePreferredActivitiesLPw(null, userId); 15978 mSettings.applyDefaultPreferredAppsLPw(this, userId); 15979 // TODO: We have to reset the default SMS and Phone. This requires 15980 // significant refactoring to keep all default apps in the package 15981 // manager (cleaner but more work) or have the services provide 15982 // callbacks to the package manager to request a default app reset. 15983 applyFactoryDefaultBrowserLPw(userId); 15984 clearIntentFilterVerificationsLPw(userId); 15985 primeDomainVerificationsLPw(userId); 15986 resetUserChangesToRuntimePermissionsAndFlagsLPw(userId); 15987 scheduleWritePackageRestrictionsLocked(userId); 15988 } finally { 15989 Binder.restoreCallingIdentity(identity); 15990 } 15991 } 15992 } 15993 15994 @Override 15995 public int getPreferredActivities(List<IntentFilter> outFilters, 15996 List<ComponentName> outActivities, String packageName) { 15997 15998 int num = 0; 15999 final int userId = UserHandle.getCallingUserId(); 16000 // reader 16001 synchronized (mPackages) { 16002 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 16003 if (pir != null) { 16004 final Iterator<PreferredActivity> it = pir.filterIterator(); 16005 while (it.hasNext()) { 16006 final PreferredActivity pa = it.next(); 16007 if (packageName == null 16008 || (pa.mPref.mComponent.getPackageName().equals(packageName) 16009 && pa.mPref.mAlways)) { 16010 if (outFilters != null) { 16011 outFilters.add(new IntentFilter(pa)); 16012 } 16013 if (outActivities != null) { 16014 outActivities.add(pa.mPref.mComponent); 16015 } 16016 } 16017 } 16018 } 16019 } 16020 16021 return num; 16022 } 16023 16024 @Override 16025 public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity, 16026 int userId) { 16027 int callingUid = Binder.getCallingUid(); 16028 if (callingUid != Process.SYSTEM_UID) { 16029 throw new SecurityException( 16030 "addPersistentPreferredActivity can only be run by the system"); 16031 } 16032 if (filter.countActions() == 0) { 16033 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 16034 return; 16035 } 16036 synchronized (mPackages) { 16037 Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId + 16038 ":"); 16039 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 16040 mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter( 16041 new PersistentPreferredActivity(filter, activity)); 16042 scheduleWritePackageRestrictionsLocked(userId); 16043 } 16044 } 16045 16046 @Override 16047 public void clearPackagePersistentPreferredActivities(String packageName, int userId) { 16048 int callingUid = Binder.getCallingUid(); 16049 if (callingUid != Process.SYSTEM_UID) { 16050 throw new SecurityException( 16051 "clearPackagePersistentPreferredActivities can only be run by the system"); 16052 } 16053 ArrayList<PersistentPreferredActivity> removed = null; 16054 boolean changed = false; 16055 synchronized (mPackages) { 16056 for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) { 16057 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i); 16058 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 16059 .valueAt(i); 16060 if (userId != thisUserId) { 16061 continue; 16062 } 16063 Iterator<PersistentPreferredActivity> it = ppir.filterIterator(); 16064 while (it.hasNext()) { 16065 PersistentPreferredActivity ppa = it.next(); 16066 // Mark entry for removal only if it matches the package name. 16067 if (ppa.mComponent.getPackageName().equals(packageName)) { 16068 if (removed == null) { 16069 removed = new ArrayList<PersistentPreferredActivity>(); 16070 } 16071 removed.add(ppa); 16072 } 16073 } 16074 if (removed != null) { 16075 for (int j=0; j<removed.size(); j++) { 16076 PersistentPreferredActivity ppa = removed.get(j); 16077 ppir.removeFilter(ppa); 16078 } 16079 changed = true; 16080 } 16081 } 16082 16083 if (changed) { 16084 scheduleWritePackageRestrictionsLocked(userId); 16085 } 16086 } 16087 } 16088 16089 /** 16090 * Common machinery for picking apart a restored XML blob and passing 16091 * it to a caller-supplied functor to be applied to the running system. 16092 */ 16093 private void restoreFromXml(XmlPullParser parser, int userId, 16094 String expectedStartTag, BlobXmlRestorer functor) 16095 throws IOException, XmlPullParserException { 16096 int type; 16097 while ((type = parser.next()) != XmlPullParser.START_TAG 16098 && type != XmlPullParser.END_DOCUMENT) { 16099 } 16100 if (type != XmlPullParser.START_TAG) { 16101 // oops didn't find a start tag?! 16102 if (DEBUG_BACKUP) { 16103 Slog.e(TAG, "Didn't find start tag during restore"); 16104 } 16105 return; 16106 } 16107Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName()); 16108 // this is supposed to be TAG_PREFERRED_BACKUP 16109 if (!expectedStartTag.equals(parser.getName())) { 16110 if (DEBUG_BACKUP) { 16111 Slog.e(TAG, "Found unexpected tag " + parser.getName()); 16112 } 16113 return; 16114 } 16115 16116 // skip interfering stuff, then we're aligned with the backing implementation 16117 while ((type = parser.next()) == XmlPullParser.TEXT) { } 16118Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); 16119 functor.apply(parser, userId); 16120 } 16121 16122 private interface BlobXmlRestorer { 16123 public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException; 16124 } 16125 16126 /** 16127 * Non-Binder method, support for the backup/restore mechanism: write the 16128 * full set of preferred activities in its canonical XML format. Returns the 16129 * XML output as a byte array, or null if there is none. 16130 */ 16131 @Override 16132 public byte[] getPreferredActivityBackup(int userId) { 16133 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16134 throw new SecurityException("Only the system may call getPreferredActivityBackup()"); 16135 } 16136 16137 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 16138 try { 16139 final XmlSerializer serializer = new FastXmlSerializer(); 16140 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 16141 serializer.startDocument(null, true); 16142 serializer.startTag(null, TAG_PREFERRED_BACKUP); 16143 16144 synchronized (mPackages) { 16145 mSettings.writePreferredActivitiesLPr(serializer, userId, true); 16146 } 16147 16148 serializer.endTag(null, TAG_PREFERRED_BACKUP); 16149 serializer.endDocument(); 16150 serializer.flush(); 16151 } catch (Exception e) { 16152 if (DEBUG_BACKUP) { 16153 Slog.e(TAG, "Unable to write preferred activities for backup", e); 16154 } 16155 return null; 16156 } 16157 16158 return dataStream.toByteArray(); 16159 } 16160 16161 @Override 16162 public void restorePreferredActivities(byte[] backup, int userId) { 16163 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16164 throw new SecurityException("Only the system may call restorePreferredActivities()"); 16165 } 16166 16167 try { 16168 final XmlPullParser parser = Xml.newPullParser(); 16169 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 16170 restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP, 16171 new BlobXmlRestorer() { 16172 @Override 16173 public void apply(XmlPullParser parser, int userId) 16174 throws XmlPullParserException, IOException { 16175 synchronized (mPackages) { 16176 mSettings.readPreferredActivitiesLPw(parser, userId); 16177 } 16178 } 16179 } ); 16180 } catch (Exception e) { 16181 if (DEBUG_BACKUP) { 16182 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 16183 } 16184 } 16185 } 16186 16187 /** 16188 * Non-Binder method, support for the backup/restore mechanism: write the 16189 * default browser (etc) settings in its canonical XML format. Returns the default 16190 * browser XML representation as a byte array, or null if there is none. 16191 */ 16192 @Override 16193 public byte[] getDefaultAppsBackup(int userId) { 16194 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16195 throw new SecurityException("Only the system may call getDefaultAppsBackup()"); 16196 } 16197 16198 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 16199 try { 16200 final XmlSerializer serializer = new FastXmlSerializer(); 16201 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 16202 serializer.startDocument(null, true); 16203 serializer.startTag(null, TAG_DEFAULT_APPS); 16204 16205 synchronized (mPackages) { 16206 mSettings.writeDefaultAppsLPr(serializer, userId); 16207 } 16208 16209 serializer.endTag(null, TAG_DEFAULT_APPS); 16210 serializer.endDocument(); 16211 serializer.flush(); 16212 } catch (Exception e) { 16213 if (DEBUG_BACKUP) { 16214 Slog.e(TAG, "Unable to write default apps for backup", e); 16215 } 16216 return null; 16217 } 16218 16219 return dataStream.toByteArray(); 16220 } 16221 16222 @Override 16223 public void restoreDefaultApps(byte[] backup, int userId) { 16224 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16225 throw new SecurityException("Only the system may call restoreDefaultApps()"); 16226 } 16227 16228 try { 16229 final XmlPullParser parser = Xml.newPullParser(); 16230 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 16231 restoreFromXml(parser, userId, TAG_DEFAULT_APPS, 16232 new BlobXmlRestorer() { 16233 @Override 16234 public void apply(XmlPullParser parser, int userId) 16235 throws XmlPullParserException, IOException { 16236 synchronized (mPackages) { 16237 mSettings.readDefaultAppsLPw(parser, userId); 16238 } 16239 } 16240 } ); 16241 } catch (Exception e) { 16242 if (DEBUG_BACKUP) { 16243 Slog.e(TAG, "Exception restoring default apps: " + e.getMessage()); 16244 } 16245 } 16246 } 16247 16248 @Override 16249 public byte[] getIntentFilterVerificationBackup(int userId) { 16250 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16251 throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()"); 16252 } 16253 16254 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 16255 try { 16256 final XmlSerializer serializer = new FastXmlSerializer(); 16257 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 16258 serializer.startDocument(null, true); 16259 serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION); 16260 16261 synchronized (mPackages) { 16262 mSettings.writeAllDomainVerificationsLPr(serializer, userId); 16263 } 16264 16265 serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION); 16266 serializer.endDocument(); 16267 serializer.flush(); 16268 } catch (Exception e) { 16269 if (DEBUG_BACKUP) { 16270 Slog.e(TAG, "Unable to write default apps for backup", e); 16271 } 16272 return null; 16273 } 16274 16275 return dataStream.toByteArray(); 16276 } 16277 16278 @Override 16279 public void restoreIntentFilterVerification(byte[] backup, int userId) { 16280 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16281 throw new SecurityException("Only the system may call restorePreferredActivities()"); 16282 } 16283 16284 try { 16285 final XmlPullParser parser = Xml.newPullParser(); 16286 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 16287 restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION, 16288 new BlobXmlRestorer() { 16289 @Override 16290 public void apply(XmlPullParser parser, int userId) 16291 throws XmlPullParserException, IOException { 16292 synchronized (mPackages) { 16293 mSettings.readAllDomainVerificationsLPr(parser, userId); 16294 mSettings.writeLPr(); 16295 } 16296 } 16297 } ); 16298 } catch (Exception e) { 16299 if (DEBUG_BACKUP) { 16300 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 16301 } 16302 } 16303 } 16304 16305 @Override 16306 public byte[] getPermissionGrantBackup(int userId) { 16307 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16308 throw new SecurityException("Only the system may call getPermissionGrantBackup()"); 16309 } 16310 16311 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 16312 try { 16313 final XmlSerializer serializer = new FastXmlSerializer(); 16314 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 16315 serializer.startDocument(null, true); 16316 serializer.startTag(null, TAG_PERMISSION_BACKUP); 16317 16318 synchronized (mPackages) { 16319 serializeRuntimePermissionGrantsLPr(serializer, userId); 16320 } 16321 16322 serializer.endTag(null, TAG_PERMISSION_BACKUP); 16323 serializer.endDocument(); 16324 serializer.flush(); 16325 } catch (Exception e) { 16326 if (DEBUG_BACKUP) { 16327 Slog.e(TAG, "Unable to write default apps for backup", e); 16328 } 16329 return null; 16330 } 16331 16332 return dataStream.toByteArray(); 16333 } 16334 16335 @Override 16336 public void restorePermissionGrants(byte[] backup, int userId) { 16337 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16338 throw new SecurityException("Only the system may call restorePermissionGrants()"); 16339 } 16340 16341 try { 16342 final XmlPullParser parser = Xml.newPullParser(); 16343 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 16344 restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP, 16345 new BlobXmlRestorer() { 16346 @Override 16347 public void apply(XmlPullParser parser, int userId) 16348 throws XmlPullParserException, IOException { 16349 synchronized (mPackages) { 16350 processRestoredPermissionGrantsLPr(parser, userId); 16351 } 16352 } 16353 } ); 16354 } catch (Exception e) { 16355 if (DEBUG_BACKUP) { 16356 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 16357 } 16358 } 16359 } 16360 16361 private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId) 16362 throws IOException { 16363 serializer.startTag(null, TAG_ALL_GRANTS); 16364 16365 final int N = mSettings.mPackages.size(); 16366 for (int i = 0; i < N; i++) { 16367 final PackageSetting ps = mSettings.mPackages.valueAt(i); 16368 boolean pkgGrantsKnown = false; 16369 16370 PermissionsState packagePerms = ps.getPermissionsState(); 16371 16372 for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) { 16373 final int grantFlags = state.getFlags(); 16374 // only look at grants that are not system/policy fixed 16375 if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) { 16376 final boolean isGranted = state.isGranted(); 16377 // And only back up the user-twiddled state bits 16378 if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) { 16379 final String packageName = mSettings.mPackages.keyAt(i); 16380 if (!pkgGrantsKnown) { 16381 serializer.startTag(null, TAG_GRANT); 16382 serializer.attribute(null, ATTR_PACKAGE_NAME, packageName); 16383 pkgGrantsKnown = true; 16384 } 16385 16386 final boolean userSet = 16387 (grantFlags & FLAG_PERMISSION_USER_SET) != 0; 16388 final boolean userFixed = 16389 (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0; 16390 final boolean revoke = 16391 (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0; 16392 16393 serializer.startTag(null, TAG_PERMISSION); 16394 serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName()); 16395 if (isGranted) { 16396 serializer.attribute(null, ATTR_IS_GRANTED, "true"); 16397 } 16398 if (userSet) { 16399 serializer.attribute(null, ATTR_USER_SET, "true"); 16400 } 16401 if (userFixed) { 16402 serializer.attribute(null, ATTR_USER_FIXED, "true"); 16403 } 16404 if (revoke) { 16405 serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true"); 16406 } 16407 serializer.endTag(null, TAG_PERMISSION); 16408 } 16409 } 16410 } 16411 16412 if (pkgGrantsKnown) { 16413 serializer.endTag(null, TAG_GRANT); 16414 } 16415 } 16416 16417 serializer.endTag(null, TAG_ALL_GRANTS); 16418 } 16419 16420 private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId) 16421 throws XmlPullParserException, IOException { 16422 String pkgName = null; 16423 int outerDepth = parser.getDepth(); 16424 int type; 16425 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 16426 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 16427 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 16428 continue; 16429 } 16430 16431 final String tagName = parser.getName(); 16432 if (tagName.equals(TAG_GRANT)) { 16433 pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME); 16434 if (DEBUG_BACKUP) { 16435 Slog.v(TAG, "+++ Restoring grants for package " + pkgName); 16436 } 16437 } else if (tagName.equals(TAG_PERMISSION)) { 16438 16439 final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED)); 16440 final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME); 16441 16442 int newFlagSet = 0; 16443 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) { 16444 newFlagSet |= FLAG_PERMISSION_USER_SET; 16445 } 16446 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) { 16447 newFlagSet |= FLAG_PERMISSION_USER_FIXED; 16448 } 16449 if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) { 16450 newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE; 16451 } 16452 if (DEBUG_BACKUP) { 16453 Slog.v(TAG, " + Restoring grant: pkg=" + pkgName + " perm=" + permName 16454 + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet)); 16455 } 16456 final PackageSetting ps = mSettings.mPackages.get(pkgName); 16457 if (ps != null) { 16458 // Already installed so we apply the grant immediately 16459 if (DEBUG_BACKUP) { 16460 Slog.v(TAG, " + already installed; applying"); 16461 } 16462 PermissionsState perms = ps.getPermissionsState(); 16463 BasePermission bp = mSettings.mPermissions.get(permName); 16464 if (bp != null) { 16465 if (isGranted) { 16466 perms.grantRuntimePermission(bp, userId); 16467 } 16468 if (newFlagSet != 0) { 16469 perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet); 16470 } 16471 } 16472 } else { 16473 // Need to wait for post-restore install to apply the grant 16474 if (DEBUG_BACKUP) { 16475 Slog.v(TAG, " - not yet installed; saving for later"); 16476 } 16477 mSettings.processRestoredPermissionGrantLPr(pkgName, permName, 16478 isGranted, newFlagSet, userId); 16479 } 16480 } else { 16481 PackageManagerService.reportSettingsProblem(Log.WARN, 16482 "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName); 16483 XmlUtils.skipCurrentTag(parser); 16484 } 16485 } 16486 16487 scheduleWriteSettingsLocked(); 16488 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 16489 } 16490 16491 @Override 16492 public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage, 16493 int sourceUserId, int targetUserId, int flags) { 16494 mContext.enforceCallingOrSelfPermission( 16495 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 16496 int callingUid = Binder.getCallingUid(); 16497 enforceOwnerRights(ownerPackage, callingUid); 16498 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 16499 if (intentFilter.countActions() == 0) { 16500 Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions"); 16501 return; 16502 } 16503 synchronized (mPackages) { 16504 CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter, 16505 ownerPackage, targetUserId, flags); 16506 CrossProfileIntentResolver resolver = 16507 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 16508 ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter); 16509 // We have all those whose filter is equal. Now checking if the rest is equal as well. 16510 if (existing != null) { 16511 int size = existing.size(); 16512 for (int i = 0; i < size; i++) { 16513 if (newFilter.equalsIgnoreFilter(existing.get(i))) { 16514 return; 16515 } 16516 } 16517 } 16518 resolver.addFilter(newFilter); 16519 scheduleWritePackageRestrictionsLocked(sourceUserId); 16520 } 16521 } 16522 16523 @Override 16524 public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) { 16525 mContext.enforceCallingOrSelfPermission( 16526 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 16527 int callingUid = Binder.getCallingUid(); 16528 enforceOwnerRights(ownerPackage, callingUid); 16529 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 16530 synchronized (mPackages) { 16531 CrossProfileIntentResolver resolver = 16532 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 16533 ArraySet<CrossProfileIntentFilter> set = 16534 new ArraySet<CrossProfileIntentFilter>(resolver.filterSet()); 16535 for (CrossProfileIntentFilter filter : set) { 16536 if (filter.getOwnerPackage().equals(ownerPackage)) { 16537 resolver.removeFilter(filter); 16538 } 16539 } 16540 scheduleWritePackageRestrictionsLocked(sourceUserId); 16541 } 16542 } 16543 16544 // Enforcing that callingUid is owning pkg on userId 16545 private void enforceOwnerRights(String pkg, int callingUid) { 16546 // The system owns everything. 16547 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) { 16548 return; 16549 } 16550 int callingUserId = UserHandle.getUserId(callingUid); 16551 PackageInfo pi = getPackageInfo(pkg, 0, callingUserId); 16552 if (pi == null) { 16553 throw new IllegalArgumentException("Unknown package " + pkg + " on user " 16554 + callingUserId); 16555 } 16556 if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) { 16557 throw new SecurityException("Calling uid " + callingUid 16558 + " does not own package " + pkg); 16559 } 16560 } 16561 16562 @Override 16563 public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) { 16564 return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId()); 16565 } 16566 16567 private Intent getHomeIntent() { 16568 Intent intent = new Intent(Intent.ACTION_MAIN); 16569 intent.addCategory(Intent.CATEGORY_HOME); 16570 return intent; 16571 } 16572 16573 private IntentFilter getHomeFilter() { 16574 IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN); 16575 filter.addCategory(Intent.CATEGORY_HOME); 16576 filter.addCategory(Intent.CATEGORY_DEFAULT); 16577 return filter; 16578 } 16579 16580 ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, 16581 int userId) { 16582 Intent intent = getHomeIntent(); 16583 List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null, 16584 PackageManager.GET_META_DATA, userId); 16585 ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0, 16586 true, false, false, userId); 16587 16588 allHomeCandidates.clear(); 16589 if (list != null) { 16590 for (ResolveInfo ri : list) { 16591 allHomeCandidates.add(ri); 16592 } 16593 } 16594 return (preferred == null || preferred.activityInfo == null) 16595 ? null 16596 : new ComponentName(preferred.activityInfo.packageName, 16597 preferred.activityInfo.name); 16598 } 16599 16600 @Override 16601 public void setHomeActivity(ComponentName comp, int userId) { 16602 ArrayList<ResolveInfo> homeActivities = new ArrayList<>(); 16603 getHomeActivitiesAsUser(homeActivities, userId); 16604 16605 boolean found = false; 16606 16607 final int size = homeActivities.size(); 16608 final ComponentName[] set = new ComponentName[size]; 16609 for (int i = 0; i < size; i++) { 16610 final ResolveInfo candidate = homeActivities.get(i); 16611 final ActivityInfo info = candidate.activityInfo; 16612 final ComponentName activityName = new ComponentName(info.packageName, info.name); 16613 set[i] = activityName; 16614 if (!found && activityName.equals(comp)) { 16615 found = true; 16616 } 16617 } 16618 if (!found) { 16619 throw new IllegalArgumentException("Component " + comp + " cannot be home on user " 16620 + userId); 16621 } 16622 replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY, 16623 set, comp, userId); 16624 } 16625 16626 @Override 16627 public void setApplicationEnabledSetting(String appPackageName, 16628 int newState, int flags, int userId, String callingPackage) { 16629 if (!sUserManager.exists(userId)) return; 16630 if (callingPackage == null) { 16631 callingPackage = Integer.toString(Binder.getCallingUid()); 16632 } 16633 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage); 16634 } 16635 16636 @Override 16637 public void setComponentEnabledSetting(ComponentName componentName, 16638 int newState, int flags, int userId) { 16639 if (!sUserManager.exists(userId)) return; 16640 setEnabledSetting(componentName.getPackageName(), 16641 componentName.getClassName(), newState, flags, userId, null); 16642 } 16643 16644 private void setEnabledSetting(final String packageName, String className, int newState, 16645 final int flags, int userId, String callingPackage) { 16646 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT 16647 || newState == COMPONENT_ENABLED_STATE_ENABLED 16648 || newState == COMPONENT_ENABLED_STATE_DISABLED 16649 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER 16650 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) { 16651 throw new IllegalArgumentException("Invalid new component state: " 16652 + newState); 16653 } 16654 PackageSetting pkgSetting; 16655 final int uid = Binder.getCallingUid(); 16656 final int permission = mContext.checkCallingOrSelfPermission( 16657 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 16658 enforceCrossUserPermission(uid, userId, 16659 false /* requireFullPermission */, true /* checkShell */, "set enabled"); 16660 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 16661 boolean sendNow = false; 16662 boolean isApp = (className == null); 16663 String componentName = isApp ? packageName : className; 16664 int packageUid = -1; 16665 ArrayList<String> components; 16666 16667 // writer 16668 synchronized (mPackages) { 16669 pkgSetting = mSettings.mPackages.get(packageName); 16670 if (pkgSetting == null) { 16671 if (className == null) { 16672 throw new IllegalArgumentException("Unknown package: " + packageName); 16673 } 16674 throw new IllegalArgumentException( 16675 "Unknown component: " + packageName + "/" + className); 16676 } 16677 // Allow root and verify that userId is not being specified by a different user 16678 if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) { 16679 throw new SecurityException( 16680 "Permission Denial: attempt to change component state from pid=" 16681 + Binder.getCallingPid() 16682 + ", uid=" + uid + ", package uid=" + pkgSetting.appId); 16683 } 16684 if (className == null) { 16685 // We're dealing with an application/package level state change 16686 if (pkgSetting.getEnabled(userId) == newState) { 16687 // Nothing to do 16688 return; 16689 } 16690 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT 16691 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { 16692 // Don't care about who enables an app. 16693 callingPackage = null; 16694 } 16695 pkgSetting.setEnabled(newState, userId, callingPackage); 16696 // pkgSetting.pkg.mSetEnabled = newState; 16697 } else { 16698 // We're dealing with a component level state change 16699 // First, verify that this is a valid class name. 16700 PackageParser.Package pkg = pkgSetting.pkg; 16701 if (pkg == null || !pkg.hasComponentClassName(className)) { 16702 if (pkg != null && 16703 pkg.applicationInfo.targetSdkVersion >= 16704 Build.VERSION_CODES.JELLY_BEAN) { 16705 throw new IllegalArgumentException("Component class " + className 16706 + " does not exist in " + packageName); 16707 } else { 16708 Slog.w(TAG, "Failed setComponentEnabledSetting: component class " 16709 + className + " does not exist in " + packageName); 16710 } 16711 } 16712 switch (newState) { 16713 case COMPONENT_ENABLED_STATE_ENABLED: 16714 if (!pkgSetting.enableComponentLPw(className, userId)) { 16715 return; 16716 } 16717 break; 16718 case COMPONENT_ENABLED_STATE_DISABLED: 16719 if (!pkgSetting.disableComponentLPw(className, userId)) { 16720 return; 16721 } 16722 break; 16723 case COMPONENT_ENABLED_STATE_DEFAULT: 16724 if (!pkgSetting.restoreComponentLPw(className, userId)) { 16725 return; 16726 } 16727 break; 16728 default: 16729 Slog.e(TAG, "Invalid new component state: " + newState); 16730 return; 16731 } 16732 } 16733 scheduleWritePackageRestrictionsLocked(userId); 16734 components = mPendingBroadcasts.get(userId, packageName); 16735 final boolean newPackage = components == null; 16736 if (newPackage) { 16737 components = new ArrayList<String>(); 16738 } 16739 if (!components.contains(componentName)) { 16740 components.add(componentName); 16741 } 16742 if ((flags&PackageManager.DONT_KILL_APP) == 0) { 16743 sendNow = true; 16744 // Purge entry from pending broadcast list if another one exists already 16745 // since we are sending one right away. 16746 mPendingBroadcasts.remove(userId, packageName); 16747 } else { 16748 if (newPackage) { 16749 mPendingBroadcasts.put(userId, packageName, components); 16750 } 16751 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) { 16752 // Schedule a message 16753 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY); 16754 } 16755 } 16756 } 16757 16758 long callingId = Binder.clearCallingIdentity(); 16759 try { 16760 if (sendNow) { 16761 packageUid = UserHandle.getUid(userId, pkgSetting.appId); 16762 sendPackageChangedBroadcast(packageName, 16763 (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid); 16764 } 16765 } finally { 16766 Binder.restoreCallingIdentity(callingId); 16767 } 16768 } 16769 16770 @Override 16771 public void flushPackageRestrictionsAsUser(int userId) { 16772 if (!sUserManager.exists(userId)) { 16773 return; 16774 } 16775 enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/, 16776 false /* checkShell */, "flushPackageRestrictions"); 16777 synchronized (mPackages) { 16778 mSettings.writePackageRestrictionsLPr(userId); 16779 mDirtyUsers.remove(userId); 16780 if (mDirtyUsers.isEmpty()) { 16781 mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS); 16782 } 16783 } 16784 } 16785 16786 private void sendPackageChangedBroadcast(String packageName, 16787 boolean killFlag, ArrayList<String> componentNames, int packageUid) { 16788 if (DEBUG_INSTALL) 16789 Log.v(TAG, "Sending package changed: package=" + packageName + " components=" 16790 + componentNames); 16791 Bundle extras = new Bundle(4); 16792 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0)); 16793 String nameList[] = new String[componentNames.size()]; 16794 componentNames.toArray(nameList); 16795 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList); 16796 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag); 16797 extras.putInt(Intent.EXTRA_UID, packageUid); 16798 // If this is not reporting a change of the overall package, then only send it 16799 // to registered receivers. We don't want to launch a swath of apps for every 16800 // little component state change. 16801 final int flags = !componentNames.contains(packageName) 16802 ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0; 16803 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, flags, null, null, 16804 new int[] {UserHandle.getUserId(packageUid)}); 16805 } 16806 16807 @Override 16808 public void setPackageStoppedState(String packageName, boolean stopped, int userId) { 16809 if (!sUserManager.exists(userId)) return; 16810 final int uid = Binder.getCallingUid(); 16811 final int permission = mContext.checkCallingOrSelfPermission( 16812 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 16813 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 16814 enforceCrossUserPermission(uid, userId, 16815 true /* requireFullPermission */, true /* checkShell */, "stop package"); 16816 // writer 16817 synchronized (mPackages) { 16818 if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped, 16819 allowedByPermission, uid, userId)) { 16820 scheduleWritePackageRestrictionsLocked(userId); 16821 } 16822 } 16823 } 16824 16825 @Override 16826 public String getInstallerPackageName(String packageName) { 16827 // reader 16828 synchronized (mPackages) { 16829 return mSettings.getInstallerPackageNameLPr(packageName); 16830 } 16831 } 16832 16833 @Override 16834 public int getApplicationEnabledSetting(String packageName, int userId) { 16835 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 16836 int uid = Binder.getCallingUid(); 16837 enforceCrossUserPermission(uid, userId, 16838 false /* requireFullPermission */, false /* checkShell */, "get enabled"); 16839 // reader 16840 synchronized (mPackages) { 16841 return mSettings.getApplicationEnabledSettingLPr(packageName, userId); 16842 } 16843 } 16844 16845 @Override 16846 public int getComponentEnabledSetting(ComponentName componentName, int userId) { 16847 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 16848 int uid = Binder.getCallingUid(); 16849 enforceCrossUserPermission(uid, userId, 16850 false /* requireFullPermission */, false /* checkShell */, "get component enabled"); 16851 // reader 16852 synchronized (mPackages) { 16853 return mSettings.getComponentEnabledSettingLPr(componentName, userId); 16854 } 16855 } 16856 16857 @Override 16858 public void enterSafeMode() { 16859 enforceSystemOrRoot("Only the system can request entering safe mode"); 16860 16861 if (!mSystemReady) { 16862 mSafeMode = true; 16863 } 16864 } 16865 16866 @Override 16867 public void systemReady() { 16868 mSystemReady = true; 16869 16870 // Read the compatibilty setting when the system is ready. 16871 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt( 16872 mContext.getContentResolver(), 16873 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1; 16874 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled); 16875 if (DEBUG_SETTINGS) { 16876 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled); 16877 } 16878 16879 int[] grantPermissionsUserIds = EMPTY_INT_ARRAY; 16880 16881 synchronized (mPackages) { 16882 // Verify that all of the preferred activity components actually 16883 // exist. It is possible for applications to be updated and at 16884 // that point remove a previously declared activity component that 16885 // had been set as a preferred activity. We try to clean this up 16886 // the next time we encounter that preferred activity, but it is 16887 // possible for the user flow to never be able to return to that 16888 // situation so here we do a sanity check to make sure we haven't 16889 // left any junk around. 16890 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>(); 16891 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 16892 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 16893 removed.clear(); 16894 for (PreferredActivity pa : pir.filterSet()) { 16895 if (mActivities.mActivities.get(pa.mPref.mComponent) == null) { 16896 removed.add(pa); 16897 } 16898 } 16899 if (removed.size() > 0) { 16900 for (int r=0; r<removed.size(); r++) { 16901 PreferredActivity pa = removed.get(r); 16902 Slog.w(TAG, "Removing dangling preferred activity: " 16903 + pa.mPref.mComponent); 16904 pir.removeFilter(pa); 16905 } 16906 mSettings.writePackageRestrictionsLPr( 16907 mSettings.mPreferredActivities.keyAt(i)); 16908 } 16909 } 16910 16911 for (int userId : UserManagerService.getInstance().getUserIds()) { 16912 if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) { 16913 grantPermissionsUserIds = ArrayUtils.appendInt( 16914 grantPermissionsUserIds, userId); 16915 } 16916 } 16917 } 16918 sUserManager.systemReady(); 16919 16920 // If we upgraded grant all default permissions before kicking off. 16921 for (int userId : grantPermissionsUserIds) { 16922 mDefaultPermissionPolicy.grantDefaultPermissions(userId); 16923 } 16924 16925 // Kick off any messages waiting for system ready 16926 if (mPostSystemReadyMessages != null) { 16927 for (Message msg : mPostSystemReadyMessages) { 16928 msg.sendToTarget(); 16929 } 16930 mPostSystemReadyMessages = null; 16931 } 16932 16933 // Watch for external volumes that come and go over time 16934 final StorageManager storage = mContext.getSystemService(StorageManager.class); 16935 storage.registerListener(mStorageListener); 16936 16937 mInstallerService.systemReady(); 16938 mPackageDexOptimizer.systemReady(); 16939 16940 MountServiceInternal mountServiceInternal = LocalServices.getService( 16941 MountServiceInternal.class); 16942 mountServiceInternal.addExternalStoragePolicy( 16943 new MountServiceInternal.ExternalStorageMountPolicy() { 16944 @Override 16945 public int getMountMode(int uid, String packageName) { 16946 if (Process.isIsolated(uid)) { 16947 return Zygote.MOUNT_EXTERNAL_NONE; 16948 } 16949 if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) { 16950 return Zygote.MOUNT_EXTERNAL_DEFAULT; 16951 } 16952 if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { 16953 return Zygote.MOUNT_EXTERNAL_DEFAULT; 16954 } 16955 if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { 16956 return Zygote.MOUNT_EXTERNAL_READ; 16957 } 16958 return Zygote.MOUNT_EXTERNAL_WRITE; 16959 } 16960 16961 @Override 16962 public boolean hasExternalStorage(int uid, String packageName) { 16963 return true; 16964 } 16965 }); 16966 } 16967 16968 @Override 16969 public boolean isSafeMode() { 16970 return mSafeMode; 16971 } 16972 16973 @Override 16974 public boolean hasSystemUidErrors() { 16975 return mHasSystemUidErrors; 16976 } 16977 16978 static String arrayToString(int[] array) { 16979 StringBuffer buf = new StringBuffer(128); 16980 buf.append('['); 16981 if (array != null) { 16982 for (int i=0; i<array.length; i++) { 16983 if (i > 0) buf.append(", "); 16984 buf.append(array[i]); 16985 } 16986 } 16987 buf.append(']'); 16988 return buf.toString(); 16989 } 16990 16991 static class DumpState { 16992 public static final int DUMP_LIBS = 1 << 0; 16993 public static final int DUMP_FEATURES = 1 << 1; 16994 public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2; 16995 public static final int DUMP_SERVICE_RESOLVERS = 1 << 3; 16996 public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4; 16997 public static final int DUMP_CONTENT_RESOLVERS = 1 << 5; 16998 public static final int DUMP_PERMISSIONS = 1 << 6; 16999 public static final int DUMP_PACKAGES = 1 << 7; 17000 public static final int DUMP_SHARED_USERS = 1 << 8; 17001 public static final int DUMP_MESSAGES = 1 << 9; 17002 public static final int DUMP_PROVIDERS = 1 << 10; 17003 public static final int DUMP_VERIFIERS = 1 << 11; 17004 public static final int DUMP_PREFERRED = 1 << 12; 17005 public static final int DUMP_PREFERRED_XML = 1 << 13; 17006 public static final int DUMP_KEYSETS = 1 << 14; 17007 public static final int DUMP_VERSION = 1 << 15; 17008 public static final int DUMP_INSTALLS = 1 << 16; 17009 public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17; 17010 public static final int DUMP_DOMAIN_PREFERRED = 1 << 18; 17011 17012 public static final int OPTION_SHOW_FILTERS = 1 << 0; 17013 17014 private int mTypes; 17015 17016 private int mOptions; 17017 17018 private boolean mTitlePrinted; 17019 17020 private SharedUserSetting mSharedUser; 17021 17022 public boolean isDumping(int type) { 17023 if (mTypes == 0 && type != DUMP_PREFERRED_XML) { 17024 return true; 17025 } 17026 17027 return (mTypes & type) != 0; 17028 } 17029 17030 public void setDump(int type) { 17031 mTypes |= type; 17032 } 17033 17034 public boolean isOptionEnabled(int option) { 17035 return (mOptions & option) != 0; 17036 } 17037 17038 public void setOptionEnabled(int option) { 17039 mOptions |= option; 17040 } 17041 17042 public boolean onTitlePrinted() { 17043 final boolean printed = mTitlePrinted; 17044 mTitlePrinted = true; 17045 return printed; 17046 } 17047 17048 public boolean getTitlePrinted() { 17049 return mTitlePrinted; 17050 } 17051 17052 public void setTitlePrinted(boolean enabled) { 17053 mTitlePrinted = enabled; 17054 } 17055 17056 public SharedUserSetting getSharedUser() { 17057 return mSharedUser; 17058 } 17059 17060 public void setSharedUser(SharedUserSetting user) { 17061 mSharedUser = user; 17062 } 17063 } 17064 17065 @Override 17066 public void onShellCommand(FileDescriptor in, FileDescriptor out, 17067 FileDescriptor err, String[] args, ResultReceiver resultReceiver) { 17068 (new PackageManagerShellCommand(this)).exec( 17069 this, in, out, err, args, resultReceiver); 17070 } 17071 17072 @Override 17073 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 17074 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 17075 != PackageManager.PERMISSION_GRANTED) { 17076 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 17077 + Binder.getCallingPid() 17078 + ", uid=" + Binder.getCallingUid() 17079 + " without permission " 17080 + android.Manifest.permission.DUMP); 17081 return; 17082 } 17083 17084 DumpState dumpState = new DumpState(); 17085 boolean fullPreferred = false; 17086 boolean checkin = false; 17087 17088 String packageName = null; 17089 ArraySet<String> permissionNames = null; 17090 17091 int opti = 0; 17092 while (opti < args.length) { 17093 String opt = args[opti]; 17094 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 17095 break; 17096 } 17097 opti++; 17098 17099 if ("-a".equals(opt)) { 17100 // Right now we only know how to print all. 17101 } else if ("-h".equals(opt)) { 17102 pw.println("Package manager dump options:"); 17103 pw.println(" [-h] [-f] [--checkin] [cmd] ..."); 17104 pw.println(" --checkin: dump for a checkin"); 17105 pw.println(" -f: print details of intent filters"); 17106 pw.println(" -h: print this help"); 17107 pw.println(" cmd may be one of:"); 17108 pw.println(" l[ibraries]: list known shared libraries"); 17109 pw.println(" f[eatures]: list device features"); 17110 pw.println(" k[eysets]: print known keysets"); 17111 pw.println(" r[esolvers] [activity|service|receiver|content]: dump intent resolvers"); 17112 pw.println(" perm[issions]: dump permissions"); 17113 pw.println(" permission [name ...]: dump declaration and use of given permission"); 17114 pw.println(" pref[erred]: print preferred package settings"); 17115 pw.println(" preferred-xml [--full]: print preferred package settings as xml"); 17116 pw.println(" prov[iders]: dump content providers"); 17117 pw.println(" p[ackages]: dump installed packages"); 17118 pw.println(" s[hared-users]: dump shared user IDs"); 17119 pw.println(" m[essages]: print collected runtime messages"); 17120 pw.println(" v[erifiers]: print package verifier info"); 17121 pw.println(" d[omain-preferred-apps]: print domains preferred apps"); 17122 pw.println(" i[ntent-filter-verifiers]|ifv: print intent filter verifier info"); 17123 pw.println(" version: print database version info"); 17124 pw.println(" write: write current settings now"); 17125 pw.println(" installs: details about install sessions"); 17126 pw.println(" check-permission <permission> <package> [<user>]: does pkg hold perm?"); 17127 pw.println(" <package.name>: info about given package"); 17128 return; 17129 } else if ("--checkin".equals(opt)) { 17130 checkin = true; 17131 } else if ("-f".equals(opt)) { 17132 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 17133 } else { 17134 pw.println("Unknown argument: " + opt + "; use -h for help"); 17135 } 17136 } 17137 17138 // Is the caller requesting to dump a particular piece of data? 17139 if (opti < args.length) { 17140 String cmd = args[opti]; 17141 opti++; 17142 // Is this a package name? 17143 if ("android".equals(cmd) || cmd.contains(".")) { 17144 packageName = cmd; 17145 // When dumping a single package, we always dump all of its 17146 // filter information since the amount of data will be reasonable. 17147 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 17148 } else if ("check-permission".equals(cmd)) { 17149 if (opti >= args.length) { 17150 pw.println("Error: check-permission missing permission argument"); 17151 return; 17152 } 17153 String perm = args[opti]; 17154 opti++; 17155 if (opti >= args.length) { 17156 pw.println("Error: check-permission missing package argument"); 17157 return; 17158 } 17159 String pkg = args[opti]; 17160 opti++; 17161 int user = UserHandle.getUserId(Binder.getCallingUid()); 17162 if (opti < args.length) { 17163 try { 17164 user = Integer.parseInt(args[opti]); 17165 } catch (NumberFormatException e) { 17166 pw.println("Error: check-permission user argument is not a number: " 17167 + args[opti]); 17168 return; 17169 } 17170 } 17171 pw.println(checkPermission(perm, pkg, user)); 17172 return; 17173 } else if ("l".equals(cmd) || "libraries".equals(cmd)) { 17174 dumpState.setDump(DumpState.DUMP_LIBS); 17175 } else if ("f".equals(cmd) || "features".equals(cmd)) { 17176 dumpState.setDump(DumpState.DUMP_FEATURES); 17177 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) { 17178 if (opti >= args.length) { 17179 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS 17180 | DumpState.DUMP_SERVICE_RESOLVERS 17181 | DumpState.DUMP_RECEIVER_RESOLVERS 17182 | DumpState.DUMP_CONTENT_RESOLVERS); 17183 } else { 17184 while (opti < args.length) { 17185 String name = args[opti]; 17186 if ("a".equals(name) || "activity".equals(name)) { 17187 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS); 17188 } else if ("s".equals(name) || "service".equals(name)) { 17189 dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS); 17190 } else if ("r".equals(name) || "receiver".equals(name)) { 17191 dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS); 17192 } else if ("c".equals(name) || "content".equals(name)) { 17193 dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS); 17194 } else { 17195 pw.println("Error: unknown resolver table type: " + name); 17196 return; 17197 } 17198 opti++; 17199 } 17200 } 17201 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) { 17202 dumpState.setDump(DumpState.DUMP_PERMISSIONS); 17203 } else if ("permission".equals(cmd)) { 17204 if (opti >= args.length) { 17205 pw.println("Error: permission requires permission name"); 17206 return; 17207 } 17208 permissionNames = new ArraySet<>(); 17209 while (opti < args.length) { 17210 permissionNames.add(args[opti]); 17211 opti++; 17212 } 17213 dumpState.setDump(DumpState.DUMP_PERMISSIONS 17214 | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS); 17215 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) { 17216 dumpState.setDump(DumpState.DUMP_PREFERRED); 17217 } else if ("preferred-xml".equals(cmd)) { 17218 dumpState.setDump(DumpState.DUMP_PREFERRED_XML); 17219 if (opti < args.length && "--full".equals(args[opti])) { 17220 fullPreferred = true; 17221 opti++; 17222 } 17223 } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) { 17224 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED); 17225 } else if ("p".equals(cmd) || "packages".equals(cmd)) { 17226 dumpState.setDump(DumpState.DUMP_PACKAGES); 17227 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) { 17228 dumpState.setDump(DumpState.DUMP_SHARED_USERS); 17229 } else if ("prov".equals(cmd) || "providers".equals(cmd)) { 17230 dumpState.setDump(DumpState.DUMP_PROVIDERS); 17231 } else if ("m".equals(cmd) || "messages".equals(cmd)) { 17232 dumpState.setDump(DumpState.DUMP_MESSAGES); 17233 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) { 17234 dumpState.setDump(DumpState.DUMP_VERIFIERS); 17235 } else if ("i".equals(cmd) || "ifv".equals(cmd) 17236 || "intent-filter-verifiers".equals(cmd)) { 17237 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS); 17238 } else if ("version".equals(cmd)) { 17239 dumpState.setDump(DumpState.DUMP_VERSION); 17240 } else if ("k".equals(cmd) || "keysets".equals(cmd)) { 17241 dumpState.setDump(DumpState.DUMP_KEYSETS); 17242 } else if ("installs".equals(cmd)) { 17243 dumpState.setDump(DumpState.DUMP_INSTALLS); 17244 } else if ("write".equals(cmd)) { 17245 synchronized (mPackages) { 17246 mSettings.writeLPr(); 17247 pw.println("Settings written."); 17248 return; 17249 } 17250 } 17251 } 17252 17253 if (checkin) { 17254 pw.println("vers,1"); 17255 } 17256 17257 // reader 17258 synchronized (mPackages) { 17259 if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) { 17260 if (!checkin) { 17261 if (dumpState.onTitlePrinted()) 17262 pw.println(); 17263 pw.println("Database versions:"); 17264 mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, " ")); 17265 } 17266 } 17267 17268 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) { 17269 if (!checkin) { 17270 if (dumpState.onTitlePrinted()) 17271 pw.println(); 17272 pw.println("Verifiers:"); 17273 pw.print(" Required: "); 17274 pw.print(mRequiredVerifierPackage); 17275 pw.print(" (uid="); 17276 pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 17277 UserHandle.USER_SYSTEM)); 17278 pw.println(")"); 17279 } else if (mRequiredVerifierPackage != null) { 17280 pw.print("vrfy,"); pw.print(mRequiredVerifierPackage); 17281 pw.print(","); 17282 pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 17283 UserHandle.USER_SYSTEM)); 17284 } 17285 } 17286 17287 if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) && 17288 packageName == null) { 17289 if (mIntentFilterVerifierComponent != null) { 17290 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName(); 17291 if (!checkin) { 17292 if (dumpState.onTitlePrinted()) 17293 pw.println(); 17294 pw.println("Intent Filter Verifier:"); 17295 pw.print(" Using: "); 17296 pw.print(verifierPackageName); 17297 pw.print(" (uid="); 17298 pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING, 17299 UserHandle.USER_SYSTEM)); 17300 pw.println(")"); 17301 } else if (verifierPackageName != null) { 17302 pw.print("ifv,"); pw.print(verifierPackageName); 17303 pw.print(","); 17304 pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING, 17305 UserHandle.USER_SYSTEM)); 17306 } 17307 } else { 17308 pw.println(); 17309 pw.println("No Intent Filter Verifier available!"); 17310 } 17311 } 17312 17313 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) { 17314 boolean printedHeader = false; 17315 final Iterator<String> it = mSharedLibraries.keySet().iterator(); 17316 while (it.hasNext()) { 17317 String name = it.next(); 17318 SharedLibraryEntry ent = mSharedLibraries.get(name); 17319 if (!checkin) { 17320 if (!printedHeader) { 17321 if (dumpState.onTitlePrinted()) 17322 pw.println(); 17323 pw.println("Libraries:"); 17324 printedHeader = true; 17325 } 17326 pw.print(" "); 17327 } else { 17328 pw.print("lib,"); 17329 } 17330 pw.print(name); 17331 if (!checkin) { 17332 pw.print(" -> "); 17333 } 17334 if (ent.path != null) { 17335 if (!checkin) { 17336 pw.print("(jar) "); 17337 pw.print(ent.path); 17338 } else { 17339 pw.print(",jar,"); 17340 pw.print(ent.path); 17341 } 17342 } else { 17343 if (!checkin) { 17344 pw.print("(apk) "); 17345 pw.print(ent.apk); 17346 } else { 17347 pw.print(",apk,"); 17348 pw.print(ent.apk); 17349 } 17350 } 17351 pw.println(); 17352 } 17353 } 17354 17355 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) { 17356 if (dumpState.onTitlePrinted()) 17357 pw.println(); 17358 if (!checkin) { 17359 pw.println("Features:"); 17360 } 17361 17362 for (FeatureInfo feat : mAvailableFeatures.values()) { 17363 if (checkin) { 17364 pw.print("feat,"); 17365 pw.print(feat.name); 17366 pw.print(","); 17367 pw.println(feat.version); 17368 } else { 17369 pw.print(" "); 17370 pw.print(feat.name); 17371 if (feat.version > 0) { 17372 pw.print(" version="); 17373 pw.print(feat.version); 17374 } 17375 pw.println(); 17376 } 17377 } 17378 } 17379 17380 if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) { 17381 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:" 17382 : "Activity Resolver Table:", " ", packageName, 17383 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 17384 dumpState.setTitlePrinted(true); 17385 } 17386 } 17387 if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) { 17388 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:" 17389 : "Receiver Resolver Table:", " ", packageName, 17390 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 17391 dumpState.setTitlePrinted(true); 17392 } 17393 } 17394 if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) { 17395 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:" 17396 : "Service Resolver Table:", " ", packageName, 17397 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 17398 dumpState.setTitlePrinted(true); 17399 } 17400 } 17401 if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) { 17402 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:" 17403 : "Provider Resolver Table:", " ", packageName, 17404 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 17405 dumpState.setTitlePrinted(true); 17406 } 17407 } 17408 17409 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) { 17410 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 17411 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 17412 int user = mSettings.mPreferredActivities.keyAt(i); 17413 if (pir.dump(pw, 17414 dumpState.getTitlePrinted() 17415 ? "\nPreferred Activities User " + user + ":" 17416 : "Preferred Activities User " + user + ":", " ", 17417 packageName, true, false)) { 17418 dumpState.setTitlePrinted(true); 17419 } 17420 } 17421 } 17422 17423 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) { 17424 pw.flush(); 17425 FileOutputStream fout = new FileOutputStream(fd); 17426 BufferedOutputStream str = new BufferedOutputStream(fout); 17427 XmlSerializer serializer = new FastXmlSerializer(); 17428 try { 17429 serializer.setOutput(str, StandardCharsets.UTF_8.name()); 17430 serializer.startDocument(null, true); 17431 serializer.setFeature( 17432 "http://xmlpull.org/v1/doc/features.html#indent-output", true); 17433 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred); 17434 serializer.endDocument(); 17435 serializer.flush(); 17436 } catch (IllegalArgumentException e) { 17437 pw.println("Failed writing: " + e); 17438 } catch (IllegalStateException e) { 17439 pw.println("Failed writing: " + e); 17440 } catch (IOException e) { 17441 pw.println("Failed writing: " + e); 17442 } 17443 } 17444 17445 if (!checkin 17446 && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED) 17447 && packageName == null) { 17448 pw.println(); 17449 int count = mSettings.mPackages.size(); 17450 if (count == 0) { 17451 pw.println("No applications!"); 17452 pw.println(); 17453 } else { 17454 final String prefix = " "; 17455 Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values(); 17456 if (allPackageSettings.size() == 0) { 17457 pw.println("No domain preferred apps!"); 17458 pw.println(); 17459 } else { 17460 pw.println("App verification status:"); 17461 pw.println(); 17462 count = 0; 17463 for (PackageSetting ps : allPackageSettings) { 17464 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo(); 17465 if (ivi == null || ivi.getPackageName() == null) continue; 17466 pw.println(prefix + "Package: " + ivi.getPackageName()); 17467 pw.println(prefix + "Domains: " + ivi.getDomainsString()); 17468 pw.println(prefix + "Status: " + ivi.getStatusString()); 17469 pw.println(); 17470 count++; 17471 } 17472 if (count == 0) { 17473 pw.println(prefix + "No app verification established."); 17474 pw.println(); 17475 } 17476 for (int userId : sUserManager.getUserIds()) { 17477 pw.println("App linkages for user " + userId + ":"); 17478 pw.println(); 17479 count = 0; 17480 for (PackageSetting ps : allPackageSettings) { 17481 final long status = ps.getDomainVerificationStatusForUser(userId); 17482 if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 17483 continue; 17484 } 17485 pw.println(prefix + "Package: " + ps.name); 17486 pw.println(prefix + "Domains: " + dumpDomainString(ps.name)); 17487 String statusStr = IntentFilterVerificationInfo. 17488 getStatusStringFromValue(status); 17489 pw.println(prefix + "Status: " + statusStr); 17490 pw.println(); 17491 count++; 17492 } 17493 if (count == 0) { 17494 pw.println(prefix + "No configured app linkages."); 17495 pw.println(); 17496 } 17497 } 17498 } 17499 } 17500 } 17501 17502 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) { 17503 mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState); 17504 if (packageName == null && permissionNames == null) { 17505 for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) { 17506 if (iperm == 0) { 17507 if (dumpState.onTitlePrinted()) 17508 pw.println(); 17509 pw.println("AppOp Permissions:"); 17510 } 17511 pw.print(" AppOp Permission "); 17512 pw.print(mAppOpPermissionPackages.keyAt(iperm)); 17513 pw.println(":"); 17514 ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm); 17515 for (int ipkg=0; ipkg<pkgs.size(); ipkg++) { 17516 pw.print(" "); pw.println(pkgs.valueAt(ipkg)); 17517 } 17518 } 17519 } 17520 } 17521 17522 if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) { 17523 boolean printedSomething = false; 17524 for (PackageParser.Provider p : mProviders.mProviders.values()) { 17525 if (packageName != null && !packageName.equals(p.info.packageName)) { 17526 continue; 17527 } 17528 if (!printedSomething) { 17529 if (dumpState.onTitlePrinted()) 17530 pw.println(); 17531 pw.println("Registered ContentProviders:"); 17532 printedSomething = true; 17533 } 17534 pw.print(" "); p.printComponentShortName(pw); pw.println(":"); 17535 pw.print(" "); pw.println(p.toString()); 17536 } 17537 printedSomething = false; 17538 for (Map.Entry<String, PackageParser.Provider> entry : 17539 mProvidersByAuthority.entrySet()) { 17540 PackageParser.Provider p = entry.getValue(); 17541 if (packageName != null && !packageName.equals(p.info.packageName)) { 17542 continue; 17543 } 17544 if (!printedSomething) { 17545 if (dumpState.onTitlePrinted()) 17546 pw.println(); 17547 pw.println("ContentProvider Authorities:"); 17548 printedSomething = true; 17549 } 17550 pw.print(" ["); pw.print(entry.getKey()); pw.println("]:"); 17551 pw.print(" "); pw.println(p.toString()); 17552 if (p.info != null && p.info.applicationInfo != null) { 17553 final String appInfo = p.info.applicationInfo.toString(); 17554 pw.print(" applicationInfo="); pw.println(appInfo); 17555 } 17556 } 17557 } 17558 17559 if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) { 17560 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState); 17561 } 17562 17563 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) { 17564 mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin); 17565 } 17566 17567 if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) { 17568 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin); 17569 } 17570 17571 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) { 17572 mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState); 17573 } 17574 17575 if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) { 17576 // XXX should handle packageName != null by dumping only install data that 17577 // the given package is involved with. 17578 if (dumpState.onTitlePrinted()) pw.println(); 17579 mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120)); 17580 } 17581 17582 if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) { 17583 if (dumpState.onTitlePrinted()) pw.println(); 17584 mSettings.dumpReadMessagesLPr(pw, dumpState); 17585 17586 pw.println(); 17587 pw.println("Package warning messages:"); 17588 BufferedReader in = null; 17589 String line = null; 17590 try { 17591 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 17592 while ((line = in.readLine()) != null) { 17593 if (line.contains("ignored: updated version")) continue; 17594 pw.println(line); 17595 } 17596 } catch (IOException ignored) { 17597 } finally { 17598 IoUtils.closeQuietly(in); 17599 } 17600 } 17601 17602 if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) { 17603 BufferedReader in = null; 17604 String line = null; 17605 try { 17606 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 17607 while ((line = in.readLine()) != null) { 17608 if (line.contains("ignored: updated version")) continue; 17609 pw.print("msg,"); 17610 pw.println(line); 17611 } 17612 } catch (IOException ignored) { 17613 } finally { 17614 IoUtils.closeQuietly(in); 17615 } 17616 } 17617 } 17618 } 17619 17620 private String dumpDomainString(String packageName) { 17621 List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName) 17622 .getList(); 17623 List<IntentFilter> filters = getAllIntentFilters(packageName).getList(); 17624 17625 ArraySet<String> result = new ArraySet<>(); 17626 if (iviList.size() > 0) { 17627 for (IntentFilterVerificationInfo ivi : iviList) { 17628 for (String host : ivi.getDomains()) { 17629 result.add(host); 17630 } 17631 } 17632 } 17633 if (filters != null && filters.size() > 0) { 17634 for (IntentFilter filter : filters) { 17635 if (filter.hasCategory(Intent.CATEGORY_BROWSABLE) 17636 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 17637 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) { 17638 result.addAll(filter.getHostsList()); 17639 } 17640 } 17641 } 17642 17643 StringBuilder sb = new StringBuilder(result.size() * 16); 17644 for (String domain : result) { 17645 if (sb.length() > 0) sb.append(" "); 17646 sb.append(domain); 17647 } 17648 return sb.toString(); 17649 } 17650 17651 // ------- apps on sdcard specific code ------- 17652 static final boolean DEBUG_SD_INSTALL = false; 17653 17654 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD"; 17655 17656 private static final String SD_ENCRYPTION_ALGORITHM = "AES"; 17657 17658 private boolean mMediaMounted = false; 17659 17660 static String getEncryptKey() { 17661 try { 17662 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString( 17663 SD_ENCRYPTION_KEYSTORE_NAME); 17664 if (sdEncKey == null) { 17665 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128, 17666 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME); 17667 if (sdEncKey == null) { 17668 Slog.e(TAG, "Failed to create encryption keys"); 17669 return null; 17670 } 17671 } 17672 return sdEncKey; 17673 } catch (NoSuchAlgorithmException nsae) { 17674 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae); 17675 return null; 17676 } catch (IOException ioe) { 17677 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe); 17678 return null; 17679 } 17680 } 17681 17682 /* 17683 * Update media status on PackageManager. 17684 */ 17685 @Override 17686 public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) { 17687 int callingUid = Binder.getCallingUid(); 17688 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 17689 throw new SecurityException("Media status can only be updated by the system"); 17690 } 17691 // reader; this apparently protects mMediaMounted, but should probably 17692 // be a different lock in that case. 17693 synchronized (mPackages) { 17694 Log.i(TAG, "Updating external media status from " 17695 + (mMediaMounted ? "mounted" : "unmounted") + " to " 17696 + (mediaStatus ? "mounted" : "unmounted")); 17697 if (DEBUG_SD_INSTALL) 17698 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus 17699 + ", mMediaMounted=" + mMediaMounted); 17700 if (mediaStatus == mMediaMounted) { 17701 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 17702 : 0, -1); 17703 mHandler.sendMessage(msg); 17704 return; 17705 } 17706 mMediaMounted = mediaStatus; 17707 } 17708 // Queue up an async operation since the package installation may take a 17709 // little while. 17710 mHandler.post(new Runnable() { 17711 public void run() { 17712 updateExternalMediaStatusInner(mediaStatus, reportStatus, true); 17713 } 17714 }); 17715 } 17716 17717 /** 17718 * Called by MountService when the initial ASECs to scan are available. 17719 * Should block until all the ASEC containers are finished being scanned. 17720 */ 17721 public void scanAvailableAsecs() { 17722 updateExternalMediaStatusInner(true, false, false); 17723 } 17724 17725 /* 17726 * Collect information of applications on external media, map them against 17727 * existing containers and update information based on current mount status. 17728 * Please note that we always have to report status if reportStatus has been 17729 * set to true especially when unloading packages. 17730 */ 17731 private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus, 17732 boolean externalStorage) { 17733 ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>(); 17734 int[] uidArr = EmptyArray.INT; 17735 17736 final String[] list = PackageHelper.getSecureContainerList(); 17737 if (ArrayUtils.isEmpty(list)) { 17738 Log.i(TAG, "No secure containers found"); 17739 } else { 17740 // Process list of secure containers and categorize them 17741 // as active or stale based on their package internal state. 17742 17743 // reader 17744 synchronized (mPackages) { 17745 for (String cid : list) { 17746 // Leave stages untouched for now; installer service owns them 17747 if (PackageInstallerService.isStageName(cid)) continue; 17748 17749 if (DEBUG_SD_INSTALL) 17750 Log.i(TAG, "Processing container " + cid); 17751 String pkgName = getAsecPackageName(cid); 17752 if (pkgName == null) { 17753 Slog.i(TAG, "Found stale container " + cid + " with no package name"); 17754 continue; 17755 } 17756 if (DEBUG_SD_INSTALL) 17757 Log.i(TAG, "Looking for pkg : " + pkgName); 17758 17759 final PackageSetting ps = mSettings.mPackages.get(pkgName); 17760 if (ps == null) { 17761 Slog.i(TAG, "Found stale container " + cid + " with no matching settings"); 17762 continue; 17763 } 17764 17765 /* 17766 * Skip packages that are not external if we're unmounting 17767 * external storage. 17768 */ 17769 if (externalStorage && !isMounted && !isExternal(ps)) { 17770 continue; 17771 } 17772 17773 final AsecInstallArgs args = new AsecInstallArgs(cid, 17774 getAppDexInstructionSets(ps), ps.isForwardLocked()); 17775 // The package status is changed only if the code path 17776 // matches between settings and the container id. 17777 if (ps.codePathString != null 17778 && ps.codePathString.startsWith(args.getCodePath())) { 17779 if (DEBUG_SD_INSTALL) { 17780 Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName 17781 + " at code path: " + ps.codePathString); 17782 } 17783 17784 // We do have a valid package installed on sdcard 17785 processCids.put(args, ps.codePathString); 17786 final int uid = ps.appId; 17787 if (uid != -1) { 17788 uidArr = ArrayUtils.appendInt(uidArr, uid); 17789 } 17790 } else { 17791 Slog.i(TAG, "Found stale container " + cid + ": expected codePath=" 17792 + ps.codePathString); 17793 } 17794 } 17795 } 17796 17797 Arrays.sort(uidArr); 17798 } 17799 17800 // Process packages with valid entries. 17801 if (isMounted) { 17802 if (DEBUG_SD_INSTALL) 17803 Log.i(TAG, "Loading packages"); 17804 loadMediaPackages(processCids, uidArr, externalStorage); 17805 startCleaningPackages(); 17806 mInstallerService.onSecureContainersAvailable(); 17807 } else { 17808 if (DEBUG_SD_INSTALL) 17809 Log.i(TAG, "Unloading packages"); 17810 unloadMediaPackages(processCids, uidArr, reportStatus); 17811 } 17812 } 17813 17814 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 17815 ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) { 17816 final int size = infos.size(); 17817 final String[] packageNames = new String[size]; 17818 final int[] packageUids = new int[size]; 17819 for (int i = 0; i < size; i++) { 17820 final ApplicationInfo info = infos.get(i); 17821 packageNames[i] = info.packageName; 17822 packageUids[i] = info.uid; 17823 } 17824 sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids, 17825 finishedReceiver); 17826 } 17827 17828 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 17829 ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 17830 sendResourcesChangedBroadcast(mediaStatus, replacing, 17831 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver); 17832 } 17833 17834 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 17835 String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 17836 int size = pkgList.length; 17837 if (size > 0) { 17838 // Send broadcasts here 17839 Bundle extras = new Bundle(); 17840 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 17841 if (uidArr != null) { 17842 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr); 17843 } 17844 if (replacing) { 17845 extras.putBoolean(Intent.EXTRA_REPLACING, replacing); 17846 } 17847 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE 17848 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE; 17849 sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null); 17850 } 17851 } 17852 17853 /* 17854 * Look at potentially valid container ids from processCids If package 17855 * information doesn't match the one on record or package scanning fails, 17856 * the cid is added to list of removeCids. We currently don't delete stale 17857 * containers. 17858 */ 17859 private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr, 17860 boolean externalStorage) { 17861 ArrayList<String> pkgList = new ArrayList<String>(); 17862 Set<AsecInstallArgs> keys = processCids.keySet(); 17863 17864 for (AsecInstallArgs args : keys) { 17865 String codePath = processCids.get(args); 17866 if (DEBUG_SD_INSTALL) 17867 Log.i(TAG, "Loading container : " + args.cid); 17868 int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 17869 try { 17870 // Make sure there are no container errors first. 17871 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) { 17872 Slog.e(TAG, "Failed to mount cid : " + args.cid 17873 + " when installing from sdcard"); 17874 continue; 17875 } 17876 // Check code path here. 17877 if (codePath == null || !codePath.startsWith(args.getCodePath())) { 17878 Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath() 17879 + " does not match one in settings " + codePath); 17880 continue; 17881 } 17882 // Parse package 17883 int parseFlags = mDefParseFlags; 17884 if (args.isExternalAsec()) { 17885 parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE; 17886 } 17887 if (args.isFwdLocked()) { 17888 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 17889 } 17890 17891 synchronized (mInstallLock) { 17892 PackageParser.Package pkg = null; 17893 try { 17894 pkg = scanPackageTracedLI(new File(codePath), parseFlags, 0, 0, null); 17895 } catch (PackageManagerException e) { 17896 Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage()); 17897 } 17898 // Scan the package 17899 if (pkg != null) { 17900 /* 17901 * TODO why is the lock being held? doPostInstall is 17902 * called in other places without the lock. This needs 17903 * to be straightened out. 17904 */ 17905 // writer 17906 synchronized (mPackages) { 17907 retCode = PackageManager.INSTALL_SUCCEEDED; 17908 pkgList.add(pkg.packageName); 17909 // Post process args 17910 args.doPostInstall(PackageManager.INSTALL_SUCCEEDED, 17911 pkg.applicationInfo.uid); 17912 } 17913 } else { 17914 Slog.i(TAG, "Failed to install pkg from " + codePath + " from sdcard"); 17915 } 17916 } 17917 17918 } finally { 17919 if (retCode != PackageManager.INSTALL_SUCCEEDED) { 17920 Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode); 17921 } 17922 } 17923 } 17924 // writer 17925 synchronized (mPackages) { 17926 // If the platform SDK has changed since the last time we booted, 17927 // we need to re-grant app permission to catch any new ones that 17928 // appear. This is really a hack, and means that apps can in some 17929 // cases get permissions that the user didn't initially explicitly 17930 // allow... it would be nice to have some better way to handle 17931 // this situation. 17932 final VersionInfo ver = externalStorage ? mSettings.getExternalVersion() 17933 : mSettings.getInternalVersion(); 17934 final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL 17935 : StorageManager.UUID_PRIVATE_INTERNAL; 17936 17937 int updateFlags = UPDATE_PERMISSIONS_ALL; 17938 if (ver.sdkVersion != mSdkVersion) { 17939 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " 17940 + mSdkVersion + "; regranting permissions for external"); 17941 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 17942 } 17943 updatePermissionsLPw(null, null, volumeUuid, updateFlags); 17944 17945 // Yay, everything is now upgraded 17946 ver.forceCurrent(); 17947 17948 // can downgrade to reader 17949 // Persist settings 17950 mSettings.writeLPr(); 17951 } 17952 // Send a broadcast to let everyone know we are done processing 17953 if (pkgList.size() > 0) { 17954 sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null); 17955 } 17956 } 17957 17958 /* 17959 * Utility method to unload a list of specified containers 17960 */ 17961 private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) { 17962 // Just unmount all valid containers. 17963 for (AsecInstallArgs arg : cidArgs) { 17964 synchronized (mInstallLock) { 17965 arg.doPostDeleteLI(false); 17966 } 17967 } 17968 } 17969 17970 /* 17971 * Unload packages mounted on external media. This involves deleting package 17972 * data from internal structures, sending broadcasts about disabled packages, 17973 * gc'ing to free up references, unmounting all secure containers 17974 * corresponding to packages on external media, and posting a 17975 * UPDATED_MEDIA_STATUS message if status has been requested. Please note 17976 * that we always have to post this message if status has been requested no 17977 * matter what. 17978 */ 17979 private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[], 17980 final boolean reportStatus) { 17981 if (DEBUG_SD_INSTALL) 17982 Log.i(TAG, "unloading media packages"); 17983 ArrayList<String> pkgList = new ArrayList<String>(); 17984 ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>(); 17985 final Set<AsecInstallArgs> keys = processCids.keySet(); 17986 for (AsecInstallArgs args : keys) { 17987 String pkgName = args.getPackageName(); 17988 if (DEBUG_SD_INSTALL) 17989 Log.i(TAG, "Trying to unload pkg : " + pkgName); 17990 // Delete package internally 17991 PackageRemovedInfo outInfo = new PackageRemovedInfo(); 17992 synchronized (mInstallLock) { 17993 boolean res = deletePackageLI(pkgName, null, false, null, 17994 PackageManager.DELETE_KEEP_DATA, outInfo, false, null); 17995 if (res) { 17996 pkgList.add(pkgName); 17997 } else { 17998 Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName); 17999 failedList.add(args); 18000 } 18001 } 18002 } 18003 18004 // reader 18005 synchronized (mPackages) { 18006 // We didn't update the settings after removing each package; 18007 // write them now for all packages. 18008 mSettings.writeLPr(); 18009 } 18010 18011 // We have to absolutely send UPDATED_MEDIA_STATUS only 18012 // after confirming that all the receivers processed the ordered 18013 // broadcast when packages get disabled, force a gc to clean things up. 18014 // and unload all the containers. 18015 if (pkgList.size() > 0) { 18016 sendResourcesChangedBroadcast(false, false, pkgList, uidArr, 18017 new IIntentReceiver.Stub() { 18018 public void performReceive(Intent intent, int resultCode, String data, 18019 Bundle extras, boolean ordered, boolean sticky, 18020 int sendingUser) throws RemoteException { 18021 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, 18022 reportStatus ? 1 : 0, 1, keys); 18023 mHandler.sendMessage(msg); 18024 } 18025 }); 18026 } else { 18027 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1, 18028 keys); 18029 mHandler.sendMessage(msg); 18030 } 18031 } 18032 18033 private void loadPrivatePackages(final VolumeInfo vol) { 18034 mHandler.post(new Runnable() { 18035 @Override 18036 public void run() { 18037 loadPrivatePackagesInner(vol); 18038 } 18039 }); 18040 } 18041 18042 private void loadPrivatePackagesInner(VolumeInfo vol) { 18043 final String volumeUuid = vol.fsUuid; 18044 if (TextUtils.isEmpty(volumeUuid)) { 18045 Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring"); 18046 return; 18047 } 18048 18049 final ArrayList<ApplicationInfo> loaded = new ArrayList<>(); 18050 final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE; 18051 18052 final VersionInfo ver; 18053 final List<PackageSetting> packages; 18054 synchronized (mPackages) { 18055 ver = mSettings.findOrCreateVersion(volumeUuid); 18056 packages = mSettings.getVolumePackagesLPr(volumeUuid); 18057 } 18058 18059 // TODO: introduce a new concept similar to "frozen" to prevent these 18060 // apps from being launched until after data has been fully reconciled 18061 for (PackageSetting ps : packages) { 18062 synchronized (mInstallLock) { 18063 final PackageParser.Package pkg; 18064 try { 18065 pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null); 18066 loaded.add(pkg.applicationInfo); 18067 18068 } catch (PackageManagerException e) { 18069 Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage()); 18070 } 18071 18072 if (!Build.FINGERPRINT.equals(ver.fingerprint)) { 18073 deleteCodeCacheDirsLI(ps.volumeUuid, ps.name); 18074 } 18075 } 18076 } 18077 18078 // Reconcile app data for all started/unlocked users 18079 final StorageManager sm = mContext.getSystemService(StorageManager.class); 18080 final UserManager um = mContext.getSystemService(UserManager.class); 18081 for (UserInfo user : um.getUsers()) { 18082 final int flags; 18083 if (um.isUserUnlocked(user.id)) { 18084 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 18085 } else if (um.isUserRunning(user.id)) { 18086 flags = StorageManager.FLAG_STORAGE_DE; 18087 } else { 18088 continue; 18089 } 18090 18091 sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags); 18092 reconcileAppsData(volumeUuid, user.id, flags); 18093 } 18094 18095 synchronized (mPackages) { 18096 int updateFlags = UPDATE_PERMISSIONS_ALL; 18097 if (ver.sdkVersion != mSdkVersion) { 18098 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " 18099 + mSdkVersion + "; regranting permissions for " + volumeUuid); 18100 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 18101 } 18102 updatePermissionsLPw(null, null, volumeUuid, updateFlags); 18103 18104 // Yay, everything is now upgraded 18105 ver.forceCurrent(); 18106 18107 mSettings.writeLPr(); 18108 } 18109 18110 if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded); 18111 sendResourcesChangedBroadcast(true, false, loaded, null); 18112 } 18113 18114 private void unloadPrivatePackages(final VolumeInfo vol) { 18115 mHandler.post(new Runnable() { 18116 @Override 18117 public void run() { 18118 unloadPrivatePackagesInner(vol); 18119 } 18120 }); 18121 } 18122 18123 private void unloadPrivatePackagesInner(VolumeInfo vol) { 18124 final String volumeUuid = vol.fsUuid; 18125 if (TextUtils.isEmpty(volumeUuid)) { 18126 Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring"); 18127 return; 18128 } 18129 18130 final ArrayList<ApplicationInfo> unloaded = new ArrayList<>(); 18131 synchronized (mInstallLock) { 18132 synchronized (mPackages) { 18133 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid); 18134 for (PackageSetting ps : packages) { 18135 if (ps.pkg == null) continue; 18136 18137 final ApplicationInfo info = ps.pkg.applicationInfo; 18138 final PackageRemovedInfo outInfo = new PackageRemovedInfo(); 18139 if (deletePackageLI(ps.name, null, false, null, 18140 PackageManager.DELETE_KEEP_DATA, outInfo, false, null)) { 18141 unloaded.add(info); 18142 } else { 18143 Slog.w(TAG, "Failed to unload " + ps.codePath); 18144 } 18145 } 18146 18147 mSettings.writeLPr(); 18148 } 18149 } 18150 18151 if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded); 18152 sendResourcesChangedBroadcast(false, false, unloaded, null); 18153 } 18154 18155 /** 18156 * Examine all users present on given mounted volume, and destroy data 18157 * belonging to users that are no longer valid, or whose user ID has been 18158 * recycled. 18159 */ 18160 private void reconcileUsers(String volumeUuid) { 18161 // TODO: also reconcile DE directories 18162 final File[] files = FileUtils 18163 .listFilesOrEmpty(Environment.getDataUserCeDirectory(volumeUuid)); 18164 for (File file : files) { 18165 if (!file.isDirectory()) continue; 18166 18167 final int userId; 18168 final UserInfo info; 18169 try { 18170 userId = Integer.parseInt(file.getName()); 18171 info = sUserManager.getUserInfo(userId); 18172 } catch (NumberFormatException e) { 18173 Slog.w(TAG, "Invalid user directory " + file); 18174 continue; 18175 } 18176 18177 boolean destroyUser = false; 18178 if (info == null) { 18179 logCriticalInfo(Log.WARN, "Destroying user directory " + file 18180 + " because no matching user was found"); 18181 destroyUser = true; 18182 } else { 18183 try { 18184 UserManagerService.enforceSerialNumber(file, info.serialNumber); 18185 } catch (IOException e) { 18186 logCriticalInfo(Log.WARN, "Destroying user directory " + file 18187 + " because we failed to enforce serial number: " + e); 18188 destroyUser = true; 18189 } 18190 } 18191 18192 if (destroyUser) { 18193 synchronized (mInstallLock) { 18194 try { 18195 mInstaller.removeUserDataDirs(volumeUuid, userId); 18196 } catch (InstallerException e) { 18197 Slog.w(TAG, "Failed to clean up user dirs", e); 18198 } 18199 } 18200 } 18201 } 18202 } 18203 18204 private void assertPackageKnown(String volumeUuid, String packageName) 18205 throws PackageManagerException { 18206 synchronized (mPackages) { 18207 final PackageSetting ps = mSettings.mPackages.get(packageName); 18208 if (ps == null) { 18209 throw new PackageManagerException("Package " + packageName + " is unknown"); 18210 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) { 18211 throw new PackageManagerException( 18212 "Package " + packageName + " found on unknown volume " + volumeUuid 18213 + "; expected volume " + ps.volumeUuid); 18214 } 18215 } 18216 } 18217 18218 private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId) 18219 throws PackageManagerException { 18220 synchronized (mPackages) { 18221 final PackageSetting ps = mSettings.mPackages.get(packageName); 18222 if (ps == null) { 18223 throw new PackageManagerException("Package " + packageName + " is unknown"); 18224 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) { 18225 throw new PackageManagerException( 18226 "Package " + packageName + " found on unknown volume " + volumeUuid 18227 + "; expected volume " + ps.volumeUuid); 18228 } else if (!ps.getInstalled(userId)) { 18229 throw new PackageManagerException( 18230 "Package " + packageName + " not installed for user " + userId); 18231 } 18232 } 18233 } 18234 18235 /** 18236 * Examine all apps present on given mounted volume, and destroy apps that 18237 * aren't expected, either due to uninstallation or reinstallation on 18238 * another volume. 18239 */ 18240 private void reconcileApps(String volumeUuid) { 18241 final File[] files = FileUtils 18242 .listFilesOrEmpty(Environment.getDataAppDirectory(volumeUuid)); 18243 for (File file : files) { 18244 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 18245 && !PackageInstallerService.isStageName(file.getName()); 18246 if (!isPackage) { 18247 // Ignore entries which are not packages 18248 continue; 18249 } 18250 18251 try { 18252 final PackageLite pkg = PackageParser.parsePackageLite(file, 18253 PackageParser.PARSE_MUST_BE_APK); 18254 assertPackageKnown(volumeUuid, pkg.packageName); 18255 18256 } catch (PackageParserException | PackageManagerException e) { 18257 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 18258 synchronized (mInstallLock) { 18259 removeCodePathLI(file); 18260 } 18261 } 18262 } 18263 } 18264 18265 /** 18266 * Reconcile all app data for the given user. 18267 * <p> 18268 * Verifies that directories exist and that ownership and labeling is 18269 * correct for all installed apps on all mounted volumes. 18270 */ 18271 void reconcileAppsData(int userId, int flags) { 18272 final StorageManager storage = mContext.getSystemService(StorageManager.class); 18273 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 18274 final String volumeUuid = vol.getFsUuid(); 18275 reconcileAppsData(volumeUuid, userId, flags); 18276 } 18277 } 18278 18279 /** 18280 * Reconcile all app data on given mounted volume. 18281 * <p> 18282 * Destroys app data that isn't expected, either due to uninstallation or 18283 * reinstallation on another volume. 18284 * <p> 18285 * Verifies that directories exist and that ownership and labeling is 18286 * correct for all installed apps. 18287 */ 18288 private void reconcileAppsData(String volumeUuid, int userId, int flags) { 18289 Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x" 18290 + Integer.toHexString(flags)); 18291 18292 final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId); 18293 final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId); 18294 18295 boolean restoreconNeeded = false; 18296 18297 // First look for stale data that doesn't belong, and check if things 18298 // have changed since we did our last restorecon 18299 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 18300 if (!isUserKeyUnlocked(userId)) { 18301 throw new RuntimeException( 18302 "Yikes, someone asked us to reconcile CE storage while " + userId 18303 + " was still locked; this would have caused massive data loss!"); 18304 } 18305 18306 restoreconNeeded |= SELinuxMMAC.isRestoreconNeeded(ceDir); 18307 18308 final File[] files = FileUtils.listFilesOrEmpty(ceDir); 18309 for (File file : files) { 18310 final String packageName = file.getName(); 18311 try { 18312 assertPackageKnownAndInstalled(volumeUuid, packageName, userId); 18313 } catch (PackageManagerException e) { 18314 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 18315 synchronized (mInstallLock) { 18316 destroyAppDataLI(volumeUuid, packageName, userId, 18317 StorageManager.FLAG_STORAGE_CE); 18318 } 18319 } 18320 } 18321 } 18322 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) { 18323 restoreconNeeded |= SELinuxMMAC.isRestoreconNeeded(deDir); 18324 18325 final File[] files = FileUtils.listFilesOrEmpty(deDir); 18326 for (File file : files) { 18327 final String packageName = file.getName(); 18328 try { 18329 assertPackageKnownAndInstalled(volumeUuid, packageName, userId); 18330 } catch (PackageManagerException e) { 18331 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 18332 synchronized (mInstallLock) { 18333 destroyAppDataLI(volumeUuid, packageName, userId, 18334 StorageManager.FLAG_STORAGE_DE); 18335 } 18336 } 18337 } 18338 } 18339 18340 // Ensure that data directories are ready to roll for all packages 18341 // installed for this volume and user 18342 final List<PackageSetting> packages; 18343 synchronized (mPackages) { 18344 packages = mSettings.getVolumePackagesLPr(volumeUuid); 18345 } 18346 int preparedCount = 0; 18347 for (PackageSetting ps : packages) { 18348 final String packageName = ps.name; 18349 if (ps.pkg == null) { 18350 Slog.w(TAG, "Odd, missing scanned package " + packageName); 18351 // TODO: might be due to legacy ASEC apps; we should circle back 18352 // and reconcile again once they're scanned 18353 continue; 18354 } 18355 18356 if (ps.getInstalled(userId)) { 18357 prepareAppData(volumeUuid, userId, flags, ps.pkg, restoreconNeeded); 18358 18359 if (maybeMigrateAppData(volumeUuid, userId, ps.pkg)) { 18360 // We may have just shuffled around app data directories, so 18361 // prepare them one more time 18362 prepareAppData(volumeUuid, userId, flags, ps.pkg, restoreconNeeded); 18363 } 18364 18365 preparedCount++; 18366 } 18367 } 18368 18369 if (restoreconNeeded) { 18370 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 18371 SELinuxMMAC.setRestoreconDone(ceDir); 18372 } 18373 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) { 18374 SELinuxMMAC.setRestoreconDone(deDir); 18375 } 18376 } 18377 18378 Slog.v(TAG, "reconcileAppsData finished " + preparedCount 18379 + " packages; restoreconNeeded was " + restoreconNeeded); 18380 } 18381 18382 /** 18383 * Prepare app data for the given app just after it was installed or 18384 * upgraded. This method carefully only touches users that it's installed 18385 * for, and it forces a restorecon to handle any seinfo changes. 18386 * <p> 18387 * Verifies that directories exist and that ownership and labeling is 18388 * correct for all installed apps. If there is an ownership mismatch, it 18389 * will try recovering system apps by wiping data; third-party app data is 18390 * left intact. 18391 * <p> 18392 * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em> 18393 */ 18394 private void prepareAppDataAfterInstall(PackageParser.Package pkg) { 18395 prepareAppDataAfterInstallInternal(pkg); 18396 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 18397 for (int i = 0; i < childCount; i++) { 18398 PackageParser.Package childPackage = pkg.childPackages.get(i); 18399 prepareAppDataAfterInstallInternal(childPackage); 18400 } 18401 } 18402 18403 private void prepareAppDataAfterInstallInternal(PackageParser.Package pkg) { 18404 final PackageSetting ps; 18405 synchronized (mPackages) { 18406 ps = mSettings.mPackages.get(pkg.packageName); 18407 mSettings.writeKernelMappingLPr(ps); 18408 } 18409 18410 final UserManager um = mContext.getSystemService(UserManager.class); 18411 for (UserInfo user : um.getUsers()) { 18412 final int flags; 18413 if (um.isUserUnlocked(user.id)) { 18414 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 18415 } else if (um.isUserRunning(user.id)) { 18416 flags = StorageManager.FLAG_STORAGE_DE; 18417 } else { 18418 continue; 18419 } 18420 18421 if (ps.getInstalled(user.id)) { 18422 // Whenever an app changes, force a restorecon of its data 18423 // TODO: when user data is locked, mark that we're still dirty 18424 prepareAppData(pkg.volumeUuid, user.id, flags, pkg, true); 18425 } 18426 } 18427 } 18428 18429 /** 18430 * Prepare app data for the given app. 18431 * <p> 18432 * Verifies that directories exist and that ownership and labeling is 18433 * correct for all installed apps. If there is an ownership mismatch, this 18434 * will try recovering system apps by wiping data; third-party app data is 18435 * left intact. 18436 */ 18437 private void prepareAppData(String volumeUuid, int userId, int flags, 18438 PackageParser.Package pkg, boolean restoreconNeeded) { 18439 if (DEBUG_APP_DATA) { 18440 Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x" 18441 + Integer.toHexString(flags) + (restoreconNeeded ? " restoreconNeeded" : "")); 18442 } 18443 18444 final String packageName = pkg.packageName; 18445 final ApplicationInfo app = pkg.applicationInfo; 18446 final int appId = UserHandle.getAppId(app.uid); 18447 18448 Preconditions.checkNotNull(app.seinfo); 18449 18450 synchronized (mInstallLock) { 18451 try { 18452 mInstaller.createAppData(volumeUuid, packageName, userId, flags, 18453 appId, app.seinfo, app.targetSdkVersion); 18454 } catch (InstallerException e) { 18455 if (app.isSystemApp()) { 18456 logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName 18457 + ", but trying to recover: " + e); 18458 destroyAppDataLI(volumeUuid, packageName, userId, flags); 18459 try { 18460 mInstaller.createAppData(volumeUuid, packageName, userId, flags, 18461 appId, app.seinfo, app.targetSdkVersion); 18462 logCriticalInfo(Log.DEBUG, "Recovery succeeded!"); 18463 } catch (InstallerException e2) { 18464 logCriticalInfo(Log.DEBUG, "Recovery failed!"); 18465 } 18466 } else { 18467 Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e); 18468 } 18469 } 18470 18471 if (restoreconNeeded) { 18472 restoreconAppDataLI(volumeUuid, packageName, userId, flags, appId, app.seinfo); 18473 } 18474 18475 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 18476 // Create a native library symlink only if we have native libraries 18477 // and if the native libraries are 32 bit libraries. We do not provide 18478 // this symlink for 64 bit libraries. 18479 if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) { 18480 final String nativeLibPath = app.nativeLibraryDir; 18481 try { 18482 mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName, 18483 nativeLibPath, userId); 18484 } catch (InstallerException e) { 18485 Slog.e(TAG, "Failed to link native for " + packageName + ": " + e); 18486 } 18487 } 18488 } 18489 } 18490 } 18491 18492 /** 18493 * For system apps on non-FBE devices, this method migrates any existing 18494 * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag 18495 * requested by the app. 18496 */ 18497 private boolean maybeMigrateAppData(String volumeUuid, int userId, PackageParser.Package pkg) { 18498 if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated() 18499 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) { 18500 final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage() 18501 ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE; 18502 synchronized (mInstallLock) { 18503 try { 18504 mInstaller.migrateAppData(volumeUuid, pkg.packageName, userId, storageTarget); 18505 } catch (InstallerException e) { 18506 logCriticalInfo(Log.WARN, 18507 "Failed to migrate " + pkg.packageName + ": " + e.getMessage()); 18508 } 18509 } 18510 return true; 18511 } else { 18512 return false; 18513 } 18514 } 18515 18516 private void unfreezePackage(String packageName) { 18517 synchronized (mPackages) { 18518 final PackageSetting ps = mSettings.mPackages.get(packageName); 18519 if (ps != null) { 18520 ps.frozen = false; 18521 } 18522 } 18523 } 18524 18525 @Override 18526 public int movePackage(final String packageName, final String volumeUuid) { 18527 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 18528 18529 final int moveId = mNextMoveId.getAndIncrement(); 18530 mHandler.post(new Runnable() { 18531 @Override 18532 public void run() { 18533 try { 18534 movePackageInternal(packageName, volumeUuid, moveId); 18535 } catch (PackageManagerException e) { 18536 Slog.w(TAG, "Failed to move " + packageName, e); 18537 mMoveCallbacks.notifyStatusChanged(moveId, 18538 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 18539 } 18540 } 18541 }); 18542 return moveId; 18543 } 18544 18545 private void movePackageInternal(final String packageName, final String volumeUuid, 18546 final int moveId) throws PackageManagerException { 18547 final UserHandle user = new UserHandle(UserHandle.getCallingUserId()); 18548 final StorageManager storage = mContext.getSystemService(StorageManager.class); 18549 final PackageManager pm = mContext.getPackageManager(); 18550 18551 final boolean currentAsec; 18552 final String currentVolumeUuid; 18553 final File codeFile; 18554 final String installerPackageName; 18555 final String packageAbiOverride; 18556 final int appId; 18557 final String seinfo; 18558 final String label; 18559 final int targetSdkVersion; 18560 18561 // reader 18562 synchronized (mPackages) { 18563 final PackageParser.Package pkg = mPackages.get(packageName); 18564 final PackageSetting ps = mSettings.mPackages.get(packageName); 18565 if (pkg == null || ps == null) { 18566 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package"); 18567 } 18568 18569 if (pkg.applicationInfo.isSystemApp()) { 18570 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE, 18571 "Cannot move system application"); 18572 } 18573 18574 if (pkg.applicationInfo.isExternalAsec()) { 18575 currentAsec = true; 18576 currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL; 18577 } else if (pkg.applicationInfo.isForwardLocked()) { 18578 currentAsec = true; 18579 currentVolumeUuid = "forward_locked"; 18580 } else { 18581 currentAsec = false; 18582 currentVolumeUuid = ps.volumeUuid; 18583 18584 final File probe = new File(pkg.codePath); 18585 final File probeOat = new File(probe, "oat"); 18586 if (!probe.isDirectory() || !probeOat.isDirectory()) { 18587 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 18588 "Move only supported for modern cluster style installs"); 18589 } 18590 } 18591 18592 if (Objects.equals(currentVolumeUuid, volumeUuid)) { 18593 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 18594 "Package already moved to " + volumeUuid); 18595 } 18596 if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) { 18597 throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN, 18598 "Device admin cannot be moved"); 18599 } 18600 18601 if (ps.frozen) { 18602 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING, 18603 "Failed to move already frozen package"); 18604 } 18605 ps.frozen = true; 18606 18607 codeFile = new File(pkg.codePath); 18608 installerPackageName = ps.installerPackageName; 18609 packageAbiOverride = ps.cpuAbiOverrideString; 18610 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 18611 seinfo = pkg.applicationInfo.seinfo; 18612 label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo)); 18613 targetSdkVersion = pkg.applicationInfo.targetSdkVersion; 18614 } 18615 18616 // Now that we're guarded by frozen state, kill app during move 18617 final long token = Binder.clearCallingIdentity(); 18618 try { 18619 killApplication(packageName, appId, "move pkg"); 18620 } finally { 18621 Binder.restoreCallingIdentity(token); 18622 } 18623 18624 final Bundle extras = new Bundle(); 18625 extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName); 18626 extras.putString(Intent.EXTRA_TITLE, label); 18627 mMoveCallbacks.notifyCreated(moveId, extras); 18628 18629 int installFlags; 18630 final boolean moveCompleteApp; 18631 final File measurePath; 18632 18633 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) { 18634 installFlags = INSTALL_INTERNAL; 18635 moveCompleteApp = !currentAsec; 18636 measurePath = Environment.getDataAppDirectory(volumeUuid); 18637 } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) { 18638 installFlags = INSTALL_EXTERNAL; 18639 moveCompleteApp = false; 18640 measurePath = storage.getPrimaryPhysicalVolume().getPath(); 18641 } else { 18642 final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid); 18643 if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE 18644 || !volume.isMountedWritable()) { 18645 unfreezePackage(packageName); 18646 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 18647 "Move location not mounted private volume"); 18648 } 18649 18650 Preconditions.checkState(!currentAsec); 18651 18652 installFlags = INSTALL_INTERNAL; 18653 moveCompleteApp = true; 18654 measurePath = Environment.getDataAppDirectory(volumeUuid); 18655 } 18656 18657 final PackageStats stats = new PackageStats(null, -1); 18658 synchronized (mInstaller) { 18659 if (!getPackageSizeInfoLI(packageName, -1, stats)) { 18660 unfreezePackage(packageName); 18661 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 18662 "Failed to measure package size"); 18663 } 18664 } 18665 18666 if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size " 18667 + stats.dataSize); 18668 18669 final long startFreeBytes = measurePath.getFreeSpace(); 18670 final long sizeBytes; 18671 if (moveCompleteApp) { 18672 sizeBytes = stats.codeSize + stats.dataSize; 18673 } else { 18674 sizeBytes = stats.codeSize; 18675 } 18676 18677 if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) { 18678 unfreezePackage(packageName); 18679 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 18680 "Not enough free space to move"); 18681 } 18682 18683 mMoveCallbacks.notifyStatusChanged(moveId, 10); 18684 18685 final CountDownLatch installedLatch = new CountDownLatch(1); 18686 final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() { 18687 @Override 18688 public void onUserActionRequired(Intent intent) throws RemoteException { 18689 throw new IllegalStateException(); 18690 } 18691 18692 @Override 18693 public void onPackageInstalled(String basePackageName, int returnCode, String msg, 18694 Bundle extras) throws RemoteException { 18695 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: " 18696 + PackageManager.installStatusToString(returnCode, msg)); 18697 18698 installedLatch.countDown(); 18699 18700 // Regardless of success or failure of the move operation, 18701 // always unfreeze the package 18702 unfreezePackage(packageName); 18703 18704 final int status = PackageManager.installStatusToPublicStatus(returnCode); 18705 switch (status) { 18706 case PackageInstaller.STATUS_SUCCESS: 18707 mMoveCallbacks.notifyStatusChanged(moveId, 18708 PackageManager.MOVE_SUCCEEDED); 18709 break; 18710 case PackageInstaller.STATUS_FAILURE_STORAGE: 18711 mMoveCallbacks.notifyStatusChanged(moveId, 18712 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE); 18713 break; 18714 default: 18715 mMoveCallbacks.notifyStatusChanged(moveId, 18716 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 18717 break; 18718 } 18719 } 18720 }; 18721 18722 final MoveInfo move; 18723 if (moveCompleteApp) { 18724 // Kick off a thread to report progress estimates 18725 new Thread() { 18726 @Override 18727 public void run() { 18728 while (true) { 18729 try { 18730 if (installedLatch.await(1, TimeUnit.SECONDS)) { 18731 break; 18732 } 18733 } catch (InterruptedException ignored) { 18734 } 18735 18736 final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace(); 18737 final int progress = 10 + (int) MathUtils.constrain( 18738 ((deltaFreeBytes * 80) / sizeBytes), 0, 80); 18739 mMoveCallbacks.notifyStatusChanged(moveId, progress); 18740 } 18741 } 18742 }.start(); 18743 18744 final String dataAppName = codeFile.getName(); 18745 move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName, 18746 dataAppName, appId, seinfo, targetSdkVersion); 18747 } else { 18748 move = null; 18749 } 18750 18751 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 18752 18753 final Message msg = mHandler.obtainMessage(INIT_COPY); 18754 final OriginInfo origin = OriginInfo.fromExistingFile(codeFile); 18755 final InstallParams params = new InstallParams(origin, move, installObserver, installFlags, 18756 installerPackageName, volumeUuid, null /*verificationInfo*/, user, 18757 packageAbiOverride, null); 18758 params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params)); 18759 msg.obj = params; 18760 18761 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage", 18762 System.identityHashCode(msg.obj)); 18763 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 18764 System.identityHashCode(msg.obj)); 18765 18766 mHandler.sendMessage(msg); 18767 } 18768 18769 @Override 18770 public int movePrimaryStorage(String volumeUuid) throws RemoteException { 18771 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 18772 18773 final int realMoveId = mNextMoveId.getAndIncrement(); 18774 final Bundle extras = new Bundle(); 18775 extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid); 18776 mMoveCallbacks.notifyCreated(realMoveId, extras); 18777 18778 final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() { 18779 @Override 18780 public void onCreated(int moveId, Bundle extras) { 18781 // Ignored 18782 } 18783 18784 @Override 18785 public void onStatusChanged(int moveId, int status, long estMillis) { 18786 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis); 18787 } 18788 }; 18789 18790 final StorageManager storage = mContext.getSystemService(StorageManager.class); 18791 storage.setPrimaryStorageUuid(volumeUuid, callback); 18792 return realMoveId; 18793 } 18794 18795 @Override 18796 public int getMoveStatus(int moveId) { 18797 mContext.enforceCallingOrSelfPermission( 18798 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 18799 return mMoveCallbacks.mLastStatus.get(moveId); 18800 } 18801 18802 @Override 18803 public void registerMoveCallback(IPackageMoveObserver callback) { 18804 mContext.enforceCallingOrSelfPermission( 18805 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 18806 mMoveCallbacks.register(callback); 18807 } 18808 18809 @Override 18810 public void unregisterMoveCallback(IPackageMoveObserver callback) { 18811 mContext.enforceCallingOrSelfPermission( 18812 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 18813 mMoveCallbacks.unregister(callback); 18814 } 18815 18816 @Override 18817 public boolean setInstallLocation(int loc) { 18818 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, 18819 null); 18820 if (getInstallLocation() == loc) { 18821 return true; 18822 } 18823 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL 18824 || loc == PackageHelper.APP_INSTALL_EXTERNAL) { 18825 android.provider.Settings.Global.putInt(mContext.getContentResolver(), 18826 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc); 18827 return true; 18828 } 18829 return false; 18830 } 18831 18832 @Override 18833 public int getInstallLocation() { 18834 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 18835 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, 18836 PackageHelper.APP_INSTALL_AUTO); 18837 } 18838 18839 /** Called by UserManagerService */ 18840 void cleanUpUser(UserManagerService userManager, int userHandle) { 18841 synchronized (mPackages) { 18842 mDirtyUsers.remove(userHandle); 18843 mUserNeedsBadging.delete(userHandle); 18844 mSettings.removeUserLPw(userHandle); 18845 mPendingBroadcasts.remove(userHandle); 18846 mEphemeralApplicationRegistry.onUserRemovedLPw(userHandle); 18847 } 18848 synchronized (mInstallLock) { 18849 final StorageManager storage = mContext.getSystemService(StorageManager.class); 18850 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 18851 final String volumeUuid = vol.getFsUuid(); 18852 if (DEBUG_INSTALL) Slog.d(TAG, "Removing user data on volume " + volumeUuid); 18853 try { 18854 mInstaller.removeUserDataDirs(volumeUuid, userHandle); 18855 } catch (InstallerException e) { 18856 Slog.w(TAG, "Failed to remove user data", e); 18857 } 18858 } 18859 synchronized (mPackages) { 18860 removeUnusedPackagesLILPw(userManager, userHandle); 18861 } 18862 } 18863 } 18864 18865 /** 18866 * We're removing userHandle and would like to remove any downloaded packages 18867 * that are no longer in use by any other user. 18868 * @param userHandle the user being removed 18869 */ 18870 private void removeUnusedPackagesLILPw(UserManagerService userManager, final int userHandle) { 18871 final boolean DEBUG_CLEAN_APKS = false; 18872 int [] users = userManager.getUserIds(); 18873 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 18874 while (psit.hasNext()) { 18875 PackageSetting ps = psit.next(); 18876 if (ps.pkg == null) { 18877 continue; 18878 } 18879 final String packageName = ps.pkg.packageName; 18880 // Skip over if system app 18881 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) { 18882 continue; 18883 } 18884 if (DEBUG_CLEAN_APKS) { 18885 Slog.i(TAG, "Checking package " + packageName); 18886 } 18887 boolean keep = shouldKeepUninstalledPackageLPr(packageName); 18888 if (keep) { 18889 if (DEBUG_CLEAN_APKS) { 18890 Slog.i(TAG, " Keeping package " + packageName + " - requested by DO"); 18891 } 18892 } else { 18893 for (int i = 0; i < users.length; i++) { 18894 if (users[i] != userHandle && ps.getInstalled(users[i])) { 18895 keep = true; 18896 if (DEBUG_CLEAN_APKS) { 18897 Slog.i(TAG, " Keeping package " + packageName + " for user " 18898 + users[i]); 18899 } 18900 break; 18901 } 18902 } 18903 } 18904 if (!keep) { 18905 if (DEBUG_CLEAN_APKS) { 18906 Slog.i(TAG, " Removing package " + packageName); 18907 } 18908 mHandler.post(new Runnable() { 18909 public void run() { 18910 deletePackageX(packageName, userHandle, 0); 18911 } //end run 18912 }); 18913 } 18914 } 18915 } 18916 18917 /** Called by UserManagerService */ 18918 void createNewUser(int userHandle) { 18919 synchronized (mInstallLock) { 18920 try { 18921 mInstaller.createUserConfig(userHandle); 18922 } catch (InstallerException e) { 18923 Slog.w(TAG, "Failed to create user config", e); 18924 } 18925 mSettings.createNewUserLI(this, mInstaller, userHandle); 18926 } 18927 synchronized (mPackages) { 18928 applyFactoryDefaultBrowserLPw(userHandle); 18929 primeDomainVerificationsLPw(userHandle); 18930 } 18931 } 18932 18933 void newUserCreated(final int userHandle) { 18934 mDefaultPermissionPolicy.grantDefaultPermissions(userHandle); 18935 // If permission review for legacy apps is required, we represent 18936 // dagerous permissions for such apps as always granted runtime 18937 // permissions to keep per user flag state whether review is needed. 18938 // Hence, if a new user is added we have to propagate dangerous 18939 // permission grants for these legacy apps. 18940 if (Build.PERMISSIONS_REVIEW_REQUIRED) { 18941 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL 18942 | UPDATE_PERMISSIONS_REPLACE_ALL); 18943 } 18944 } 18945 18946 @Override 18947 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException { 18948 mContext.enforceCallingOrSelfPermission( 18949 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 18950 "Only package verification agents can read the verifier device identity"); 18951 18952 synchronized (mPackages) { 18953 return mSettings.getVerifierDeviceIdentityLPw(); 18954 } 18955 } 18956 18957 @Override 18958 public void setPermissionEnforced(String permission, boolean enforced) { 18959 // TODO: Now that we no longer change GID for storage, this should to away. 18960 mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 18961 "setPermissionEnforced"); 18962 if (READ_EXTERNAL_STORAGE.equals(permission)) { 18963 synchronized (mPackages) { 18964 if (mSettings.mReadExternalStorageEnforced == null 18965 || mSettings.mReadExternalStorageEnforced != enforced) { 18966 mSettings.mReadExternalStorageEnforced = enforced; 18967 mSettings.writeLPr(); 18968 } 18969 } 18970 // kill any non-foreground processes so we restart them and 18971 // grant/revoke the GID. 18972 final IActivityManager am = ActivityManagerNative.getDefault(); 18973 if (am != null) { 18974 final long token = Binder.clearCallingIdentity(); 18975 try { 18976 am.killProcessesBelowForeground("setPermissionEnforcement"); 18977 } catch (RemoteException e) { 18978 } finally { 18979 Binder.restoreCallingIdentity(token); 18980 } 18981 } 18982 } else { 18983 throw new IllegalArgumentException("No selective enforcement for " + permission); 18984 } 18985 } 18986 18987 @Override 18988 @Deprecated 18989 public boolean isPermissionEnforced(String permission) { 18990 return true; 18991 } 18992 18993 @Override 18994 public boolean isStorageLow() { 18995 final long token = Binder.clearCallingIdentity(); 18996 try { 18997 final DeviceStorageMonitorInternal 18998 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 18999 if (dsm != null) { 19000 return dsm.isMemoryLow(); 19001 } else { 19002 return false; 19003 } 19004 } finally { 19005 Binder.restoreCallingIdentity(token); 19006 } 19007 } 19008 19009 @Override 19010 public IPackageInstaller getPackageInstaller() { 19011 return mInstallerService; 19012 } 19013 19014 private boolean userNeedsBadging(int userId) { 19015 int index = mUserNeedsBadging.indexOfKey(userId); 19016 if (index < 0) { 19017 final UserInfo userInfo; 19018 final long token = Binder.clearCallingIdentity(); 19019 try { 19020 userInfo = sUserManager.getUserInfo(userId); 19021 } finally { 19022 Binder.restoreCallingIdentity(token); 19023 } 19024 final boolean b; 19025 if (userInfo != null && userInfo.isManagedProfile()) { 19026 b = true; 19027 } else { 19028 b = false; 19029 } 19030 mUserNeedsBadging.put(userId, b); 19031 return b; 19032 } 19033 return mUserNeedsBadging.valueAt(index); 19034 } 19035 19036 @Override 19037 public KeySet getKeySetByAlias(String packageName, String alias) { 19038 if (packageName == null || alias == null) { 19039 return null; 19040 } 19041 synchronized(mPackages) { 19042 final PackageParser.Package pkg = mPackages.get(packageName); 19043 if (pkg == null) { 19044 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 19045 throw new IllegalArgumentException("Unknown package: " + packageName); 19046 } 19047 KeySetManagerService ksms = mSettings.mKeySetManagerService; 19048 return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias)); 19049 } 19050 } 19051 19052 @Override 19053 public KeySet getSigningKeySet(String packageName) { 19054 if (packageName == null) { 19055 return null; 19056 } 19057 synchronized(mPackages) { 19058 final PackageParser.Package pkg = mPackages.get(packageName); 19059 if (pkg == null) { 19060 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 19061 throw new IllegalArgumentException("Unknown package: " + packageName); 19062 } 19063 if (pkg.applicationInfo.uid != Binder.getCallingUid() 19064 && Process.SYSTEM_UID != Binder.getCallingUid()) { 19065 throw new SecurityException("May not access signing KeySet of other apps."); 19066 } 19067 KeySetManagerService ksms = mSettings.mKeySetManagerService; 19068 return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName)); 19069 } 19070 } 19071 19072 @Override 19073 public boolean isPackageSignedByKeySet(String packageName, KeySet ks) { 19074 if (packageName == null || ks == null) { 19075 return false; 19076 } 19077 synchronized(mPackages) { 19078 final PackageParser.Package pkg = mPackages.get(packageName); 19079 if (pkg == null) { 19080 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 19081 throw new IllegalArgumentException("Unknown package: " + packageName); 19082 } 19083 IBinder ksh = ks.getToken(); 19084 if (ksh instanceof KeySetHandle) { 19085 KeySetManagerService ksms = mSettings.mKeySetManagerService; 19086 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh); 19087 } 19088 return false; 19089 } 19090 } 19091 19092 @Override 19093 public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) { 19094 if (packageName == null || ks == null) { 19095 return false; 19096 } 19097 synchronized(mPackages) { 19098 final PackageParser.Package pkg = mPackages.get(packageName); 19099 if (pkg == null) { 19100 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 19101 throw new IllegalArgumentException("Unknown package: " + packageName); 19102 } 19103 IBinder ksh = ks.getToken(); 19104 if (ksh instanceof KeySetHandle) { 19105 KeySetManagerService ksms = mSettings.mKeySetManagerService; 19106 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh); 19107 } 19108 return false; 19109 } 19110 } 19111 19112 private void deletePackageIfUnusedLPr(final String packageName) { 19113 PackageSetting ps = mSettings.mPackages.get(packageName); 19114 if (ps == null) { 19115 return; 19116 } 19117 if (!ps.isAnyInstalled(sUserManager.getUserIds())) { 19118 // TODO Implement atomic delete if package is unused 19119 // It is currently possible that the package will be deleted even if it is installed 19120 // after this method returns. 19121 mHandler.post(new Runnable() { 19122 public void run() { 19123 deletePackageX(packageName, 0, PackageManager.DELETE_ALL_USERS); 19124 } 19125 }); 19126 } 19127 } 19128 19129 /** 19130 * Check and throw if the given before/after packages would be considered a 19131 * downgrade. 19132 */ 19133 private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after) 19134 throws PackageManagerException { 19135 if (after.versionCode < before.mVersionCode) { 19136 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 19137 "Update version code " + after.versionCode + " is older than current " 19138 + before.mVersionCode); 19139 } else if (after.versionCode == before.mVersionCode) { 19140 if (after.baseRevisionCode < before.baseRevisionCode) { 19141 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 19142 "Update base revision code " + after.baseRevisionCode 19143 + " is older than current " + before.baseRevisionCode); 19144 } 19145 19146 if (!ArrayUtils.isEmpty(after.splitNames)) { 19147 for (int i = 0; i < after.splitNames.length; i++) { 19148 final String splitName = after.splitNames[i]; 19149 final int j = ArrayUtils.indexOf(before.splitNames, splitName); 19150 if (j != -1) { 19151 if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) { 19152 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 19153 "Update split " + splitName + " revision code " 19154 + after.splitRevisionCodes[i] + " is older than current " 19155 + before.splitRevisionCodes[j]); 19156 } 19157 } 19158 } 19159 } 19160 } 19161 } 19162 19163 private static class MoveCallbacks extends Handler { 19164 private static final int MSG_CREATED = 1; 19165 private static final int MSG_STATUS_CHANGED = 2; 19166 19167 private final RemoteCallbackList<IPackageMoveObserver> 19168 mCallbacks = new RemoteCallbackList<>(); 19169 19170 private final SparseIntArray mLastStatus = new SparseIntArray(); 19171 19172 public MoveCallbacks(Looper looper) { 19173 super(looper); 19174 } 19175 19176 public void register(IPackageMoveObserver callback) { 19177 mCallbacks.register(callback); 19178 } 19179 19180 public void unregister(IPackageMoveObserver callback) { 19181 mCallbacks.unregister(callback); 19182 } 19183 19184 @Override 19185 public void handleMessage(Message msg) { 19186 final SomeArgs args = (SomeArgs) msg.obj; 19187 final int n = mCallbacks.beginBroadcast(); 19188 for (int i = 0; i < n; i++) { 19189 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i); 19190 try { 19191 invokeCallback(callback, msg.what, args); 19192 } catch (RemoteException ignored) { 19193 } 19194 } 19195 mCallbacks.finishBroadcast(); 19196 args.recycle(); 19197 } 19198 19199 private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args) 19200 throws RemoteException { 19201 switch (what) { 19202 case MSG_CREATED: { 19203 callback.onCreated(args.argi1, (Bundle) args.arg2); 19204 break; 19205 } 19206 case MSG_STATUS_CHANGED: { 19207 callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3); 19208 break; 19209 } 19210 } 19211 } 19212 19213 private void notifyCreated(int moveId, Bundle extras) { 19214 Slog.v(TAG, "Move " + moveId + " created " + extras.toString()); 19215 19216 final SomeArgs args = SomeArgs.obtain(); 19217 args.argi1 = moveId; 19218 args.arg2 = extras; 19219 obtainMessage(MSG_CREATED, args).sendToTarget(); 19220 } 19221 19222 private void notifyStatusChanged(int moveId, int status) { 19223 notifyStatusChanged(moveId, status, -1); 19224 } 19225 19226 private void notifyStatusChanged(int moveId, int status, long estMillis) { 19227 Slog.v(TAG, "Move " + moveId + " status " + status); 19228 19229 final SomeArgs args = SomeArgs.obtain(); 19230 args.argi1 = moveId; 19231 args.argi2 = status; 19232 args.arg3 = estMillis; 19233 obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget(); 19234 19235 synchronized (mLastStatus) { 19236 mLastStatus.put(moveId, status); 19237 } 19238 } 19239 } 19240 19241 private final static class OnPermissionChangeListeners extends Handler { 19242 private static final int MSG_ON_PERMISSIONS_CHANGED = 1; 19243 19244 private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners = 19245 new RemoteCallbackList<>(); 19246 19247 public OnPermissionChangeListeners(Looper looper) { 19248 super(looper); 19249 } 19250 19251 @Override 19252 public void handleMessage(Message msg) { 19253 switch (msg.what) { 19254 case MSG_ON_PERMISSIONS_CHANGED: { 19255 final int uid = msg.arg1; 19256 handleOnPermissionsChanged(uid); 19257 } break; 19258 } 19259 } 19260 19261 public void addListenerLocked(IOnPermissionsChangeListener listener) { 19262 mPermissionListeners.register(listener); 19263 19264 } 19265 19266 public void removeListenerLocked(IOnPermissionsChangeListener listener) { 19267 mPermissionListeners.unregister(listener); 19268 } 19269 19270 public void onPermissionsChanged(int uid) { 19271 if (mPermissionListeners.getRegisteredCallbackCount() > 0) { 19272 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget(); 19273 } 19274 } 19275 19276 private void handleOnPermissionsChanged(int uid) { 19277 final int count = mPermissionListeners.beginBroadcast(); 19278 try { 19279 for (int i = 0; i < count; i++) { 19280 IOnPermissionsChangeListener callback = mPermissionListeners 19281 .getBroadcastItem(i); 19282 try { 19283 callback.onPermissionsChanged(uid); 19284 } catch (RemoteException e) { 19285 Log.e(TAG, "Permission listener is dead", e); 19286 } 19287 } 19288 } finally { 19289 mPermissionListeners.finishBroadcast(); 19290 } 19291 } 19292 } 19293 19294 private class PackageManagerInternalImpl extends PackageManagerInternal { 19295 @Override 19296 public void setLocationPackagesProvider(PackagesProvider provider) { 19297 synchronized (mPackages) { 19298 mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider); 19299 } 19300 } 19301 19302 @Override 19303 public void setVoiceInteractionPackagesProvider(PackagesProvider provider) { 19304 synchronized (mPackages) { 19305 mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider); 19306 } 19307 } 19308 19309 @Override 19310 public void setSmsAppPackagesProvider(PackagesProvider provider) { 19311 synchronized (mPackages) { 19312 mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider); 19313 } 19314 } 19315 19316 @Override 19317 public void setDialerAppPackagesProvider(PackagesProvider provider) { 19318 synchronized (mPackages) { 19319 mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider); 19320 } 19321 } 19322 19323 @Override 19324 public void setSimCallManagerPackagesProvider(PackagesProvider provider) { 19325 synchronized (mPackages) { 19326 mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider); 19327 } 19328 } 19329 19330 @Override 19331 public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) { 19332 synchronized (mPackages) { 19333 mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider); 19334 } 19335 } 19336 19337 @Override 19338 public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) { 19339 synchronized (mPackages) { 19340 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr( 19341 packageName, userId); 19342 } 19343 } 19344 19345 @Override 19346 public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) { 19347 synchronized (mPackages) { 19348 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr( 19349 packageName, userId); 19350 } 19351 } 19352 19353 @Override 19354 public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) { 19355 synchronized (mPackages) { 19356 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr( 19357 packageName, userId); 19358 } 19359 } 19360 19361 @Override 19362 public void setKeepUninstalledPackages(final List<String> packageList) { 19363 Preconditions.checkNotNull(packageList); 19364 List<String> removedFromList = null; 19365 synchronized (mPackages) { 19366 if (mKeepUninstalledPackages != null) { 19367 final int packagesCount = mKeepUninstalledPackages.size(); 19368 for (int i = 0; i < packagesCount; i++) { 19369 String oldPackage = mKeepUninstalledPackages.get(i); 19370 if (packageList != null && packageList.contains(oldPackage)) { 19371 continue; 19372 } 19373 if (removedFromList == null) { 19374 removedFromList = new ArrayList<>(); 19375 } 19376 removedFromList.add(oldPackage); 19377 } 19378 } 19379 mKeepUninstalledPackages = new ArrayList<>(packageList); 19380 if (removedFromList != null) { 19381 final int removedCount = removedFromList.size(); 19382 for (int i = 0; i < removedCount; i++) { 19383 deletePackageIfUnusedLPr(removedFromList.get(i)); 19384 } 19385 } 19386 } 19387 } 19388 19389 @Override 19390 public boolean isPermissionsReviewRequired(String packageName, int userId) { 19391 synchronized (mPackages) { 19392 // If we do not support permission review, done. 19393 if (!Build.PERMISSIONS_REVIEW_REQUIRED) { 19394 return false; 19395 } 19396 19397 PackageSetting packageSetting = mSettings.mPackages.get(packageName); 19398 if (packageSetting == null) { 19399 return false; 19400 } 19401 19402 // Permission review applies only to apps not supporting the new permission model. 19403 if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) { 19404 return false; 19405 } 19406 19407 // Legacy apps have the permission and get user consent on launch. 19408 PermissionsState permissionsState = packageSetting.getPermissionsState(); 19409 return permissionsState.isPermissionReviewRequired(userId); 19410 } 19411 } 19412 19413 @Override 19414 public ApplicationInfo getApplicationInfo(String packageName, int userId) { 19415 return PackageManagerService.this.getApplicationInfo(packageName, 0 /*flags*/, userId); 19416 } 19417 19418 @Override 19419 public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, 19420 int userId) { 19421 return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId); 19422 } 19423 } 19424 19425 @Override 19426 public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) { 19427 enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps"); 19428 synchronized (mPackages) { 19429 final long identity = Binder.clearCallingIdentity(); 19430 try { 19431 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr( 19432 packageNames, userId); 19433 } finally { 19434 Binder.restoreCallingIdentity(identity); 19435 } 19436 } 19437 } 19438 19439 private static void enforceSystemOrPhoneCaller(String tag) { 19440 int callingUid = Binder.getCallingUid(); 19441 if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) { 19442 throw new SecurityException( 19443 "Cannot call " + tag + " from UID " + callingUid); 19444 } 19445 } 19446 19447 boolean isHistoricalPackageUsageAvailable() { 19448 return mPackageUsage.isHistoricalPackageUsageAvailable(); 19449 } 19450 19451 /** 19452 * Return a <b>copy</b> of the collection of packages known to the package manager. 19453 * @return A copy of the values of mPackages. 19454 */ 19455 Collection<PackageParser.Package> getPackages() { 19456 synchronized (mPackages) { 19457 return new ArrayList<>(mPackages.values()); 19458 } 19459 } 19460} 19461