PackageManagerService.java revision 2d71f41beab55fdc038f07ec109e4223fb162343
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 (mSafeMode && !ps.isSystem()) { 2910 throw new SecurityException("Package " + packageName + " not a system app!"); 2911 } 2912 2913 if (ps.frozen) { 2914 throw new SecurityException("Package " + packageName + " is currently frozen!"); 2915 } 2916 2917 if (!userKeyUnlocked && !(ps.pkg.applicationInfo.isDirectBootAware() 2918 || ps.pkg.applicationInfo.isPartiallyDirectBootAware())) { 2919 throw new SecurityException("Package " + packageName + " is not encryption aware!"); 2920 } 2921 } 2922 } 2923 2924 @Override 2925 public boolean isPackageAvailable(String packageName, int userId) { 2926 if (!sUserManager.exists(userId)) return false; 2927 enforceCrossUserPermission(Binder.getCallingUid(), userId, 2928 false /* requireFullPermission */, false /* checkShell */, "is package available"); 2929 synchronized (mPackages) { 2930 PackageParser.Package p = mPackages.get(packageName); 2931 if (p != null) { 2932 final PackageSetting ps = (PackageSetting) p.mExtras; 2933 if (ps != null) { 2934 final PackageUserState state = ps.readUserState(userId); 2935 if (state != null) { 2936 return PackageParser.isAvailable(state); 2937 } 2938 } 2939 } 2940 } 2941 return false; 2942 } 2943 2944 @Override 2945 public PackageInfo getPackageInfo(String packageName, int flags, int userId) { 2946 if (!sUserManager.exists(userId)) return null; 2947 flags = updateFlagsForPackage(flags, userId, packageName); 2948 enforceCrossUserPermission(Binder.getCallingUid(), userId, 2949 false /* requireFullPermission */, false /* checkShell */, "get package info"); 2950 // reader 2951 synchronized (mPackages) { 2952 PackageParser.Package p = mPackages.get(packageName); 2953 if (DEBUG_PACKAGE_INFO) 2954 Log.v(TAG, "getPackageInfo " + packageName + ": " + p); 2955 if (p != null) { 2956 return generatePackageInfo(p, flags, userId); 2957 } 2958 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 2959 return generatePackageInfoFromSettingsLPw(packageName, flags, userId); 2960 } 2961 } 2962 return null; 2963 } 2964 2965 @Override 2966 public String[] currentToCanonicalPackageNames(String[] names) { 2967 String[] out = new String[names.length]; 2968 // reader 2969 synchronized (mPackages) { 2970 for (int i=names.length-1; i>=0; i--) { 2971 PackageSetting ps = mSettings.mPackages.get(names[i]); 2972 out[i] = ps != null && ps.realName != null ? ps.realName : names[i]; 2973 } 2974 } 2975 return out; 2976 } 2977 2978 @Override 2979 public String[] canonicalToCurrentPackageNames(String[] names) { 2980 String[] out = new String[names.length]; 2981 // reader 2982 synchronized (mPackages) { 2983 for (int i=names.length-1; i>=0; i--) { 2984 String cur = mSettings.mRenamedPackages.get(names[i]); 2985 out[i] = cur != null ? cur : names[i]; 2986 } 2987 } 2988 return out; 2989 } 2990 2991 @Override 2992 public int getPackageUid(String packageName, int flags, int userId) { 2993 if (!sUserManager.exists(userId)) return -1; 2994 flags = updateFlagsForPackage(flags, userId, packageName); 2995 enforceCrossUserPermission(Binder.getCallingUid(), userId, 2996 false /* requireFullPermission */, false /* checkShell */, "get package uid"); 2997 2998 // reader 2999 synchronized (mPackages) { 3000 final PackageParser.Package p = mPackages.get(packageName); 3001 if (p != null && p.isMatch(flags)) { 3002 return UserHandle.getUid(userId, p.applicationInfo.uid); 3003 } 3004 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 3005 final PackageSetting ps = mSettings.mPackages.get(packageName); 3006 if (ps != null && ps.isMatch(flags)) { 3007 return UserHandle.getUid(userId, ps.appId); 3008 } 3009 } 3010 } 3011 3012 return -1; 3013 } 3014 3015 @Override 3016 public int[] getPackageGids(String packageName, int flags, int userId) { 3017 if (!sUserManager.exists(userId)) return null; 3018 flags = updateFlagsForPackage(flags, userId, packageName); 3019 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3020 false /* requireFullPermission */, false /* checkShell */, 3021 "getPackageGids"); 3022 3023 // reader 3024 synchronized (mPackages) { 3025 final PackageParser.Package p = mPackages.get(packageName); 3026 if (p != null && p.isMatch(flags)) { 3027 PackageSetting ps = (PackageSetting) p.mExtras; 3028 return ps.getPermissionsState().computeGids(userId); 3029 } 3030 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 3031 final PackageSetting ps = mSettings.mPackages.get(packageName); 3032 if (ps != null && ps.isMatch(flags)) { 3033 return ps.getPermissionsState().computeGids(userId); 3034 } 3035 } 3036 } 3037 3038 return null; 3039 } 3040 3041 static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) { 3042 if (bp.perm != null) { 3043 return PackageParser.generatePermissionInfo(bp.perm, flags); 3044 } 3045 PermissionInfo pi = new PermissionInfo(); 3046 pi.name = bp.name; 3047 pi.packageName = bp.sourcePackage; 3048 pi.nonLocalizedLabel = bp.name; 3049 pi.protectionLevel = bp.protectionLevel; 3050 return pi; 3051 } 3052 3053 @Override 3054 public PermissionInfo getPermissionInfo(String name, int flags) { 3055 // reader 3056 synchronized (mPackages) { 3057 final BasePermission p = mSettings.mPermissions.get(name); 3058 if (p != null) { 3059 return generatePermissionInfo(p, flags); 3060 } 3061 return null; 3062 } 3063 } 3064 3065 @Override 3066 public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group, 3067 int flags) { 3068 // reader 3069 synchronized (mPackages) { 3070 if (group != null && !mPermissionGroups.containsKey(group)) { 3071 // This is thrown as NameNotFoundException 3072 return null; 3073 } 3074 3075 ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10); 3076 for (BasePermission p : mSettings.mPermissions.values()) { 3077 if (group == null) { 3078 if (p.perm == null || p.perm.info.group == null) { 3079 out.add(generatePermissionInfo(p, flags)); 3080 } 3081 } else { 3082 if (p.perm != null && group.equals(p.perm.info.group)) { 3083 out.add(PackageParser.generatePermissionInfo(p.perm, flags)); 3084 } 3085 } 3086 } 3087 return new ParceledListSlice<>(out); 3088 } 3089 } 3090 3091 @Override 3092 public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) { 3093 // reader 3094 synchronized (mPackages) { 3095 return PackageParser.generatePermissionGroupInfo( 3096 mPermissionGroups.get(name), flags); 3097 } 3098 } 3099 3100 @Override 3101 public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) { 3102 // reader 3103 synchronized (mPackages) { 3104 final int N = mPermissionGroups.size(); 3105 ArrayList<PermissionGroupInfo> out 3106 = new ArrayList<PermissionGroupInfo>(N); 3107 for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) { 3108 out.add(PackageParser.generatePermissionGroupInfo(pg, flags)); 3109 } 3110 return new ParceledListSlice<>(out); 3111 } 3112 } 3113 3114 private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags, 3115 int userId) { 3116 if (!sUserManager.exists(userId)) return null; 3117 PackageSetting ps = mSettings.mPackages.get(packageName); 3118 if (ps != null) { 3119 if (ps.pkg == null) { 3120 PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName, 3121 flags, userId); 3122 if (pInfo != null) { 3123 return pInfo.applicationInfo; 3124 } 3125 return null; 3126 } 3127 return PackageParser.generateApplicationInfo(ps.pkg, flags, 3128 ps.readUserState(userId), userId); 3129 } 3130 return null; 3131 } 3132 3133 private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags, 3134 int userId) { 3135 if (!sUserManager.exists(userId)) return null; 3136 PackageSetting ps = mSettings.mPackages.get(packageName); 3137 if (ps != null) { 3138 PackageParser.Package pkg = ps.pkg; 3139 if (pkg == null) { 3140 if ((flags & MATCH_UNINSTALLED_PACKAGES) == 0) { 3141 return null; 3142 } 3143 // Only data remains, so we aren't worried about code paths 3144 pkg = new PackageParser.Package(packageName); 3145 pkg.applicationInfo.packageName = packageName; 3146 pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY; 3147 pkg.applicationInfo.privateFlags = ps.pkgPrivateFlags; 3148 pkg.applicationInfo.uid = ps.appId; 3149 pkg.applicationInfo.initForUser(userId); 3150 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString; 3151 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString; 3152 } 3153 return generatePackageInfo(pkg, flags, userId); 3154 } 3155 return null; 3156 } 3157 3158 @Override 3159 public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) { 3160 if (!sUserManager.exists(userId)) return null; 3161 flags = updateFlagsForApplication(flags, userId, packageName); 3162 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3163 false /* requireFullPermission */, false /* checkShell */, "get application info"); 3164 // writer 3165 synchronized (mPackages) { 3166 PackageParser.Package p = mPackages.get(packageName); 3167 if (DEBUG_PACKAGE_INFO) Log.v( 3168 TAG, "getApplicationInfo " + packageName 3169 + ": " + p); 3170 if (p != null) { 3171 PackageSetting ps = mSettings.mPackages.get(packageName); 3172 if (ps == null) return null; 3173 // Note: isEnabledLP() does not apply here - always return info 3174 return PackageParser.generateApplicationInfo( 3175 p, flags, ps.readUserState(userId), userId); 3176 } 3177 if ("android".equals(packageName)||"system".equals(packageName)) { 3178 return mAndroidApplication; 3179 } 3180 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 3181 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId); 3182 } 3183 } 3184 return null; 3185 } 3186 3187 @Override 3188 public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize, 3189 final IPackageDataObserver observer) { 3190 mContext.enforceCallingOrSelfPermission( 3191 android.Manifest.permission.CLEAR_APP_CACHE, null); 3192 // Queue up an async operation since clearing cache may take a little while. 3193 mHandler.post(new Runnable() { 3194 public void run() { 3195 mHandler.removeCallbacks(this); 3196 boolean success = true; 3197 synchronized (mInstallLock) { 3198 try { 3199 mInstaller.freeCache(volumeUuid, freeStorageSize); 3200 } catch (InstallerException e) { 3201 Slog.w(TAG, "Couldn't clear application caches: " + e); 3202 success = false; 3203 } 3204 } 3205 if (observer != null) { 3206 try { 3207 observer.onRemoveCompleted(null, success); 3208 } catch (RemoteException e) { 3209 Slog.w(TAG, "RemoveException when invoking call back"); 3210 } 3211 } 3212 } 3213 }); 3214 } 3215 3216 @Override 3217 public void freeStorage(final String volumeUuid, final long freeStorageSize, 3218 final IntentSender pi) { 3219 mContext.enforceCallingOrSelfPermission( 3220 android.Manifest.permission.CLEAR_APP_CACHE, null); 3221 // Queue up an async operation since clearing cache may take a little while. 3222 mHandler.post(new Runnable() { 3223 public void run() { 3224 mHandler.removeCallbacks(this); 3225 boolean success = true; 3226 synchronized (mInstallLock) { 3227 try { 3228 mInstaller.freeCache(volumeUuid, freeStorageSize); 3229 } catch (InstallerException e) { 3230 Slog.w(TAG, "Couldn't clear application caches: " + e); 3231 success = false; 3232 } 3233 } 3234 if(pi != null) { 3235 try { 3236 // Callback via pending intent 3237 int code = success ? 1 : 0; 3238 pi.sendIntent(null, code, null, 3239 null, null); 3240 } catch (SendIntentException e1) { 3241 Slog.i(TAG, "Failed to send pending intent"); 3242 } 3243 } 3244 } 3245 }); 3246 } 3247 3248 void freeStorage(String volumeUuid, long freeStorageSize) throws IOException { 3249 synchronized (mInstallLock) { 3250 try { 3251 mInstaller.freeCache(volumeUuid, freeStorageSize); 3252 } catch (InstallerException e) { 3253 throw new IOException("Failed to free enough space", e); 3254 } 3255 } 3256 } 3257 3258 /** 3259 * Return if the user key is currently unlocked. 3260 */ 3261 private boolean isUserKeyUnlocked(int userId) { 3262 if (StorageManager.isFileEncryptedNativeOrEmulated()) { 3263 final IMountService mount = IMountService.Stub 3264 .asInterface(ServiceManager.getService("mount")); 3265 if (mount == null) { 3266 Slog.w(TAG, "Early during boot, assuming locked"); 3267 return false; 3268 } 3269 final long token = Binder.clearCallingIdentity(); 3270 try { 3271 return mount.isUserKeyUnlocked(userId); 3272 } catch (RemoteException e) { 3273 throw e.rethrowAsRuntimeException(); 3274 } finally { 3275 Binder.restoreCallingIdentity(token); 3276 } 3277 } else { 3278 return true; 3279 } 3280 } 3281 3282 /** 3283 * Update given flags based on encryption status of current user. 3284 */ 3285 private int updateFlags(int flags, int userId) { 3286 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE 3287 | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) { 3288 // Caller expressed an explicit opinion about what encryption 3289 // aware/unaware components they want to see, so fall through and 3290 // give them what they want 3291 } else { 3292 // Caller expressed no opinion, so match based on user state 3293 if (isUserKeyUnlocked(userId)) { 3294 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE; 3295 } else { 3296 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE; 3297 } 3298 } 3299 return flags; 3300 } 3301 3302 /** 3303 * Update given flags when being used to request {@link PackageInfo}. 3304 */ 3305 private int updateFlagsForPackage(int flags, int userId, Object cookie) { 3306 boolean triaged = true; 3307 if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS 3308 | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) { 3309 // Caller is asking for component details, so they'd better be 3310 // asking for specific encryption matching behavior, or be triaged 3311 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE 3312 | PackageManager.MATCH_DIRECT_BOOT_AWARE 3313 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3314 triaged = false; 3315 } 3316 } 3317 if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES 3318 | PackageManager.MATCH_SYSTEM_ONLY 3319 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3320 triaged = false; 3321 } 3322 if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) { 3323 Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie 3324 + " with flags 0x" + Integer.toHexString(flags), new Throwable()); 3325 } 3326 return updateFlags(flags, userId); 3327 } 3328 3329 /** 3330 * Update given flags when being used to request {@link ApplicationInfo}. 3331 */ 3332 private int updateFlagsForApplication(int flags, int userId, Object cookie) { 3333 return updateFlagsForPackage(flags, userId, cookie); 3334 } 3335 3336 /** 3337 * Update given flags when being used to request {@link ComponentInfo}. 3338 */ 3339 private int updateFlagsForComponent(int flags, int userId, Object cookie) { 3340 if (cookie instanceof Intent) { 3341 if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) { 3342 flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING; 3343 } 3344 } 3345 3346 boolean triaged = true; 3347 // Caller is asking for component details, so they'd better be 3348 // asking for specific encryption matching behavior, or be triaged 3349 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE 3350 | PackageManager.MATCH_DIRECT_BOOT_AWARE 3351 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3352 triaged = false; 3353 } 3354 if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) { 3355 Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie 3356 + " with flags 0x" + Integer.toHexString(flags), new Throwable()); 3357 } 3358 3359 return updateFlags(flags, userId); 3360 } 3361 3362 /** 3363 * Update given flags when being used to request {@link ResolveInfo}. 3364 */ 3365 int updateFlagsForResolve(int flags, int userId, Object cookie) { 3366 // Safe mode means we shouldn't match any third-party components 3367 if (mSafeMode) { 3368 flags |= PackageManager.MATCH_SYSTEM_ONLY; 3369 } 3370 3371 return updateFlagsForComponent(flags, userId, cookie); 3372 } 3373 3374 @Override 3375 public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) { 3376 if (!sUserManager.exists(userId)) return null; 3377 flags = updateFlagsForComponent(flags, userId, component); 3378 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3379 false /* requireFullPermission */, false /* checkShell */, "get activity info"); 3380 synchronized (mPackages) { 3381 PackageParser.Activity a = mActivities.mActivities.get(component); 3382 3383 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a); 3384 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) { 3385 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3386 if (ps == null) return null; 3387 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 3388 userId); 3389 } 3390 if (mResolveComponentName.equals(component)) { 3391 return PackageParser.generateActivityInfo(mResolveActivity, flags, 3392 new PackageUserState(), userId); 3393 } 3394 } 3395 return null; 3396 } 3397 3398 @Override 3399 public boolean activitySupportsIntent(ComponentName component, Intent intent, 3400 String resolvedType) { 3401 synchronized (mPackages) { 3402 if (component.equals(mResolveComponentName)) { 3403 // The resolver supports EVERYTHING! 3404 return true; 3405 } 3406 PackageParser.Activity a = mActivities.mActivities.get(component); 3407 if (a == null) { 3408 return false; 3409 } 3410 for (int i=0; i<a.intents.size(); i++) { 3411 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(), 3412 intent.getData(), intent.getCategories(), TAG) >= 0) { 3413 return true; 3414 } 3415 } 3416 return false; 3417 } 3418 } 3419 3420 @Override 3421 public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) { 3422 if (!sUserManager.exists(userId)) return null; 3423 flags = updateFlagsForComponent(flags, userId, component); 3424 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3425 false /* requireFullPermission */, false /* checkShell */, "get receiver info"); 3426 synchronized (mPackages) { 3427 PackageParser.Activity a = mReceivers.mActivities.get(component); 3428 if (DEBUG_PACKAGE_INFO) Log.v( 3429 TAG, "getReceiverInfo " + component + ": " + a); 3430 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) { 3431 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3432 if (ps == null) return null; 3433 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 3434 userId); 3435 } 3436 } 3437 return null; 3438 } 3439 3440 @Override 3441 public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) { 3442 if (!sUserManager.exists(userId)) return null; 3443 flags = updateFlagsForComponent(flags, userId, component); 3444 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3445 false /* requireFullPermission */, false /* checkShell */, "get service info"); 3446 synchronized (mPackages) { 3447 PackageParser.Service s = mServices.mServices.get(component); 3448 if (DEBUG_PACKAGE_INFO) Log.v( 3449 TAG, "getServiceInfo " + component + ": " + s); 3450 if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) { 3451 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3452 if (ps == null) return null; 3453 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId), 3454 userId); 3455 } 3456 } 3457 return null; 3458 } 3459 3460 @Override 3461 public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) { 3462 if (!sUserManager.exists(userId)) return null; 3463 flags = updateFlagsForComponent(flags, userId, component); 3464 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3465 false /* requireFullPermission */, false /* checkShell */, "get provider info"); 3466 synchronized (mPackages) { 3467 PackageParser.Provider p = mProviders.mProviders.get(component); 3468 if (DEBUG_PACKAGE_INFO) Log.v( 3469 TAG, "getProviderInfo " + component + ": " + p); 3470 if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) { 3471 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3472 if (ps == null) return null; 3473 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId), 3474 userId); 3475 } 3476 } 3477 return null; 3478 } 3479 3480 @Override 3481 public String[] getSystemSharedLibraryNames() { 3482 Set<String> libSet; 3483 synchronized (mPackages) { 3484 libSet = mSharedLibraries.keySet(); 3485 int size = libSet.size(); 3486 if (size > 0) { 3487 String[] libs = new String[size]; 3488 libSet.toArray(libs); 3489 return libs; 3490 } 3491 } 3492 return null; 3493 } 3494 3495 @Override 3496 public @Nullable String getServicesSystemSharedLibraryPackageName() { 3497 synchronized (mPackages) { 3498 SharedLibraryEntry libraryEntry = mSharedLibraries.get( 3499 PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES); 3500 if (libraryEntry != null) { 3501 return libraryEntry.apk; 3502 } 3503 } 3504 return null; 3505 } 3506 3507 @Override 3508 public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() { 3509 synchronized (mPackages) { 3510 final ArrayList<FeatureInfo> res = new ArrayList<>(mAvailableFeatures.values()); 3511 3512 final FeatureInfo fi = new FeatureInfo(); 3513 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version", 3514 FeatureInfo.GL_ES_VERSION_UNDEFINED); 3515 res.add(fi); 3516 3517 return new ParceledListSlice<>(res); 3518 } 3519 } 3520 3521 @Override 3522 public boolean hasSystemFeature(String name, int version) { 3523 synchronized (mPackages) { 3524 final FeatureInfo feat = mAvailableFeatures.get(name); 3525 if (feat == null) { 3526 return false; 3527 } else { 3528 return feat.version >= version; 3529 } 3530 } 3531 } 3532 3533 @Override 3534 public int checkPermission(String permName, String pkgName, int userId) { 3535 if (!sUserManager.exists(userId)) { 3536 return PackageManager.PERMISSION_DENIED; 3537 } 3538 3539 synchronized (mPackages) { 3540 final PackageParser.Package p = mPackages.get(pkgName); 3541 if (p != null && p.mExtras != null) { 3542 final PackageSetting ps = (PackageSetting) p.mExtras; 3543 final PermissionsState permissionsState = ps.getPermissionsState(); 3544 if (permissionsState.hasPermission(permName, userId)) { 3545 return PackageManager.PERMISSION_GRANTED; 3546 } 3547 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION 3548 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState 3549 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { 3550 return PackageManager.PERMISSION_GRANTED; 3551 } 3552 } 3553 } 3554 3555 return PackageManager.PERMISSION_DENIED; 3556 } 3557 3558 @Override 3559 public int checkUidPermission(String permName, int uid) { 3560 final int userId = UserHandle.getUserId(uid); 3561 3562 if (!sUserManager.exists(userId)) { 3563 return PackageManager.PERMISSION_DENIED; 3564 } 3565 3566 synchronized (mPackages) { 3567 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 3568 if (obj != null) { 3569 final SettingBase ps = (SettingBase) obj; 3570 final PermissionsState permissionsState = ps.getPermissionsState(); 3571 if (permissionsState.hasPermission(permName, userId)) { 3572 return PackageManager.PERMISSION_GRANTED; 3573 } 3574 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION 3575 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState 3576 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { 3577 return PackageManager.PERMISSION_GRANTED; 3578 } 3579 } else { 3580 ArraySet<String> perms = mSystemPermissions.get(uid); 3581 if (perms != null) { 3582 if (perms.contains(permName)) { 3583 return PackageManager.PERMISSION_GRANTED; 3584 } 3585 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms 3586 .contains(Manifest.permission.ACCESS_FINE_LOCATION)) { 3587 return PackageManager.PERMISSION_GRANTED; 3588 } 3589 } 3590 } 3591 } 3592 3593 return PackageManager.PERMISSION_DENIED; 3594 } 3595 3596 @Override 3597 public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) { 3598 if (UserHandle.getCallingUserId() != userId) { 3599 mContext.enforceCallingPermission( 3600 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 3601 "isPermissionRevokedByPolicy for user " + userId); 3602 } 3603 3604 if (checkPermission(permission, packageName, userId) 3605 == PackageManager.PERMISSION_GRANTED) { 3606 return false; 3607 } 3608 3609 final long identity = Binder.clearCallingIdentity(); 3610 try { 3611 final int flags = getPermissionFlags(permission, packageName, userId); 3612 return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0; 3613 } finally { 3614 Binder.restoreCallingIdentity(identity); 3615 } 3616 } 3617 3618 @Override 3619 public String getPermissionControllerPackageName() { 3620 synchronized (mPackages) { 3621 return mRequiredInstallerPackage; 3622 } 3623 } 3624 3625 /** 3626 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS 3627 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller. 3628 * @param checkShell whether to prevent shell from access if there's a debugging restriction 3629 * @param message the message to log on security exception 3630 */ 3631 void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, 3632 boolean checkShell, String message) { 3633 if (userId < 0) { 3634 throw new IllegalArgumentException("Invalid userId " + userId); 3635 } 3636 if (checkShell) { 3637 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); 3638 } 3639 if (userId == UserHandle.getUserId(callingUid)) return; 3640 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 3641 if (requireFullPermission) { 3642 mContext.enforceCallingOrSelfPermission( 3643 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 3644 } else { 3645 try { 3646 mContext.enforceCallingOrSelfPermission( 3647 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 3648 } catch (SecurityException se) { 3649 mContext.enforceCallingOrSelfPermission( 3650 android.Manifest.permission.INTERACT_ACROSS_USERS, message); 3651 } 3652 } 3653 } 3654 } 3655 3656 void enforceShellRestriction(String restriction, int callingUid, int userHandle) { 3657 if (callingUid == Process.SHELL_UID) { 3658 if (userHandle >= 0 3659 && sUserManager.hasUserRestriction(restriction, userHandle)) { 3660 throw new SecurityException("Shell does not have permission to access user " 3661 + userHandle); 3662 } else if (userHandle < 0) { 3663 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t" 3664 + Debug.getCallers(3)); 3665 } 3666 } 3667 } 3668 3669 private BasePermission findPermissionTreeLP(String permName) { 3670 for(BasePermission bp : mSettings.mPermissionTrees.values()) { 3671 if (permName.startsWith(bp.name) && 3672 permName.length() > bp.name.length() && 3673 permName.charAt(bp.name.length()) == '.') { 3674 return bp; 3675 } 3676 } 3677 return null; 3678 } 3679 3680 private BasePermission checkPermissionTreeLP(String permName) { 3681 if (permName != null) { 3682 BasePermission bp = findPermissionTreeLP(permName); 3683 if (bp != null) { 3684 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) { 3685 return bp; 3686 } 3687 throw new SecurityException("Calling uid " 3688 + Binder.getCallingUid() 3689 + " is not allowed to add to permission tree " 3690 + bp.name + " owned by uid " + bp.uid); 3691 } 3692 } 3693 throw new SecurityException("No permission tree found for " + permName); 3694 } 3695 3696 static boolean compareStrings(CharSequence s1, CharSequence s2) { 3697 if (s1 == null) { 3698 return s2 == null; 3699 } 3700 if (s2 == null) { 3701 return false; 3702 } 3703 if (s1.getClass() != s2.getClass()) { 3704 return false; 3705 } 3706 return s1.equals(s2); 3707 } 3708 3709 static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) { 3710 if (pi1.icon != pi2.icon) return false; 3711 if (pi1.logo != pi2.logo) return false; 3712 if (pi1.protectionLevel != pi2.protectionLevel) return false; 3713 if (!compareStrings(pi1.name, pi2.name)) return false; 3714 if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false; 3715 // We'll take care of setting this one. 3716 if (!compareStrings(pi1.packageName, pi2.packageName)) return false; 3717 // These are not currently stored in settings. 3718 //if (!compareStrings(pi1.group, pi2.group)) return false; 3719 //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false; 3720 //if (pi1.labelRes != pi2.labelRes) return false; 3721 //if (pi1.descriptionRes != pi2.descriptionRes) return false; 3722 return true; 3723 } 3724 3725 int permissionInfoFootprint(PermissionInfo info) { 3726 int size = info.name.length(); 3727 if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length(); 3728 if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length(); 3729 return size; 3730 } 3731 3732 int calculateCurrentPermissionFootprintLocked(BasePermission tree) { 3733 int size = 0; 3734 for (BasePermission perm : mSettings.mPermissions.values()) { 3735 if (perm.uid == tree.uid) { 3736 size += perm.name.length() + permissionInfoFootprint(perm.perm.info); 3737 } 3738 } 3739 return size; 3740 } 3741 3742 void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) { 3743 // We calculate the max size of permissions defined by this uid and throw 3744 // if that plus the size of 'info' would exceed our stated maximum. 3745 if (tree.uid != Process.SYSTEM_UID) { 3746 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree); 3747 if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) { 3748 throw new SecurityException("Permission tree size cap exceeded"); 3749 } 3750 } 3751 } 3752 3753 boolean addPermissionLocked(PermissionInfo info, boolean async) { 3754 if (info.labelRes == 0 && info.nonLocalizedLabel == null) { 3755 throw new SecurityException("Label must be specified in permission"); 3756 } 3757 BasePermission tree = checkPermissionTreeLP(info.name); 3758 BasePermission bp = mSettings.mPermissions.get(info.name); 3759 boolean added = bp == null; 3760 boolean changed = true; 3761 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel); 3762 if (added) { 3763 enforcePermissionCapLocked(info, tree); 3764 bp = new BasePermission(info.name, tree.sourcePackage, 3765 BasePermission.TYPE_DYNAMIC); 3766 } else if (bp.type != BasePermission.TYPE_DYNAMIC) { 3767 throw new SecurityException( 3768 "Not allowed to modify non-dynamic permission " 3769 + info.name); 3770 } else { 3771 if (bp.protectionLevel == fixedLevel 3772 && bp.perm.owner.equals(tree.perm.owner) 3773 && bp.uid == tree.uid 3774 && comparePermissionInfos(bp.perm.info, info)) { 3775 changed = false; 3776 } 3777 } 3778 bp.protectionLevel = fixedLevel; 3779 info = new PermissionInfo(info); 3780 info.protectionLevel = fixedLevel; 3781 bp.perm = new PackageParser.Permission(tree.perm.owner, info); 3782 bp.perm.info.packageName = tree.perm.info.packageName; 3783 bp.uid = tree.uid; 3784 if (added) { 3785 mSettings.mPermissions.put(info.name, bp); 3786 } 3787 if (changed) { 3788 if (!async) { 3789 mSettings.writeLPr(); 3790 } else { 3791 scheduleWriteSettingsLocked(); 3792 } 3793 } 3794 return added; 3795 } 3796 3797 @Override 3798 public boolean addPermission(PermissionInfo info) { 3799 synchronized (mPackages) { 3800 return addPermissionLocked(info, false); 3801 } 3802 } 3803 3804 @Override 3805 public boolean addPermissionAsync(PermissionInfo info) { 3806 synchronized (mPackages) { 3807 return addPermissionLocked(info, true); 3808 } 3809 } 3810 3811 @Override 3812 public void removePermission(String name) { 3813 synchronized (mPackages) { 3814 checkPermissionTreeLP(name); 3815 BasePermission bp = mSettings.mPermissions.get(name); 3816 if (bp != null) { 3817 if (bp.type != BasePermission.TYPE_DYNAMIC) { 3818 throw new SecurityException( 3819 "Not allowed to modify non-dynamic permission " 3820 + name); 3821 } 3822 mSettings.mPermissions.remove(name); 3823 mSettings.writeLPr(); 3824 } 3825 } 3826 } 3827 3828 private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg, 3829 BasePermission bp) { 3830 int index = pkg.requestedPermissions.indexOf(bp.name); 3831 if (index == -1) { 3832 throw new SecurityException("Package " + pkg.packageName 3833 + " has not requested permission " + bp.name); 3834 } 3835 if (!bp.isRuntime() && !bp.isDevelopment()) { 3836 throw new SecurityException("Permission " + bp.name 3837 + " is not a changeable permission type"); 3838 } 3839 } 3840 3841 @Override 3842 public void grantRuntimePermission(String packageName, String name, final int userId) { 3843 if (!sUserManager.exists(userId)) { 3844 Log.e(TAG, "No such user:" + userId); 3845 return; 3846 } 3847 3848 mContext.enforceCallingOrSelfPermission( 3849 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 3850 "grantRuntimePermission"); 3851 3852 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3853 true /* requireFullPermission */, true /* checkShell */, 3854 "grantRuntimePermission"); 3855 3856 final int uid; 3857 final SettingBase sb; 3858 3859 synchronized (mPackages) { 3860 final PackageParser.Package pkg = mPackages.get(packageName); 3861 if (pkg == null) { 3862 throw new IllegalArgumentException("Unknown package: " + packageName); 3863 } 3864 3865 final BasePermission bp = mSettings.mPermissions.get(name); 3866 if (bp == null) { 3867 throw new IllegalArgumentException("Unknown permission: " + name); 3868 } 3869 3870 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp); 3871 3872 // If a permission review is required for legacy apps we represent 3873 // their permissions as always granted runtime ones since we need 3874 // to keep the review required permission flag per user while an 3875 // install permission's state is shared across all users. 3876 if (Build.PERMISSIONS_REVIEW_REQUIRED 3877 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M 3878 && bp.isRuntime()) { 3879 return; 3880 } 3881 3882 uid = UserHandle.getUid(userId, pkg.applicationInfo.uid); 3883 sb = (SettingBase) pkg.mExtras; 3884 if (sb == null) { 3885 throw new IllegalArgumentException("Unknown package: " + packageName); 3886 } 3887 3888 final PermissionsState permissionsState = sb.getPermissionsState(); 3889 3890 final int flags = permissionsState.getPermissionFlags(name, userId); 3891 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 3892 throw new SecurityException("Cannot grant system fixed permission " 3893 + name + " for package " + packageName); 3894 } 3895 3896 if (bp.isDevelopment()) { 3897 // Development permissions must be handled specially, since they are not 3898 // normal runtime permissions. For now they apply to all users. 3899 if (permissionsState.grantInstallPermission(bp) != 3900 PermissionsState.PERMISSION_OPERATION_FAILURE) { 3901 scheduleWriteSettingsLocked(); 3902 } 3903 return; 3904 } 3905 3906 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 3907 Slog.w(TAG, "Cannot grant runtime permission to a legacy app"); 3908 return; 3909 } 3910 3911 final int result = permissionsState.grantRuntimePermission(bp, userId); 3912 switch (result) { 3913 case PermissionsState.PERMISSION_OPERATION_FAILURE: { 3914 return; 3915 } 3916 3917 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 3918 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); 3919 mHandler.post(new Runnable() { 3920 @Override 3921 public void run() { 3922 killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED); 3923 } 3924 }); 3925 } 3926 break; 3927 } 3928 3929 mOnPermissionChangeListeners.onPermissionsChanged(uid); 3930 3931 // Not critical if that is lost - app has to request again. 3932 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 3933 } 3934 3935 // Only need to do this if user is initialized. Otherwise it's a new user 3936 // and there are no processes running as the user yet and there's no need 3937 // to make an expensive call to remount processes for the changed permissions. 3938 if (READ_EXTERNAL_STORAGE.equals(name) 3939 || WRITE_EXTERNAL_STORAGE.equals(name)) { 3940 final long token = Binder.clearCallingIdentity(); 3941 try { 3942 if (sUserManager.isInitialized(userId)) { 3943 MountServiceInternal mountServiceInternal = LocalServices.getService( 3944 MountServiceInternal.class); 3945 mountServiceInternal.onExternalStoragePolicyChanged(uid, packageName); 3946 } 3947 } finally { 3948 Binder.restoreCallingIdentity(token); 3949 } 3950 } 3951 } 3952 3953 @Override 3954 public void revokeRuntimePermission(String packageName, String name, int userId) { 3955 if (!sUserManager.exists(userId)) { 3956 Log.e(TAG, "No such user:" + userId); 3957 return; 3958 } 3959 3960 mContext.enforceCallingOrSelfPermission( 3961 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 3962 "revokeRuntimePermission"); 3963 3964 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3965 true /* requireFullPermission */, true /* checkShell */, 3966 "revokeRuntimePermission"); 3967 3968 final int appId; 3969 3970 synchronized (mPackages) { 3971 final PackageParser.Package pkg = mPackages.get(packageName); 3972 if (pkg == null) { 3973 throw new IllegalArgumentException("Unknown package: " + packageName); 3974 } 3975 3976 final BasePermission bp = mSettings.mPermissions.get(name); 3977 if (bp == null) { 3978 throw new IllegalArgumentException("Unknown permission: " + name); 3979 } 3980 3981 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp); 3982 3983 // If a permission review is required for legacy apps we represent 3984 // their permissions as always granted runtime ones since we need 3985 // to keep the review required permission flag per user while an 3986 // install permission's state is shared across all users. 3987 if (Build.PERMISSIONS_REVIEW_REQUIRED 3988 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M 3989 && bp.isRuntime()) { 3990 return; 3991 } 3992 3993 SettingBase sb = (SettingBase) pkg.mExtras; 3994 if (sb == null) { 3995 throw new IllegalArgumentException("Unknown package: " + packageName); 3996 } 3997 3998 final PermissionsState permissionsState = sb.getPermissionsState(); 3999 4000 final int flags = permissionsState.getPermissionFlags(name, userId); 4001 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 4002 throw new SecurityException("Cannot revoke system fixed permission " 4003 + name + " for package " + packageName); 4004 } 4005 4006 if (bp.isDevelopment()) { 4007 // Development permissions must be handled specially, since they are not 4008 // normal runtime permissions. For now they apply to all users. 4009 if (permissionsState.revokeInstallPermission(bp) != 4010 PermissionsState.PERMISSION_OPERATION_FAILURE) { 4011 scheduleWriteSettingsLocked(); 4012 } 4013 return; 4014 } 4015 4016 if (permissionsState.revokeRuntimePermission(bp, userId) == 4017 PermissionsState.PERMISSION_OPERATION_FAILURE) { 4018 return; 4019 } 4020 4021 mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid); 4022 4023 // Critical, after this call app should never have the permission. 4024 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 4025 4026 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 4027 } 4028 4029 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED); 4030 } 4031 4032 @Override 4033 public void resetRuntimePermissions() { 4034 mContext.enforceCallingOrSelfPermission( 4035 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 4036 "revokeRuntimePermission"); 4037 4038 int callingUid = Binder.getCallingUid(); 4039 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 4040 mContext.enforceCallingOrSelfPermission( 4041 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 4042 "resetRuntimePermissions"); 4043 } 4044 4045 synchronized (mPackages) { 4046 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL); 4047 for (int userId : UserManagerService.getInstance().getUserIds()) { 4048 final int packageCount = mPackages.size(); 4049 for (int i = 0; i < packageCount; i++) { 4050 PackageParser.Package pkg = mPackages.valueAt(i); 4051 if (!(pkg.mExtras instanceof PackageSetting)) { 4052 continue; 4053 } 4054 PackageSetting ps = (PackageSetting) pkg.mExtras; 4055 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 4056 } 4057 } 4058 } 4059 } 4060 4061 @Override 4062 public int getPermissionFlags(String name, String packageName, int userId) { 4063 if (!sUserManager.exists(userId)) { 4064 return 0; 4065 } 4066 4067 enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags"); 4068 4069 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4070 true /* requireFullPermission */, false /* checkShell */, 4071 "getPermissionFlags"); 4072 4073 synchronized (mPackages) { 4074 final PackageParser.Package pkg = mPackages.get(packageName); 4075 if (pkg == null) { 4076 throw new IllegalArgumentException("Unknown package: " + packageName); 4077 } 4078 4079 final BasePermission bp = mSettings.mPermissions.get(name); 4080 if (bp == null) { 4081 throw new IllegalArgumentException("Unknown permission: " + name); 4082 } 4083 4084 SettingBase sb = (SettingBase) pkg.mExtras; 4085 if (sb == null) { 4086 throw new IllegalArgumentException("Unknown package: " + packageName); 4087 } 4088 4089 PermissionsState permissionsState = sb.getPermissionsState(); 4090 return permissionsState.getPermissionFlags(name, userId); 4091 } 4092 } 4093 4094 @Override 4095 public void updatePermissionFlags(String name, String packageName, int flagMask, 4096 int flagValues, int userId) { 4097 if (!sUserManager.exists(userId)) { 4098 return; 4099 } 4100 4101 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags"); 4102 4103 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4104 true /* requireFullPermission */, true /* checkShell */, 4105 "updatePermissionFlags"); 4106 4107 // Only the system can change these flags and nothing else. 4108 if (getCallingUid() != Process.SYSTEM_UID) { 4109 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4110 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4111 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 4112 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 4113 flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 4114 } 4115 4116 synchronized (mPackages) { 4117 final PackageParser.Package pkg = mPackages.get(packageName); 4118 if (pkg == null) { 4119 throw new IllegalArgumentException("Unknown package: " + packageName); 4120 } 4121 4122 final BasePermission bp = mSettings.mPermissions.get(name); 4123 if (bp == null) { 4124 throw new IllegalArgumentException("Unknown permission: " + name); 4125 } 4126 4127 SettingBase sb = (SettingBase) pkg.mExtras; 4128 if (sb == null) { 4129 throw new IllegalArgumentException("Unknown package: " + packageName); 4130 } 4131 4132 PermissionsState permissionsState = sb.getPermissionsState(); 4133 4134 boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null; 4135 4136 if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) { 4137 // Install and runtime permissions are stored in different places, 4138 // so figure out what permission changed and persist the change. 4139 if (permissionsState.getInstallPermissionState(name) != null) { 4140 scheduleWriteSettingsLocked(); 4141 } else if (permissionsState.getRuntimePermissionState(name, userId) != null 4142 || hadState) { 4143 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 4144 } 4145 } 4146 } 4147 } 4148 4149 /** 4150 * Update the permission flags for all packages and runtime permissions of a user in order 4151 * to allow device or profile owner to remove POLICY_FIXED. 4152 */ 4153 @Override 4154 public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) { 4155 if (!sUserManager.exists(userId)) { 4156 return; 4157 } 4158 4159 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps"); 4160 4161 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4162 true /* requireFullPermission */, true /* checkShell */, 4163 "updatePermissionFlagsForAllApps"); 4164 4165 // Only the system can change system fixed flags. 4166 if (getCallingUid() != Process.SYSTEM_UID) { 4167 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4168 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4169 } 4170 4171 synchronized (mPackages) { 4172 boolean changed = false; 4173 final int packageCount = mPackages.size(); 4174 for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) { 4175 final PackageParser.Package pkg = mPackages.valueAt(pkgIndex); 4176 SettingBase sb = (SettingBase) pkg.mExtras; 4177 if (sb == null) { 4178 continue; 4179 } 4180 PermissionsState permissionsState = sb.getPermissionsState(); 4181 changed |= permissionsState.updatePermissionFlagsForAllPermissions( 4182 userId, flagMask, flagValues); 4183 } 4184 if (changed) { 4185 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 4186 } 4187 } 4188 } 4189 4190 private void enforceGrantRevokeRuntimePermissionPermissions(String message) { 4191 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS) 4192 != PackageManager.PERMISSION_GRANTED 4193 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) 4194 != PackageManager.PERMISSION_GRANTED) { 4195 throw new SecurityException(message + " requires " 4196 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or " 4197 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS); 4198 } 4199 } 4200 4201 @Override 4202 public boolean shouldShowRequestPermissionRationale(String permissionName, 4203 String packageName, int userId) { 4204 if (UserHandle.getCallingUserId() != userId) { 4205 mContext.enforceCallingPermission( 4206 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 4207 "canShowRequestPermissionRationale for user " + userId); 4208 } 4209 4210 final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId); 4211 if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) { 4212 return false; 4213 } 4214 4215 if (checkPermission(permissionName, packageName, userId) 4216 == PackageManager.PERMISSION_GRANTED) { 4217 return false; 4218 } 4219 4220 final int flags; 4221 4222 final long identity = Binder.clearCallingIdentity(); 4223 try { 4224 flags = getPermissionFlags(permissionName, 4225 packageName, userId); 4226 } finally { 4227 Binder.restoreCallingIdentity(identity); 4228 } 4229 4230 final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 4231 | PackageManager.FLAG_PERMISSION_POLICY_FIXED 4232 | PackageManager.FLAG_PERMISSION_USER_FIXED; 4233 4234 if ((flags & fixedFlags) != 0) { 4235 return false; 4236 } 4237 4238 return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0; 4239 } 4240 4241 @Override 4242 public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 4243 mContext.enforceCallingOrSelfPermission( 4244 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS, 4245 "addOnPermissionsChangeListener"); 4246 4247 synchronized (mPackages) { 4248 mOnPermissionChangeListeners.addListenerLocked(listener); 4249 } 4250 } 4251 4252 @Override 4253 public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 4254 synchronized (mPackages) { 4255 mOnPermissionChangeListeners.removeListenerLocked(listener); 4256 } 4257 } 4258 4259 @Override 4260 public boolean isProtectedBroadcast(String actionName) { 4261 synchronized (mPackages) { 4262 if (mProtectedBroadcasts.contains(actionName)) { 4263 return true; 4264 } else if (actionName != null) { 4265 // TODO: remove these terrible hacks 4266 if (actionName.startsWith("android.net.netmon.lingerExpired") 4267 || actionName.startsWith("com.android.server.sip.SipWakeupTimer") 4268 || actionName.startsWith("com.android.internal.telephony.data-reconnect") 4269 || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) { 4270 return true; 4271 } 4272 } 4273 } 4274 return false; 4275 } 4276 4277 @Override 4278 public int checkSignatures(String pkg1, String pkg2) { 4279 synchronized (mPackages) { 4280 final PackageParser.Package p1 = mPackages.get(pkg1); 4281 final PackageParser.Package p2 = mPackages.get(pkg2); 4282 if (p1 == null || p1.mExtras == null 4283 || p2 == null || p2.mExtras == null) { 4284 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4285 } 4286 return compareSignatures(p1.mSignatures, p2.mSignatures); 4287 } 4288 } 4289 4290 @Override 4291 public int checkUidSignatures(int uid1, int uid2) { 4292 // Map to base uids. 4293 uid1 = UserHandle.getAppId(uid1); 4294 uid2 = UserHandle.getAppId(uid2); 4295 // reader 4296 synchronized (mPackages) { 4297 Signature[] s1; 4298 Signature[] s2; 4299 Object obj = mSettings.getUserIdLPr(uid1); 4300 if (obj != null) { 4301 if (obj instanceof SharedUserSetting) { 4302 s1 = ((SharedUserSetting)obj).signatures.mSignatures; 4303 } else if (obj instanceof PackageSetting) { 4304 s1 = ((PackageSetting)obj).signatures.mSignatures; 4305 } else { 4306 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4307 } 4308 } else { 4309 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4310 } 4311 obj = mSettings.getUserIdLPr(uid2); 4312 if (obj != null) { 4313 if (obj instanceof SharedUserSetting) { 4314 s2 = ((SharedUserSetting)obj).signatures.mSignatures; 4315 } else if (obj instanceof PackageSetting) { 4316 s2 = ((PackageSetting)obj).signatures.mSignatures; 4317 } else { 4318 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4319 } 4320 } else { 4321 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4322 } 4323 return compareSignatures(s1, s2); 4324 } 4325 } 4326 4327 private void killUid(int appId, int userId, String reason) { 4328 final long identity = Binder.clearCallingIdentity(); 4329 try { 4330 IActivityManager am = ActivityManagerNative.getDefault(); 4331 if (am != null) { 4332 try { 4333 am.killUid(appId, userId, reason); 4334 } catch (RemoteException e) { 4335 /* ignore - same process */ 4336 } 4337 } 4338 } finally { 4339 Binder.restoreCallingIdentity(identity); 4340 } 4341 } 4342 4343 /** 4344 * Compares two sets of signatures. Returns: 4345 * <br /> 4346 * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null, 4347 * <br /> 4348 * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null, 4349 * <br /> 4350 * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null, 4351 * <br /> 4352 * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical, 4353 * <br /> 4354 * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ. 4355 */ 4356 static int compareSignatures(Signature[] s1, Signature[] s2) { 4357 if (s1 == null) { 4358 return s2 == null 4359 ? PackageManager.SIGNATURE_NEITHER_SIGNED 4360 : PackageManager.SIGNATURE_FIRST_NOT_SIGNED; 4361 } 4362 4363 if (s2 == null) { 4364 return PackageManager.SIGNATURE_SECOND_NOT_SIGNED; 4365 } 4366 4367 if (s1.length != s2.length) { 4368 return PackageManager.SIGNATURE_NO_MATCH; 4369 } 4370 4371 // Since both signature sets are of size 1, we can compare without HashSets. 4372 if (s1.length == 1) { 4373 return s1[0].equals(s2[0]) ? 4374 PackageManager.SIGNATURE_MATCH : 4375 PackageManager.SIGNATURE_NO_MATCH; 4376 } 4377 4378 ArraySet<Signature> set1 = new ArraySet<Signature>(); 4379 for (Signature sig : s1) { 4380 set1.add(sig); 4381 } 4382 ArraySet<Signature> set2 = new ArraySet<Signature>(); 4383 for (Signature sig : s2) { 4384 set2.add(sig); 4385 } 4386 // Make sure s2 contains all signatures in s1. 4387 if (set1.equals(set2)) { 4388 return PackageManager.SIGNATURE_MATCH; 4389 } 4390 return PackageManager.SIGNATURE_NO_MATCH; 4391 } 4392 4393 /** 4394 * If the database version for this type of package (internal storage or 4395 * external storage) is less than the version where package signatures 4396 * were updated, return true. 4397 */ 4398 private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 4399 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); 4400 return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY; 4401 } 4402 4403 /** 4404 * Used for backward compatibility to make sure any packages with 4405 * certificate chains get upgraded to the new style. {@code existingSigs} 4406 * will be in the old format (since they were stored on disk from before the 4407 * system upgrade) and {@code scannedSigs} will be in the newer format. 4408 */ 4409 private int compareSignaturesCompat(PackageSignatures existingSigs, 4410 PackageParser.Package scannedPkg) { 4411 if (!isCompatSignatureUpdateNeeded(scannedPkg)) { 4412 return PackageManager.SIGNATURE_NO_MATCH; 4413 } 4414 4415 ArraySet<Signature> existingSet = new ArraySet<Signature>(); 4416 for (Signature sig : existingSigs.mSignatures) { 4417 existingSet.add(sig); 4418 } 4419 ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>(); 4420 for (Signature sig : scannedPkg.mSignatures) { 4421 try { 4422 Signature[] chainSignatures = sig.getChainSignatures(); 4423 for (Signature chainSig : chainSignatures) { 4424 scannedCompatSet.add(chainSig); 4425 } 4426 } catch (CertificateEncodingException e) { 4427 scannedCompatSet.add(sig); 4428 } 4429 } 4430 /* 4431 * Make sure the expanded scanned set contains all signatures in the 4432 * existing one. 4433 */ 4434 if (scannedCompatSet.equals(existingSet)) { 4435 // Migrate the old signatures to the new scheme. 4436 existingSigs.assignSignatures(scannedPkg.mSignatures); 4437 // The new KeySets will be re-added later in the scanning process. 4438 synchronized (mPackages) { 4439 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName); 4440 } 4441 return PackageManager.SIGNATURE_MATCH; 4442 } 4443 return PackageManager.SIGNATURE_NO_MATCH; 4444 } 4445 4446 private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 4447 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); 4448 return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER; 4449 } 4450 4451 private int compareSignaturesRecover(PackageSignatures existingSigs, 4452 PackageParser.Package scannedPkg) { 4453 if (!isRecoverSignatureUpdateNeeded(scannedPkg)) { 4454 return PackageManager.SIGNATURE_NO_MATCH; 4455 } 4456 4457 String msg = null; 4458 try { 4459 if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) { 4460 logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for " 4461 + scannedPkg.packageName); 4462 return PackageManager.SIGNATURE_MATCH; 4463 } 4464 } catch (CertificateException e) { 4465 msg = e.getMessage(); 4466 } 4467 4468 logCriticalInfo(Log.INFO, 4469 "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg); 4470 return PackageManager.SIGNATURE_NO_MATCH; 4471 } 4472 4473 @Override 4474 public List<String> getAllPackages() { 4475 synchronized (mPackages) { 4476 return new ArrayList<String>(mPackages.keySet()); 4477 } 4478 } 4479 4480 @Override 4481 public String[] getPackagesForUid(int uid) { 4482 uid = UserHandle.getAppId(uid); 4483 // reader 4484 synchronized (mPackages) { 4485 Object obj = mSettings.getUserIdLPr(uid); 4486 if (obj instanceof SharedUserSetting) { 4487 final SharedUserSetting sus = (SharedUserSetting) obj; 4488 final int N = sus.packages.size(); 4489 final String[] res = new String[N]; 4490 final Iterator<PackageSetting> it = sus.packages.iterator(); 4491 int i = 0; 4492 while (it.hasNext()) { 4493 res[i++] = it.next().name; 4494 } 4495 return res; 4496 } else if (obj instanceof PackageSetting) { 4497 final PackageSetting ps = (PackageSetting) obj; 4498 return new String[] { ps.name }; 4499 } 4500 } 4501 return null; 4502 } 4503 4504 @Override 4505 public String getNameForUid(int uid) { 4506 // reader 4507 synchronized (mPackages) { 4508 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4509 if (obj instanceof SharedUserSetting) { 4510 final SharedUserSetting sus = (SharedUserSetting) obj; 4511 return sus.name + ":" + sus.userId; 4512 } else if (obj instanceof PackageSetting) { 4513 final PackageSetting ps = (PackageSetting) obj; 4514 return ps.name; 4515 } 4516 } 4517 return null; 4518 } 4519 4520 @Override 4521 public int getUidForSharedUser(String sharedUserName) { 4522 if(sharedUserName == null) { 4523 return -1; 4524 } 4525 // reader 4526 synchronized (mPackages) { 4527 final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false); 4528 if (suid == null) { 4529 return -1; 4530 } 4531 return suid.userId; 4532 } 4533 } 4534 4535 @Override 4536 public int getFlagsForUid(int uid) { 4537 synchronized (mPackages) { 4538 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4539 if (obj instanceof SharedUserSetting) { 4540 final SharedUserSetting sus = (SharedUserSetting) obj; 4541 return sus.pkgFlags; 4542 } else if (obj instanceof PackageSetting) { 4543 final PackageSetting ps = (PackageSetting) obj; 4544 return ps.pkgFlags; 4545 } 4546 } 4547 return 0; 4548 } 4549 4550 @Override 4551 public int getPrivateFlagsForUid(int uid) { 4552 synchronized (mPackages) { 4553 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4554 if (obj instanceof SharedUserSetting) { 4555 final SharedUserSetting sus = (SharedUserSetting) obj; 4556 return sus.pkgPrivateFlags; 4557 } else if (obj instanceof PackageSetting) { 4558 final PackageSetting ps = (PackageSetting) obj; 4559 return ps.pkgPrivateFlags; 4560 } 4561 } 4562 return 0; 4563 } 4564 4565 @Override 4566 public boolean isUidPrivileged(int uid) { 4567 uid = UserHandle.getAppId(uid); 4568 // reader 4569 synchronized (mPackages) { 4570 Object obj = mSettings.getUserIdLPr(uid); 4571 if (obj instanceof SharedUserSetting) { 4572 final SharedUserSetting sus = (SharedUserSetting) obj; 4573 final Iterator<PackageSetting> it = sus.packages.iterator(); 4574 while (it.hasNext()) { 4575 if (it.next().isPrivileged()) { 4576 return true; 4577 } 4578 } 4579 } else if (obj instanceof PackageSetting) { 4580 final PackageSetting ps = (PackageSetting) obj; 4581 return ps.isPrivileged(); 4582 } 4583 } 4584 return false; 4585 } 4586 4587 @Override 4588 public String[] getAppOpPermissionPackages(String permissionName) { 4589 synchronized (mPackages) { 4590 ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName); 4591 if (pkgs == null) { 4592 return null; 4593 } 4594 return pkgs.toArray(new String[pkgs.size()]); 4595 } 4596 } 4597 4598 @Override 4599 public ResolveInfo resolveIntent(Intent intent, String resolvedType, 4600 int flags, int userId) { 4601 if (!sUserManager.exists(userId)) return null; 4602 flags = updateFlagsForResolve(flags, userId, intent); 4603 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4604 false /* requireFullPermission */, false /* checkShell */, "resolve intent"); 4605 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags, 4606 userId); 4607 final ResolveInfo bestChoice = 4608 chooseBestActivity(intent, resolvedType, flags, query, userId); 4609 4610 if (isEphemeralAllowed(intent, query, userId)) { 4611 final EphemeralResolveInfo ai = 4612 getEphemeralResolveInfo(intent, resolvedType, userId); 4613 if (ai != null) { 4614 if (DEBUG_EPHEMERAL) { 4615 Slog.v(TAG, "Returning an EphemeralResolveInfo"); 4616 } 4617 bestChoice.ephemeralInstaller = mEphemeralInstallerInfo; 4618 bestChoice.ephemeralResolveInfo = ai; 4619 } 4620 } 4621 return bestChoice; 4622 } 4623 4624 @Override 4625 public void setLastChosenActivity(Intent intent, String resolvedType, int flags, 4626 IntentFilter filter, int match, ComponentName activity) { 4627 final int userId = UserHandle.getCallingUserId(); 4628 if (DEBUG_PREFERRED) { 4629 Log.v(TAG, "setLastChosenActivity intent=" + intent 4630 + " resolvedType=" + resolvedType 4631 + " flags=" + flags 4632 + " filter=" + filter 4633 + " match=" + match 4634 + " activity=" + activity); 4635 filter.dump(new PrintStreamPrinter(System.out), " "); 4636 } 4637 intent.setComponent(null); 4638 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags, 4639 userId); 4640 // Find any earlier preferred or last chosen entries and nuke them 4641 findPreferredActivity(intent, resolvedType, 4642 flags, query, 0, false, true, false, userId); 4643 // Add the new activity as the last chosen for this filter 4644 addPreferredActivityInternal(filter, match, null, activity, false, userId, 4645 "Setting last chosen"); 4646 } 4647 4648 @Override 4649 public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) { 4650 final int userId = UserHandle.getCallingUserId(); 4651 if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent); 4652 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags, 4653 userId); 4654 return findPreferredActivity(intent, resolvedType, flags, query, 0, 4655 false, false, false, userId); 4656 } 4657 4658 4659 private boolean isEphemeralAllowed( 4660 Intent intent, List<ResolveInfo> resolvedActivites, int userId) { 4661 // Short circuit and return early if possible. 4662 if (DISABLE_EPHEMERAL_APPS) { 4663 return false; 4664 } 4665 final int callingUser = UserHandle.getCallingUserId(); 4666 if (callingUser != UserHandle.USER_SYSTEM) { 4667 return false; 4668 } 4669 if (mEphemeralResolverConnection == null) { 4670 return false; 4671 } 4672 if (intent.getComponent() != null) { 4673 return false; 4674 } 4675 if (intent.getPackage() != null) { 4676 return false; 4677 } 4678 final boolean isWebUri = hasWebURI(intent); 4679 if (!isWebUri) { 4680 return false; 4681 } 4682 // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution. 4683 synchronized (mPackages) { 4684 final int count = resolvedActivites.size(); 4685 for (int n = 0; n < count; n++) { 4686 ResolveInfo info = resolvedActivites.get(n); 4687 String packageName = info.activityInfo.packageName; 4688 PackageSetting ps = mSettings.mPackages.get(packageName); 4689 if (ps != null) { 4690 // Try to get the status from User settings first 4691 long packedStatus = getDomainVerificationStatusLPr(ps, userId); 4692 int status = (int) (packedStatus >> 32); 4693 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS 4694 || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) { 4695 if (DEBUG_EPHEMERAL) { 4696 Slog.v(TAG, "DENY ephemeral apps;" 4697 + " pkg: " + packageName + ", status: " + status); 4698 } 4699 return false; 4700 } 4701 } 4702 } 4703 } 4704 // We've exhausted all ways to deny ephemeral application; let the system look for them. 4705 return true; 4706 } 4707 4708 private EphemeralResolveInfo getEphemeralResolveInfo(Intent intent, String resolvedType, 4709 int userId) { 4710 MessageDigest digest = null; 4711 try { 4712 digest = MessageDigest.getInstance(EphemeralResolveInfo.SHA_ALGORITHM); 4713 } catch (NoSuchAlgorithmException e) { 4714 // If we can't create a digest, ignore ephemeral apps. 4715 return null; 4716 } 4717 4718 final byte[] hostBytes = intent.getData().getHost().getBytes(); 4719 final byte[] digestBytes = digest.digest(hostBytes); 4720 int shaPrefix = 4721 digestBytes[0] << 24 4722 | digestBytes[1] << 16 4723 | digestBytes[2] << 8 4724 | digestBytes[3] << 0; 4725 final List<EphemeralResolveInfo> ephemeralResolveInfoList = 4726 mEphemeralResolverConnection.getEphemeralResolveInfoList(shaPrefix); 4727 if (ephemeralResolveInfoList == null || ephemeralResolveInfoList.size() == 0) { 4728 // No hash prefix match; there are no ephemeral apps for this domain. 4729 return null; 4730 } 4731 for (int i = ephemeralResolveInfoList.size() - 1; i >= 0; --i) { 4732 EphemeralResolveInfo ephemeralApplication = ephemeralResolveInfoList.get(i); 4733 if (!Arrays.equals(digestBytes, ephemeralApplication.getDigestBytes())) { 4734 continue; 4735 } 4736 final List<IntentFilter> filters = ephemeralApplication.getFilters(); 4737 // No filters; this should never happen. 4738 if (filters.isEmpty()) { 4739 continue; 4740 } 4741 // We have a domain match; resolve the filters to see if anything matches. 4742 final EphemeralIntentResolver ephemeralResolver = new EphemeralIntentResolver(); 4743 for (int j = filters.size() - 1; j >= 0; --j) { 4744 final EphemeralResolveIntentInfo intentInfo = 4745 new EphemeralResolveIntentInfo(filters.get(j), ephemeralApplication); 4746 ephemeralResolver.addFilter(intentInfo); 4747 } 4748 List<EphemeralResolveInfo> matchedResolveInfoList = ephemeralResolver.queryIntent( 4749 intent, resolvedType, false /*defaultOnly*/, userId); 4750 if (!matchedResolveInfoList.isEmpty()) { 4751 return matchedResolveInfoList.get(0); 4752 } 4753 } 4754 // Hash or filter mis-match; no ephemeral apps for this domain. 4755 return null; 4756 } 4757 4758 private ResolveInfo chooseBestActivity(Intent intent, String resolvedType, 4759 int flags, List<ResolveInfo> query, int userId) { 4760 if (query != null) { 4761 final int N = query.size(); 4762 if (N == 1) { 4763 return query.get(0); 4764 } else if (N > 1) { 4765 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 4766 // If there is more than one activity with the same priority, 4767 // then let the user decide between them. 4768 ResolveInfo r0 = query.get(0); 4769 ResolveInfo r1 = query.get(1); 4770 if (DEBUG_INTENT_MATCHING || debug) { 4771 Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs " 4772 + r1.activityInfo.name + "=" + r1.priority); 4773 } 4774 // If the first activity has a higher priority, or a different 4775 // default, then it is always desirable to pick it. 4776 if (r0.priority != r1.priority 4777 || r0.preferredOrder != r1.preferredOrder 4778 || r0.isDefault != r1.isDefault) { 4779 return query.get(0); 4780 } 4781 // If we have saved a preference for a preferred activity for 4782 // this Intent, use that. 4783 ResolveInfo ri = findPreferredActivity(intent, resolvedType, 4784 flags, query, r0.priority, true, false, debug, userId); 4785 if (ri != null) { 4786 return ri; 4787 } 4788 ri = new ResolveInfo(mResolveInfo); 4789 ri.activityInfo = new ActivityInfo(ri.activityInfo); 4790 ri.activityInfo.applicationInfo = new ApplicationInfo( 4791 ri.activityInfo.applicationInfo); 4792 if (userId != 0) { 4793 ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId, 4794 UserHandle.getAppId(ri.activityInfo.applicationInfo.uid)); 4795 } 4796 // Make sure that the resolver is displayable in car mode 4797 if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle(); 4798 ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true); 4799 return ri; 4800 } 4801 } 4802 return null; 4803 } 4804 4805 private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType, 4806 int flags, List<ResolveInfo> query, boolean debug, int userId) { 4807 final int N = query.size(); 4808 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 4809 .get(userId); 4810 // Get the list of persistent preferred activities that handle the intent 4811 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities..."); 4812 List<PersistentPreferredActivity> pprefs = ppir != null 4813 ? ppir.queryIntent(intent, resolvedType, 4814 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 4815 : null; 4816 if (pprefs != null && pprefs.size() > 0) { 4817 final int M = pprefs.size(); 4818 for (int i=0; i<M; i++) { 4819 final PersistentPreferredActivity ppa = pprefs.get(i); 4820 if (DEBUG_PREFERRED || debug) { 4821 Slog.v(TAG, "Checking PersistentPreferredActivity ds=" 4822 + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>") 4823 + "\n component=" + ppa.mComponent); 4824 ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4825 } 4826 final ActivityInfo ai = getActivityInfo(ppa.mComponent, 4827 flags | MATCH_DISABLED_COMPONENTS, userId); 4828 if (DEBUG_PREFERRED || debug) { 4829 Slog.v(TAG, "Found persistent preferred activity:"); 4830 if (ai != null) { 4831 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4832 } else { 4833 Slog.v(TAG, " null"); 4834 } 4835 } 4836 if (ai == null) { 4837 // This previously registered persistent preferred activity 4838 // component is no longer known. Ignore it and do NOT remove it. 4839 continue; 4840 } 4841 for (int j=0; j<N; j++) { 4842 final ResolveInfo ri = query.get(j); 4843 if (!ri.activityInfo.applicationInfo.packageName 4844 .equals(ai.applicationInfo.packageName)) { 4845 continue; 4846 } 4847 if (!ri.activityInfo.name.equals(ai.name)) { 4848 continue; 4849 } 4850 // Found a persistent preference that can handle the intent. 4851 if (DEBUG_PREFERRED || debug) { 4852 Slog.v(TAG, "Returning persistent preferred activity: " + 4853 ri.activityInfo.packageName + "/" + ri.activityInfo.name); 4854 } 4855 return ri; 4856 } 4857 } 4858 } 4859 return null; 4860 } 4861 4862 // TODO: handle preferred activities missing while user has amnesia 4863 ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags, 4864 List<ResolveInfo> query, int priority, boolean always, 4865 boolean removeMatches, boolean debug, int userId) { 4866 if (!sUserManager.exists(userId)) return null; 4867 flags = updateFlagsForResolve(flags, userId, intent); 4868 // writer 4869 synchronized (mPackages) { 4870 if (intent.getSelector() != null) { 4871 intent = intent.getSelector(); 4872 } 4873 if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION); 4874 4875 // Try to find a matching persistent preferred activity. 4876 ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query, 4877 debug, userId); 4878 4879 // If a persistent preferred activity matched, use it. 4880 if (pri != null) { 4881 return pri; 4882 } 4883 4884 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 4885 // Get the list of preferred activities that handle the intent 4886 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities..."); 4887 List<PreferredActivity> prefs = pir != null 4888 ? pir.queryIntent(intent, resolvedType, 4889 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 4890 : null; 4891 if (prefs != null && prefs.size() > 0) { 4892 boolean changed = false; 4893 try { 4894 // First figure out how good the original match set is. 4895 // We will only allow preferred activities that came 4896 // from the same match quality. 4897 int match = 0; 4898 4899 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match..."); 4900 4901 final int N = query.size(); 4902 for (int j=0; j<N; j++) { 4903 final ResolveInfo ri = query.get(j); 4904 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo 4905 + ": 0x" + Integer.toHexString(match)); 4906 if (ri.match > match) { 4907 match = ri.match; 4908 } 4909 } 4910 4911 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x" 4912 + Integer.toHexString(match)); 4913 4914 match &= IntentFilter.MATCH_CATEGORY_MASK; 4915 final int M = prefs.size(); 4916 for (int i=0; i<M; i++) { 4917 final PreferredActivity pa = prefs.get(i); 4918 if (DEBUG_PREFERRED || debug) { 4919 Slog.v(TAG, "Checking PreferredActivity ds=" 4920 + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>") 4921 + "\n component=" + pa.mPref.mComponent); 4922 pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4923 } 4924 if (pa.mPref.mMatch != match) { 4925 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match " 4926 + Integer.toHexString(pa.mPref.mMatch)); 4927 continue; 4928 } 4929 // If it's not an "always" type preferred activity and that's what we're 4930 // looking for, skip it. 4931 if (always && !pa.mPref.mAlways) { 4932 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry"); 4933 continue; 4934 } 4935 final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent, 4936 flags | MATCH_DISABLED_COMPONENTS, userId); 4937 if (DEBUG_PREFERRED || debug) { 4938 Slog.v(TAG, "Found preferred activity:"); 4939 if (ai != null) { 4940 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4941 } else { 4942 Slog.v(TAG, " null"); 4943 } 4944 } 4945 if (ai == null) { 4946 // This previously registered preferred activity 4947 // component is no longer known. Most likely an update 4948 // to the app was installed and in the new version this 4949 // component no longer exists. Clean it up by removing 4950 // it from the preferred activities list, and skip it. 4951 Slog.w(TAG, "Removing dangling preferred activity: " 4952 + pa.mPref.mComponent); 4953 pir.removeFilter(pa); 4954 changed = true; 4955 continue; 4956 } 4957 for (int j=0; j<N; j++) { 4958 final ResolveInfo ri = query.get(j); 4959 if (!ri.activityInfo.applicationInfo.packageName 4960 .equals(ai.applicationInfo.packageName)) { 4961 continue; 4962 } 4963 if (!ri.activityInfo.name.equals(ai.name)) { 4964 continue; 4965 } 4966 4967 if (removeMatches) { 4968 pir.removeFilter(pa); 4969 changed = true; 4970 if (DEBUG_PREFERRED) { 4971 Slog.v(TAG, "Removing match " + pa.mPref.mComponent); 4972 } 4973 break; 4974 } 4975 4976 // Okay we found a previously set preferred or last chosen app. 4977 // If the result set is different from when this 4978 // was created, we need to clear it and re-ask the 4979 // user their preference, if we're looking for an "always" type entry. 4980 if (always && !pa.mPref.sameSet(query)) { 4981 Slog.i(TAG, "Result set changed, dropping preferred activity for " 4982 + intent + " type " + resolvedType); 4983 if (DEBUG_PREFERRED) { 4984 Slog.v(TAG, "Removing preferred activity since set changed " 4985 + pa.mPref.mComponent); 4986 } 4987 pir.removeFilter(pa); 4988 // Re-add the filter as a "last chosen" entry (!always) 4989 PreferredActivity lastChosen = new PreferredActivity( 4990 pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false); 4991 pir.addFilter(lastChosen); 4992 changed = true; 4993 return null; 4994 } 4995 4996 // Yay! Either the set matched or we're looking for the last chosen 4997 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: " 4998 + ri.activityInfo.packageName + "/" + ri.activityInfo.name); 4999 return ri; 5000 } 5001 } 5002 } finally { 5003 if (changed) { 5004 if (DEBUG_PREFERRED) { 5005 Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions"); 5006 } 5007 scheduleWritePackageRestrictionsLocked(userId); 5008 } 5009 } 5010 } 5011 } 5012 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return"); 5013 return null; 5014 } 5015 5016 /* 5017 * Returns if intent can be forwarded from the sourceUserId to the targetUserId 5018 */ 5019 @Override 5020 public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId, 5021 int targetUserId) { 5022 mContext.enforceCallingOrSelfPermission( 5023 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 5024 List<CrossProfileIntentFilter> matches = 5025 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId); 5026 if (matches != null) { 5027 int size = matches.size(); 5028 for (int i = 0; i < size; i++) { 5029 if (matches.get(i).getTargetUserId() == targetUserId) return true; 5030 } 5031 } 5032 if (hasWebURI(intent)) { 5033 // cross-profile app linking works only towards the parent. 5034 final UserInfo parent = getProfileParent(sourceUserId); 5035 synchronized(mPackages) { 5036 int flags = updateFlagsForResolve(0, parent.id, intent); 5037 CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr( 5038 intent, resolvedType, flags, sourceUserId, parent.id); 5039 return xpDomainInfo != null; 5040 } 5041 } 5042 return false; 5043 } 5044 5045 private UserInfo getProfileParent(int userId) { 5046 final long identity = Binder.clearCallingIdentity(); 5047 try { 5048 return sUserManager.getProfileParent(userId); 5049 } finally { 5050 Binder.restoreCallingIdentity(identity); 5051 } 5052 } 5053 5054 private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent, 5055 String resolvedType, int userId) { 5056 CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId); 5057 if (resolver != null) { 5058 return resolver.queryIntent(intent, resolvedType, false, userId); 5059 } 5060 return null; 5061 } 5062 5063 @Override 5064 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent, 5065 String resolvedType, int flags, int userId) { 5066 return new ParceledListSlice<>( 5067 queryIntentActivitiesInternal(intent, resolvedType, flags, userId)); 5068 } 5069 5070 private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, 5071 String resolvedType, int flags, int userId) { 5072 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5073 flags = updateFlagsForResolve(flags, userId, intent); 5074 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5075 false /* requireFullPermission */, false /* checkShell */, 5076 "query intent activities"); 5077 ComponentName comp = intent.getComponent(); 5078 if (comp == null) { 5079 if (intent.getSelector() != null) { 5080 intent = intent.getSelector(); 5081 comp = intent.getComponent(); 5082 } 5083 } 5084 5085 if (comp != null) { 5086 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5087 final ActivityInfo ai = getActivityInfo(comp, flags, userId); 5088 if (ai != null) { 5089 final ResolveInfo ri = new ResolveInfo(); 5090 ri.activityInfo = ai; 5091 list.add(ri); 5092 } 5093 return list; 5094 } 5095 5096 // reader 5097 synchronized (mPackages) { 5098 final String pkgName = intent.getPackage(); 5099 if (pkgName == null) { 5100 List<CrossProfileIntentFilter> matchingFilters = 5101 getMatchingCrossProfileIntentFilters(intent, resolvedType, userId); 5102 // Check for results that need to skip the current profile. 5103 ResolveInfo xpResolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent, 5104 resolvedType, flags, userId); 5105 if (xpResolveInfo != null) { 5106 List<ResolveInfo> result = new ArrayList<ResolveInfo>(1); 5107 result.add(xpResolveInfo); 5108 return filterIfNotSystemUser(result, userId); 5109 } 5110 5111 // Check for results in the current profile. 5112 List<ResolveInfo> result = mActivities.queryIntent( 5113 intent, resolvedType, flags, userId); 5114 result = filterIfNotSystemUser(result, userId); 5115 5116 // Check for cross profile results. 5117 boolean hasNonNegativePriorityResult = hasNonNegativePriority(result); 5118 xpResolveInfo = queryCrossProfileIntents( 5119 matchingFilters, intent, resolvedType, flags, userId, 5120 hasNonNegativePriorityResult); 5121 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) { 5122 boolean isVisibleToUser = filterIfNotSystemUser( 5123 Collections.singletonList(xpResolveInfo), userId).size() > 0; 5124 if (isVisibleToUser) { 5125 result.add(xpResolveInfo); 5126 Collections.sort(result, mResolvePrioritySorter); 5127 } 5128 } 5129 if (hasWebURI(intent)) { 5130 CrossProfileDomainInfo xpDomainInfo = null; 5131 final UserInfo parent = getProfileParent(userId); 5132 if (parent != null) { 5133 xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType, 5134 flags, userId, parent.id); 5135 } 5136 if (xpDomainInfo != null) { 5137 if (xpResolveInfo != null) { 5138 // If we didn't remove it, the cross-profile ResolveInfo would be twice 5139 // in the result. 5140 result.remove(xpResolveInfo); 5141 } 5142 if (result.size() == 0) { 5143 result.add(xpDomainInfo.resolveInfo); 5144 return result; 5145 } 5146 } else if (result.size() <= 1) { 5147 return result; 5148 } 5149 result = filterCandidatesWithDomainPreferredActivitiesLPr(intent, flags, result, 5150 xpDomainInfo, userId); 5151 Collections.sort(result, mResolvePrioritySorter); 5152 } 5153 return result; 5154 } 5155 final PackageParser.Package pkg = mPackages.get(pkgName); 5156 if (pkg != null) { 5157 return filterIfNotSystemUser( 5158 mActivities.queryIntentForPackage( 5159 intent, resolvedType, flags, pkg.activities, userId), 5160 userId); 5161 } 5162 return new ArrayList<ResolveInfo>(); 5163 } 5164 } 5165 5166 private static class CrossProfileDomainInfo { 5167 /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */ 5168 ResolveInfo resolveInfo; 5169 /* Best domain verification status of the activities found in the other profile */ 5170 int bestDomainVerificationStatus; 5171 } 5172 5173 private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent, 5174 String resolvedType, int flags, int sourceUserId, int parentUserId) { 5175 if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING, 5176 sourceUserId)) { 5177 return null; 5178 } 5179 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 5180 resolvedType, flags, parentUserId); 5181 5182 if (resultTargetUser == null || resultTargetUser.isEmpty()) { 5183 return null; 5184 } 5185 CrossProfileDomainInfo result = null; 5186 int size = resultTargetUser.size(); 5187 for (int i = 0; i < size; i++) { 5188 ResolveInfo riTargetUser = resultTargetUser.get(i); 5189 // Intent filter verification is only for filters that specify a host. So don't return 5190 // those that handle all web uris. 5191 if (riTargetUser.handleAllWebDataURI) { 5192 continue; 5193 } 5194 String packageName = riTargetUser.activityInfo.packageName; 5195 PackageSetting ps = mSettings.mPackages.get(packageName); 5196 if (ps == null) { 5197 continue; 5198 } 5199 long verificationState = getDomainVerificationStatusLPr(ps, parentUserId); 5200 int status = (int)(verificationState >> 32); 5201 if (result == null) { 5202 result = new CrossProfileDomainInfo(); 5203 result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(), 5204 sourceUserId, parentUserId); 5205 result.bestDomainVerificationStatus = status; 5206 } else { 5207 result.bestDomainVerificationStatus = bestDomainVerificationStatus(status, 5208 result.bestDomainVerificationStatus); 5209 } 5210 } 5211 // Don't consider matches with status NEVER across profiles. 5212 if (result != null && result.bestDomainVerificationStatus 5213 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5214 return null; 5215 } 5216 return result; 5217 } 5218 5219 /** 5220 * Verification statuses are ordered from the worse to the best, except for 5221 * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse. 5222 */ 5223 private int bestDomainVerificationStatus(int status1, int status2) { 5224 if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5225 return status2; 5226 } 5227 if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5228 return status1; 5229 } 5230 return (int) MathUtils.max(status1, status2); 5231 } 5232 5233 private boolean isUserEnabled(int userId) { 5234 long callingId = Binder.clearCallingIdentity(); 5235 try { 5236 UserInfo userInfo = sUserManager.getUserInfo(userId); 5237 return userInfo != null && userInfo.isEnabled(); 5238 } finally { 5239 Binder.restoreCallingIdentity(callingId); 5240 } 5241 } 5242 5243 /** 5244 * Filter out activities with systemUserOnly flag set, when current user is not System. 5245 * 5246 * @return filtered list 5247 */ 5248 private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) { 5249 if (userId == UserHandle.USER_SYSTEM) { 5250 return resolveInfos; 5251 } 5252 for (int i = resolveInfos.size() - 1; i >= 0; i--) { 5253 ResolveInfo info = resolveInfos.get(i); 5254 if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) { 5255 resolveInfos.remove(i); 5256 } 5257 } 5258 return resolveInfos; 5259 } 5260 5261 /** 5262 * @param resolveInfos list of resolve infos in descending priority order 5263 * @return if the list contains a resolve info with non-negative priority 5264 */ 5265 private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) { 5266 return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0; 5267 } 5268 5269 private static boolean hasWebURI(Intent intent) { 5270 if (intent.getData() == null) { 5271 return false; 5272 } 5273 final String scheme = intent.getScheme(); 5274 if (TextUtils.isEmpty(scheme)) { 5275 return false; 5276 } 5277 return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS); 5278 } 5279 5280 private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent, 5281 int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo, 5282 int userId) { 5283 final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0; 5284 5285 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) { 5286 Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " + 5287 candidates.size()); 5288 } 5289 5290 ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>(); 5291 ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>(); 5292 ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>(); 5293 ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>(); 5294 ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>(); 5295 ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>(); 5296 5297 synchronized (mPackages) { 5298 final int count = candidates.size(); 5299 // First, try to use linked apps. Partition the candidates into four lists: 5300 // one for the final results, one for the "do not use ever", one for "undefined status" 5301 // and finally one for "browser app type". 5302 for (int n=0; n<count; n++) { 5303 ResolveInfo info = candidates.get(n); 5304 String packageName = info.activityInfo.packageName; 5305 PackageSetting ps = mSettings.mPackages.get(packageName); 5306 if (ps != null) { 5307 // Add to the special match all list (Browser use case) 5308 if (info.handleAllWebDataURI) { 5309 matchAllList.add(info); 5310 continue; 5311 } 5312 // Try to get the status from User settings first 5313 long packedStatus = getDomainVerificationStatusLPr(ps, userId); 5314 int status = (int)(packedStatus >> 32); 5315 int linkGeneration = (int)(packedStatus & 0xFFFFFFFF); 5316 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) { 5317 if (DEBUG_DOMAIN_VERIFICATION) { 5318 Slog.i(TAG, " + always: " + info.activityInfo.packageName 5319 + " : linkgen=" + linkGeneration); 5320 } 5321 // Use link-enabled generation as preferredOrder, i.e. 5322 // prefer newly-enabled over earlier-enabled. 5323 info.preferredOrder = linkGeneration; 5324 alwaysList.add(info); 5325 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5326 if (DEBUG_DOMAIN_VERIFICATION) { 5327 Slog.i(TAG, " + never: " + info.activityInfo.packageName); 5328 } 5329 neverList.add(info); 5330 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) { 5331 if (DEBUG_DOMAIN_VERIFICATION) { 5332 Slog.i(TAG, " + always-ask: " + info.activityInfo.packageName); 5333 } 5334 alwaysAskList.add(info); 5335 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED || 5336 status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) { 5337 if (DEBUG_DOMAIN_VERIFICATION) { 5338 Slog.i(TAG, " + ask: " + info.activityInfo.packageName); 5339 } 5340 undefinedList.add(info); 5341 } 5342 } 5343 } 5344 5345 // We'll want to include browser possibilities in a few cases 5346 boolean includeBrowser = false; 5347 5348 // First try to add the "always" resolution(s) for the current user, if any 5349 if (alwaysList.size() > 0) { 5350 result.addAll(alwaysList); 5351 } else { 5352 // Add all undefined apps as we want them to appear in the disambiguation dialog. 5353 result.addAll(undefinedList); 5354 // Maybe add one for the other profile. 5355 if (xpDomainInfo != null && ( 5356 xpDomainInfo.bestDomainVerificationStatus 5357 != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) { 5358 result.add(xpDomainInfo.resolveInfo); 5359 } 5360 includeBrowser = true; 5361 } 5362 5363 // The presence of any 'always ask' alternatives means we'll also offer browsers. 5364 // If there were 'always' entries their preferred order has been set, so we also 5365 // back that off to make the alternatives equivalent 5366 if (alwaysAskList.size() > 0) { 5367 for (ResolveInfo i : result) { 5368 i.preferredOrder = 0; 5369 } 5370 result.addAll(alwaysAskList); 5371 includeBrowser = true; 5372 } 5373 5374 if (includeBrowser) { 5375 // Also add browsers (all of them or only the default one) 5376 if (DEBUG_DOMAIN_VERIFICATION) { 5377 Slog.v(TAG, " ...including browsers in candidate set"); 5378 } 5379 if ((matchFlags & MATCH_ALL) != 0) { 5380 result.addAll(matchAllList); 5381 } else { 5382 // Browser/generic handling case. If there's a default browser, go straight 5383 // to that (but only if there is no other higher-priority match). 5384 final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId); 5385 int maxMatchPrio = 0; 5386 ResolveInfo defaultBrowserMatch = null; 5387 final int numCandidates = matchAllList.size(); 5388 for (int n = 0; n < numCandidates; n++) { 5389 ResolveInfo info = matchAllList.get(n); 5390 // track the highest overall match priority... 5391 if (info.priority > maxMatchPrio) { 5392 maxMatchPrio = info.priority; 5393 } 5394 // ...and the highest-priority default browser match 5395 if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) { 5396 if (defaultBrowserMatch == null 5397 || (defaultBrowserMatch.priority < info.priority)) { 5398 if (debug) { 5399 Slog.v(TAG, "Considering default browser match " + info); 5400 } 5401 defaultBrowserMatch = info; 5402 } 5403 } 5404 } 5405 if (defaultBrowserMatch != null 5406 && defaultBrowserMatch.priority >= maxMatchPrio 5407 && !TextUtils.isEmpty(defaultBrowserPackageName)) 5408 { 5409 if (debug) { 5410 Slog.v(TAG, "Default browser match " + defaultBrowserMatch); 5411 } 5412 result.add(defaultBrowserMatch); 5413 } else { 5414 result.addAll(matchAllList); 5415 } 5416 } 5417 5418 // If there is nothing selected, add all candidates and remove the ones that the user 5419 // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state 5420 if (result.size() == 0) { 5421 result.addAll(candidates); 5422 result.removeAll(neverList); 5423 } 5424 } 5425 } 5426 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) { 5427 Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " + 5428 result.size()); 5429 for (ResolveInfo info : result) { 5430 Slog.v(TAG, " + " + info.activityInfo); 5431 } 5432 } 5433 return result; 5434 } 5435 5436 // Returns a packed value as a long: 5437 // 5438 // high 'int'-sized word: link status: undefined/ask/never/always. 5439 // low 'int'-sized word: relative priority among 'always' results. 5440 private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) { 5441 long result = ps.getDomainVerificationStatusForUser(userId); 5442 // if none available, get the master status 5443 if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 5444 if (ps.getIntentFilterVerificationInfo() != null) { 5445 result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32; 5446 } 5447 } 5448 return result; 5449 } 5450 5451 private ResolveInfo querySkipCurrentProfileIntents( 5452 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 5453 int flags, int sourceUserId) { 5454 if (matchingFilters != null) { 5455 int size = matchingFilters.size(); 5456 for (int i = 0; i < size; i ++) { 5457 CrossProfileIntentFilter filter = matchingFilters.get(i); 5458 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) { 5459 // Checking if there are activities in the target user that can handle the 5460 // intent. 5461 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent, 5462 resolvedType, flags, sourceUserId); 5463 if (resolveInfo != null) { 5464 return resolveInfo; 5465 } 5466 } 5467 } 5468 } 5469 return null; 5470 } 5471 5472 // Return matching ResolveInfo in target user if any. 5473 private ResolveInfo queryCrossProfileIntents( 5474 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 5475 int flags, int sourceUserId, boolean matchInCurrentProfile) { 5476 if (matchingFilters != null) { 5477 // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and 5478 // match the same intent. For performance reasons, it is better not to 5479 // run queryIntent twice for the same userId 5480 SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray(); 5481 int size = matchingFilters.size(); 5482 for (int i = 0; i < size; i++) { 5483 CrossProfileIntentFilter filter = matchingFilters.get(i); 5484 int targetUserId = filter.getTargetUserId(); 5485 boolean skipCurrentProfile = 5486 (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0; 5487 boolean skipCurrentProfileIfNoMatchFound = 5488 (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0; 5489 if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId) 5490 && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) { 5491 // Checking if there are activities in the target user that can handle the 5492 // intent. 5493 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent, 5494 resolvedType, flags, sourceUserId); 5495 if (resolveInfo != null) return resolveInfo; 5496 alreadyTriedUserIds.put(targetUserId, true); 5497 } 5498 } 5499 } 5500 return null; 5501 } 5502 5503 /** 5504 * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that 5505 * will forward the intent to the filter's target user. 5506 * Otherwise, returns null. 5507 */ 5508 private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent, 5509 String resolvedType, int flags, int sourceUserId) { 5510 int targetUserId = filter.getTargetUserId(); 5511 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 5512 resolvedType, flags, targetUserId); 5513 if (resultTargetUser != null && isUserEnabled(targetUserId)) { 5514 // If all the matches in the target profile are suspended, return null. 5515 for (int i = resultTargetUser.size() - 1; i >= 0; i--) { 5516 if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags 5517 & ApplicationInfo.FLAG_SUSPENDED) == 0) { 5518 return createForwardingResolveInfoUnchecked(filter, sourceUserId, 5519 targetUserId); 5520 } 5521 } 5522 } 5523 return null; 5524 } 5525 5526 private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter, 5527 int sourceUserId, int targetUserId) { 5528 ResolveInfo forwardingResolveInfo = new ResolveInfo(); 5529 long ident = Binder.clearCallingIdentity(); 5530 boolean targetIsProfile; 5531 try { 5532 targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile(); 5533 } finally { 5534 Binder.restoreCallingIdentity(ident); 5535 } 5536 String className; 5537 if (targetIsProfile) { 5538 className = FORWARD_INTENT_TO_MANAGED_PROFILE; 5539 } else { 5540 className = FORWARD_INTENT_TO_PARENT; 5541 } 5542 ComponentName forwardingActivityComponentName = new ComponentName( 5543 mAndroidApplication.packageName, className); 5544 ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0, 5545 sourceUserId); 5546 if (!targetIsProfile) { 5547 forwardingActivityInfo.showUserIcon = targetUserId; 5548 forwardingResolveInfo.noResourceId = true; 5549 } 5550 forwardingResolveInfo.activityInfo = forwardingActivityInfo; 5551 forwardingResolveInfo.priority = 0; 5552 forwardingResolveInfo.preferredOrder = 0; 5553 forwardingResolveInfo.match = 0; 5554 forwardingResolveInfo.isDefault = true; 5555 forwardingResolveInfo.filter = filter; 5556 forwardingResolveInfo.targetUserId = targetUserId; 5557 return forwardingResolveInfo; 5558 } 5559 5560 @Override 5561 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller, 5562 Intent[] specifics, String[] specificTypes, Intent intent, 5563 String resolvedType, int flags, int userId) { 5564 return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics, 5565 specificTypes, intent, resolvedType, flags, userId)); 5566 } 5567 5568 private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller, 5569 Intent[] specifics, String[] specificTypes, Intent intent, 5570 String resolvedType, int flags, int userId) { 5571 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5572 flags = updateFlagsForResolve(flags, userId, intent); 5573 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5574 false /* requireFullPermission */, false /* checkShell */, 5575 "query intent activity options"); 5576 final String resultsAction = intent.getAction(); 5577 5578 final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags 5579 | PackageManager.GET_RESOLVED_FILTER, userId); 5580 5581 if (DEBUG_INTENT_MATCHING) { 5582 Log.v(TAG, "Query " + intent + ": " + results); 5583 } 5584 5585 int specificsPos = 0; 5586 int N; 5587 5588 // todo: note that the algorithm used here is O(N^2). This 5589 // isn't a problem in our current environment, but if we start running 5590 // into situations where we have more than 5 or 10 matches then this 5591 // should probably be changed to something smarter... 5592 5593 // First we go through and resolve each of the specific items 5594 // that were supplied, taking care of removing any corresponding 5595 // duplicate items in the generic resolve list. 5596 if (specifics != null) { 5597 for (int i=0; i<specifics.length; i++) { 5598 final Intent sintent = specifics[i]; 5599 if (sintent == null) { 5600 continue; 5601 } 5602 5603 if (DEBUG_INTENT_MATCHING) { 5604 Log.v(TAG, "Specific #" + i + ": " + sintent); 5605 } 5606 5607 String action = sintent.getAction(); 5608 if (resultsAction != null && resultsAction.equals(action)) { 5609 // If this action was explicitly requested, then don't 5610 // remove things that have it. 5611 action = null; 5612 } 5613 5614 ResolveInfo ri = null; 5615 ActivityInfo ai = null; 5616 5617 ComponentName comp = sintent.getComponent(); 5618 if (comp == null) { 5619 ri = resolveIntent( 5620 sintent, 5621 specificTypes != null ? specificTypes[i] : null, 5622 flags, userId); 5623 if (ri == null) { 5624 continue; 5625 } 5626 if (ri == mResolveInfo) { 5627 // ACK! Must do something better with this. 5628 } 5629 ai = ri.activityInfo; 5630 comp = new ComponentName(ai.applicationInfo.packageName, 5631 ai.name); 5632 } else { 5633 ai = getActivityInfo(comp, flags, userId); 5634 if (ai == null) { 5635 continue; 5636 } 5637 } 5638 5639 // Look for any generic query activities that are duplicates 5640 // of this specific one, and remove them from the results. 5641 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai); 5642 N = results.size(); 5643 int j; 5644 for (j=specificsPos; j<N; j++) { 5645 ResolveInfo sri = results.get(j); 5646 if ((sri.activityInfo.name.equals(comp.getClassName()) 5647 && sri.activityInfo.applicationInfo.packageName.equals( 5648 comp.getPackageName())) 5649 || (action != null && sri.filter.matchAction(action))) { 5650 results.remove(j); 5651 if (DEBUG_INTENT_MATCHING) Log.v( 5652 TAG, "Removing duplicate item from " + j 5653 + " due to specific " + specificsPos); 5654 if (ri == null) { 5655 ri = sri; 5656 } 5657 j--; 5658 N--; 5659 } 5660 } 5661 5662 // Add this specific item to its proper place. 5663 if (ri == null) { 5664 ri = new ResolveInfo(); 5665 ri.activityInfo = ai; 5666 } 5667 results.add(specificsPos, ri); 5668 ri.specificIndex = i; 5669 specificsPos++; 5670 } 5671 } 5672 5673 // Now we go through the remaining generic results and remove any 5674 // duplicate actions that are found here. 5675 N = results.size(); 5676 for (int i=specificsPos; i<N-1; i++) { 5677 final ResolveInfo rii = results.get(i); 5678 if (rii.filter == null) { 5679 continue; 5680 } 5681 5682 // Iterate over all of the actions of this result's intent 5683 // filter... typically this should be just one. 5684 final Iterator<String> it = rii.filter.actionsIterator(); 5685 if (it == null) { 5686 continue; 5687 } 5688 while (it.hasNext()) { 5689 final String action = it.next(); 5690 if (resultsAction != null && resultsAction.equals(action)) { 5691 // If this action was explicitly requested, then don't 5692 // remove things that have it. 5693 continue; 5694 } 5695 for (int j=i+1; j<N; j++) { 5696 final ResolveInfo rij = results.get(j); 5697 if (rij.filter != null && rij.filter.hasAction(action)) { 5698 results.remove(j); 5699 if (DEBUG_INTENT_MATCHING) Log.v( 5700 TAG, "Removing duplicate item from " + j 5701 + " due to action " + action + " at " + i); 5702 j--; 5703 N--; 5704 } 5705 } 5706 } 5707 5708 // If the caller didn't request filter information, drop it now 5709 // so we don't have to marshall/unmarshall it. 5710 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 5711 rii.filter = null; 5712 } 5713 } 5714 5715 // Filter out the caller activity if so requested. 5716 if (caller != null) { 5717 N = results.size(); 5718 for (int i=0; i<N; i++) { 5719 ActivityInfo ainfo = results.get(i).activityInfo; 5720 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName) 5721 && caller.getClassName().equals(ainfo.name)) { 5722 results.remove(i); 5723 break; 5724 } 5725 } 5726 } 5727 5728 // If the caller didn't request filter information, 5729 // drop them now so we don't have to 5730 // marshall/unmarshall it. 5731 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 5732 N = results.size(); 5733 for (int i=0; i<N; i++) { 5734 results.get(i).filter = null; 5735 } 5736 } 5737 5738 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results); 5739 return results; 5740 } 5741 5742 @Override 5743 public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent, 5744 String resolvedType, int flags, int userId) { 5745 return new ParceledListSlice<>( 5746 queryIntentReceiversInternal(intent, resolvedType, flags, userId)); 5747 } 5748 5749 private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent, 5750 String resolvedType, int flags, int userId) { 5751 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5752 flags = updateFlagsForResolve(flags, userId, intent); 5753 ComponentName comp = intent.getComponent(); 5754 if (comp == null) { 5755 if (intent.getSelector() != null) { 5756 intent = intent.getSelector(); 5757 comp = intent.getComponent(); 5758 } 5759 } 5760 if (comp != null) { 5761 List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5762 ActivityInfo ai = getReceiverInfo(comp, flags, userId); 5763 if (ai != null) { 5764 ResolveInfo ri = new ResolveInfo(); 5765 ri.activityInfo = ai; 5766 list.add(ri); 5767 } 5768 return list; 5769 } 5770 5771 // reader 5772 synchronized (mPackages) { 5773 String pkgName = intent.getPackage(); 5774 if (pkgName == null) { 5775 return mReceivers.queryIntent(intent, resolvedType, flags, userId); 5776 } 5777 final PackageParser.Package pkg = mPackages.get(pkgName); 5778 if (pkg != null) { 5779 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers, 5780 userId); 5781 } 5782 return Collections.emptyList(); 5783 } 5784 } 5785 5786 @Override 5787 public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) { 5788 if (!sUserManager.exists(userId)) return null; 5789 flags = updateFlagsForResolve(flags, userId, intent); 5790 List<ResolveInfo> query = queryIntentServicesInternal(intent, resolvedType, flags, userId); 5791 if (query != null) { 5792 if (query.size() >= 1) { 5793 // If there is more than one service with the same priority, 5794 // just arbitrarily pick the first one. 5795 return query.get(0); 5796 } 5797 } 5798 return null; 5799 } 5800 5801 @Override 5802 public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent, 5803 String resolvedType, int flags, int userId) { 5804 return new ParceledListSlice<>( 5805 queryIntentServicesInternal(intent, resolvedType, flags, userId)); 5806 } 5807 5808 private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent, 5809 String resolvedType, int flags, int userId) { 5810 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5811 flags = updateFlagsForResolve(flags, userId, intent); 5812 ComponentName comp = intent.getComponent(); 5813 if (comp == null) { 5814 if (intent.getSelector() != null) { 5815 intent = intent.getSelector(); 5816 comp = intent.getComponent(); 5817 } 5818 } 5819 if (comp != null) { 5820 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5821 final ServiceInfo si = getServiceInfo(comp, flags, userId); 5822 if (si != null) { 5823 final ResolveInfo ri = new ResolveInfo(); 5824 ri.serviceInfo = si; 5825 list.add(ri); 5826 } 5827 return list; 5828 } 5829 5830 // reader 5831 synchronized (mPackages) { 5832 String pkgName = intent.getPackage(); 5833 if (pkgName == null) { 5834 return mServices.queryIntent(intent, resolvedType, flags, userId); 5835 } 5836 final PackageParser.Package pkg = mPackages.get(pkgName); 5837 if (pkg != null) { 5838 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services, 5839 userId); 5840 } 5841 return Collections.emptyList(); 5842 } 5843 } 5844 5845 @Override 5846 public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent, 5847 String resolvedType, int flags, int userId) { 5848 return new ParceledListSlice<>( 5849 queryIntentContentProvidersInternal(intent, resolvedType, flags, userId)); 5850 } 5851 5852 private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal( 5853 Intent intent, String resolvedType, int flags, int userId) { 5854 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5855 flags = updateFlagsForResolve(flags, userId, intent); 5856 ComponentName comp = intent.getComponent(); 5857 if (comp == null) { 5858 if (intent.getSelector() != null) { 5859 intent = intent.getSelector(); 5860 comp = intent.getComponent(); 5861 } 5862 } 5863 if (comp != null) { 5864 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5865 final ProviderInfo pi = getProviderInfo(comp, flags, userId); 5866 if (pi != null) { 5867 final ResolveInfo ri = new ResolveInfo(); 5868 ri.providerInfo = pi; 5869 list.add(ri); 5870 } 5871 return list; 5872 } 5873 5874 // reader 5875 synchronized (mPackages) { 5876 String pkgName = intent.getPackage(); 5877 if (pkgName == null) { 5878 return mProviders.queryIntent(intent, resolvedType, flags, userId); 5879 } 5880 final PackageParser.Package pkg = mPackages.get(pkgName); 5881 if (pkg != null) { 5882 return mProviders.queryIntentForPackage( 5883 intent, resolvedType, flags, pkg.providers, userId); 5884 } 5885 return Collections.emptyList(); 5886 } 5887 } 5888 5889 @Override 5890 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) { 5891 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 5892 flags = updateFlagsForPackage(flags, userId, null); 5893 final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0; 5894 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5895 true /* requireFullPermission */, false /* checkShell */, 5896 "get installed packages"); 5897 5898 // writer 5899 synchronized (mPackages) { 5900 ArrayList<PackageInfo> list; 5901 if (listUninstalled) { 5902 list = new ArrayList<PackageInfo>(mSettings.mPackages.size()); 5903 for (PackageSetting ps : mSettings.mPackages.values()) { 5904 PackageInfo pi; 5905 if (ps.pkg != null) { 5906 pi = generatePackageInfo(ps.pkg, flags, userId); 5907 } else { 5908 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId); 5909 } 5910 if (pi != null) { 5911 list.add(pi); 5912 } 5913 } 5914 } else { 5915 list = new ArrayList<PackageInfo>(mPackages.size()); 5916 for (PackageParser.Package p : mPackages.values()) { 5917 PackageInfo pi = generatePackageInfo(p, flags, userId); 5918 if (pi != null) { 5919 list.add(pi); 5920 } 5921 } 5922 } 5923 5924 return new ParceledListSlice<PackageInfo>(list); 5925 } 5926 } 5927 5928 private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps, 5929 String[] permissions, boolean[] tmp, int flags, int userId) { 5930 int numMatch = 0; 5931 final PermissionsState permissionsState = ps.getPermissionsState(); 5932 for (int i=0; i<permissions.length; i++) { 5933 final String permission = permissions[i]; 5934 if (permissionsState.hasPermission(permission, userId)) { 5935 tmp[i] = true; 5936 numMatch++; 5937 } else { 5938 tmp[i] = false; 5939 } 5940 } 5941 if (numMatch == 0) { 5942 return; 5943 } 5944 PackageInfo pi; 5945 if (ps.pkg != null) { 5946 pi = generatePackageInfo(ps.pkg, flags, userId); 5947 } else { 5948 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId); 5949 } 5950 // The above might return null in cases of uninstalled apps or install-state 5951 // skew across users/profiles. 5952 if (pi != null) { 5953 if ((flags&PackageManager.GET_PERMISSIONS) == 0) { 5954 if (numMatch == permissions.length) { 5955 pi.requestedPermissions = permissions; 5956 } else { 5957 pi.requestedPermissions = new String[numMatch]; 5958 numMatch = 0; 5959 for (int i=0; i<permissions.length; i++) { 5960 if (tmp[i]) { 5961 pi.requestedPermissions[numMatch] = permissions[i]; 5962 numMatch++; 5963 } 5964 } 5965 } 5966 } 5967 list.add(pi); 5968 } 5969 } 5970 5971 @Override 5972 public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions( 5973 String[] permissions, int flags, int userId) { 5974 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 5975 flags = updateFlagsForPackage(flags, userId, permissions); 5976 final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0; 5977 5978 // writer 5979 synchronized (mPackages) { 5980 ArrayList<PackageInfo> list = new ArrayList<PackageInfo>(); 5981 boolean[] tmpBools = new boolean[permissions.length]; 5982 if (listUninstalled) { 5983 for (PackageSetting ps : mSettings.mPackages.values()) { 5984 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId); 5985 } 5986 } else { 5987 for (PackageParser.Package pkg : mPackages.values()) { 5988 PackageSetting ps = (PackageSetting)pkg.mExtras; 5989 if (ps != null) { 5990 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, 5991 userId); 5992 } 5993 } 5994 } 5995 5996 return new ParceledListSlice<PackageInfo>(list); 5997 } 5998 } 5999 6000 @Override 6001 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) { 6002 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 6003 flags = updateFlagsForApplication(flags, userId, null); 6004 final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0; 6005 6006 // writer 6007 synchronized (mPackages) { 6008 ArrayList<ApplicationInfo> list; 6009 if (listUninstalled) { 6010 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size()); 6011 for (PackageSetting ps : mSettings.mPackages.values()) { 6012 ApplicationInfo ai; 6013 if (ps.pkg != null) { 6014 ai = PackageParser.generateApplicationInfo(ps.pkg, flags, 6015 ps.readUserState(userId), userId); 6016 } else { 6017 ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId); 6018 } 6019 if (ai != null) { 6020 list.add(ai); 6021 } 6022 } 6023 } else { 6024 list = new ArrayList<ApplicationInfo>(mPackages.size()); 6025 for (PackageParser.Package p : mPackages.values()) { 6026 if (p.mExtras != null) { 6027 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 6028 ((PackageSetting)p.mExtras).readUserState(userId), userId); 6029 if (ai != null) { 6030 list.add(ai); 6031 } 6032 } 6033 } 6034 } 6035 6036 return new ParceledListSlice<ApplicationInfo>(list); 6037 } 6038 } 6039 6040 @Override 6041 public ParceledListSlice<EphemeralApplicationInfo> getEphemeralApplications(int userId) { 6042 if (DISABLE_EPHEMERAL_APPS) { 6043 return null; 6044 } 6045 6046 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS, 6047 "getEphemeralApplications"); 6048 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6049 true /* requireFullPermission */, false /* checkShell */, 6050 "getEphemeralApplications"); 6051 synchronized (mPackages) { 6052 List<EphemeralApplicationInfo> ephemeralApps = mEphemeralApplicationRegistry 6053 .getEphemeralApplicationsLPw(userId); 6054 if (ephemeralApps != null) { 6055 return new ParceledListSlice<>(ephemeralApps); 6056 } 6057 } 6058 return null; 6059 } 6060 6061 @Override 6062 public boolean isEphemeralApplication(String packageName, int userId) { 6063 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6064 true /* requireFullPermission */, false /* checkShell */, 6065 "isEphemeral"); 6066 if (DISABLE_EPHEMERAL_APPS) { 6067 return false; 6068 } 6069 6070 if (!isCallerSameApp(packageName)) { 6071 return false; 6072 } 6073 synchronized (mPackages) { 6074 PackageParser.Package pkg = mPackages.get(packageName); 6075 if (pkg != null) { 6076 return pkg.applicationInfo.isEphemeralApp(); 6077 } 6078 } 6079 return false; 6080 } 6081 6082 @Override 6083 public byte[] getEphemeralApplicationCookie(String packageName, int userId) { 6084 if (DISABLE_EPHEMERAL_APPS) { 6085 return null; 6086 } 6087 6088 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6089 true /* requireFullPermission */, false /* checkShell */, 6090 "getCookie"); 6091 if (!isCallerSameApp(packageName)) { 6092 return null; 6093 } 6094 synchronized (mPackages) { 6095 return mEphemeralApplicationRegistry.getEphemeralApplicationCookieLPw( 6096 packageName, userId); 6097 } 6098 } 6099 6100 @Override 6101 public boolean setEphemeralApplicationCookie(String packageName, byte[] cookie, int userId) { 6102 if (DISABLE_EPHEMERAL_APPS) { 6103 return true; 6104 } 6105 6106 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6107 true /* requireFullPermission */, true /* checkShell */, 6108 "setCookie"); 6109 if (!isCallerSameApp(packageName)) { 6110 return false; 6111 } 6112 synchronized (mPackages) { 6113 return mEphemeralApplicationRegistry.setEphemeralApplicationCookieLPw( 6114 packageName, cookie, userId); 6115 } 6116 } 6117 6118 @Override 6119 public Bitmap getEphemeralApplicationIcon(String packageName, int userId) { 6120 if (DISABLE_EPHEMERAL_APPS) { 6121 return null; 6122 } 6123 6124 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS, 6125 "getEphemeralApplicationIcon"); 6126 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6127 true /* requireFullPermission */, false /* checkShell */, 6128 "getEphemeralApplicationIcon"); 6129 synchronized (mPackages) { 6130 return mEphemeralApplicationRegistry.getEphemeralApplicationIconLPw( 6131 packageName, userId); 6132 } 6133 } 6134 6135 private boolean isCallerSameApp(String packageName) { 6136 PackageParser.Package pkg = mPackages.get(packageName); 6137 return pkg != null 6138 && UserHandle.getAppId(Binder.getCallingUid()) == pkg.applicationInfo.uid; 6139 } 6140 6141 @Override 6142 public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) { 6143 return new ParceledListSlice<>(getPersistentApplicationsInternal(flags)); 6144 } 6145 6146 private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) { 6147 final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>(); 6148 6149 // reader 6150 synchronized (mPackages) { 6151 final Iterator<PackageParser.Package> i = mPackages.values().iterator(); 6152 final int userId = UserHandle.getCallingUserId(); 6153 while (i.hasNext()) { 6154 final PackageParser.Package p = i.next(); 6155 if (p.applicationInfo == null) continue; 6156 6157 final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0) 6158 && !p.applicationInfo.isDirectBootAware(); 6159 final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0) 6160 && p.applicationInfo.isDirectBootAware(); 6161 6162 if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0 6163 && (!mSafeMode || isSystemApp(p)) 6164 && (matchesUnaware || matchesAware)) { 6165 PackageSetting ps = mSettings.mPackages.get(p.packageName); 6166 if (ps != null) { 6167 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 6168 ps.readUserState(userId), userId); 6169 if (ai != null) { 6170 finalList.add(ai); 6171 } 6172 } 6173 } 6174 } 6175 } 6176 6177 return finalList; 6178 } 6179 6180 @Override 6181 public ProviderInfo resolveContentProvider(String name, int flags, int userId) { 6182 if (!sUserManager.exists(userId)) return null; 6183 flags = updateFlagsForComponent(flags, userId, name); 6184 // reader 6185 synchronized (mPackages) { 6186 final PackageParser.Provider provider = mProvidersByAuthority.get(name); 6187 PackageSetting ps = provider != null 6188 ? mSettings.mPackages.get(provider.owner.packageName) 6189 : null; 6190 return ps != null 6191 && mSettings.isEnabledAndMatchLPr(provider.info, flags, userId) 6192 ? PackageParser.generateProviderInfo(provider, flags, 6193 ps.readUserState(userId), userId) 6194 : null; 6195 } 6196 } 6197 6198 /** 6199 * @deprecated 6200 */ 6201 @Deprecated 6202 public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) { 6203 // reader 6204 synchronized (mPackages) { 6205 final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority 6206 .entrySet().iterator(); 6207 final int userId = UserHandle.getCallingUserId(); 6208 while (i.hasNext()) { 6209 Map.Entry<String, PackageParser.Provider> entry = i.next(); 6210 PackageParser.Provider p = entry.getValue(); 6211 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 6212 6213 if (ps != null && p.syncable 6214 && (!mSafeMode || (p.info.applicationInfo.flags 6215 &ApplicationInfo.FLAG_SYSTEM) != 0)) { 6216 ProviderInfo info = PackageParser.generateProviderInfo(p, 0, 6217 ps.readUserState(userId), userId); 6218 if (info != null) { 6219 outNames.add(entry.getKey()); 6220 outInfo.add(info); 6221 } 6222 } 6223 } 6224 } 6225 } 6226 6227 @Override 6228 public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName, 6229 int uid, int flags) { 6230 final int userId = processName != null ? UserHandle.getUserId(uid) 6231 : UserHandle.getCallingUserId(); 6232 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 6233 flags = updateFlagsForComponent(flags, userId, processName); 6234 6235 ArrayList<ProviderInfo> finalList = null; 6236 // reader 6237 synchronized (mPackages) { 6238 final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator(); 6239 while (i.hasNext()) { 6240 final PackageParser.Provider p = i.next(); 6241 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 6242 if (ps != null && p.info.authority != null 6243 && (processName == null 6244 || (p.info.processName.equals(processName) 6245 && UserHandle.isSameApp(p.info.applicationInfo.uid, uid))) 6246 && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) { 6247 if (finalList == null) { 6248 finalList = new ArrayList<ProviderInfo>(3); 6249 } 6250 ProviderInfo info = PackageParser.generateProviderInfo(p, flags, 6251 ps.readUserState(userId), userId); 6252 if (info != null) { 6253 finalList.add(info); 6254 } 6255 } 6256 } 6257 } 6258 6259 if (finalList != null) { 6260 Collections.sort(finalList, mProviderInitOrderSorter); 6261 return new ParceledListSlice<ProviderInfo>(finalList); 6262 } 6263 6264 return ParceledListSlice.emptyList(); 6265 } 6266 6267 @Override 6268 public InstrumentationInfo getInstrumentationInfo(ComponentName name, int flags) { 6269 // reader 6270 synchronized (mPackages) { 6271 final PackageParser.Instrumentation i = mInstrumentation.get(name); 6272 return PackageParser.generateInstrumentationInfo(i, flags); 6273 } 6274 } 6275 6276 @Override 6277 public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation( 6278 String targetPackage, int flags) { 6279 return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags)); 6280 } 6281 6282 private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage, 6283 int flags) { 6284 ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>(); 6285 6286 // reader 6287 synchronized (mPackages) { 6288 final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator(); 6289 while (i.hasNext()) { 6290 final PackageParser.Instrumentation p = i.next(); 6291 if (targetPackage == null 6292 || targetPackage.equals(p.info.targetPackage)) { 6293 InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p, 6294 flags); 6295 if (ii != null) { 6296 finalList.add(ii); 6297 } 6298 } 6299 } 6300 } 6301 6302 return finalList; 6303 } 6304 6305 private void createIdmapsForPackageLI(PackageParser.Package pkg) { 6306 ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName); 6307 if (overlays == null) { 6308 Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages"); 6309 return; 6310 } 6311 for (PackageParser.Package opkg : overlays.values()) { 6312 // Not much to do if idmap fails: we already logged the error 6313 // and we certainly don't want to abort installation of pkg simply 6314 // because an overlay didn't fit properly. For these reasons, 6315 // ignore the return value of createIdmapForPackagePairLI. 6316 createIdmapForPackagePairLI(pkg, opkg); 6317 } 6318 } 6319 6320 private boolean createIdmapForPackagePairLI(PackageParser.Package pkg, 6321 PackageParser.Package opkg) { 6322 if (!opkg.mTrustedOverlay) { 6323 Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " + 6324 opkg.baseCodePath + ": overlay not trusted"); 6325 return false; 6326 } 6327 ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName); 6328 if (overlaySet == null) { 6329 Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " + 6330 opkg.baseCodePath + " but target package has no known overlays"); 6331 return false; 6332 } 6333 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 6334 // TODO: generate idmap for split APKs 6335 try { 6336 mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid); 6337 } catch (InstallerException e) { 6338 Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and " 6339 + opkg.baseCodePath); 6340 return false; 6341 } 6342 PackageParser.Package[] overlayArray = 6343 overlaySet.values().toArray(new PackageParser.Package[0]); 6344 Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() { 6345 public int compare(PackageParser.Package p1, PackageParser.Package p2) { 6346 return p1.mOverlayPriority - p2.mOverlayPriority; 6347 } 6348 }; 6349 Arrays.sort(overlayArray, cmp); 6350 6351 pkg.applicationInfo.resourceDirs = new String[overlayArray.length]; 6352 int i = 0; 6353 for (PackageParser.Package p : overlayArray) { 6354 pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath; 6355 } 6356 return true; 6357 } 6358 6359 private void scanDirTracedLI(File dir, int parseFlags, int scanFlags, long currentTime) { 6360 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir"); 6361 try { 6362 scanDirLI(dir, parseFlags, scanFlags, currentTime); 6363 } finally { 6364 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6365 } 6366 } 6367 6368 private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) { 6369 final File[] files = dir.listFiles(); 6370 if (ArrayUtils.isEmpty(files)) { 6371 Log.d(TAG, "No files in app dir " + dir); 6372 return; 6373 } 6374 6375 if (DEBUG_PACKAGE_SCANNING) { 6376 Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags 6377 + " flags=0x" + Integer.toHexString(parseFlags)); 6378 } 6379 6380 for (File file : files) { 6381 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 6382 && !PackageInstallerService.isStageName(file.getName()); 6383 if (!isPackage) { 6384 // Ignore entries which are not packages 6385 continue; 6386 } 6387 try { 6388 scanPackageTracedLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK, 6389 scanFlags, currentTime, null); 6390 } catch (PackageManagerException e) { 6391 Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage()); 6392 6393 // Delete invalid userdata apps 6394 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 && 6395 e.error == PackageManager.INSTALL_FAILED_INVALID_APK) { 6396 logCriticalInfo(Log.WARN, "Deleting invalid package at " + file); 6397 removeCodePathLI(file); 6398 } 6399 } 6400 } 6401 } 6402 6403 private static File getSettingsProblemFile() { 6404 File dataDir = Environment.getDataDirectory(); 6405 File systemDir = new File(dataDir, "system"); 6406 File fname = new File(systemDir, "uiderrors.txt"); 6407 return fname; 6408 } 6409 6410 static void reportSettingsProblem(int priority, String msg) { 6411 logCriticalInfo(priority, msg); 6412 } 6413 6414 static void logCriticalInfo(int priority, String msg) { 6415 Slog.println(priority, TAG, msg); 6416 EventLogTags.writePmCriticalInfo(msg); 6417 try { 6418 File fname = getSettingsProblemFile(); 6419 FileOutputStream out = new FileOutputStream(fname, true); 6420 PrintWriter pw = new FastPrintWriter(out); 6421 SimpleDateFormat formatter = new SimpleDateFormat(); 6422 String dateString = formatter.format(new Date(System.currentTimeMillis())); 6423 pw.println(dateString + ": " + msg); 6424 pw.close(); 6425 FileUtils.setPermissions( 6426 fname.toString(), 6427 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH, 6428 -1, -1); 6429 } catch (java.io.IOException e) { 6430 } 6431 } 6432 6433 private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile, 6434 int parseFlags) throws PackageManagerException { 6435 if (ps != null 6436 && ps.codePath.equals(srcFile) 6437 && ps.timeStamp == srcFile.lastModified() 6438 && !isCompatSignatureUpdateNeeded(pkg) 6439 && !isRecoverSignatureUpdateNeeded(pkg)) { 6440 long mSigningKeySetId = ps.keySetData.getProperSigningKeySet(); 6441 KeySetManagerService ksms = mSettings.mKeySetManagerService; 6442 ArraySet<PublicKey> signingKs; 6443 synchronized (mPackages) { 6444 signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId); 6445 } 6446 if (ps.signatures.mSignatures != null 6447 && ps.signatures.mSignatures.length != 0 6448 && signingKs != null) { 6449 // Optimization: reuse the existing cached certificates 6450 // if the package appears to be unchanged. 6451 pkg.mSignatures = ps.signatures.mSignatures; 6452 pkg.mSigningKeys = signingKs; 6453 return; 6454 } 6455 6456 Slog.w(TAG, "PackageSetting for " + ps.name 6457 + " is missing signatures. Collecting certs again to recover them."); 6458 } else { 6459 Log.i(TAG, srcFile.toString() + " changed; collecting certs"); 6460 } 6461 6462 try { 6463 PackageParser.collectCertificates(pkg, parseFlags); 6464 } catch (PackageParserException e) { 6465 throw PackageManagerException.from(e); 6466 } 6467 } 6468 6469 /** 6470 * Traces a package scan. 6471 * @see #scanPackageLI(File, int, int, long, UserHandle) 6472 */ 6473 private PackageParser.Package scanPackageTracedLI(File scanFile, int parseFlags, int scanFlags, 6474 long currentTime, UserHandle user) throws PackageManagerException { 6475 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage"); 6476 try { 6477 return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user); 6478 } finally { 6479 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6480 } 6481 } 6482 6483 /** 6484 * Scans a package and returns the newly parsed package. 6485 * Returns {@code null} in case of errors and the error code is stored in mLastScanError 6486 */ 6487 private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags, 6488 long currentTime, UserHandle user) throws PackageManagerException { 6489 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile); 6490 parseFlags |= mDefParseFlags; 6491 PackageParser pp = new PackageParser(); 6492 pp.setSeparateProcesses(mSeparateProcesses); 6493 pp.setOnlyCoreApps(mOnlyCore); 6494 pp.setDisplayMetrics(mMetrics); 6495 6496 if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) { 6497 parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY; 6498 } 6499 6500 final PackageParser.Package pkg; 6501 try { 6502 pkg = pp.parsePackage(scanFile, parseFlags); 6503 } catch (PackageParserException e) { 6504 throw PackageManagerException.from(e); 6505 } 6506 6507 return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user); 6508 } 6509 6510 /** 6511 * Scans a package and returns the newly parsed package. 6512 * @throws PackageManagerException on a parse error. 6513 */ 6514 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile, 6515 int parseFlags, int scanFlags, long currentTime, UserHandle user) 6516 throws PackageManagerException { 6517 // If the package has children and this is the first dive in the function 6518 // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all 6519 // packages (parent and children) would be successfully scanned before the 6520 // actual scan since scanning mutates internal state and we want to atomically 6521 // install the package and its children. 6522 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 6523 if (pkg.childPackages != null && pkg.childPackages.size() > 0) { 6524 scanFlags |= SCAN_CHECK_ONLY; 6525 } 6526 } else { 6527 scanFlags &= ~SCAN_CHECK_ONLY; 6528 } 6529 6530 // Scan the parent 6531 PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, parseFlags, 6532 scanFlags, currentTime, user); 6533 6534 // Scan the children 6535 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 6536 for (int i = 0; i < childCount; i++) { 6537 PackageParser.Package childPackage = pkg.childPackages.get(i); 6538 scanPackageInternalLI(childPackage, scanFile, parseFlags, scanFlags, 6539 currentTime, user); 6540 } 6541 6542 6543 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 6544 return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user); 6545 } 6546 6547 return scannedPkg; 6548 } 6549 6550 /** 6551 * Scans a package and returns the newly parsed package. 6552 * @throws PackageManagerException on a parse error. 6553 */ 6554 private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile, 6555 int parseFlags, int scanFlags, long currentTime, UserHandle user) 6556 throws PackageManagerException { 6557 PackageSetting ps = null; 6558 PackageSetting updatedPkg; 6559 // reader 6560 synchronized (mPackages) { 6561 // Look to see if we already know about this package. 6562 String oldName = mSettings.mRenamedPackages.get(pkg.packageName); 6563 if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) { 6564 // This package has been renamed to its original name. Let's 6565 // use that. 6566 ps = mSettings.peekPackageLPr(oldName); 6567 } 6568 // If there was no original package, see one for the real package name. 6569 if (ps == null) { 6570 ps = mSettings.peekPackageLPr(pkg.packageName); 6571 } 6572 // Check to see if this package could be hiding/updating a system 6573 // package. Must look for it either under the original or real 6574 // package name depending on our state. 6575 updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName); 6576 if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg); 6577 6578 // If this is a package we don't know about on the system partition, we 6579 // may need to remove disabled child packages on the system partition 6580 // or may need to not add child packages if the parent apk is updated 6581 // on the data partition and no longer defines this child package. 6582 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) != 0) { 6583 // If this is a parent package for an updated system app and this system 6584 // app got an OTA update which no longer defines some of the child packages 6585 // we have to prune them from the disabled system packages. 6586 PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName); 6587 if (disabledPs != null) { 6588 final int scannedChildCount = (pkg.childPackages != null) 6589 ? pkg.childPackages.size() : 0; 6590 final int disabledChildCount = disabledPs.childPackageNames != null 6591 ? disabledPs.childPackageNames.size() : 0; 6592 for (int i = 0; i < disabledChildCount; i++) { 6593 String disabledChildPackageName = disabledPs.childPackageNames.get(i); 6594 boolean disabledPackageAvailable = false; 6595 for (int j = 0; j < scannedChildCount; j++) { 6596 PackageParser.Package childPkg = pkg.childPackages.get(j); 6597 if (childPkg.packageName.equals(disabledChildPackageName)) { 6598 disabledPackageAvailable = true; 6599 break; 6600 } 6601 } 6602 if (!disabledPackageAvailable) { 6603 mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName); 6604 } 6605 } 6606 } 6607 } 6608 } 6609 6610 boolean updatedPkgBetter = false; 6611 // First check if this is a system package that may involve an update 6612 if (updatedPkg != null && (parseFlags & PackageParser.PARSE_IS_SYSTEM) != 0) { 6613 // If new package is not located in "/system/priv-app" (e.g. due to an OTA), 6614 // it needs to drop FLAG_PRIVILEGED. 6615 if (locationIsPrivileged(scanFile)) { 6616 updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 6617 } else { 6618 updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 6619 } 6620 6621 if (ps != null && !ps.codePath.equals(scanFile)) { 6622 // The path has changed from what was last scanned... check the 6623 // version of the new path against what we have stored to determine 6624 // what to do. 6625 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath); 6626 if (pkg.mVersionCode <= ps.versionCode) { 6627 // The system package has been updated and the code path does not match 6628 // Ignore entry. Skip it. 6629 if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile 6630 + " ignored: updated version " + ps.versionCode 6631 + " better than this " + pkg.mVersionCode); 6632 if (!updatedPkg.codePath.equals(scanFile)) { 6633 Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg " 6634 + ps.name + " changing from " + updatedPkg.codePathString 6635 + " to " + scanFile); 6636 updatedPkg.codePath = scanFile; 6637 updatedPkg.codePathString = scanFile.toString(); 6638 updatedPkg.resourcePath = scanFile; 6639 updatedPkg.resourcePathString = scanFile.toString(); 6640 } 6641 updatedPkg.pkg = pkg; 6642 updatedPkg.versionCode = pkg.mVersionCode; 6643 6644 // Update the disabled system child packages to point to the package too. 6645 final int childCount = updatedPkg.childPackageNames != null 6646 ? updatedPkg.childPackageNames.size() : 0; 6647 for (int i = 0; i < childCount; i++) { 6648 String childPackageName = updatedPkg.childPackageNames.get(i); 6649 PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr( 6650 childPackageName); 6651 if (updatedChildPkg != null) { 6652 updatedChildPkg.pkg = pkg; 6653 updatedChildPkg.versionCode = pkg.mVersionCode; 6654 } 6655 } 6656 6657 throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at " 6658 + scanFile + " ignored: updated version " + ps.versionCode 6659 + " better than this " + pkg.mVersionCode); 6660 } else { 6661 // The current app on the system partition is better than 6662 // what we have updated to on the data partition; switch 6663 // back to the system partition version. 6664 // At this point, its safely assumed that package installation for 6665 // apps in system partition will go through. If not there won't be a working 6666 // version of the app 6667 // writer 6668 synchronized (mPackages) { 6669 // Just remove the loaded entries from package lists. 6670 mPackages.remove(ps.name); 6671 } 6672 6673 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 6674 + " reverting from " + ps.codePathString 6675 + ": new version " + pkg.mVersionCode 6676 + " better than installed " + ps.versionCode); 6677 6678 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 6679 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 6680 synchronized (mInstallLock) { 6681 args.cleanUpResourcesLI(); 6682 } 6683 synchronized (mPackages) { 6684 mSettings.enableSystemPackageLPw(ps.name); 6685 } 6686 updatedPkgBetter = true; 6687 } 6688 } 6689 } 6690 6691 if (updatedPkg != null) { 6692 // An updated system app will not have the PARSE_IS_SYSTEM flag set 6693 // initially 6694 parseFlags |= PackageParser.PARSE_IS_SYSTEM; 6695 6696 // An updated privileged app will not have the PARSE_IS_PRIVILEGED 6697 // flag set initially 6698 if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) { 6699 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 6700 } 6701 } 6702 6703 // Verify certificates against what was last scanned 6704 collectCertificatesLI(ps, pkg, scanFile, parseFlags); 6705 6706 /* 6707 * A new system app appeared, but we already had a non-system one of the 6708 * same name installed earlier. 6709 */ 6710 boolean shouldHideSystemApp = false; 6711 if (updatedPkg == null && ps != null 6712 && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) { 6713 /* 6714 * Check to make sure the signatures match first. If they don't, 6715 * wipe the installed application and its data. 6716 */ 6717 if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures) 6718 != PackageManager.SIGNATURE_MATCH) { 6719 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but" 6720 + " signatures don't match existing userdata copy; removing"); 6721 deletePackageLI(pkg.packageName, null, true, null, 0, null, false, null); 6722 ps = null; 6723 } else { 6724 /* 6725 * If the newly-added system app is an older version than the 6726 * already installed version, hide it. It will be scanned later 6727 * and re-added like an update. 6728 */ 6729 if (pkg.mVersionCode <= ps.versionCode) { 6730 shouldHideSystemApp = true; 6731 logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile 6732 + " but new version " + pkg.mVersionCode + " better than installed " 6733 + ps.versionCode + "; hiding system"); 6734 } else { 6735 /* 6736 * The newly found system app is a newer version that the 6737 * one previously installed. Simply remove the 6738 * already-installed application and replace it with our own 6739 * while keeping the application data. 6740 */ 6741 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 6742 + " reverting from " + ps.codePathString + ": new version " 6743 + pkg.mVersionCode + " better than installed " + ps.versionCode); 6744 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 6745 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 6746 synchronized (mInstallLock) { 6747 args.cleanUpResourcesLI(); 6748 } 6749 } 6750 } 6751 } 6752 6753 // The apk is forward locked (not public) if its code and resources 6754 // are kept in different files. (except for app in either system or 6755 // vendor path). 6756 // TODO grab this value from PackageSettings 6757 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 6758 if (ps != null && !ps.codePath.equals(ps.resourcePath)) { 6759 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 6760 } 6761 } 6762 6763 // TODO: extend to support forward-locked splits 6764 String resourcePath = null; 6765 String baseResourcePath = null; 6766 if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) { 6767 if (ps != null && ps.resourcePathString != null) { 6768 resourcePath = ps.resourcePathString; 6769 baseResourcePath = ps.resourcePathString; 6770 } else { 6771 // Should not happen at all. Just log an error. 6772 Slog.e(TAG, "Resource path not set for package " + pkg.packageName); 6773 } 6774 } else { 6775 resourcePath = pkg.codePath; 6776 baseResourcePath = pkg.baseCodePath; 6777 } 6778 6779 // Set application objects path explicitly. 6780 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 6781 pkg.setApplicationInfoCodePath(pkg.codePath); 6782 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 6783 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 6784 pkg.setApplicationInfoResourcePath(resourcePath); 6785 pkg.setApplicationInfoBaseResourcePath(baseResourcePath); 6786 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 6787 6788 // Note that we invoke the following method only if we are about to unpack an application 6789 PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags 6790 | SCAN_UPDATE_SIGNATURE, currentTime, user); 6791 6792 /* 6793 * If the system app should be overridden by a previously installed 6794 * data, hide the system app now and let the /data/app scan pick it up 6795 * again. 6796 */ 6797 if (shouldHideSystemApp) { 6798 synchronized (mPackages) { 6799 mSettings.disableSystemPackageLPw(pkg.packageName, true); 6800 } 6801 } 6802 6803 return scannedPkg; 6804 } 6805 6806 private static String fixProcessName(String defProcessName, 6807 String processName, int uid) { 6808 if (processName == null) { 6809 return defProcessName; 6810 } 6811 return processName; 6812 } 6813 6814 private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg) 6815 throws PackageManagerException { 6816 if (pkgSetting.signatures.mSignatures != null) { 6817 // Already existing package. Make sure signatures match 6818 boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures) 6819 == PackageManager.SIGNATURE_MATCH; 6820 if (!match) { 6821 match = compareSignaturesCompat(pkgSetting.signatures, pkg) 6822 == PackageManager.SIGNATURE_MATCH; 6823 } 6824 if (!match) { 6825 match = compareSignaturesRecover(pkgSetting.signatures, pkg) 6826 == PackageManager.SIGNATURE_MATCH; 6827 } 6828 if (!match) { 6829 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 6830 + pkg.packageName + " signatures do not match the " 6831 + "previously installed version; ignoring!"); 6832 } 6833 } 6834 6835 // Check for shared user signatures 6836 if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) { 6837 // Already existing package. Make sure signatures match 6838 boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 6839 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 6840 if (!match) { 6841 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg) 6842 == PackageManager.SIGNATURE_MATCH; 6843 } 6844 if (!match) { 6845 match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg) 6846 == PackageManager.SIGNATURE_MATCH; 6847 } 6848 if (!match) { 6849 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 6850 "Package " + pkg.packageName 6851 + " has no signatures that match those in shared user " 6852 + pkgSetting.sharedUser.name + "; ignoring!"); 6853 } 6854 } 6855 } 6856 6857 /** 6858 * Enforces that only the system UID or root's UID can call a method exposed 6859 * via Binder. 6860 * 6861 * @param message used as message if SecurityException is thrown 6862 * @throws SecurityException if the caller is not system or root 6863 */ 6864 private static final void enforceSystemOrRoot(String message) { 6865 final int uid = Binder.getCallingUid(); 6866 if (uid != Process.SYSTEM_UID && uid != 0) { 6867 throw new SecurityException(message); 6868 } 6869 } 6870 6871 @Override 6872 public void performFstrimIfNeeded() { 6873 enforceSystemOrRoot("Only the system can request fstrim"); 6874 6875 // Before everything else, see whether we need to fstrim. 6876 try { 6877 IMountService ms = PackageHelper.getMountService(); 6878 if (ms != null) { 6879 final boolean isUpgrade = isUpgrade(); 6880 boolean doTrim = isUpgrade; 6881 if (doTrim) { 6882 Slog.w(TAG, "Running disk maintenance immediately due to system update"); 6883 } else { 6884 final long interval = android.provider.Settings.Global.getLong( 6885 mContext.getContentResolver(), 6886 android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL, 6887 DEFAULT_MANDATORY_FSTRIM_INTERVAL); 6888 if (interval > 0) { 6889 final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance(); 6890 if (timeSinceLast > interval) { 6891 doTrim = true; 6892 Slog.w(TAG, "No disk maintenance in " + timeSinceLast 6893 + "; running immediately"); 6894 } 6895 } 6896 } 6897 if (doTrim) { 6898 if (!isFirstBoot()) { 6899 try { 6900 ActivityManagerNative.getDefault().showBootMessage( 6901 mContext.getResources().getString( 6902 R.string.android_upgrading_fstrim), true); 6903 } catch (RemoteException e) { 6904 } 6905 } 6906 ms.runMaintenance(); 6907 } 6908 } else { 6909 Slog.e(TAG, "Mount service unavailable!"); 6910 } 6911 } catch (RemoteException e) { 6912 // Can't happen; MountService is local 6913 } 6914 } 6915 6916 @Override 6917 public void extractPackagesIfNeeded() { 6918 enforceSystemOrRoot("Only the system can request package extraction"); 6919 6920 // We need to re-extract after an OTA. 6921 boolean causeUpgrade = isUpgrade(); 6922 6923 // First boot or factory reset. 6924 // Note: we also handle devices that are upgrading to N right now as if it is their 6925 // first boot, as they do not have profile data. 6926 boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade; 6927 6928 // We need to re-extract after a pruned cache, as AoT-ed files will be out of date. 6929 boolean causePrunedCache = VMRuntime.didPruneDalvikCache(); 6930 6931 if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) { 6932 return; 6933 } 6934 6935 List<PackageParser.Package> pkgs; 6936 synchronized (mPackages) { 6937 pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this); 6938 } 6939 6940 int curr = 0; 6941 int total = pkgs.size(); 6942 for (PackageParser.Package pkg : pkgs) { 6943 curr++; 6944 6945 if (DEBUG_DEXOPT) { 6946 Log.i(TAG, "Extracting app " + curr + " of " + total + ": " + pkg.packageName); 6947 } 6948 6949 if (!isFirstBoot()) { 6950 try { 6951 ActivityManagerNative.getDefault().showBootMessage( 6952 mContext.getResources().getString(R.string.android_upgrading_apk, 6953 curr, total), true); 6954 } catch (RemoteException e) { 6955 } 6956 } 6957 6958 if (PackageDexOptimizer.canOptimizePackage(pkg)) { 6959 // If the cache was pruned, any compiled odex files will likely be out of date 6960 // and would have to be patched (would be SELF_PATCHOAT, which is deprecated). 6961 // Instead, force the extraction in this case. 6962 performDexOpt(pkg.packageName, null /* instructionSet */, 6963 false /* checkProfiles */, 6964 causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT, 6965 causePrunedCache); 6966 } 6967 } 6968 } 6969 6970 @Override 6971 public void notifyPackageUse(String packageName) { 6972 synchronized (mPackages) { 6973 PackageParser.Package p = mPackages.get(packageName); 6974 if (p == null) { 6975 return; 6976 } 6977 p.mLastPackageUsageTimeInMills = System.currentTimeMillis(); 6978 } 6979 } 6980 6981 // TODO: this is not used nor needed. Delete it. 6982 @Override 6983 public boolean performDexOptIfNeeded(String packageName, String instructionSet) { 6984 return performDexOptTraced(packageName, instructionSet, false /* checkProfiles */, 6985 getFullCompilerFilter(), false /* force */); 6986 } 6987 6988 @Override 6989 public boolean performDexOpt(String packageName, String instructionSet, 6990 boolean checkProfiles, int compileReason, boolean force) { 6991 return performDexOptTraced(packageName, instructionSet, checkProfiles, 6992 getCompilerFilterForReason(compileReason), force); 6993 } 6994 6995 @Override 6996 public boolean performDexOptMode(String packageName, String instructionSet, 6997 boolean checkProfiles, String targetCompilerFilter, boolean force) { 6998 return performDexOptTraced(packageName, instructionSet, checkProfiles, 6999 targetCompilerFilter, force); 7000 } 7001 7002 private boolean performDexOptTraced(String packageName, String instructionSet, 7003 boolean checkProfiles, String targetCompilerFilter, boolean force) { 7004 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 7005 try { 7006 return performDexOptInternal(packageName, instructionSet, checkProfiles, 7007 targetCompilerFilter, force); 7008 } finally { 7009 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7010 } 7011 } 7012 7013 private boolean performDexOptInternal(String packageName, String instructionSet, 7014 boolean checkProfiles, String targetCompilerFilter, boolean force) { 7015 PackageParser.Package p; 7016 final String targetInstructionSet; 7017 synchronized (mPackages) { 7018 p = mPackages.get(packageName); 7019 if (p == null) { 7020 return false; 7021 } 7022 mPackageUsage.write(false); 7023 7024 targetInstructionSet = instructionSet != null ? instructionSet : 7025 getPrimaryInstructionSet(p.applicationInfo); 7026 } 7027 long callingId = Binder.clearCallingIdentity(); 7028 try { 7029 synchronized (mInstallLock) { 7030 final String[] instructionSets = new String[] { targetInstructionSet }; 7031 int result = performDexOptInternalWithDependenciesLI(p, instructionSets, 7032 checkProfiles, targetCompilerFilter, force); 7033 return result == PackageDexOptimizer.DEX_OPT_PERFORMED; 7034 } 7035 } finally { 7036 Binder.restoreCallingIdentity(callingId); 7037 } 7038 } 7039 7040 public ArraySet<String> getOptimizablePackages() { 7041 ArraySet<String> pkgs = new ArraySet<String>(); 7042 synchronized (mPackages) { 7043 for (PackageParser.Package p : mPackages.values()) { 7044 if (PackageDexOptimizer.canOptimizePackage(p)) { 7045 pkgs.add(p.packageName); 7046 } 7047 } 7048 } 7049 return pkgs; 7050 } 7051 7052 private int performDexOptInternalWithDependenciesLI(PackageParser.Package p, 7053 String instructionSets[], boolean checkProfiles, String targetCompilerFilter, 7054 boolean force) { 7055 // Select the dex optimizer based on the force parameter. 7056 // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to 7057 // allocate an object here. 7058 PackageDexOptimizer pdo = force 7059 ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer) 7060 : mPackageDexOptimizer; 7061 7062 // Optimize all dependencies first. Note: we ignore the return value and march on 7063 // on errors. 7064 Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p); 7065 if (!deps.isEmpty()) { 7066 for (PackageParser.Package depPackage : deps) { 7067 // TODO: Analyze and investigate if we (should) profile libraries. 7068 // Currently this will do a full compilation of the library by default. 7069 pdo.performDexOpt(depPackage, instructionSets, false /* checkProfiles */, 7070 getCompilerFilterForReason(REASON_NON_SYSTEM_LIBRARY)); 7071 } 7072 } 7073 7074 return pdo.performDexOpt(p, instructionSets, checkProfiles, targetCompilerFilter); 7075 } 7076 7077 Collection<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) { 7078 if (p.usesLibraries != null || p.usesOptionalLibraries != null) { 7079 ArrayList<PackageParser.Package> retValue = new ArrayList<>(); 7080 Set<String> collectedNames = new HashSet<>(); 7081 findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames); 7082 7083 retValue.remove(p); 7084 7085 return retValue; 7086 } else { 7087 return Collections.emptyList(); 7088 } 7089 } 7090 7091 private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p, 7092 Collection<PackageParser.Package> collected, Set<String> collectedNames) { 7093 if (!collectedNames.contains(p.packageName)) { 7094 collectedNames.add(p.packageName); 7095 collected.add(p); 7096 7097 if (p.usesLibraries != null) { 7098 findSharedNonSystemLibrariesRecursive(p.usesLibraries, collected, collectedNames); 7099 } 7100 if (p.usesOptionalLibraries != null) { 7101 findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries, collected, 7102 collectedNames); 7103 } 7104 } 7105 } 7106 7107 private void findSharedNonSystemLibrariesRecursive(Collection<String> libs, 7108 Collection<PackageParser.Package> collected, Set<String> collectedNames) { 7109 for (String libName : libs) { 7110 PackageParser.Package libPkg = findSharedNonSystemLibrary(libName); 7111 if (libPkg != null) { 7112 findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames); 7113 } 7114 } 7115 } 7116 7117 private PackageParser.Package findSharedNonSystemLibrary(String libName) { 7118 synchronized (mPackages) { 7119 PackageManagerService.SharedLibraryEntry lib = mSharedLibraries.get(libName); 7120 if (lib != null && lib.apk != null) { 7121 return mPackages.get(lib.apk); 7122 } 7123 } 7124 return null; 7125 } 7126 7127 public void shutdown() { 7128 mPackageUsage.write(true); 7129 } 7130 7131 @Override 7132 public void forceDexOpt(String packageName) { 7133 enforceSystemOrRoot("forceDexOpt"); 7134 7135 PackageParser.Package pkg; 7136 synchronized (mPackages) { 7137 pkg = mPackages.get(packageName); 7138 if (pkg == null) { 7139 throw new IllegalArgumentException("Unknown package: " + packageName); 7140 } 7141 } 7142 7143 synchronized (mInstallLock) { 7144 final String[] instructionSets = new String[] { 7145 getPrimaryInstructionSet(pkg.applicationInfo) }; 7146 7147 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 7148 7149 // Whoever is calling forceDexOpt wants a fully compiled package. 7150 // Don't use profiles since that may cause compilation to be skipped. 7151 final int res = performDexOptInternalWithDependenciesLI(pkg, instructionSets, 7152 false /* checkProfiles */, getCompilerFilterForReason(REASON_FORCED_DEXOPT), 7153 true /* force */); 7154 7155 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7156 if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) { 7157 throw new IllegalStateException("Failed to dexopt: " + res); 7158 } 7159 } 7160 } 7161 7162 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) { 7163 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) { 7164 Slog.w(TAG, "Unable to update from " + oldPkg.name 7165 + " to " + newPkg.packageName 7166 + ": old package not in system partition"); 7167 return false; 7168 } else if (mPackages.get(oldPkg.name) != null) { 7169 Slog.w(TAG, "Unable to update from " + oldPkg.name 7170 + " to " + newPkg.packageName 7171 + ": old package still exists"); 7172 return false; 7173 } 7174 return true; 7175 } 7176 7177 private boolean removeDataDirsLI(String volumeUuid, String packageName) { 7178 // TODO: triage flags as part of 26466827 7179 final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE; 7180 7181 boolean res = true; 7182 final int[] users = sUserManager.getUserIds(); 7183 for (int user : users) { 7184 try { 7185 mInstaller.destroyAppData(volumeUuid, packageName, user, flags); 7186 } catch (InstallerException e) { 7187 Slog.w(TAG, "Failed to delete data directory", e); 7188 res = false; 7189 } 7190 } 7191 return res; 7192 } 7193 7194 void removeCodePathLI(File codePath) { 7195 if (codePath.isDirectory()) { 7196 try { 7197 mInstaller.rmPackageDir(codePath.getAbsolutePath()); 7198 } catch (InstallerException e) { 7199 Slog.w(TAG, "Failed to remove code path", e); 7200 } 7201 } else { 7202 codePath.delete(); 7203 } 7204 } 7205 7206 void destroyAppDataLI(String volumeUuid, String packageName, int userId, int flags) { 7207 try { 7208 mInstaller.destroyAppData(volumeUuid, packageName, userId, flags); 7209 } catch (InstallerException e) { 7210 Slog.w(TAG, "Failed to destroy app data", e); 7211 } 7212 } 7213 7214 void restoreconAppDataLI(String volumeUuid, String packageName, int userId, int flags, 7215 int appId, String seinfo) { 7216 try { 7217 mInstaller.restoreconAppData(volumeUuid, packageName, userId, flags, appId, seinfo); 7218 } catch (InstallerException e) { 7219 Slog.e(TAG, "Failed to restorecon for " + packageName + ": " + e); 7220 } 7221 } 7222 7223 private void deleteProfilesLI(String packageName, boolean destroy) { 7224 final PackageParser.Package pkg; 7225 synchronized (mPackages) { 7226 pkg = mPackages.get(packageName); 7227 } 7228 if (pkg == null) { 7229 Slog.w(TAG, "Failed to delete profiles. No package: " + packageName); 7230 return; 7231 } 7232 deleteProfilesLI(pkg, destroy); 7233 } 7234 7235 private void deleteProfilesLI(PackageParser.Package pkg, boolean destroy) { 7236 try { 7237 if (destroy) { 7238 mInstaller.destroyAppProfiles(pkg.packageName); 7239 } else { 7240 mInstaller.clearAppProfiles(pkg.packageName); 7241 } 7242 } catch (InstallerException ex) { 7243 Log.e(TAG, "Could not delete profiles for package " + pkg.packageName); 7244 } 7245 } 7246 7247 private void deleteCodeCacheDirsLI(String volumeUuid, String packageName) { 7248 final PackageParser.Package pkg; 7249 synchronized (mPackages) { 7250 pkg = mPackages.get(packageName); 7251 } 7252 if (pkg == null) { 7253 Slog.w(TAG, "Failed to delete code cache directory. No package: " + packageName); 7254 return; 7255 } 7256 deleteCodeCacheDirsLI(pkg); 7257 } 7258 7259 private void deleteCodeCacheDirsLI(PackageParser.Package pkg) { 7260 // TODO: triage flags as part of 26466827 7261 final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE; 7262 7263 int[] users = sUserManager.getUserIds(); 7264 int res = 0; 7265 for (int user : users) { 7266 // Remove the parent code cache 7267 try { 7268 mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, user, 7269 flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 7270 } catch (InstallerException e) { 7271 Slog.w(TAG, "Failed to delete code cache directory", e); 7272 } 7273 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7274 for (int i = 0; i < childCount; i++) { 7275 PackageParser.Package childPkg = pkg.childPackages.get(i); 7276 // Remove the child code cache 7277 try { 7278 mInstaller.clearAppData(childPkg.volumeUuid, childPkg.packageName, 7279 user, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 7280 } catch (InstallerException e) { 7281 Slog.w(TAG, "Failed to delete code cache directory", e); 7282 } 7283 } 7284 } 7285 } 7286 7287 private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime, 7288 long lastUpdateTime) { 7289 // Set parent install/update time 7290 PackageSetting ps = (PackageSetting) pkg.mExtras; 7291 if (ps != null) { 7292 ps.firstInstallTime = firstInstallTime; 7293 ps.lastUpdateTime = lastUpdateTime; 7294 } 7295 // Set children install/update time 7296 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7297 for (int i = 0; i < childCount; i++) { 7298 PackageParser.Package childPkg = pkg.childPackages.get(i); 7299 ps = (PackageSetting) childPkg.mExtras; 7300 if (ps != null) { 7301 ps.firstInstallTime = firstInstallTime; 7302 ps.lastUpdateTime = lastUpdateTime; 7303 } 7304 } 7305 } 7306 7307 private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file, 7308 PackageParser.Package changingLib) { 7309 if (file.path != null) { 7310 usesLibraryFiles.add(file.path); 7311 return; 7312 } 7313 PackageParser.Package p = mPackages.get(file.apk); 7314 if (changingLib != null && changingLib.packageName.equals(file.apk)) { 7315 // If we are doing this while in the middle of updating a library apk, 7316 // then we need to make sure to use that new apk for determining the 7317 // dependencies here. (We haven't yet finished committing the new apk 7318 // to the package manager state.) 7319 if (p == null || p.packageName.equals(changingLib.packageName)) { 7320 p = changingLib; 7321 } 7322 } 7323 if (p != null) { 7324 usesLibraryFiles.addAll(p.getAllCodePaths()); 7325 } 7326 } 7327 7328 private void updateSharedLibrariesLPw(PackageParser.Package pkg, 7329 PackageParser.Package changingLib) throws PackageManagerException { 7330 if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) { 7331 final ArraySet<String> usesLibraryFiles = new ArraySet<>(); 7332 int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0; 7333 for (int i=0; i<N; i++) { 7334 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i)); 7335 if (file == null) { 7336 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, 7337 "Package " + pkg.packageName + " requires unavailable shared library " 7338 + pkg.usesLibraries.get(i) + "; failing!"); 7339 } 7340 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 7341 } 7342 N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0; 7343 for (int i=0; i<N; i++) { 7344 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i)); 7345 if (file == null) { 7346 Slog.w(TAG, "Package " + pkg.packageName 7347 + " desires unavailable shared library " 7348 + pkg.usesOptionalLibraries.get(i) + "; ignoring!"); 7349 } else { 7350 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 7351 } 7352 } 7353 N = usesLibraryFiles.size(); 7354 if (N > 0) { 7355 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]); 7356 } else { 7357 pkg.usesLibraryFiles = null; 7358 } 7359 } 7360 } 7361 7362 private static boolean hasString(List<String> list, List<String> which) { 7363 if (list == null) { 7364 return false; 7365 } 7366 for (int i=list.size()-1; i>=0; i--) { 7367 for (int j=which.size()-1; j>=0; j--) { 7368 if (which.get(j).equals(list.get(i))) { 7369 return true; 7370 } 7371 } 7372 } 7373 return false; 7374 } 7375 7376 private void updateAllSharedLibrariesLPw() { 7377 for (PackageParser.Package pkg : mPackages.values()) { 7378 try { 7379 updateSharedLibrariesLPw(pkg, null); 7380 } catch (PackageManagerException e) { 7381 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 7382 } 7383 } 7384 } 7385 7386 private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw( 7387 PackageParser.Package changingPkg) { 7388 ArrayList<PackageParser.Package> res = null; 7389 for (PackageParser.Package pkg : mPackages.values()) { 7390 if (hasString(pkg.usesLibraries, changingPkg.libraryNames) 7391 || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) { 7392 if (res == null) { 7393 res = new ArrayList<PackageParser.Package>(); 7394 } 7395 res.add(pkg); 7396 try { 7397 updateSharedLibrariesLPw(pkg, changingPkg); 7398 } catch (PackageManagerException e) { 7399 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 7400 } 7401 } 7402 } 7403 return res; 7404 } 7405 7406 /** 7407 * Derive the value of the {@code cpuAbiOverride} based on the provided 7408 * value and an optional stored value from the package settings. 7409 */ 7410 private static String deriveAbiOverride(String abiOverride, PackageSetting settings) { 7411 String cpuAbiOverride = null; 7412 7413 if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) { 7414 cpuAbiOverride = null; 7415 } else if (abiOverride != null) { 7416 cpuAbiOverride = abiOverride; 7417 } else if (settings != null) { 7418 cpuAbiOverride = settings.cpuAbiOverrideString; 7419 } 7420 7421 return cpuAbiOverride; 7422 } 7423 7424 private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg, int parseFlags, 7425 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 7426 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage"); 7427 // If the package has children and this is the first dive in the function 7428 // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see 7429 // whether all packages (parent and children) would be successfully scanned 7430 // before the actual scan since scanning mutates internal state and we want 7431 // to atomically install the package and its children. 7432 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 7433 if (pkg.childPackages != null && pkg.childPackages.size() > 0) { 7434 scanFlags |= SCAN_CHECK_ONLY; 7435 } 7436 } else { 7437 scanFlags &= ~SCAN_CHECK_ONLY; 7438 } 7439 7440 final PackageParser.Package scannedPkg; 7441 try { 7442 // Scan the parent 7443 scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags, currentTime, user); 7444 // Scan the children 7445 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7446 for (int i = 0; i < childCount; i++) { 7447 PackageParser.Package childPkg = pkg.childPackages.get(i); 7448 scanPackageLI(childPkg, parseFlags, 7449 scanFlags, currentTime, user); 7450 } 7451 } finally { 7452 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7453 } 7454 7455 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 7456 return scanPackageTracedLI(pkg, parseFlags, scanFlags, currentTime, user); 7457 } 7458 7459 return scannedPkg; 7460 } 7461 7462 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags, 7463 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 7464 boolean success = false; 7465 try { 7466 final PackageParser.Package res = scanPackageDirtyLI(pkg, parseFlags, scanFlags, 7467 currentTime, user); 7468 success = true; 7469 return res; 7470 } finally { 7471 if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) { 7472 removeDataDirsLI(pkg.volumeUuid, pkg.packageName); 7473 } 7474 } 7475 } 7476 7477 private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags, 7478 int scanFlags, long currentTime, UserHandle user) 7479 throws PackageManagerException { 7480 final File scanFile = new File(pkg.codePath); 7481 if (pkg.applicationInfo.getCodePath() == null || 7482 pkg.applicationInfo.getResourcePath() == null) { 7483 // Bail out. The resource and code paths haven't been set. 7484 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 7485 "Code and resource paths haven't been set correctly"); 7486 } 7487 7488 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 7489 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; 7490 } else { 7491 // Only allow system apps to be flagged as core apps. 7492 pkg.coreApp = false; 7493 } 7494 7495 if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) { 7496 pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 7497 } 7498 7499 if (mCustomResolverComponentName != null && 7500 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) { 7501 setUpCustomResolverActivity(pkg); 7502 } 7503 7504 if (pkg.packageName.equals("android")) { 7505 synchronized (mPackages) { 7506 if (mAndroidApplication != null) { 7507 Slog.w(TAG, "*************************************************"); 7508 Slog.w(TAG, "Core android package being redefined. Skipping."); 7509 Slog.w(TAG, " file=" + scanFile); 7510 Slog.w(TAG, "*************************************************"); 7511 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 7512 "Core android package being redefined. Skipping."); 7513 } 7514 7515 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 7516 // Set up information for our fall-back user intent resolution activity. 7517 mPlatformPackage = pkg; 7518 pkg.mVersionCode = mSdkVersion; 7519 mAndroidApplication = pkg.applicationInfo; 7520 7521 if (!mResolverReplaced) { 7522 mResolveActivity.applicationInfo = mAndroidApplication; 7523 mResolveActivity.name = ResolverActivity.class.getName(); 7524 mResolveActivity.packageName = mAndroidApplication.packageName; 7525 mResolveActivity.processName = "system:ui"; 7526 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 7527 mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER; 7528 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS; 7529 mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert; 7530 mResolveActivity.exported = true; 7531 mResolveActivity.enabled = true; 7532 mResolveInfo.activityInfo = mResolveActivity; 7533 mResolveInfo.priority = 0; 7534 mResolveInfo.preferredOrder = 0; 7535 mResolveInfo.match = 0; 7536 mResolveComponentName = new ComponentName( 7537 mAndroidApplication.packageName, mResolveActivity.name); 7538 } 7539 } 7540 } 7541 } 7542 7543 if (DEBUG_PACKAGE_SCANNING) { 7544 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 7545 Log.d(TAG, "Scanning package " + pkg.packageName); 7546 } 7547 7548 synchronized (mPackages) { 7549 if (mPackages.containsKey(pkg.packageName) 7550 || mSharedLibraries.containsKey(pkg.packageName)) { 7551 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 7552 "Application package " + pkg.packageName 7553 + " already installed. Skipping duplicate."); 7554 } 7555 7556 // If we're only installing presumed-existing packages, require that the 7557 // scanned APK is both already known and at the path previously established 7558 // for it. Previously unknown packages we pick up normally, but if we have an 7559 // a priori expectation about this package's install presence, enforce it. 7560 // With a singular exception for new system packages. When an OTA contains 7561 // a new system package, we allow the codepath to change from a system location 7562 // to the user-installed location. If we don't allow this change, any newer, 7563 // user-installed version of the application will be ignored. 7564 if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) { 7565 if (mExpectingBetter.containsKey(pkg.packageName)) { 7566 logCriticalInfo(Log.WARN, 7567 "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName); 7568 } else { 7569 PackageSetting known = mSettings.peekPackageLPr(pkg.packageName); 7570 if (known != null) { 7571 if (DEBUG_PACKAGE_SCANNING) { 7572 Log.d(TAG, "Examining " + pkg.codePath 7573 + " and requiring known paths " + known.codePathString 7574 + " & " + known.resourcePathString); 7575 } 7576 if (!pkg.applicationInfo.getCodePath().equals(known.codePathString) 7577 || !pkg.applicationInfo.getResourcePath().equals( 7578 known.resourcePathString)) { 7579 throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED, 7580 "Application package " + pkg.packageName 7581 + " found at " + pkg.applicationInfo.getCodePath() 7582 + " but expected at " + known.codePathString 7583 + "; ignoring."); 7584 } 7585 } 7586 } 7587 } 7588 } 7589 7590 // Initialize package source and resource directories 7591 File destCodeFile = new File(pkg.applicationInfo.getCodePath()); 7592 File destResourceFile = new File(pkg.applicationInfo.getResourcePath()); 7593 7594 SharedUserSetting suid = null; 7595 PackageSetting pkgSetting = null; 7596 7597 if (!isSystemApp(pkg)) { 7598 // Only system apps can use these features. 7599 pkg.mOriginalPackages = null; 7600 pkg.mRealPackage = null; 7601 pkg.mAdoptPermissions = null; 7602 } 7603 7604 // Getting the package setting may have a side-effect, so if we 7605 // are only checking if scan would succeed, stash a copy of the 7606 // old setting to restore at the end. 7607 PackageSetting nonMutatedPs = null; 7608 7609 // writer 7610 synchronized (mPackages) { 7611 if (pkg.mSharedUserId != null) { 7612 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, true); 7613 if (suid == null) { 7614 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 7615 "Creating application package " + pkg.packageName 7616 + " for shared user failed"); 7617 } 7618 if (DEBUG_PACKAGE_SCANNING) { 7619 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 7620 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId 7621 + "): packages=" + suid.packages); 7622 } 7623 } 7624 7625 // Check if we are renaming from an original package name. 7626 PackageSetting origPackage = null; 7627 String realName = null; 7628 if (pkg.mOriginalPackages != null) { 7629 // This package may need to be renamed to a previously 7630 // installed name. Let's check on that... 7631 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage); 7632 if (pkg.mOriginalPackages.contains(renamed)) { 7633 // This package had originally been installed as the 7634 // original name, and we have already taken care of 7635 // transitioning to the new one. Just update the new 7636 // one to continue using the old name. 7637 realName = pkg.mRealPackage; 7638 if (!pkg.packageName.equals(renamed)) { 7639 // Callers into this function may have already taken 7640 // care of renaming the package; only do it here if 7641 // it is not already done. 7642 pkg.setPackageName(renamed); 7643 } 7644 7645 } else { 7646 for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) { 7647 if ((origPackage = mSettings.peekPackageLPr( 7648 pkg.mOriginalPackages.get(i))) != null) { 7649 // We do have the package already installed under its 7650 // original name... should we use it? 7651 if (!verifyPackageUpdateLPr(origPackage, pkg)) { 7652 // New package is not compatible with original. 7653 origPackage = null; 7654 continue; 7655 } else if (origPackage.sharedUser != null) { 7656 // Make sure uid is compatible between packages. 7657 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) { 7658 Slog.w(TAG, "Unable to migrate data from " + origPackage.name 7659 + " to " + pkg.packageName + ": old uid " 7660 + origPackage.sharedUser.name 7661 + " differs from " + pkg.mSharedUserId); 7662 origPackage = null; 7663 continue; 7664 } 7665 } else { 7666 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package " 7667 + pkg.packageName + " to old name " + origPackage.name); 7668 } 7669 break; 7670 } 7671 } 7672 } 7673 } 7674 7675 if (mTransferedPackages.contains(pkg.packageName)) { 7676 Slog.w(TAG, "Package " + pkg.packageName 7677 + " was transferred to another, but its .apk remains"); 7678 } 7679 7680 // See comments in nonMutatedPs declaration 7681 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 7682 PackageSetting foundPs = mSettings.peekPackageLPr(pkg.packageName); 7683 if (foundPs != null) { 7684 nonMutatedPs = new PackageSetting(foundPs); 7685 } 7686 } 7687 7688 // Just create the setting, don't add it yet. For already existing packages 7689 // the PkgSetting exists already and doesn't have to be created. 7690 pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile, 7691 destResourceFile, pkg.applicationInfo.nativeLibraryRootDir, 7692 pkg.applicationInfo.primaryCpuAbi, 7693 pkg.applicationInfo.secondaryCpuAbi, 7694 pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, 7695 user, false); 7696 if (pkgSetting == null) { 7697 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 7698 "Creating application package " + pkg.packageName + " failed"); 7699 } 7700 7701 if (pkgSetting.origPackage != null) { 7702 // If we are first transitioning from an original package, 7703 // fix up the new package's name now. We need to do this after 7704 // looking up the package under its new name, so getPackageLP 7705 // can take care of fiddling things correctly. 7706 pkg.setPackageName(origPackage.name); 7707 7708 // File a report about this. 7709 String msg = "New package " + pkgSetting.realName 7710 + " renamed to replace old package " + pkgSetting.name; 7711 reportSettingsProblem(Log.WARN, msg); 7712 7713 // Make a note of it. 7714 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 7715 mTransferedPackages.add(origPackage.name); 7716 } 7717 7718 // No longer need to retain this. 7719 pkgSetting.origPackage = null; 7720 } 7721 7722 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) { 7723 // Make a note of it. 7724 mTransferedPackages.add(pkg.packageName); 7725 } 7726 7727 if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) { 7728 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 7729 } 7730 7731 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 7732 // Check all shared libraries and map to their actual file path. 7733 // We only do this here for apps not on a system dir, because those 7734 // are the only ones that can fail an install due to this. We 7735 // will take care of the system apps by updating all of their 7736 // library paths after the scan is done. 7737 updateSharedLibrariesLPw(pkg, null); 7738 } 7739 7740 if (mFoundPolicyFile) { 7741 SELinuxMMAC.assignSeinfoValue(pkg); 7742 } 7743 7744 pkg.applicationInfo.uid = pkgSetting.appId; 7745 pkg.mExtras = pkgSetting; 7746 if (shouldCheckUpgradeKeySetLP(pkgSetting, scanFlags)) { 7747 if (checkUpgradeKeySetLP(pkgSetting, pkg)) { 7748 // We just determined the app is signed correctly, so bring 7749 // over the latest parsed certs. 7750 pkgSetting.signatures.mSignatures = pkg.mSignatures; 7751 } else { 7752 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 7753 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 7754 "Package " + pkg.packageName + " upgrade keys do not match the " 7755 + "previously installed version"); 7756 } else { 7757 pkgSetting.signatures.mSignatures = pkg.mSignatures; 7758 String msg = "System package " + pkg.packageName 7759 + " signature changed; retaining data."; 7760 reportSettingsProblem(Log.WARN, msg); 7761 } 7762 } 7763 } else { 7764 try { 7765 verifySignaturesLP(pkgSetting, pkg); 7766 // We just determined the app is signed correctly, so bring 7767 // over the latest parsed certs. 7768 pkgSetting.signatures.mSignatures = pkg.mSignatures; 7769 } catch (PackageManagerException e) { 7770 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 7771 throw e; 7772 } 7773 // The signature has changed, but this package is in the system 7774 // image... let's recover! 7775 pkgSetting.signatures.mSignatures = pkg.mSignatures; 7776 // However... if this package is part of a shared user, but it 7777 // doesn't match the signature of the shared user, let's fail. 7778 // What this means is that you can't change the signatures 7779 // associated with an overall shared user, which doesn't seem all 7780 // that unreasonable. 7781 if (pkgSetting.sharedUser != null) { 7782 if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 7783 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { 7784 throw new PackageManagerException( 7785 INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES, 7786 "Signature mismatch for shared user: " 7787 + pkgSetting.sharedUser); 7788 } 7789 } 7790 // File a report about this. 7791 String msg = "System package " + pkg.packageName 7792 + " signature changed; retaining data."; 7793 reportSettingsProblem(Log.WARN, msg); 7794 } 7795 } 7796 // Verify that this new package doesn't have any content providers 7797 // that conflict with existing packages. Only do this if the 7798 // package isn't already installed, since we don't want to break 7799 // things that are installed. 7800 if ((scanFlags & SCAN_NEW_INSTALL) != 0) { 7801 final int N = pkg.providers.size(); 7802 int i; 7803 for (i=0; i<N; i++) { 7804 PackageParser.Provider p = pkg.providers.get(i); 7805 if (p.info.authority != null) { 7806 String names[] = p.info.authority.split(";"); 7807 for (int j = 0; j < names.length; j++) { 7808 if (mProvidersByAuthority.containsKey(names[j])) { 7809 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 7810 final String otherPackageName = 7811 ((other != null && other.getComponentName() != null) ? 7812 other.getComponentName().getPackageName() : "?"); 7813 throw new PackageManagerException( 7814 INSTALL_FAILED_CONFLICTING_PROVIDER, 7815 "Can't install because provider name " + names[j] 7816 + " (in package " + pkg.applicationInfo.packageName 7817 + ") is already used by " + otherPackageName); 7818 } 7819 } 7820 } 7821 } 7822 } 7823 7824 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) { 7825 // This package wants to adopt ownership of permissions from 7826 // another package. 7827 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) { 7828 final String origName = pkg.mAdoptPermissions.get(i); 7829 final PackageSetting orig = mSettings.peekPackageLPr(origName); 7830 if (orig != null) { 7831 if (verifyPackageUpdateLPr(orig, pkg)) { 7832 Slog.i(TAG, "Adopting permissions from " + origName + " to " 7833 + pkg.packageName); 7834 mSettings.transferPermissionsLPw(origName, pkg.packageName); 7835 } 7836 } 7837 } 7838 } 7839 } 7840 7841 final String pkgName = pkg.packageName; 7842 7843 final long scanFileTime = scanFile.lastModified(); 7844 final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0; 7845 pkg.applicationInfo.processName = fixProcessName( 7846 pkg.applicationInfo.packageName, 7847 pkg.applicationInfo.processName, 7848 pkg.applicationInfo.uid); 7849 7850 if (pkg != mPlatformPackage) { 7851 // Get all of our default paths setup 7852 pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM); 7853 } 7854 7855 final String path = scanFile.getPath(); 7856 final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting); 7857 7858 if ((scanFlags & SCAN_NEW_INSTALL) == 0) { 7859 derivePackageAbi(pkg, scanFile, cpuAbiOverride, true /* extract libs */); 7860 7861 // Some system apps still use directory structure for native libraries 7862 // in which case we might end up not detecting abi solely based on apk 7863 // structure. Try to detect abi based on directory structure. 7864 if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() && 7865 pkg.applicationInfo.primaryCpuAbi == null) { 7866 setBundledAppAbisAndRoots(pkg, pkgSetting); 7867 setNativeLibraryPaths(pkg); 7868 } 7869 7870 } else { 7871 if ((scanFlags & SCAN_MOVE) != 0) { 7872 // We haven't run dex-opt for this move (since we've moved the compiled output too) 7873 // but we already have this packages package info in the PackageSetting. We just 7874 // use that and derive the native library path based on the new codepath. 7875 pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString; 7876 pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString; 7877 } 7878 7879 // Set native library paths again. For moves, the path will be updated based on the 7880 // ABIs we've determined above. For non-moves, the path will be updated based on the 7881 // ABIs we determined during compilation, but the path will depend on the final 7882 // package path (after the rename away from the stage path). 7883 setNativeLibraryPaths(pkg); 7884 } 7885 7886 // This is a special case for the "system" package, where the ABI is 7887 // dictated by the zygote configuration (and init.rc). We should keep track 7888 // of this ABI so that we can deal with "normal" applications that run under 7889 // the same UID correctly. 7890 if (mPlatformPackage == pkg) { 7891 pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ? 7892 Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]; 7893 } 7894 7895 // If there's a mismatch between the abi-override in the package setting 7896 // and the abiOverride specified for the install. Warn about this because we 7897 // would've already compiled the app without taking the package setting into 7898 // account. 7899 if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) { 7900 if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) { 7901 Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride + 7902 " for package " + pkg.packageName); 7903 } 7904 } 7905 7906 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 7907 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 7908 pkgSetting.cpuAbiOverrideString = cpuAbiOverride; 7909 7910 // Copy the derived override back to the parsed package, so that we can 7911 // update the package settings accordingly. 7912 pkg.cpuAbiOverride = cpuAbiOverride; 7913 7914 if (DEBUG_ABI_SELECTION) { 7915 Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName 7916 + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa=" 7917 + pkg.applicationInfo.nativeLibraryRootRequiresIsa); 7918 } 7919 7920 // Push the derived path down into PackageSettings so we know what to 7921 // clean up at uninstall time. 7922 pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir; 7923 7924 if (DEBUG_ABI_SELECTION) { 7925 Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" + 7926 " primary=" + pkg.applicationInfo.primaryCpuAbi + 7927 " secondary=" + pkg.applicationInfo.secondaryCpuAbi); 7928 } 7929 7930 if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) { 7931 // We don't do this here during boot because we can do it all 7932 // at once after scanning all existing packages. 7933 // 7934 // We also do this *before* we perform dexopt on this package, so that 7935 // we can avoid redundant dexopts, and also to make sure we've got the 7936 // code and package path correct. 7937 adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, 7938 pkg, true /* boot complete */); 7939 } 7940 7941 if (mFactoryTest && pkg.requestedPermissions.contains( 7942 android.Manifest.permission.FACTORY_TEST)) { 7943 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST; 7944 } 7945 7946 ArrayList<PackageParser.Package> clientLibPkgs = null; 7947 7948 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 7949 if (nonMutatedPs != null) { 7950 synchronized (mPackages) { 7951 mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs); 7952 } 7953 } 7954 return pkg; 7955 } 7956 7957 // Only privileged apps and updated privileged apps can add child packages. 7958 if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) { 7959 if ((parseFlags & PARSE_IS_PRIVILEGED) == 0) { 7960 throw new PackageManagerException("Only privileged apps and updated " 7961 + "privileged apps can add child packages. Ignoring package " 7962 + pkg.packageName); 7963 } 7964 final int childCount = pkg.childPackages.size(); 7965 for (int i = 0; i < childCount; i++) { 7966 PackageParser.Package childPkg = pkg.childPackages.get(i); 7967 if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName, 7968 childPkg.packageName)) { 7969 throw new PackageManagerException("Cannot override a child package of " 7970 + "another disabled system app. Ignoring package " + pkg.packageName); 7971 } 7972 } 7973 } 7974 7975 // writer 7976 synchronized (mPackages) { 7977 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7978 // Only system apps can add new shared libraries. 7979 if (pkg.libraryNames != null) { 7980 for (int i=0; i<pkg.libraryNames.size(); i++) { 7981 String name = pkg.libraryNames.get(i); 7982 boolean allowed = false; 7983 if (pkg.isUpdatedSystemApp()) { 7984 // New library entries can only be added through the 7985 // system image. This is important to get rid of a lot 7986 // of nasty edge cases: for example if we allowed a non- 7987 // system update of the app to add a library, then uninstalling 7988 // the update would make the library go away, and assumptions 7989 // we made such as through app install filtering would now 7990 // have allowed apps on the device which aren't compatible 7991 // with it. Better to just have the restriction here, be 7992 // conservative, and create many fewer cases that can negatively 7993 // impact the user experience. 7994 final PackageSetting sysPs = mSettings 7995 .getDisabledSystemPkgLPr(pkg.packageName); 7996 if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) { 7997 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) { 7998 if (name.equals(sysPs.pkg.libraryNames.get(j))) { 7999 allowed = true; 8000 break; 8001 } 8002 } 8003 } 8004 } else { 8005 allowed = true; 8006 } 8007 if (allowed) { 8008 if (!mSharedLibraries.containsKey(name)) { 8009 mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName)); 8010 } else if (!name.equals(pkg.packageName)) { 8011 Slog.w(TAG, "Package " + pkg.packageName + " library " 8012 + name + " already exists; skipping"); 8013 } 8014 } else { 8015 Slog.w(TAG, "Package " + pkg.packageName + " declares lib " 8016 + name + " that is not declared on system image; skipping"); 8017 } 8018 } 8019 if ((scanFlags & SCAN_BOOTING) == 0) { 8020 // If we are not booting, we need to update any applications 8021 // that are clients of our shared library. If we are booting, 8022 // this will all be done once the scan is complete. 8023 clientLibPkgs = updateAllSharedLibrariesLPw(pkg); 8024 } 8025 } 8026 } 8027 } 8028 8029 // Request the ActivityManager to kill the process(only for existing packages) 8030 // so that we do not end up in a confused state while the user is still using the older 8031 // version of the application while the new one gets installed. 8032 final boolean isReplacing = (scanFlags & SCAN_REPLACING) != 0; 8033 final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0; 8034 if (killApp) { 8035 if (isReplacing) { 8036 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "killApplication"); 8037 8038 killApplication(pkg.applicationInfo.packageName, 8039 pkg.applicationInfo.uid, "replace pkg"); 8040 8041 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 8042 } 8043 } 8044 8045 // Also need to kill any apps that are dependent on the library. 8046 if (clientLibPkgs != null) { 8047 for (int i=0; i<clientLibPkgs.size(); i++) { 8048 PackageParser.Package clientPkg = clientLibPkgs.get(i); 8049 killApplication(clientPkg.applicationInfo.packageName, 8050 clientPkg.applicationInfo.uid, "update lib"); 8051 } 8052 } 8053 8054 // Make sure we're not adding any bogus keyset info 8055 KeySetManagerService ksms = mSettings.mKeySetManagerService; 8056 ksms.assertScannedPackageValid(pkg); 8057 8058 // writer 8059 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 8060 8061 boolean createIdmapFailed = false; 8062 synchronized (mPackages) { 8063 // We don't expect installation to fail beyond this point 8064 8065 // Add the new setting to mSettings 8066 mSettings.insertPackageSettingLPw(pkgSetting, pkg); 8067 // Add the new setting to mPackages 8068 mPackages.put(pkg.applicationInfo.packageName, pkg); 8069 // Make sure we don't accidentally delete its data. 8070 final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator(); 8071 while (iter.hasNext()) { 8072 PackageCleanItem item = iter.next(); 8073 if (pkgName.equals(item.packageName)) { 8074 iter.remove(); 8075 } 8076 } 8077 8078 // Take care of first install / last update times. 8079 if (currentTime != 0) { 8080 if (pkgSetting.firstInstallTime == 0) { 8081 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime; 8082 } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) { 8083 pkgSetting.lastUpdateTime = currentTime; 8084 } 8085 } else if (pkgSetting.firstInstallTime == 0) { 8086 // We need *something*. Take time time stamp of the file. 8087 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime; 8088 } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) { 8089 if (scanFileTime != pkgSetting.timeStamp) { 8090 // A package on the system image has changed; consider this 8091 // to be an update. 8092 pkgSetting.lastUpdateTime = scanFileTime; 8093 } 8094 } 8095 8096 // Add the package's KeySets to the global KeySetManagerService 8097 ksms.addScannedPackageLPw(pkg); 8098 8099 int N = pkg.providers.size(); 8100 StringBuilder r = null; 8101 int i; 8102 for (i=0; i<N; i++) { 8103 PackageParser.Provider p = pkg.providers.get(i); 8104 p.info.processName = fixProcessName(pkg.applicationInfo.processName, 8105 p.info.processName, pkg.applicationInfo.uid); 8106 mProviders.addProvider(p); 8107 p.syncable = p.info.isSyncable; 8108 if (p.info.authority != null) { 8109 String names[] = p.info.authority.split(";"); 8110 p.info.authority = null; 8111 for (int j = 0; j < names.length; j++) { 8112 if (j == 1 && p.syncable) { 8113 // We only want the first authority for a provider to possibly be 8114 // syncable, so if we already added this provider using a different 8115 // authority clear the syncable flag. We copy the provider before 8116 // changing it because the mProviders object contains a reference 8117 // to a provider that we don't want to change. 8118 // Only do this for the second authority since the resulting provider 8119 // object can be the same for all future authorities for this provider. 8120 p = new PackageParser.Provider(p); 8121 p.syncable = false; 8122 } 8123 if (!mProvidersByAuthority.containsKey(names[j])) { 8124 mProvidersByAuthority.put(names[j], p); 8125 if (p.info.authority == null) { 8126 p.info.authority = names[j]; 8127 } else { 8128 p.info.authority = p.info.authority + ";" + names[j]; 8129 } 8130 if (DEBUG_PACKAGE_SCANNING) { 8131 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 8132 Log.d(TAG, "Registered content provider: " + names[j] 8133 + ", className = " + p.info.name + ", isSyncable = " 8134 + p.info.isSyncable); 8135 } 8136 } else { 8137 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 8138 Slog.w(TAG, "Skipping provider name " + names[j] + 8139 " (in package " + pkg.applicationInfo.packageName + 8140 "): name already used by " 8141 + ((other != null && other.getComponentName() != null) 8142 ? other.getComponentName().getPackageName() : "?")); 8143 } 8144 } 8145 } 8146 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8147 if (r == null) { 8148 r = new StringBuilder(256); 8149 } else { 8150 r.append(' '); 8151 } 8152 r.append(p.info.name); 8153 } 8154 } 8155 if (r != null) { 8156 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r); 8157 } 8158 8159 N = pkg.services.size(); 8160 r = null; 8161 for (i=0; i<N; i++) { 8162 PackageParser.Service s = pkg.services.get(i); 8163 s.info.processName = fixProcessName(pkg.applicationInfo.processName, 8164 s.info.processName, pkg.applicationInfo.uid); 8165 mServices.addService(s); 8166 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8167 if (r == null) { 8168 r = new StringBuilder(256); 8169 } else { 8170 r.append(' '); 8171 } 8172 r.append(s.info.name); 8173 } 8174 } 8175 if (r != null) { 8176 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r); 8177 } 8178 8179 N = pkg.receivers.size(); 8180 r = null; 8181 for (i=0; i<N; i++) { 8182 PackageParser.Activity a = pkg.receivers.get(i); 8183 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 8184 a.info.processName, pkg.applicationInfo.uid); 8185 mReceivers.addActivity(a, "receiver"); 8186 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8187 if (r == null) { 8188 r = new StringBuilder(256); 8189 } else { 8190 r.append(' '); 8191 } 8192 r.append(a.info.name); 8193 } 8194 } 8195 if (r != null) { 8196 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r); 8197 } 8198 8199 N = pkg.activities.size(); 8200 r = null; 8201 for (i=0; i<N; i++) { 8202 PackageParser.Activity a = pkg.activities.get(i); 8203 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 8204 a.info.processName, pkg.applicationInfo.uid); 8205 mActivities.addActivity(a, "activity"); 8206 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8207 if (r == null) { 8208 r = new StringBuilder(256); 8209 } else { 8210 r.append(' '); 8211 } 8212 r.append(a.info.name); 8213 } 8214 } 8215 if (r != null) { 8216 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r); 8217 } 8218 8219 N = pkg.permissionGroups.size(); 8220 r = null; 8221 for (i=0; i<N; i++) { 8222 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i); 8223 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name); 8224 if (cur == null) { 8225 mPermissionGroups.put(pg.info.name, pg); 8226 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8227 if (r == null) { 8228 r = new StringBuilder(256); 8229 } else { 8230 r.append(' '); 8231 } 8232 r.append(pg.info.name); 8233 } 8234 } else { 8235 Slog.w(TAG, "Permission group " + pg.info.name + " from package " 8236 + pg.info.packageName + " ignored: original from " 8237 + cur.info.packageName); 8238 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8239 if (r == null) { 8240 r = new StringBuilder(256); 8241 } else { 8242 r.append(' '); 8243 } 8244 r.append("DUP:"); 8245 r.append(pg.info.name); 8246 } 8247 } 8248 } 8249 if (r != null) { 8250 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permission Groups: " + r); 8251 } 8252 8253 N = pkg.permissions.size(); 8254 r = null; 8255 for (i=0; i<N; i++) { 8256 PackageParser.Permission p = pkg.permissions.get(i); 8257 8258 // Assume by default that we did not install this permission into the system. 8259 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED; 8260 8261 // Now that permission groups have a special meaning, we ignore permission 8262 // groups for legacy apps to prevent unexpected behavior. In particular, 8263 // permissions for one app being granted to someone just becase they happen 8264 // to be in a group defined by another app (before this had no implications). 8265 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) { 8266 p.group = mPermissionGroups.get(p.info.group); 8267 // Warn for a permission in an unknown group. 8268 if (p.info.group != null && p.group == null) { 8269 Slog.w(TAG, "Permission " + p.info.name + " from package " 8270 + p.info.packageName + " in an unknown group " + p.info.group); 8271 } 8272 } 8273 8274 ArrayMap<String, BasePermission> permissionMap = 8275 p.tree ? mSettings.mPermissionTrees 8276 : mSettings.mPermissions; 8277 BasePermission bp = permissionMap.get(p.info.name); 8278 8279 // Allow system apps to redefine non-system permissions 8280 if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) { 8281 final boolean currentOwnerIsSystem = (bp.perm != null 8282 && isSystemApp(bp.perm.owner)); 8283 if (isSystemApp(p.owner)) { 8284 if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) { 8285 // It's a built-in permission and no owner, take ownership now 8286 bp.packageSetting = pkgSetting; 8287 bp.perm = p; 8288 bp.uid = pkg.applicationInfo.uid; 8289 bp.sourcePackage = p.info.packageName; 8290 p.info.flags |= PermissionInfo.FLAG_INSTALLED; 8291 } else if (!currentOwnerIsSystem) { 8292 String msg = "New decl " + p.owner + " of permission " 8293 + p.info.name + " is system; overriding " + bp.sourcePackage; 8294 reportSettingsProblem(Log.WARN, msg); 8295 bp = null; 8296 } 8297 } 8298 } 8299 8300 if (bp == null) { 8301 bp = new BasePermission(p.info.name, p.info.packageName, 8302 BasePermission.TYPE_NORMAL); 8303 permissionMap.put(p.info.name, bp); 8304 } 8305 8306 if (bp.perm == null) { 8307 if (bp.sourcePackage == null 8308 || bp.sourcePackage.equals(p.info.packageName)) { 8309 BasePermission tree = findPermissionTreeLP(p.info.name); 8310 if (tree == null 8311 || tree.sourcePackage.equals(p.info.packageName)) { 8312 bp.packageSetting = pkgSetting; 8313 bp.perm = p; 8314 bp.uid = pkg.applicationInfo.uid; 8315 bp.sourcePackage = p.info.packageName; 8316 p.info.flags |= PermissionInfo.FLAG_INSTALLED; 8317 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8318 if (r == null) { 8319 r = new StringBuilder(256); 8320 } else { 8321 r.append(' '); 8322 } 8323 r.append(p.info.name); 8324 } 8325 } else { 8326 Slog.w(TAG, "Permission " + p.info.name + " from package " 8327 + p.info.packageName + " ignored: base tree " 8328 + tree.name + " is from package " 8329 + tree.sourcePackage); 8330 } 8331 } else { 8332 Slog.w(TAG, "Permission " + p.info.name + " from package " 8333 + p.info.packageName + " ignored: original from " 8334 + bp.sourcePackage); 8335 } 8336 } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8337 if (r == null) { 8338 r = new StringBuilder(256); 8339 } else { 8340 r.append(' '); 8341 } 8342 r.append("DUP:"); 8343 r.append(p.info.name); 8344 } 8345 if (bp.perm == p) { 8346 bp.protectionLevel = p.info.protectionLevel; 8347 } 8348 } 8349 8350 if (r != null) { 8351 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permissions: " + r); 8352 } 8353 8354 N = pkg.instrumentation.size(); 8355 r = null; 8356 for (i=0; i<N; i++) { 8357 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 8358 a.info.packageName = pkg.applicationInfo.packageName; 8359 a.info.sourceDir = pkg.applicationInfo.sourceDir; 8360 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir; 8361 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs; 8362 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs; 8363 a.info.dataDir = pkg.applicationInfo.dataDir; 8364 a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir; 8365 a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir; 8366 8367 // TODO: Update instrumentation.nativeLibraryDir as well ? Does it 8368 // need other information about the application, like the ABI and what not ? 8369 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir; 8370 mInstrumentation.put(a.getComponentName(), a); 8371 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8372 if (r == null) { 8373 r = new StringBuilder(256); 8374 } else { 8375 r.append(' '); 8376 } 8377 r.append(a.info.name); 8378 } 8379 } 8380 if (r != null) { 8381 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r); 8382 } 8383 8384 if (pkg.protectedBroadcasts != null) { 8385 N = pkg.protectedBroadcasts.size(); 8386 for (i=0; i<N; i++) { 8387 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i)); 8388 } 8389 } 8390 8391 pkgSetting.setTimeStamp(scanFileTime); 8392 8393 // Create idmap files for pairs of (packages, overlay packages). 8394 // Note: "android", ie framework-res.apk, is handled by native layers. 8395 if (pkg.mOverlayTarget != null) { 8396 // This is an overlay package. 8397 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) { 8398 if (!mOverlays.containsKey(pkg.mOverlayTarget)) { 8399 mOverlays.put(pkg.mOverlayTarget, 8400 new ArrayMap<String, PackageParser.Package>()); 8401 } 8402 ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget); 8403 map.put(pkg.packageName, pkg); 8404 PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget); 8405 if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) { 8406 createIdmapFailed = true; 8407 } 8408 } 8409 } else if (mOverlays.containsKey(pkg.packageName) && 8410 !pkg.packageName.equals("android")) { 8411 // This is a regular package, with one or more known overlay packages. 8412 createIdmapsForPackageLI(pkg); 8413 } 8414 } 8415 8416 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 8417 8418 if (createIdmapFailed) { 8419 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 8420 "scanPackageLI failed to createIdmap"); 8421 } 8422 return pkg; 8423 } 8424 8425 /** 8426 * Derive the ABI of a non-system package located at {@code scanFile}. This information 8427 * is derived purely on the basis of the contents of {@code scanFile} and 8428 * {@code cpuAbiOverride}. 8429 * 8430 * If {@code extractLibs} is true, native libraries are extracted from the app if required. 8431 */ 8432 private void derivePackageAbi(PackageParser.Package pkg, File scanFile, 8433 String cpuAbiOverride, boolean extractLibs) 8434 throws PackageManagerException { 8435 // TODO: We can probably be smarter about this stuff. For installed apps, 8436 // we can calculate this information at install time once and for all. For 8437 // system apps, we can probably assume that this information doesn't change 8438 // after the first boot scan. As things stand, we do lots of unnecessary work. 8439 8440 // Give ourselves some initial paths; we'll come back for another 8441 // pass once we've determined ABI below. 8442 setNativeLibraryPaths(pkg); 8443 8444 // We would never need to extract libs for forward-locked and external packages, 8445 // since the container service will do it for us. We shouldn't attempt to 8446 // extract libs from system app when it was not updated. 8447 if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() || 8448 (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) { 8449 extractLibs = false; 8450 } 8451 8452 final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir; 8453 final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa; 8454 8455 NativeLibraryHelper.Handle handle = null; 8456 try { 8457 handle = NativeLibraryHelper.Handle.create(pkg); 8458 // TODO(multiArch): This can be null for apps that didn't go through the 8459 // usual installation process. We can calculate it again, like we 8460 // do during install time. 8461 // 8462 // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally 8463 // unnecessary. 8464 final File nativeLibraryRoot = new File(nativeLibraryRootStr); 8465 8466 // Null out the abis so that they can be recalculated. 8467 pkg.applicationInfo.primaryCpuAbi = null; 8468 pkg.applicationInfo.secondaryCpuAbi = null; 8469 if (isMultiArch(pkg.applicationInfo)) { 8470 // Warn if we've set an abiOverride for multi-lib packages.. 8471 // By definition, we need to copy both 32 and 64 bit libraries for 8472 // such packages. 8473 if (pkg.cpuAbiOverride != null 8474 && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) { 8475 Slog.w(TAG, "Ignoring abiOverride for multi arch application."); 8476 } 8477 8478 int abi32 = PackageManager.NO_NATIVE_LIBRARIES; 8479 int abi64 = PackageManager.NO_NATIVE_LIBRARIES; 8480 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) { 8481 if (extractLibs) { 8482 abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 8483 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS, 8484 useIsaSpecificSubdirs); 8485 } else { 8486 abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS); 8487 } 8488 } 8489 8490 maybeThrowExceptionForMultiArchCopy( 8491 "Error unpackaging 32 bit native libs for multiarch app.", abi32); 8492 8493 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) { 8494 if (extractLibs) { 8495 abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 8496 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS, 8497 useIsaSpecificSubdirs); 8498 } else { 8499 abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS); 8500 } 8501 } 8502 8503 maybeThrowExceptionForMultiArchCopy( 8504 "Error unpackaging 64 bit native libs for multiarch app.", abi64); 8505 8506 if (abi64 >= 0) { 8507 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64]; 8508 } 8509 8510 if (abi32 >= 0) { 8511 final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32]; 8512 if (abi64 >= 0) { 8513 if (cpuAbiOverride == null && pkg.use32bitAbi) { 8514 pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi; 8515 pkg.applicationInfo.primaryCpuAbi = abi; 8516 } else { 8517 pkg.applicationInfo.secondaryCpuAbi = abi; 8518 } 8519 } else { 8520 pkg.applicationInfo.primaryCpuAbi = abi; 8521 } 8522 } 8523 8524 } else { 8525 String[] abiList = (cpuAbiOverride != null) ? 8526 new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS; 8527 8528 // Enable gross and lame hacks for apps that are built with old 8529 // SDK tools. We must scan their APKs for renderscript bitcode and 8530 // not launch them if it's present. Don't bother checking on devices 8531 // that don't have 64 bit support. 8532 boolean needsRenderScriptOverride = false; 8533 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null && 8534 NativeLibraryHelper.hasRenderscriptBitcode(handle)) { 8535 abiList = Build.SUPPORTED_32_BIT_ABIS; 8536 needsRenderScriptOverride = true; 8537 } 8538 8539 final int copyRet; 8540 if (extractLibs) { 8541 copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 8542 nativeLibraryRoot, abiList, useIsaSpecificSubdirs); 8543 } else { 8544 copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList); 8545 } 8546 8547 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { 8548 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, 8549 "Error unpackaging native libs for app, errorCode=" + copyRet); 8550 } 8551 8552 if (copyRet >= 0) { 8553 pkg.applicationInfo.primaryCpuAbi = abiList[copyRet]; 8554 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) { 8555 pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride; 8556 } else if (needsRenderScriptOverride) { 8557 pkg.applicationInfo.primaryCpuAbi = abiList[0]; 8558 } 8559 } 8560 } catch (IOException ioe) { 8561 Slog.e(TAG, "Unable to get canonical file " + ioe.toString()); 8562 } finally { 8563 IoUtils.closeQuietly(handle); 8564 } 8565 8566 // Now that we've calculated the ABIs and determined if it's an internal app, 8567 // we will go ahead and populate the nativeLibraryPath. 8568 setNativeLibraryPaths(pkg); 8569 } 8570 8571 /** 8572 * Adjusts ABIs for a set of packages belonging to a shared user so that they all match. 8573 * i.e, so that all packages can be run inside a single process if required. 8574 * 8575 * Optionally, callers can pass in a parsed package via {@code newPackage} in which case 8576 * this function will either try and make the ABI for all packages in {@code packagesForUser} 8577 * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match 8578 * the ABI selected for {@code packagesForUser}. This variant is used when installing or 8579 * updating a package that belongs to a shared user. 8580 * 8581 * NOTE: We currently only match for the primary CPU abi string. Matching the secondary 8582 * adds unnecessary complexity. 8583 */ 8584 private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser, 8585 PackageParser.Package scannedPackage, boolean bootComplete) { 8586 String requiredInstructionSet = null; 8587 if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) { 8588 requiredInstructionSet = VMRuntime.getInstructionSet( 8589 scannedPackage.applicationInfo.primaryCpuAbi); 8590 } 8591 8592 PackageSetting requirer = null; 8593 for (PackageSetting ps : packagesForUser) { 8594 // If packagesForUser contains scannedPackage, we skip it. This will happen 8595 // when scannedPackage is an update of an existing package. Without this check, 8596 // we will never be able to change the ABI of any package belonging to a shared 8597 // user, even if it's compatible with other packages. 8598 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 8599 if (ps.primaryCpuAbiString == null) { 8600 continue; 8601 } 8602 8603 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString); 8604 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) { 8605 // We have a mismatch between instruction sets (say arm vs arm64) warn about 8606 // this but there's not much we can do. 8607 String errorMessage = "Instruction set mismatch, " 8608 + ((requirer == null) ? "[caller]" : requirer) 8609 + " requires " + requiredInstructionSet + " whereas " + ps 8610 + " requires " + instructionSet; 8611 Slog.w(TAG, errorMessage); 8612 } 8613 8614 if (requiredInstructionSet == null) { 8615 requiredInstructionSet = instructionSet; 8616 requirer = ps; 8617 } 8618 } 8619 } 8620 8621 if (requiredInstructionSet != null) { 8622 String adjustedAbi; 8623 if (requirer != null) { 8624 // requirer != null implies that either scannedPackage was null or that scannedPackage 8625 // did not require an ABI, in which case we have to adjust scannedPackage to match 8626 // the ABI of the set (which is the same as requirer's ABI) 8627 adjustedAbi = requirer.primaryCpuAbiString; 8628 if (scannedPackage != null) { 8629 scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi; 8630 } 8631 } else { 8632 // requirer == null implies that we're updating all ABIs in the set to 8633 // match scannedPackage. 8634 adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi; 8635 } 8636 8637 for (PackageSetting ps : packagesForUser) { 8638 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 8639 if (ps.primaryCpuAbiString != null) { 8640 continue; 8641 } 8642 8643 ps.primaryCpuAbiString = adjustedAbi; 8644 if (ps.pkg != null && ps.pkg.applicationInfo != null && 8645 !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) { 8646 ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi; 8647 Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi 8648 + " (requirer=" 8649 + (requirer == null ? "null" : requirer.pkg.packageName) 8650 + ", scannedPackage=" 8651 + (scannedPackage != null ? scannedPackage.packageName : "null") 8652 + ")"); 8653 try { 8654 mInstaller.rmdex(ps.codePathString, 8655 getDexCodeInstructionSet(getPreferredInstructionSet())); 8656 } catch (InstallerException ignored) { 8657 } 8658 } 8659 } 8660 } 8661 } 8662 } 8663 8664 private void setUpCustomResolverActivity(PackageParser.Package pkg) { 8665 synchronized (mPackages) { 8666 mResolverReplaced = true; 8667 // Set up information for custom user intent resolution activity. 8668 mResolveActivity.applicationInfo = pkg.applicationInfo; 8669 mResolveActivity.name = mCustomResolverComponentName.getClassName(); 8670 mResolveActivity.packageName = pkg.applicationInfo.packageName; 8671 mResolveActivity.processName = pkg.applicationInfo.packageName; 8672 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 8673 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS | 8674 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 8675 mResolveActivity.theme = 0; 8676 mResolveActivity.exported = true; 8677 mResolveActivity.enabled = true; 8678 mResolveInfo.activityInfo = mResolveActivity; 8679 mResolveInfo.priority = 0; 8680 mResolveInfo.preferredOrder = 0; 8681 mResolveInfo.match = 0; 8682 mResolveComponentName = mCustomResolverComponentName; 8683 Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " + 8684 mResolveComponentName); 8685 } 8686 } 8687 8688 private void setUpEphemeralInstallerActivityLP(ComponentName installerComponent) { 8689 final PackageParser.Package pkg = mPackages.get(installerComponent.getPackageName()); 8690 8691 // Set up information for ephemeral installer activity 8692 mEphemeralInstallerActivity.applicationInfo = pkg.applicationInfo; 8693 mEphemeralInstallerActivity.name = mEphemeralInstallerComponent.getClassName(); 8694 mEphemeralInstallerActivity.packageName = pkg.applicationInfo.packageName; 8695 mEphemeralInstallerActivity.processName = pkg.applicationInfo.packageName; 8696 mEphemeralInstallerActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 8697 mEphemeralInstallerActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS | 8698 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 8699 mEphemeralInstallerActivity.theme = 0; 8700 mEphemeralInstallerActivity.exported = true; 8701 mEphemeralInstallerActivity.enabled = true; 8702 mEphemeralInstallerInfo.activityInfo = mEphemeralInstallerActivity; 8703 mEphemeralInstallerInfo.priority = 0; 8704 mEphemeralInstallerInfo.preferredOrder = 0; 8705 mEphemeralInstallerInfo.match = 0; 8706 8707 if (DEBUG_EPHEMERAL) { 8708 Slog.d(TAG, "Set ephemeral installer activity: " + mEphemeralInstallerComponent); 8709 } 8710 } 8711 8712 private static String calculateBundledApkRoot(final String codePathString) { 8713 final File codePath = new File(codePathString); 8714 final File codeRoot; 8715 if (FileUtils.contains(Environment.getRootDirectory(), codePath)) { 8716 codeRoot = Environment.getRootDirectory(); 8717 } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) { 8718 codeRoot = Environment.getOemDirectory(); 8719 } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) { 8720 codeRoot = Environment.getVendorDirectory(); 8721 } else { 8722 // Unrecognized code path; take its top real segment as the apk root: 8723 // e.g. /something/app/blah.apk => /something 8724 try { 8725 File f = codePath.getCanonicalFile(); 8726 File parent = f.getParentFile(); // non-null because codePath is a file 8727 File tmp; 8728 while ((tmp = parent.getParentFile()) != null) { 8729 f = parent; 8730 parent = tmp; 8731 } 8732 codeRoot = f; 8733 Slog.w(TAG, "Unrecognized code path " 8734 + codePath + " - using " + codeRoot); 8735 } catch (IOException e) { 8736 // Can't canonicalize the code path -- shenanigans? 8737 Slog.w(TAG, "Can't canonicalize code path " + codePath); 8738 return Environment.getRootDirectory().getPath(); 8739 } 8740 } 8741 return codeRoot.getPath(); 8742 } 8743 8744 /** 8745 * Derive and set the location of native libraries for the given package, 8746 * which varies depending on where and how the package was installed. 8747 */ 8748 private void setNativeLibraryPaths(PackageParser.Package pkg) { 8749 final ApplicationInfo info = pkg.applicationInfo; 8750 final String codePath = pkg.codePath; 8751 final File codeFile = new File(codePath); 8752 final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp(); 8753 final boolean asecApp = info.isForwardLocked() || info.isExternalAsec(); 8754 8755 info.nativeLibraryRootDir = null; 8756 info.nativeLibraryRootRequiresIsa = false; 8757 info.nativeLibraryDir = null; 8758 info.secondaryNativeLibraryDir = null; 8759 8760 if (isApkFile(codeFile)) { 8761 // Monolithic install 8762 if (bundledApp) { 8763 // If "/system/lib64/apkname" exists, assume that is the per-package 8764 // native library directory to use; otherwise use "/system/lib/apkname". 8765 final String apkRoot = calculateBundledApkRoot(info.sourceDir); 8766 final boolean is64Bit = VMRuntime.is64BitInstructionSet( 8767 getPrimaryInstructionSet(info)); 8768 8769 // This is a bundled system app so choose the path based on the ABI. 8770 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this 8771 // is just the default path. 8772 final String apkName = deriveCodePathName(codePath); 8773 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME; 8774 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir, 8775 apkName).getAbsolutePath(); 8776 8777 if (info.secondaryCpuAbi != null) { 8778 final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME; 8779 info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot), 8780 secondaryLibDir, apkName).getAbsolutePath(); 8781 } 8782 } else if (asecApp) { 8783 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME) 8784 .getAbsolutePath(); 8785 } else { 8786 final String apkName = deriveCodePathName(codePath); 8787 info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName) 8788 .getAbsolutePath(); 8789 } 8790 8791 info.nativeLibraryRootRequiresIsa = false; 8792 info.nativeLibraryDir = info.nativeLibraryRootDir; 8793 } else { 8794 // Cluster install 8795 info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath(); 8796 info.nativeLibraryRootRequiresIsa = true; 8797 8798 info.nativeLibraryDir = new File(info.nativeLibraryRootDir, 8799 getPrimaryInstructionSet(info)).getAbsolutePath(); 8800 8801 if (info.secondaryCpuAbi != null) { 8802 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir, 8803 VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath(); 8804 } 8805 } 8806 } 8807 8808 /** 8809 * Calculate the abis and roots for a bundled app. These can uniquely 8810 * be determined from the contents of the system partition, i.e whether 8811 * it contains 64 or 32 bit shared libraries etc. We do not validate any 8812 * of this information, and instead assume that the system was built 8813 * sensibly. 8814 */ 8815 private void setBundledAppAbisAndRoots(PackageParser.Package pkg, 8816 PackageSetting pkgSetting) { 8817 final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath()); 8818 8819 // If "/system/lib64/apkname" exists, assume that is the per-package 8820 // native library directory to use; otherwise use "/system/lib/apkname". 8821 final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir); 8822 setBundledAppAbi(pkg, apkRoot, apkName); 8823 // pkgSetting might be null during rescan following uninstall of updates 8824 // to a bundled app, so accommodate that possibility. The settings in 8825 // that case will be established later from the parsed package. 8826 // 8827 // If the settings aren't null, sync them up with what we've just derived. 8828 // note that apkRoot isn't stored in the package settings. 8829 if (pkgSetting != null) { 8830 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 8831 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 8832 } 8833 } 8834 8835 /** 8836 * Deduces the ABI of a bundled app and sets the relevant fields on the 8837 * parsed pkg object. 8838 * 8839 * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem} 8840 * under which system libraries are installed. 8841 * @param apkName the name of the installed package. 8842 */ 8843 private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) { 8844 final File codeFile = new File(pkg.codePath); 8845 8846 final boolean has64BitLibs; 8847 final boolean has32BitLibs; 8848 if (isApkFile(codeFile)) { 8849 // Monolithic install 8850 has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists(); 8851 has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists(); 8852 } else { 8853 // Cluster install 8854 final File rootDir = new File(codeFile, LIB_DIR_NAME); 8855 if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS) 8856 && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) { 8857 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]); 8858 has64BitLibs = (new File(rootDir, isa)).exists(); 8859 } else { 8860 has64BitLibs = false; 8861 } 8862 if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS) 8863 && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) { 8864 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]); 8865 has32BitLibs = (new File(rootDir, isa)).exists(); 8866 } else { 8867 has32BitLibs = false; 8868 } 8869 } 8870 8871 if (has64BitLibs && !has32BitLibs) { 8872 // The package has 64 bit libs, but not 32 bit libs. Its primary 8873 // ABI should be 64 bit. We can safely assume here that the bundled 8874 // native libraries correspond to the most preferred ABI in the list. 8875 8876 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 8877 pkg.applicationInfo.secondaryCpuAbi = null; 8878 } else if (has32BitLibs && !has64BitLibs) { 8879 // The package has 32 bit libs but not 64 bit libs. Its primary 8880 // ABI should be 32 bit. 8881 8882 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 8883 pkg.applicationInfo.secondaryCpuAbi = null; 8884 } else if (has32BitLibs && has64BitLibs) { 8885 // The application has both 64 and 32 bit bundled libraries. We check 8886 // here that the app declares multiArch support, and warn if it doesn't. 8887 // 8888 // We will be lenient here and record both ABIs. The primary will be the 8889 // ABI that's higher on the list, i.e, a device that's configured to prefer 8890 // 64 bit apps will see a 64 bit primary ABI, 8891 8892 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) { 8893 Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch."); 8894 } 8895 8896 if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) { 8897 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 8898 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 8899 } else { 8900 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 8901 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 8902 } 8903 } else { 8904 pkg.applicationInfo.primaryCpuAbi = null; 8905 pkg.applicationInfo.secondaryCpuAbi = null; 8906 } 8907 } 8908 8909 private void killPackage(PackageParser.Package pkg, String reason) { 8910 // Kill the parent package 8911 killApplication(pkg.packageName, pkg.applicationInfo.uid, reason); 8912 // Kill the child packages 8913 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8914 for (int i = 0; i < childCount; i++) { 8915 PackageParser.Package childPkg = pkg.childPackages.get(i); 8916 killApplication(childPkg.packageName, childPkg.applicationInfo.uid, reason); 8917 } 8918 } 8919 8920 private void killApplication(String pkgName, int appId, String reason) { 8921 // Request the ActivityManager to kill the process(only for existing packages) 8922 // so that we do not end up in a confused state while the user is still using the older 8923 // version of the application while the new one gets installed. 8924 IActivityManager am = ActivityManagerNative.getDefault(); 8925 if (am != null) { 8926 try { 8927 am.killApplicationWithAppId(pkgName, appId, reason); 8928 } catch (RemoteException e) { 8929 } 8930 } 8931 } 8932 8933 private void removePackageLI(PackageParser.Package pkg, boolean chatty) { 8934 // Remove the parent package setting 8935 PackageSetting ps = (PackageSetting) pkg.mExtras; 8936 if (ps != null) { 8937 removePackageLI(ps, chatty); 8938 } 8939 // Remove the child package setting 8940 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8941 for (int i = 0; i < childCount; i++) { 8942 PackageParser.Package childPkg = pkg.childPackages.get(i); 8943 ps = (PackageSetting) childPkg.mExtras; 8944 if (ps != null) { 8945 removePackageLI(ps, chatty); 8946 } 8947 } 8948 } 8949 8950 void removePackageLI(PackageSetting ps, boolean chatty) { 8951 if (DEBUG_INSTALL) { 8952 if (chatty) 8953 Log.d(TAG, "Removing package " + ps.name); 8954 } 8955 8956 // writer 8957 synchronized (mPackages) { 8958 mPackages.remove(ps.name); 8959 final PackageParser.Package pkg = ps.pkg; 8960 if (pkg != null) { 8961 cleanPackageDataStructuresLILPw(pkg, chatty); 8962 } 8963 } 8964 } 8965 8966 void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) { 8967 if (DEBUG_INSTALL) { 8968 if (chatty) 8969 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName); 8970 } 8971 8972 // writer 8973 synchronized (mPackages) { 8974 // Remove the parent package 8975 mPackages.remove(pkg.applicationInfo.packageName); 8976 cleanPackageDataStructuresLILPw(pkg, chatty); 8977 8978 // Remove the child packages 8979 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8980 for (int i = 0; i < childCount; i++) { 8981 PackageParser.Package childPkg = pkg.childPackages.get(i); 8982 mPackages.remove(childPkg.applicationInfo.packageName); 8983 cleanPackageDataStructuresLILPw(childPkg, chatty); 8984 } 8985 } 8986 } 8987 8988 void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) { 8989 int N = pkg.providers.size(); 8990 StringBuilder r = null; 8991 int i; 8992 for (i=0; i<N; i++) { 8993 PackageParser.Provider p = pkg.providers.get(i); 8994 mProviders.removeProvider(p); 8995 if (p.info.authority == null) { 8996 8997 /* There was another ContentProvider with this authority when 8998 * this app was installed so this authority is null, 8999 * Ignore it as we don't have to unregister the provider. 9000 */ 9001 continue; 9002 } 9003 String names[] = p.info.authority.split(";"); 9004 for (int j = 0; j < names.length; j++) { 9005 if (mProvidersByAuthority.get(names[j]) == p) { 9006 mProvidersByAuthority.remove(names[j]); 9007 if (DEBUG_REMOVE) { 9008 if (chatty) 9009 Log.d(TAG, "Unregistered content provider: " + names[j] 9010 + ", className = " + p.info.name + ", isSyncable = " 9011 + p.info.isSyncable); 9012 } 9013 } 9014 } 9015 if (DEBUG_REMOVE && chatty) { 9016 if (r == null) { 9017 r = new StringBuilder(256); 9018 } else { 9019 r.append(' '); 9020 } 9021 r.append(p.info.name); 9022 } 9023 } 9024 if (r != null) { 9025 if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r); 9026 } 9027 9028 N = pkg.services.size(); 9029 r = null; 9030 for (i=0; i<N; i++) { 9031 PackageParser.Service s = pkg.services.get(i); 9032 mServices.removeService(s); 9033 if (chatty) { 9034 if (r == null) { 9035 r = new StringBuilder(256); 9036 } else { 9037 r.append(' '); 9038 } 9039 r.append(s.info.name); 9040 } 9041 } 9042 if (r != null) { 9043 if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r); 9044 } 9045 9046 N = pkg.receivers.size(); 9047 r = null; 9048 for (i=0; i<N; i++) { 9049 PackageParser.Activity a = pkg.receivers.get(i); 9050 mReceivers.removeActivity(a, "receiver"); 9051 if (DEBUG_REMOVE && chatty) { 9052 if (r == null) { 9053 r = new StringBuilder(256); 9054 } else { 9055 r.append(' '); 9056 } 9057 r.append(a.info.name); 9058 } 9059 } 9060 if (r != null) { 9061 if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r); 9062 } 9063 9064 N = pkg.activities.size(); 9065 r = null; 9066 for (i=0; i<N; i++) { 9067 PackageParser.Activity a = pkg.activities.get(i); 9068 mActivities.removeActivity(a, "activity"); 9069 if (DEBUG_REMOVE && chatty) { 9070 if (r == null) { 9071 r = new StringBuilder(256); 9072 } else { 9073 r.append(' '); 9074 } 9075 r.append(a.info.name); 9076 } 9077 } 9078 if (r != null) { 9079 if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r); 9080 } 9081 9082 N = pkg.permissions.size(); 9083 r = null; 9084 for (i=0; i<N; i++) { 9085 PackageParser.Permission p = pkg.permissions.get(i); 9086 BasePermission bp = mSettings.mPermissions.get(p.info.name); 9087 if (bp == null) { 9088 bp = mSettings.mPermissionTrees.get(p.info.name); 9089 } 9090 if (bp != null && bp.perm == p) { 9091 bp.perm = null; 9092 if (DEBUG_REMOVE && chatty) { 9093 if (r == null) { 9094 r = new StringBuilder(256); 9095 } else { 9096 r.append(' '); 9097 } 9098 r.append(p.info.name); 9099 } 9100 } 9101 if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 9102 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name); 9103 if (appOpPkgs != null) { 9104 appOpPkgs.remove(pkg.packageName); 9105 } 9106 } 9107 } 9108 if (r != null) { 9109 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 9110 } 9111 9112 N = pkg.requestedPermissions.size(); 9113 r = null; 9114 for (i=0; i<N; i++) { 9115 String perm = pkg.requestedPermissions.get(i); 9116 BasePermission bp = mSettings.mPermissions.get(perm); 9117 if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 9118 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm); 9119 if (appOpPkgs != null) { 9120 appOpPkgs.remove(pkg.packageName); 9121 if (appOpPkgs.isEmpty()) { 9122 mAppOpPermissionPackages.remove(perm); 9123 } 9124 } 9125 } 9126 } 9127 if (r != null) { 9128 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 9129 } 9130 9131 N = pkg.instrumentation.size(); 9132 r = null; 9133 for (i=0; i<N; i++) { 9134 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 9135 mInstrumentation.remove(a.getComponentName()); 9136 if (DEBUG_REMOVE && chatty) { 9137 if (r == null) { 9138 r = new StringBuilder(256); 9139 } else { 9140 r.append(' '); 9141 } 9142 r.append(a.info.name); 9143 } 9144 } 9145 if (r != null) { 9146 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r); 9147 } 9148 9149 r = null; 9150 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9151 // Only system apps can hold shared libraries. 9152 if (pkg.libraryNames != null) { 9153 for (i=0; i<pkg.libraryNames.size(); i++) { 9154 String name = pkg.libraryNames.get(i); 9155 SharedLibraryEntry cur = mSharedLibraries.get(name); 9156 if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) { 9157 mSharedLibraries.remove(name); 9158 if (DEBUG_REMOVE && chatty) { 9159 if (r == null) { 9160 r = new StringBuilder(256); 9161 } else { 9162 r.append(' '); 9163 } 9164 r.append(name); 9165 } 9166 } 9167 } 9168 } 9169 } 9170 if (r != null) { 9171 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r); 9172 } 9173 } 9174 9175 private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) { 9176 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) { 9177 if (pkgInfo.permissions.get(i).info.name.equals(perm)) { 9178 return true; 9179 } 9180 } 9181 return false; 9182 } 9183 9184 static final int UPDATE_PERMISSIONS_ALL = 1<<0; 9185 static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1; 9186 static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2; 9187 9188 private void updatePermissionsLPw(PackageParser.Package pkg, int flags) { 9189 // Update the parent permissions 9190 updatePermissionsLPw(pkg.packageName, pkg, flags); 9191 // Update the child permissions 9192 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 9193 for (int i = 0; i < childCount; i++) { 9194 PackageParser.Package childPkg = pkg.childPackages.get(i); 9195 updatePermissionsLPw(childPkg.packageName, childPkg, flags); 9196 } 9197 } 9198 9199 private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo, 9200 int flags) { 9201 final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null; 9202 updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags); 9203 } 9204 9205 private void updatePermissionsLPw(String changingPkg, 9206 PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) { 9207 // Make sure there are no dangling permission trees. 9208 Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator(); 9209 while (it.hasNext()) { 9210 final BasePermission bp = it.next(); 9211 if (bp.packageSetting == null) { 9212 // We may not yet have parsed the package, so just see if 9213 // we still know about its settings. 9214 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 9215 } 9216 if (bp.packageSetting == null) { 9217 Slog.w(TAG, "Removing dangling permission tree: " + bp.name 9218 + " from package " + bp.sourcePackage); 9219 it.remove(); 9220 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 9221 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 9222 Slog.i(TAG, "Removing old permission tree: " + bp.name 9223 + " from package " + bp.sourcePackage); 9224 flags |= UPDATE_PERMISSIONS_ALL; 9225 it.remove(); 9226 } 9227 } 9228 } 9229 9230 // Make sure all dynamic permissions have been assigned to a package, 9231 // and make sure there are no dangling permissions. 9232 it = mSettings.mPermissions.values().iterator(); 9233 while (it.hasNext()) { 9234 final BasePermission bp = it.next(); 9235 if (bp.type == BasePermission.TYPE_DYNAMIC) { 9236 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name=" 9237 + bp.name + " pkg=" + bp.sourcePackage 9238 + " info=" + bp.pendingInfo); 9239 if (bp.packageSetting == null && bp.pendingInfo != null) { 9240 final BasePermission tree = findPermissionTreeLP(bp.name); 9241 if (tree != null && tree.perm != null) { 9242 bp.packageSetting = tree.packageSetting; 9243 bp.perm = new PackageParser.Permission(tree.perm.owner, 9244 new PermissionInfo(bp.pendingInfo)); 9245 bp.perm.info.packageName = tree.perm.info.packageName; 9246 bp.perm.info.name = bp.name; 9247 bp.uid = tree.uid; 9248 } 9249 } 9250 } 9251 if (bp.packageSetting == null) { 9252 // We may not yet have parsed the package, so just see if 9253 // we still know about its settings. 9254 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 9255 } 9256 if (bp.packageSetting == null) { 9257 Slog.w(TAG, "Removing dangling permission: " + bp.name 9258 + " from package " + bp.sourcePackage); 9259 it.remove(); 9260 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 9261 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 9262 Slog.i(TAG, "Removing old permission: " + bp.name 9263 + " from package " + bp.sourcePackage); 9264 flags |= UPDATE_PERMISSIONS_ALL; 9265 it.remove(); 9266 } 9267 } 9268 } 9269 9270 // Now update the permissions for all packages, in particular 9271 // replace the granted permissions of the system packages. 9272 if ((flags&UPDATE_PERMISSIONS_ALL) != 0) { 9273 for (PackageParser.Package pkg : mPackages.values()) { 9274 if (pkg != pkgInfo) { 9275 // Only replace for packages on requested volume 9276 final String volumeUuid = getVolumeUuidForPackage(pkg); 9277 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0) 9278 && Objects.equals(replaceVolumeUuid, volumeUuid); 9279 grantPermissionsLPw(pkg, replace, changingPkg); 9280 } 9281 } 9282 } 9283 9284 if (pkgInfo != null) { 9285 // Only replace for packages on requested volume 9286 final String volumeUuid = getVolumeUuidForPackage(pkgInfo); 9287 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0) 9288 && Objects.equals(replaceVolumeUuid, volumeUuid); 9289 grantPermissionsLPw(pkgInfo, replace, changingPkg); 9290 } 9291 } 9292 9293 private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace, 9294 String packageOfInterest) { 9295 // IMPORTANT: There are two types of permissions: install and runtime. 9296 // Install time permissions are granted when the app is installed to 9297 // all device users and users added in the future. Runtime permissions 9298 // are granted at runtime explicitly to specific users. Normal and signature 9299 // protected permissions are install time permissions. Dangerous permissions 9300 // are install permissions if the app's target SDK is Lollipop MR1 or older, 9301 // otherwise they are runtime permissions. This function does not manage 9302 // runtime permissions except for the case an app targeting Lollipop MR1 9303 // being upgraded to target a newer SDK, in which case dangerous permissions 9304 // are transformed from install time to runtime ones. 9305 9306 final PackageSetting ps = (PackageSetting) pkg.mExtras; 9307 if (ps == null) { 9308 return; 9309 } 9310 9311 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions"); 9312 9313 PermissionsState permissionsState = ps.getPermissionsState(); 9314 PermissionsState origPermissions = permissionsState; 9315 9316 final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); 9317 9318 boolean runtimePermissionsRevoked = false; 9319 int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY; 9320 9321 boolean changedInstallPermission = false; 9322 9323 if (replace) { 9324 ps.installPermissionsFixed = false; 9325 if (!ps.isSharedUser()) { 9326 origPermissions = new PermissionsState(permissionsState); 9327 permissionsState.reset(); 9328 } else { 9329 // We need to know only about runtime permission changes since the 9330 // calling code always writes the install permissions state but 9331 // the runtime ones are written only if changed. The only cases of 9332 // changed runtime permissions here are promotion of an install to 9333 // runtime and revocation of a runtime from a shared user. 9334 changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw( 9335 ps.sharedUser, UserManagerService.getInstance().getUserIds()); 9336 if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) { 9337 runtimePermissionsRevoked = true; 9338 } 9339 } 9340 } 9341 9342 permissionsState.setGlobalGids(mGlobalGids); 9343 9344 final int N = pkg.requestedPermissions.size(); 9345 for (int i=0; i<N; i++) { 9346 final String name = pkg.requestedPermissions.get(i); 9347 final BasePermission bp = mSettings.mPermissions.get(name); 9348 9349 if (DEBUG_INSTALL) { 9350 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp); 9351 } 9352 9353 if (bp == null || bp.packageSetting == null) { 9354 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 9355 Slog.w(TAG, "Unknown permission " + name 9356 + " in package " + pkg.packageName); 9357 } 9358 continue; 9359 } 9360 9361 final String perm = bp.name; 9362 boolean allowedSig = false; 9363 int grant = GRANT_DENIED; 9364 9365 // Keep track of app op permissions. 9366 if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 9367 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name); 9368 if (pkgs == null) { 9369 pkgs = new ArraySet<>(); 9370 mAppOpPermissionPackages.put(bp.name, pkgs); 9371 } 9372 pkgs.add(pkg.packageName); 9373 } 9374 9375 final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; 9376 final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion 9377 >= Build.VERSION_CODES.M; 9378 switch (level) { 9379 case PermissionInfo.PROTECTION_NORMAL: { 9380 // For all apps normal permissions are install time ones. 9381 grant = GRANT_INSTALL; 9382 } break; 9383 9384 case PermissionInfo.PROTECTION_DANGEROUS: { 9385 // If a permission review is required for legacy apps we represent 9386 // their permissions as always granted runtime ones since we need 9387 // to keep the review required permission flag per user while an 9388 // install permission's state is shared across all users. 9389 if (!appSupportsRuntimePermissions && !Build.PERMISSIONS_REVIEW_REQUIRED) { 9390 // For legacy apps dangerous permissions are install time ones. 9391 grant = GRANT_INSTALL; 9392 } else if (origPermissions.hasInstallPermission(bp.name)) { 9393 // For legacy apps that became modern, install becomes runtime. 9394 grant = GRANT_UPGRADE; 9395 } else if (mPromoteSystemApps 9396 && isSystemApp(ps) 9397 && mExistingSystemPackages.contains(ps.name)) { 9398 // For legacy system apps, install becomes runtime. 9399 // We cannot check hasInstallPermission() for system apps since those 9400 // permissions were granted implicitly and not persisted pre-M. 9401 grant = GRANT_UPGRADE; 9402 } else { 9403 // For modern apps keep runtime permissions unchanged. 9404 grant = GRANT_RUNTIME; 9405 } 9406 } break; 9407 9408 case PermissionInfo.PROTECTION_SIGNATURE: { 9409 // For all apps signature permissions are install time ones. 9410 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions); 9411 if (allowedSig) { 9412 grant = GRANT_INSTALL; 9413 } 9414 } break; 9415 } 9416 9417 if (DEBUG_INSTALL) { 9418 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm); 9419 } 9420 9421 if (grant != GRANT_DENIED) { 9422 if (!isSystemApp(ps) && ps.installPermissionsFixed) { 9423 // If this is an existing, non-system package, then 9424 // we can't add any new permissions to it. 9425 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) { 9426 // Except... if this is a permission that was added 9427 // to the platform (note: need to only do this when 9428 // updating the platform). 9429 if (!isNewPlatformPermissionForPackage(perm, pkg)) { 9430 grant = GRANT_DENIED; 9431 } 9432 } 9433 } 9434 9435 switch (grant) { 9436 case GRANT_INSTALL: { 9437 // Revoke this as runtime permission to handle the case of 9438 // a runtime permission being downgraded to an install one. Also in permission review mode we keep dangerous permissions for legacy apps 9439 for (int userId : UserManagerService.getInstance().getUserIds()) { 9440 if (origPermissions.getRuntimePermissionState( 9441 bp.name, userId) != null) { 9442 // Revoke the runtime permission and clear the flags. 9443 origPermissions.revokeRuntimePermission(bp, userId); 9444 origPermissions.updatePermissionFlags(bp, userId, 9445 PackageManager.MASK_PERMISSION_FLAGS, 0); 9446 // If we revoked a permission permission, we have to write. 9447 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 9448 changedRuntimePermissionUserIds, userId); 9449 } 9450 } 9451 // Grant an install permission. 9452 if (permissionsState.grantInstallPermission(bp) != 9453 PermissionsState.PERMISSION_OPERATION_FAILURE) { 9454 changedInstallPermission = true; 9455 } 9456 } break; 9457 9458 case GRANT_RUNTIME: { 9459 // Grant previously granted runtime permissions. 9460 for (int userId : UserManagerService.getInstance().getUserIds()) { 9461 PermissionState permissionState = origPermissions 9462 .getRuntimePermissionState(bp.name, userId); 9463 int flags = permissionState != null 9464 ? permissionState.getFlags() : 0; 9465 if (origPermissions.hasRuntimePermission(bp.name, userId)) { 9466 if (permissionsState.grantRuntimePermission(bp, userId) == 9467 PermissionsState.PERMISSION_OPERATION_FAILURE) { 9468 // If we cannot put the permission as it was, we have to write. 9469 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 9470 changedRuntimePermissionUserIds, userId); 9471 } 9472 // If the app supports runtime permissions no need for a review. 9473 if (Build.PERMISSIONS_REVIEW_REQUIRED 9474 && appSupportsRuntimePermissions 9475 && (flags & PackageManager 9476 .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) { 9477 flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 9478 // Since we changed the flags, we have to write. 9479 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 9480 changedRuntimePermissionUserIds, userId); 9481 } 9482 } else if (Build.PERMISSIONS_REVIEW_REQUIRED 9483 && !appSupportsRuntimePermissions) { 9484 // For legacy apps that need a permission review, every new 9485 // runtime permission is granted but it is pending a review. 9486 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) { 9487 permissionsState.grantRuntimePermission(bp, userId); 9488 flags |= FLAG_PERMISSION_REVIEW_REQUIRED; 9489 // We changed the permission and flags, hence have to write. 9490 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 9491 changedRuntimePermissionUserIds, userId); 9492 } 9493 } 9494 // Propagate the permission flags. 9495 permissionsState.updatePermissionFlags(bp, userId, flags, flags); 9496 } 9497 } break; 9498 9499 case GRANT_UPGRADE: { 9500 // Grant runtime permissions for a previously held install permission. 9501 PermissionState permissionState = origPermissions 9502 .getInstallPermissionState(bp.name); 9503 final int flags = permissionState != null ? permissionState.getFlags() : 0; 9504 9505 if (origPermissions.revokeInstallPermission(bp) 9506 != PermissionsState.PERMISSION_OPERATION_FAILURE) { 9507 // We will be transferring the permission flags, so clear them. 9508 origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL, 9509 PackageManager.MASK_PERMISSION_FLAGS, 0); 9510 changedInstallPermission = true; 9511 } 9512 9513 // If the permission is not to be promoted to runtime we ignore it and 9514 // also its other flags as they are not applicable to install permissions. 9515 if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) { 9516 for (int userId : currentUserIds) { 9517 if (permissionsState.grantRuntimePermission(bp, userId) != 9518 PermissionsState.PERMISSION_OPERATION_FAILURE) { 9519 // Transfer the permission flags. 9520 permissionsState.updatePermissionFlags(bp, userId, 9521 flags, flags); 9522 // If we granted the permission, we have to write. 9523 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 9524 changedRuntimePermissionUserIds, userId); 9525 } 9526 } 9527 } 9528 } break; 9529 9530 default: { 9531 if (packageOfInterest == null 9532 || packageOfInterest.equals(pkg.packageName)) { 9533 Slog.w(TAG, "Not granting permission " + perm 9534 + " to package " + pkg.packageName 9535 + " because it was previously installed without"); 9536 } 9537 } break; 9538 } 9539 } else { 9540 if (permissionsState.revokeInstallPermission(bp) != 9541 PermissionsState.PERMISSION_OPERATION_FAILURE) { 9542 // Also drop the permission flags. 9543 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 9544 PackageManager.MASK_PERMISSION_FLAGS, 0); 9545 changedInstallPermission = true; 9546 Slog.i(TAG, "Un-granting permission " + perm 9547 + " from package " + pkg.packageName 9548 + " (protectionLevel=" + bp.protectionLevel 9549 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 9550 + ")"); 9551 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) { 9552 // Don't print warning for app op permissions, since it is fine for them 9553 // not to be granted, there is a UI for the user to decide. 9554 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 9555 Slog.w(TAG, "Not granting permission " + perm 9556 + " to package " + pkg.packageName 9557 + " (protectionLevel=" + bp.protectionLevel 9558 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 9559 + ")"); 9560 } 9561 } 9562 } 9563 } 9564 9565 if ((changedInstallPermission || replace) && !ps.installPermissionsFixed && 9566 !isSystemApp(ps) || isUpdatedSystemApp(ps)){ 9567 // This is the first that we have heard about this package, so the 9568 // permissions we have now selected are fixed until explicitly 9569 // changed. 9570 ps.installPermissionsFixed = true; 9571 } 9572 9573 // Persist the runtime permissions state for users with changes. If permissions 9574 // were revoked because no app in the shared user declares them we have to 9575 // write synchronously to avoid losing runtime permissions state. 9576 for (int userId : changedRuntimePermissionUserIds) { 9577 mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked); 9578 } 9579 9580 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 9581 } 9582 9583 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) { 9584 boolean allowed = false; 9585 final int NP = PackageParser.NEW_PERMISSIONS.length; 9586 for (int ip=0; ip<NP; ip++) { 9587 final PackageParser.NewPermissionInfo npi 9588 = PackageParser.NEW_PERMISSIONS[ip]; 9589 if (npi.name.equals(perm) 9590 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) { 9591 allowed = true; 9592 Log.i(TAG, "Auto-granting " + perm + " to old pkg " 9593 + pkg.packageName); 9594 break; 9595 } 9596 } 9597 return allowed; 9598 } 9599 9600 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg, 9601 BasePermission bp, PermissionsState origPermissions) { 9602 boolean allowed; 9603 allowed = (compareSignatures( 9604 bp.packageSetting.signatures.mSignatures, pkg.mSignatures) 9605 == PackageManager.SIGNATURE_MATCH) 9606 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures) 9607 == PackageManager.SIGNATURE_MATCH); 9608 if (!allowed && (bp.protectionLevel 9609 & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) { 9610 if (isSystemApp(pkg)) { 9611 // For updated system applications, a system permission 9612 // is granted only if it had been defined by the original application. 9613 if (pkg.isUpdatedSystemApp()) { 9614 final PackageSetting sysPs = mSettings 9615 .getDisabledSystemPkgLPr(pkg.packageName); 9616 if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) { 9617 // If the original was granted this permission, we take 9618 // that grant decision as read and propagate it to the 9619 // update. 9620 if (sysPs.isPrivileged()) { 9621 allowed = true; 9622 } 9623 } else { 9624 // The system apk may have been updated with an older 9625 // version of the one on the data partition, but which 9626 // granted a new system permission that it didn't have 9627 // before. In this case we do want to allow the app to 9628 // now get the new permission if the ancestral apk is 9629 // privileged to get it. 9630 if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) { 9631 for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) { 9632 if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) { 9633 allowed = true; 9634 break; 9635 } 9636 } 9637 } 9638 // Also if a privileged parent package on the system image or any of 9639 // its children requested a privileged permission, the updated child 9640 // packages can also get the permission. 9641 if (pkg.parentPackage != null) { 9642 final PackageSetting disabledSysParentPs = mSettings 9643 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName); 9644 if (disabledSysParentPs != null && disabledSysParentPs.pkg != null 9645 && disabledSysParentPs.isPrivileged()) { 9646 if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) { 9647 allowed = true; 9648 } else if (disabledSysParentPs.pkg.childPackages != null) { 9649 final int count = disabledSysParentPs.pkg.childPackages.size(); 9650 for (int i = 0; i < count; i++) { 9651 PackageParser.Package disabledSysChildPkg = 9652 disabledSysParentPs.pkg.childPackages.get(i); 9653 if (isPackageRequestingPermission(disabledSysChildPkg, 9654 perm)) { 9655 allowed = true; 9656 break; 9657 } 9658 } 9659 } 9660 } 9661 } 9662 } 9663 } else { 9664 allowed = isPrivilegedApp(pkg); 9665 } 9666 } 9667 } 9668 if (!allowed) { 9669 if (!allowed && (bp.protectionLevel 9670 & PermissionInfo.PROTECTION_FLAG_PRE23) != 0 9671 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 9672 // If this was a previously normal/dangerous permission that got moved 9673 // to a system permission as part of the runtime permission redesign, then 9674 // we still want to blindly grant it to old apps. 9675 allowed = true; 9676 } 9677 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0 9678 && pkg.packageName.equals(mRequiredInstallerPackage)) { 9679 // If this permission is to be granted to the system installer and 9680 // this app is an installer, then it gets the permission. 9681 allowed = true; 9682 } 9683 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0 9684 && pkg.packageName.equals(mRequiredVerifierPackage)) { 9685 // If this permission is to be granted to the system verifier and 9686 // this app is a verifier, then it gets the permission. 9687 allowed = true; 9688 } 9689 if (!allowed && (bp.protectionLevel 9690 & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0 9691 && isSystemApp(pkg)) { 9692 // Any pre-installed system app is allowed to get this permission. 9693 allowed = true; 9694 } 9695 if (!allowed && (bp.protectionLevel 9696 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) { 9697 // For development permissions, a development permission 9698 // is granted only if it was already granted. 9699 allowed = origPermissions.hasInstallPermission(perm); 9700 } 9701 } 9702 return allowed; 9703 } 9704 9705 private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) { 9706 final int permCount = pkg.requestedPermissions.size(); 9707 for (int j = 0; j < permCount; j++) { 9708 String requestedPermission = pkg.requestedPermissions.get(j); 9709 if (permission.equals(requestedPermission)) { 9710 return true; 9711 } 9712 } 9713 return false; 9714 } 9715 9716 final class ActivityIntentResolver 9717 extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> { 9718 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 9719 boolean defaultOnly, int userId) { 9720 if (!sUserManager.exists(userId)) return null; 9721 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 9722 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 9723 } 9724 9725 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 9726 int userId) { 9727 if (!sUserManager.exists(userId)) return null; 9728 mFlags = flags; 9729 return super.queryIntent(intent, resolvedType, 9730 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 9731 } 9732 9733 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 9734 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) { 9735 if (!sUserManager.exists(userId)) return null; 9736 if (packageActivities == null) { 9737 return null; 9738 } 9739 mFlags = flags; 9740 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 9741 final int N = packageActivities.size(); 9742 ArrayList<PackageParser.ActivityIntentInfo[]> listCut = 9743 new ArrayList<PackageParser.ActivityIntentInfo[]>(N); 9744 9745 ArrayList<PackageParser.ActivityIntentInfo> intentFilters; 9746 for (int i = 0; i < N; ++i) { 9747 intentFilters = packageActivities.get(i).intents; 9748 if (intentFilters != null && intentFilters.size() > 0) { 9749 PackageParser.ActivityIntentInfo[] array = 9750 new PackageParser.ActivityIntentInfo[intentFilters.size()]; 9751 intentFilters.toArray(array); 9752 listCut.add(array); 9753 } 9754 } 9755 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 9756 } 9757 9758 public final void addActivity(PackageParser.Activity a, String type) { 9759 final boolean systemApp = a.info.applicationInfo.isSystemApp(); 9760 mActivities.put(a.getComponentName(), a); 9761 if (DEBUG_SHOW_INFO) 9762 Log.v( 9763 TAG, " " + type + " " + 9764 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":"); 9765 if (DEBUG_SHOW_INFO) 9766 Log.v(TAG, " Class=" + a.info.name); 9767 final int NI = a.intents.size(); 9768 for (int j=0; j<NI; j++) { 9769 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 9770 if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) { 9771 intent.setPriority(0); 9772 Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity " 9773 + a.className + " with priority > 0, forcing to 0"); 9774 } 9775 if (DEBUG_SHOW_INFO) { 9776 Log.v(TAG, " IntentFilter:"); 9777 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 9778 } 9779 if (!intent.debugCheck()) { 9780 Log.w(TAG, "==> For Activity " + a.info.name); 9781 } 9782 addFilter(intent); 9783 } 9784 } 9785 9786 public final void removeActivity(PackageParser.Activity a, String type) { 9787 mActivities.remove(a.getComponentName()); 9788 if (DEBUG_SHOW_INFO) { 9789 Log.v(TAG, " " + type + " " 9790 + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel 9791 : a.info.name) + ":"); 9792 Log.v(TAG, " Class=" + a.info.name); 9793 } 9794 final int NI = a.intents.size(); 9795 for (int j=0; j<NI; j++) { 9796 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 9797 if (DEBUG_SHOW_INFO) { 9798 Log.v(TAG, " IntentFilter:"); 9799 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 9800 } 9801 removeFilter(intent); 9802 } 9803 } 9804 9805 @Override 9806 protected boolean allowFilterResult( 9807 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) { 9808 ActivityInfo filterAi = filter.activity.info; 9809 for (int i=dest.size()-1; i>=0; i--) { 9810 ActivityInfo destAi = dest.get(i).activityInfo; 9811 if (destAi.name == filterAi.name 9812 && destAi.packageName == filterAi.packageName) { 9813 return false; 9814 } 9815 } 9816 return true; 9817 } 9818 9819 @Override 9820 protected ActivityIntentInfo[] newArray(int size) { 9821 return new ActivityIntentInfo[size]; 9822 } 9823 9824 @Override 9825 protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) { 9826 if (!sUserManager.exists(userId)) return true; 9827 PackageParser.Package p = filter.activity.owner; 9828 if (p != null) { 9829 PackageSetting ps = (PackageSetting)p.mExtras; 9830 if (ps != null) { 9831 // System apps are never considered stopped for purposes of 9832 // filtering, because there may be no way for the user to 9833 // actually re-launch them. 9834 return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0 9835 && ps.getStopped(userId); 9836 } 9837 } 9838 return false; 9839 } 9840 9841 @Override 9842 protected boolean isPackageForFilter(String packageName, 9843 PackageParser.ActivityIntentInfo info) { 9844 return packageName.equals(info.activity.owner.packageName); 9845 } 9846 9847 @Override 9848 protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info, 9849 int match, int userId) { 9850 if (!sUserManager.exists(userId)) return null; 9851 if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) { 9852 return null; 9853 } 9854 final PackageParser.Activity activity = info.activity; 9855 PackageSetting ps = (PackageSetting) activity.owner.mExtras; 9856 if (ps == null) { 9857 return null; 9858 } 9859 ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags, 9860 ps.readUserState(userId), userId); 9861 if (ai == null) { 9862 return null; 9863 } 9864 final ResolveInfo res = new ResolveInfo(); 9865 res.activityInfo = ai; 9866 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 9867 res.filter = info; 9868 } 9869 if (info != null) { 9870 res.handleAllWebDataURI = info.handleAllWebDataURI(); 9871 } 9872 res.priority = info.getPriority(); 9873 res.preferredOrder = activity.owner.mPreferredOrder; 9874 //System.out.println("Result: " + res.activityInfo.className + 9875 // " = " + res.priority); 9876 res.match = match; 9877 res.isDefault = info.hasDefault; 9878 res.labelRes = info.labelRes; 9879 res.nonLocalizedLabel = info.nonLocalizedLabel; 9880 if (userNeedsBadging(userId)) { 9881 res.noResourceId = true; 9882 } else { 9883 res.icon = info.icon; 9884 } 9885 res.iconResourceId = info.icon; 9886 res.system = res.activityInfo.applicationInfo.isSystemApp(); 9887 return res; 9888 } 9889 9890 @Override 9891 protected void sortResults(List<ResolveInfo> results) { 9892 Collections.sort(results, mResolvePrioritySorter); 9893 } 9894 9895 @Override 9896 protected void dumpFilter(PrintWriter out, String prefix, 9897 PackageParser.ActivityIntentInfo filter) { 9898 out.print(prefix); out.print( 9899 Integer.toHexString(System.identityHashCode(filter.activity))); 9900 out.print(' '); 9901 filter.activity.printComponentShortName(out); 9902 out.print(" filter "); 9903 out.println(Integer.toHexString(System.identityHashCode(filter))); 9904 } 9905 9906 @Override 9907 protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) { 9908 return filter.activity; 9909 } 9910 9911 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 9912 PackageParser.Activity activity = (PackageParser.Activity)label; 9913 out.print(prefix); out.print( 9914 Integer.toHexString(System.identityHashCode(activity))); 9915 out.print(' '); 9916 activity.printComponentShortName(out); 9917 if (count > 1) { 9918 out.print(" ("); out.print(count); out.print(" filters)"); 9919 } 9920 out.println(); 9921 } 9922 9923// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 9924// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 9925// final List<ResolveInfo> retList = Lists.newArrayList(); 9926// while (i.hasNext()) { 9927// final ResolveInfo resolveInfo = i.next(); 9928// if (isEnabledLP(resolveInfo.activityInfo)) { 9929// retList.add(resolveInfo); 9930// } 9931// } 9932// return retList; 9933// } 9934 9935 // Keys are String (activity class name), values are Activity. 9936 private final ArrayMap<ComponentName, PackageParser.Activity> mActivities 9937 = new ArrayMap<ComponentName, PackageParser.Activity>(); 9938 private int mFlags; 9939 } 9940 9941 private final class ServiceIntentResolver 9942 extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> { 9943 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 9944 boolean defaultOnly, int userId) { 9945 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 9946 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 9947 } 9948 9949 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 9950 int userId) { 9951 if (!sUserManager.exists(userId)) return null; 9952 mFlags = flags; 9953 return super.queryIntent(intent, resolvedType, 9954 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 9955 } 9956 9957 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 9958 int flags, ArrayList<PackageParser.Service> packageServices, int userId) { 9959 if (!sUserManager.exists(userId)) return null; 9960 if (packageServices == null) { 9961 return null; 9962 } 9963 mFlags = flags; 9964 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 9965 final int N = packageServices.size(); 9966 ArrayList<PackageParser.ServiceIntentInfo[]> listCut = 9967 new ArrayList<PackageParser.ServiceIntentInfo[]>(N); 9968 9969 ArrayList<PackageParser.ServiceIntentInfo> intentFilters; 9970 for (int i = 0; i < N; ++i) { 9971 intentFilters = packageServices.get(i).intents; 9972 if (intentFilters != null && intentFilters.size() > 0) { 9973 PackageParser.ServiceIntentInfo[] array = 9974 new PackageParser.ServiceIntentInfo[intentFilters.size()]; 9975 intentFilters.toArray(array); 9976 listCut.add(array); 9977 } 9978 } 9979 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 9980 } 9981 9982 public final void addService(PackageParser.Service s) { 9983 mServices.put(s.getComponentName(), s); 9984 if (DEBUG_SHOW_INFO) { 9985 Log.v(TAG, " " 9986 + (s.info.nonLocalizedLabel != null 9987 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 9988 Log.v(TAG, " Class=" + s.info.name); 9989 } 9990 final int NI = s.intents.size(); 9991 int j; 9992 for (j=0; j<NI; j++) { 9993 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 9994 if (DEBUG_SHOW_INFO) { 9995 Log.v(TAG, " IntentFilter:"); 9996 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 9997 } 9998 if (!intent.debugCheck()) { 9999 Log.w(TAG, "==> For Service " + s.info.name); 10000 } 10001 addFilter(intent); 10002 } 10003 } 10004 10005 public final void removeService(PackageParser.Service s) { 10006 mServices.remove(s.getComponentName()); 10007 if (DEBUG_SHOW_INFO) { 10008 Log.v(TAG, " " + (s.info.nonLocalizedLabel != null 10009 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 10010 Log.v(TAG, " Class=" + s.info.name); 10011 } 10012 final int NI = s.intents.size(); 10013 int j; 10014 for (j=0; j<NI; j++) { 10015 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 10016 if (DEBUG_SHOW_INFO) { 10017 Log.v(TAG, " IntentFilter:"); 10018 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10019 } 10020 removeFilter(intent); 10021 } 10022 } 10023 10024 @Override 10025 protected boolean allowFilterResult( 10026 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) { 10027 ServiceInfo filterSi = filter.service.info; 10028 for (int i=dest.size()-1; i>=0; i--) { 10029 ServiceInfo destAi = dest.get(i).serviceInfo; 10030 if (destAi.name == filterSi.name 10031 && destAi.packageName == filterSi.packageName) { 10032 return false; 10033 } 10034 } 10035 return true; 10036 } 10037 10038 @Override 10039 protected PackageParser.ServiceIntentInfo[] newArray(int size) { 10040 return new PackageParser.ServiceIntentInfo[size]; 10041 } 10042 10043 @Override 10044 protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) { 10045 if (!sUserManager.exists(userId)) return true; 10046 PackageParser.Package p = filter.service.owner; 10047 if (p != null) { 10048 PackageSetting ps = (PackageSetting)p.mExtras; 10049 if (ps != null) { 10050 // System apps are never considered stopped for purposes of 10051 // filtering, because there may be no way for the user to 10052 // actually re-launch them. 10053 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 10054 && ps.getStopped(userId); 10055 } 10056 } 10057 return false; 10058 } 10059 10060 @Override 10061 protected boolean isPackageForFilter(String packageName, 10062 PackageParser.ServiceIntentInfo info) { 10063 return packageName.equals(info.service.owner.packageName); 10064 } 10065 10066 @Override 10067 protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter, 10068 int match, int userId) { 10069 if (!sUserManager.exists(userId)) return null; 10070 final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter; 10071 if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) { 10072 return null; 10073 } 10074 final PackageParser.Service service = info.service; 10075 PackageSetting ps = (PackageSetting) service.owner.mExtras; 10076 if (ps == null) { 10077 return null; 10078 } 10079 ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags, 10080 ps.readUserState(userId), userId); 10081 if (si == null) { 10082 return null; 10083 } 10084 final ResolveInfo res = new ResolveInfo(); 10085 res.serviceInfo = si; 10086 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 10087 res.filter = filter; 10088 } 10089 res.priority = info.getPriority(); 10090 res.preferredOrder = service.owner.mPreferredOrder; 10091 res.match = match; 10092 res.isDefault = info.hasDefault; 10093 res.labelRes = info.labelRes; 10094 res.nonLocalizedLabel = info.nonLocalizedLabel; 10095 res.icon = info.icon; 10096 res.system = res.serviceInfo.applicationInfo.isSystemApp(); 10097 return res; 10098 } 10099 10100 @Override 10101 protected void sortResults(List<ResolveInfo> results) { 10102 Collections.sort(results, mResolvePrioritySorter); 10103 } 10104 10105 @Override 10106 protected void dumpFilter(PrintWriter out, String prefix, 10107 PackageParser.ServiceIntentInfo filter) { 10108 out.print(prefix); out.print( 10109 Integer.toHexString(System.identityHashCode(filter.service))); 10110 out.print(' '); 10111 filter.service.printComponentShortName(out); 10112 out.print(" filter "); 10113 out.println(Integer.toHexString(System.identityHashCode(filter))); 10114 } 10115 10116 @Override 10117 protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) { 10118 return filter.service; 10119 } 10120 10121 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 10122 PackageParser.Service service = (PackageParser.Service)label; 10123 out.print(prefix); out.print( 10124 Integer.toHexString(System.identityHashCode(service))); 10125 out.print(' '); 10126 service.printComponentShortName(out); 10127 if (count > 1) { 10128 out.print(" ("); out.print(count); out.print(" filters)"); 10129 } 10130 out.println(); 10131 } 10132 10133// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 10134// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 10135// final List<ResolveInfo> retList = Lists.newArrayList(); 10136// while (i.hasNext()) { 10137// final ResolveInfo resolveInfo = (ResolveInfo) i; 10138// if (isEnabledLP(resolveInfo.serviceInfo)) { 10139// retList.add(resolveInfo); 10140// } 10141// } 10142// return retList; 10143// } 10144 10145 // Keys are String (activity class name), values are Activity. 10146 private final ArrayMap<ComponentName, PackageParser.Service> mServices 10147 = new ArrayMap<ComponentName, PackageParser.Service>(); 10148 private int mFlags; 10149 }; 10150 10151 private final class ProviderIntentResolver 10152 extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> { 10153 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 10154 boolean defaultOnly, int userId) { 10155 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 10156 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 10157 } 10158 10159 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 10160 int userId) { 10161 if (!sUserManager.exists(userId)) 10162 return null; 10163 mFlags = flags; 10164 return super.queryIntent(intent, resolvedType, 10165 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 10166 } 10167 10168 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 10169 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) { 10170 if (!sUserManager.exists(userId)) 10171 return null; 10172 if (packageProviders == null) { 10173 return null; 10174 } 10175 mFlags = flags; 10176 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; 10177 final int N = packageProviders.size(); 10178 ArrayList<PackageParser.ProviderIntentInfo[]> listCut = 10179 new ArrayList<PackageParser.ProviderIntentInfo[]>(N); 10180 10181 ArrayList<PackageParser.ProviderIntentInfo> intentFilters; 10182 for (int i = 0; i < N; ++i) { 10183 intentFilters = packageProviders.get(i).intents; 10184 if (intentFilters != null && intentFilters.size() > 0) { 10185 PackageParser.ProviderIntentInfo[] array = 10186 new PackageParser.ProviderIntentInfo[intentFilters.size()]; 10187 intentFilters.toArray(array); 10188 listCut.add(array); 10189 } 10190 } 10191 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 10192 } 10193 10194 public final void addProvider(PackageParser.Provider p) { 10195 if (mProviders.containsKey(p.getComponentName())) { 10196 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring"); 10197 return; 10198 } 10199 10200 mProviders.put(p.getComponentName(), p); 10201 if (DEBUG_SHOW_INFO) { 10202 Log.v(TAG, " " 10203 + (p.info.nonLocalizedLabel != null 10204 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 10205 Log.v(TAG, " Class=" + p.info.name); 10206 } 10207 final int NI = p.intents.size(); 10208 int j; 10209 for (j = 0; j < NI; j++) { 10210 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 10211 if (DEBUG_SHOW_INFO) { 10212 Log.v(TAG, " IntentFilter:"); 10213 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10214 } 10215 if (!intent.debugCheck()) { 10216 Log.w(TAG, "==> For Provider " + p.info.name); 10217 } 10218 addFilter(intent); 10219 } 10220 } 10221 10222 public final void removeProvider(PackageParser.Provider p) { 10223 mProviders.remove(p.getComponentName()); 10224 if (DEBUG_SHOW_INFO) { 10225 Log.v(TAG, " " + (p.info.nonLocalizedLabel != null 10226 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 10227 Log.v(TAG, " Class=" + p.info.name); 10228 } 10229 final int NI = p.intents.size(); 10230 int j; 10231 for (j = 0; j < NI; j++) { 10232 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 10233 if (DEBUG_SHOW_INFO) { 10234 Log.v(TAG, " IntentFilter:"); 10235 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10236 } 10237 removeFilter(intent); 10238 } 10239 } 10240 10241 @Override 10242 protected boolean allowFilterResult( 10243 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) { 10244 ProviderInfo filterPi = filter.provider.info; 10245 for (int i = dest.size() - 1; i >= 0; i--) { 10246 ProviderInfo destPi = dest.get(i).providerInfo; 10247 if (destPi.name == filterPi.name 10248 && destPi.packageName == filterPi.packageName) { 10249 return false; 10250 } 10251 } 10252 return true; 10253 } 10254 10255 @Override 10256 protected PackageParser.ProviderIntentInfo[] newArray(int size) { 10257 return new PackageParser.ProviderIntentInfo[size]; 10258 } 10259 10260 @Override 10261 protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) { 10262 if (!sUserManager.exists(userId)) 10263 return true; 10264 PackageParser.Package p = filter.provider.owner; 10265 if (p != null) { 10266 PackageSetting ps = (PackageSetting) p.mExtras; 10267 if (ps != null) { 10268 // System apps are never considered stopped for purposes of 10269 // filtering, because there may be no way for the user to 10270 // actually re-launch them. 10271 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 10272 && ps.getStopped(userId); 10273 } 10274 } 10275 return false; 10276 } 10277 10278 @Override 10279 protected boolean isPackageForFilter(String packageName, 10280 PackageParser.ProviderIntentInfo info) { 10281 return packageName.equals(info.provider.owner.packageName); 10282 } 10283 10284 @Override 10285 protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter, 10286 int match, int userId) { 10287 if (!sUserManager.exists(userId)) 10288 return null; 10289 final PackageParser.ProviderIntentInfo info = filter; 10290 if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) { 10291 return null; 10292 } 10293 final PackageParser.Provider provider = info.provider; 10294 PackageSetting ps = (PackageSetting) provider.owner.mExtras; 10295 if (ps == null) { 10296 return null; 10297 } 10298 ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags, 10299 ps.readUserState(userId), userId); 10300 if (pi == null) { 10301 return null; 10302 } 10303 final ResolveInfo res = new ResolveInfo(); 10304 res.providerInfo = pi; 10305 if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) { 10306 res.filter = filter; 10307 } 10308 res.priority = info.getPriority(); 10309 res.preferredOrder = provider.owner.mPreferredOrder; 10310 res.match = match; 10311 res.isDefault = info.hasDefault; 10312 res.labelRes = info.labelRes; 10313 res.nonLocalizedLabel = info.nonLocalizedLabel; 10314 res.icon = info.icon; 10315 res.system = res.providerInfo.applicationInfo.isSystemApp(); 10316 return res; 10317 } 10318 10319 @Override 10320 protected void sortResults(List<ResolveInfo> results) { 10321 Collections.sort(results, mResolvePrioritySorter); 10322 } 10323 10324 @Override 10325 protected void dumpFilter(PrintWriter out, String prefix, 10326 PackageParser.ProviderIntentInfo filter) { 10327 out.print(prefix); 10328 out.print( 10329 Integer.toHexString(System.identityHashCode(filter.provider))); 10330 out.print(' '); 10331 filter.provider.printComponentShortName(out); 10332 out.print(" filter "); 10333 out.println(Integer.toHexString(System.identityHashCode(filter))); 10334 } 10335 10336 @Override 10337 protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) { 10338 return filter.provider; 10339 } 10340 10341 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 10342 PackageParser.Provider provider = (PackageParser.Provider)label; 10343 out.print(prefix); out.print( 10344 Integer.toHexString(System.identityHashCode(provider))); 10345 out.print(' '); 10346 provider.printComponentShortName(out); 10347 if (count > 1) { 10348 out.print(" ("); out.print(count); out.print(" filters)"); 10349 } 10350 out.println(); 10351 } 10352 10353 private final ArrayMap<ComponentName, PackageParser.Provider> mProviders 10354 = new ArrayMap<ComponentName, PackageParser.Provider>(); 10355 private int mFlags; 10356 } 10357 10358 private static final class EphemeralIntentResolver 10359 extends IntentResolver<EphemeralResolveIntentInfo, EphemeralResolveInfo> { 10360 @Override 10361 protected EphemeralResolveIntentInfo[] newArray(int size) { 10362 return new EphemeralResolveIntentInfo[size]; 10363 } 10364 10365 @Override 10366 protected boolean isPackageForFilter(String packageName, EphemeralResolveIntentInfo info) { 10367 return true; 10368 } 10369 10370 @Override 10371 protected EphemeralResolveInfo newResult(EphemeralResolveIntentInfo info, int match, 10372 int userId) { 10373 if (!sUserManager.exists(userId)) { 10374 return null; 10375 } 10376 return info.getEphemeralResolveInfo(); 10377 } 10378 } 10379 10380 private static final Comparator<ResolveInfo> mResolvePrioritySorter = 10381 new Comparator<ResolveInfo>() { 10382 public int compare(ResolveInfo r1, ResolveInfo r2) { 10383 int v1 = r1.priority; 10384 int v2 = r2.priority; 10385 //System.out.println("Comparing: q1=" + q1 + " q2=" + q2); 10386 if (v1 != v2) { 10387 return (v1 > v2) ? -1 : 1; 10388 } 10389 v1 = r1.preferredOrder; 10390 v2 = r2.preferredOrder; 10391 if (v1 != v2) { 10392 return (v1 > v2) ? -1 : 1; 10393 } 10394 if (r1.isDefault != r2.isDefault) { 10395 return r1.isDefault ? -1 : 1; 10396 } 10397 v1 = r1.match; 10398 v2 = r2.match; 10399 //System.out.println("Comparing: m1=" + m1 + " m2=" + m2); 10400 if (v1 != v2) { 10401 return (v1 > v2) ? -1 : 1; 10402 } 10403 if (r1.system != r2.system) { 10404 return r1.system ? -1 : 1; 10405 } 10406 if (r1.activityInfo != null) { 10407 return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName); 10408 } 10409 if (r1.serviceInfo != null) { 10410 return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName); 10411 } 10412 if (r1.providerInfo != null) { 10413 return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName); 10414 } 10415 return 0; 10416 } 10417 }; 10418 10419 private static final Comparator<ProviderInfo> mProviderInitOrderSorter = 10420 new Comparator<ProviderInfo>() { 10421 public int compare(ProviderInfo p1, ProviderInfo p2) { 10422 final int v1 = p1.initOrder; 10423 final int v2 = p2.initOrder; 10424 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0); 10425 } 10426 }; 10427 10428 final void sendPackageBroadcast(final String action, final String pkg, final Bundle extras, 10429 final int flags, final String targetPkg, final IIntentReceiver finishedReceiver, 10430 final int[] userIds) { 10431 mHandler.post(new Runnable() { 10432 @Override 10433 public void run() { 10434 try { 10435 final IActivityManager am = ActivityManagerNative.getDefault(); 10436 if (am == null) return; 10437 final int[] resolvedUserIds; 10438 if (userIds == null) { 10439 resolvedUserIds = am.getRunningUserIds(); 10440 } else { 10441 resolvedUserIds = userIds; 10442 } 10443 for (int id : resolvedUserIds) { 10444 final Intent intent = new Intent(action, 10445 pkg != null ? Uri.fromParts("package", pkg, null) : null); 10446 if (extras != null) { 10447 intent.putExtras(extras); 10448 } 10449 if (targetPkg != null) { 10450 intent.setPackage(targetPkg); 10451 } 10452 // Modify the UID when posting to other users 10453 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); 10454 if (uid > 0 && UserHandle.getUserId(uid) != id) { 10455 uid = UserHandle.getUid(id, UserHandle.getAppId(uid)); 10456 intent.putExtra(Intent.EXTRA_UID, uid); 10457 } 10458 intent.putExtra(Intent.EXTRA_USER_HANDLE, id); 10459 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags); 10460 if (DEBUG_BROADCASTS) { 10461 RuntimeException here = new RuntimeException("here"); 10462 here.fillInStackTrace(); 10463 Slog.d(TAG, "Sending to user " + id + ": " 10464 + intent.toShortString(false, true, false, false) 10465 + " " + intent.getExtras(), here); 10466 } 10467 am.broadcastIntent(null, intent, null, finishedReceiver, 10468 0, null, null, null, android.app.AppOpsManager.OP_NONE, 10469 null, finishedReceiver != null, false, id); 10470 } 10471 } catch (RemoteException ex) { 10472 } 10473 } 10474 }); 10475 } 10476 10477 /** 10478 * Check if the external storage media is available. This is true if there 10479 * is a mounted external storage medium or if the external storage is 10480 * emulated. 10481 */ 10482 private boolean isExternalMediaAvailable() { 10483 return mMediaMounted || Environment.isExternalStorageEmulated(); 10484 } 10485 10486 @Override 10487 public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) { 10488 // writer 10489 synchronized (mPackages) { 10490 if (!isExternalMediaAvailable()) { 10491 // If the external storage is no longer mounted at this point, 10492 // the caller may not have been able to delete all of this 10493 // packages files and can not delete any more. Bail. 10494 return null; 10495 } 10496 final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned; 10497 if (lastPackage != null) { 10498 pkgs.remove(lastPackage); 10499 } 10500 if (pkgs.size() > 0) { 10501 return pkgs.get(0); 10502 } 10503 } 10504 return null; 10505 } 10506 10507 void schedulePackageCleaning(String packageName, int userId, boolean andCode) { 10508 final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE, 10509 userId, andCode ? 1 : 0, packageName); 10510 if (mSystemReady) { 10511 msg.sendToTarget(); 10512 } else { 10513 if (mPostSystemReadyMessages == null) { 10514 mPostSystemReadyMessages = new ArrayList<>(); 10515 } 10516 mPostSystemReadyMessages.add(msg); 10517 } 10518 } 10519 10520 void startCleaningPackages() { 10521 // reader 10522 if (!isExternalMediaAvailable()) { 10523 return; 10524 } 10525 synchronized (mPackages) { 10526 if (mSettings.mPackagesToBeCleaned.isEmpty()) { 10527 return; 10528 } 10529 } 10530 Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE); 10531 intent.setComponent(DEFAULT_CONTAINER_COMPONENT); 10532 IActivityManager am = ActivityManagerNative.getDefault(); 10533 if (am != null) { 10534 try { 10535 am.startService(null, intent, null, mContext.getOpPackageName(), 10536 UserHandle.USER_SYSTEM); 10537 } catch (RemoteException e) { 10538 } 10539 } 10540 } 10541 10542 @Override 10543 public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer, 10544 int installFlags, String installerPackageName, int userId) { 10545 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null); 10546 10547 final int callingUid = Binder.getCallingUid(); 10548 enforceCrossUserPermission(callingUid, userId, 10549 true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser"); 10550 10551 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 10552 try { 10553 if (observer != null) { 10554 observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null); 10555 } 10556 } catch (RemoteException re) { 10557 } 10558 return; 10559 } 10560 10561 if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) { 10562 installFlags |= PackageManager.INSTALL_FROM_ADB; 10563 10564 } else { 10565 // Caller holds INSTALL_PACKAGES permission, so we're less strict 10566 // about installerPackageName. 10567 10568 installFlags &= ~PackageManager.INSTALL_FROM_ADB; 10569 installFlags &= ~PackageManager.INSTALL_ALL_USERS; 10570 } 10571 10572 UserHandle user; 10573 if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) { 10574 user = UserHandle.ALL; 10575 } else { 10576 user = new UserHandle(userId); 10577 } 10578 10579 // Only system components can circumvent runtime permissions when installing. 10580 if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0 10581 && mContext.checkCallingOrSelfPermission(Manifest.permission 10582 .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) { 10583 throw new SecurityException("You need the " 10584 + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission " 10585 + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag"); 10586 } 10587 10588 final File originFile = new File(originPath); 10589 final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile); 10590 10591 final Message msg = mHandler.obtainMessage(INIT_COPY); 10592 final VerificationInfo verificationInfo = new VerificationInfo( 10593 null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid); 10594 final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer, 10595 installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user, 10596 null /*packageAbiOverride*/, null /*grantedPermissions*/); 10597 params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params)); 10598 msg.obj = params; 10599 10600 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser", 10601 System.identityHashCode(msg.obj)); 10602 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 10603 System.identityHashCode(msg.obj)); 10604 10605 mHandler.sendMessage(msg); 10606 } 10607 10608 void installStage(String packageName, File stagedDir, String stagedCid, 10609 IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams, 10610 String installerPackageName, int installerUid, UserHandle user) { 10611 if (DEBUG_EPHEMERAL) { 10612 if ((sessionParams.installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) { 10613 Slog.d(TAG, "Ephemeral install of " + packageName); 10614 } 10615 } 10616 final VerificationInfo verificationInfo = new VerificationInfo( 10617 sessionParams.originatingUri, sessionParams.referrerUri, 10618 sessionParams.originatingUid, installerUid); 10619 10620 final OriginInfo origin; 10621 if (stagedDir != null) { 10622 origin = OriginInfo.fromStagedFile(stagedDir); 10623 } else { 10624 origin = OriginInfo.fromStagedContainer(stagedCid); 10625 } 10626 10627 final Message msg = mHandler.obtainMessage(INIT_COPY); 10628 final InstallParams params = new InstallParams(origin, null, observer, 10629 sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid, 10630 verificationInfo, user, sessionParams.abiOverride, 10631 sessionParams.grantedRuntimePermissions); 10632 params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params)); 10633 msg.obj = params; 10634 10635 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage", 10636 System.identityHashCode(msg.obj)); 10637 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 10638 System.identityHashCode(msg.obj)); 10639 10640 mHandler.sendMessage(msg); 10641 } 10642 10643 private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, 10644 int userId) { 10645 final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting); 10646 sendPackageAddedForUser(packageName, isSystem, pkgSetting.appId, userId); 10647 } 10648 10649 private void sendPackageAddedForUser(String packageName, boolean isSystem, 10650 int appId, int userId) { 10651 Bundle extras = new Bundle(1); 10652 extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, appId)); 10653 10654 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 10655 packageName, extras, 0, null, null, new int[] {userId}); 10656 try { 10657 IActivityManager am = ActivityManagerNative.getDefault(); 10658 if (isSystem && am.isUserRunning(userId, 0)) { 10659 // The just-installed/enabled app is bundled on the system, so presumed 10660 // to be able to run automatically without needing an explicit launch. 10661 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one. 10662 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED) 10663 .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES) 10664 .setPackage(packageName); 10665 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null, 10666 android.app.AppOpsManager.OP_NONE, null, false, false, userId); 10667 } 10668 } catch (RemoteException e) { 10669 // shouldn't happen 10670 Slog.w(TAG, "Unable to bootstrap installed package", e); 10671 } 10672 } 10673 10674 @Override 10675 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, 10676 int userId) { 10677 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 10678 PackageSetting pkgSetting; 10679 final int uid = Binder.getCallingUid(); 10680 enforceCrossUserPermission(uid, userId, 10681 true /* requireFullPermission */, true /* checkShell */, 10682 "setApplicationHiddenSetting for user " + userId); 10683 10684 if (hidden && isPackageDeviceAdmin(packageName, userId)) { 10685 Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin"); 10686 return false; 10687 } 10688 10689 long callingId = Binder.clearCallingIdentity(); 10690 try { 10691 boolean sendAdded = false; 10692 boolean sendRemoved = false; 10693 // writer 10694 synchronized (mPackages) { 10695 pkgSetting = mSettings.mPackages.get(packageName); 10696 if (pkgSetting == null) { 10697 return false; 10698 } 10699 if (pkgSetting.getHidden(userId) != hidden) { 10700 pkgSetting.setHidden(hidden, userId); 10701 mSettings.writePackageRestrictionsLPr(userId); 10702 if (hidden) { 10703 sendRemoved = true; 10704 } else { 10705 sendAdded = true; 10706 } 10707 } 10708 } 10709 if (sendAdded) { 10710 sendPackageAddedForUser(packageName, pkgSetting, userId); 10711 return true; 10712 } 10713 if (sendRemoved) { 10714 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId), 10715 "hiding pkg"); 10716 sendApplicationHiddenForUser(packageName, pkgSetting, userId); 10717 return true; 10718 } 10719 } finally { 10720 Binder.restoreCallingIdentity(callingId); 10721 } 10722 return false; 10723 } 10724 10725 private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting, 10726 int userId) { 10727 final PackageRemovedInfo info = new PackageRemovedInfo(); 10728 info.removedPackage = packageName; 10729 info.removedUsers = new int[] {userId}; 10730 info.uid = UserHandle.getUid(userId, pkgSetting.appId); 10731 info.sendPackageRemovedBroadcasts(true /*killApp*/); 10732 } 10733 10734 private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) { 10735 if (pkgList.length > 0) { 10736 Bundle extras = new Bundle(1); 10737 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 10738 10739 sendPackageBroadcast( 10740 suspended ? Intent.ACTION_PACKAGES_SUSPENDED 10741 : Intent.ACTION_PACKAGES_UNSUSPENDED, 10742 null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null, 10743 new int[] {userId}); 10744 } 10745 } 10746 10747 /** 10748 * Returns true if application is not found or there was an error. Otherwise it returns 10749 * the hidden state of the package for the given user. 10750 */ 10751 @Override 10752 public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) { 10753 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 10754 enforceCrossUserPermission(Binder.getCallingUid(), userId, 10755 true /* requireFullPermission */, false /* checkShell */, 10756 "getApplicationHidden for user " + userId); 10757 PackageSetting pkgSetting; 10758 long callingId = Binder.clearCallingIdentity(); 10759 try { 10760 // writer 10761 synchronized (mPackages) { 10762 pkgSetting = mSettings.mPackages.get(packageName); 10763 if (pkgSetting == null) { 10764 return true; 10765 } 10766 return pkgSetting.getHidden(userId); 10767 } 10768 } finally { 10769 Binder.restoreCallingIdentity(callingId); 10770 } 10771 } 10772 10773 /** 10774 * @hide 10775 */ 10776 @Override 10777 public int installExistingPackageAsUser(String packageName, int userId) { 10778 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, 10779 null); 10780 PackageSetting pkgSetting; 10781 final int uid = Binder.getCallingUid(); 10782 enforceCrossUserPermission(uid, userId, 10783 true /* requireFullPermission */, true /* checkShell */, 10784 "installExistingPackage for user " + userId); 10785 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 10786 return PackageManager.INSTALL_FAILED_USER_RESTRICTED; 10787 } 10788 10789 long callingId = Binder.clearCallingIdentity(); 10790 try { 10791 boolean installed = false; 10792 10793 // writer 10794 synchronized (mPackages) { 10795 pkgSetting = mSettings.mPackages.get(packageName); 10796 if (pkgSetting == null) { 10797 return PackageManager.INSTALL_FAILED_INVALID_URI; 10798 } 10799 if (!pkgSetting.getInstalled(userId)) { 10800 pkgSetting.setInstalled(true, userId); 10801 pkgSetting.setHidden(false, userId); 10802 mSettings.writePackageRestrictionsLPr(userId); 10803 installed = true; 10804 } 10805 } 10806 10807 if (installed) { 10808 if (pkgSetting.pkg != null) { 10809 prepareAppDataAfterInstall(pkgSetting.pkg); 10810 } 10811 sendPackageAddedForUser(packageName, pkgSetting, userId); 10812 } 10813 } finally { 10814 Binder.restoreCallingIdentity(callingId); 10815 } 10816 10817 return PackageManager.INSTALL_SUCCEEDED; 10818 } 10819 10820 boolean isUserRestricted(int userId, String restrictionKey) { 10821 Bundle restrictions = sUserManager.getUserRestrictions(userId); 10822 if (restrictions.getBoolean(restrictionKey, false)) { 10823 Log.w(TAG, "User is restricted: " + restrictionKey); 10824 return true; 10825 } 10826 return false; 10827 } 10828 10829 @Override 10830 public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended, 10831 int userId) { 10832 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 10833 enforceCrossUserPermission(Binder.getCallingUid(), userId, 10834 true /* requireFullPermission */, true /* checkShell */, 10835 "setPackagesSuspended for user " + userId); 10836 10837 if (ArrayUtils.isEmpty(packageNames)) { 10838 return packageNames; 10839 } 10840 10841 // List of package names for whom the suspended state has changed. 10842 List<String> changedPackages = new ArrayList<>(packageNames.length); 10843 // List of package names for whom the suspended state is not set as requested in this 10844 // method. 10845 List<String> unactionedPackages = new ArrayList<>(packageNames.length); 10846 for (int i = 0; i < packageNames.length; i++) { 10847 String packageName = packageNames[i]; 10848 long callingId = Binder.clearCallingIdentity(); 10849 try { 10850 boolean changed = false; 10851 final int appId; 10852 synchronized (mPackages) { 10853 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName); 10854 if (pkgSetting == null) { 10855 Slog.w(TAG, "Could not find package setting for package \"" + packageName 10856 + "\". Skipping suspending/un-suspending."); 10857 unactionedPackages.add(packageName); 10858 continue; 10859 } 10860 appId = pkgSetting.appId; 10861 if (pkgSetting.getSuspended(userId) != suspended) { 10862 if (!canSuspendPackageForUserLocked(packageName, userId)) { 10863 unactionedPackages.add(packageName); 10864 continue; 10865 } 10866 pkgSetting.setSuspended(suspended, userId); 10867 mSettings.writePackageRestrictionsLPr(userId); 10868 changed = true; 10869 changedPackages.add(packageName); 10870 } 10871 } 10872 10873 if (changed && suspended) { 10874 killApplication(packageName, UserHandle.getUid(userId, appId), 10875 "suspending package"); 10876 } 10877 } finally { 10878 Binder.restoreCallingIdentity(callingId); 10879 } 10880 } 10881 10882 if (!changedPackages.isEmpty()) { 10883 sendPackagesSuspendedForUser(changedPackages.toArray( 10884 new String[changedPackages.size()]), userId, suspended); 10885 } 10886 10887 return unactionedPackages.toArray(new String[unactionedPackages.size()]); 10888 } 10889 10890 @Override 10891 public boolean isPackageSuspendedForUser(String packageName, int userId) { 10892 enforceCrossUserPermission(Binder.getCallingUid(), userId, 10893 true /* requireFullPermission */, false /* checkShell */, 10894 "isPackageSuspendedForUser for user " + userId); 10895 synchronized (mPackages) { 10896 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName); 10897 return pkgSetting != null && pkgSetting.getSuspended(userId); 10898 } 10899 } 10900 10901 /** 10902 * TODO: cache and disallow blocking the active dialer. 10903 * 10904 * @see also DefaultPermissionGrantPolicy#grantDefaultSystemHandlerPermissions 10905 */ 10906 private boolean canSuspendPackageForUserLocked(String packageName, int userId) { 10907 if (isPackageDeviceAdmin(packageName, userId)) { 10908 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 10909 + "\": has an active device admin"); 10910 return false; 10911 } 10912 10913 String activeLauncherPackageName = getActiveLauncherPackageName(userId); 10914 if (packageName.equals(activeLauncherPackageName)) { 10915 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 10916 + "\": contains the active launcher"); 10917 return false; 10918 } 10919 10920 if (packageName.equals(mRequiredInstallerPackage)) { 10921 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 10922 + "\": required for package installation"); 10923 return false; 10924 } 10925 10926 if (packageName.equals(mRequiredVerifierPackage)) { 10927 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 10928 + "\": required for package verification"); 10929 return false; 10930 } 10931 10932 final PackageParser.Package pkg = mPackages.get(packageName); 10933 if (pkg != null && isPrivilegedApp(pkg)) { 10934 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 10935 + "\": is a privileged app"); 10936 return false; 10937 } 10938 10939 return true; 10940 } 10941 10942 private String getActiveLauncherPackageName(int userId) { 10943 Intent intent = new Intent(Intent.ACTION_MAIN); 10944 intent.addCategory(Intent.CATEGORY_HOME); 10945 ResolveInfo resolveInfo = resolveIntent( 10946 intent, 10947 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 10948 PackageManager.MATCH_DEFAULT_ONLY, 10949 userId); 10950 10951 return resolveInfo == null ? null : resolveInfo.activityInfo.packageName; 10952 } 10953 10954 @Override 10955 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException { 10956 mContext.enforceCallingOrSelfPermission( 10957 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 10958 "Only package verification agents can verify applications"); 10959 10960 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 10961 final PackageVerificationResponse response = new PackageVerificationResponse( 10962 verificationCode, Binder.getCallingUid()); 10963 msg.arg1 = id; 10964 msg.obj = response; 10965 mHandler.sendMessage(msg); 10966 } 10967 10968 @Override 10969 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, 10970 long millisecondsToDelay) { 10971 mContext.enforceCallingOrSelfPermission( 10972 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 10973 "Only package verification agents can extend verification timeouts"); 10974 10975 final PackageVerificationState state = mPendingVerification.get(id); 10976 final PackageVerificationResponse response = new PackageVerificationResponse( 10977 verificationCodeAtTimeout, Binder.getCallingUid()); 10978 10979 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) { 10980 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT; 10981 } 10982 if (millisecondsToDelay < 0) { 10983 millisecondsToDelay = 0; 10984 } 10985 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW) 10986 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) { 10987 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT; 10988 } 10989 10990 if ((state != null) && !state.timeoutExtended()) { 10991 state.extendTimeout(); 10992 10993 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 10994 msg.arg1 = id; 10995 msg.obj = response; 10996 mHandler.sendMessageDelayed(msg, millisecondsToDelay); 10997 } 10998 } 10999 11000 private void broadcastPackageVerified(int verificationId, Uri packageUri, 11001 int verificationCode, UserHandle user) { 11002 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED); 11003 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE); 11004 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 11005 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 11006 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode); 11007 11008 mContext.sendBroadcastAsUser(intent, user, 11009 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT); 11010 } 11011 11012 private ComponentName matchComponentForVerifier(String packageName, 11013 List<ResolveInfo> receivers) { 11014 ActivityInfo targetReceiver = null; 11015 11016 final int NR = receivers.size(); 11017 for (int i = 0; i < NR; i++) { 11018 final ResolveInfo info = receivers.get(i); 11019 if (info.activityInfo == null) { 11020 continue; 11021 } 11022 11023 if (packageName.equals(info.activityInfo.packageName)) { 11024 targetReceiver = info.activityInfo; 11025 break; 11026 } 11027 } 11028 11029 if (targetReceiver == null) { 11030 return null; 11031 } 11032 11033 return new ComponentName(targetReceiver.packageName, targetReceiver.name); 11034 } 11035 11036 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo, 11037 List<ResolveInfo> receivers, final PackageVerificationState verificationState) { 11038 if (pkgInfo.verifiers.length == 0) { 11039 return null; 11040 } 11041 11042 final int N = pkgInfo.verifiers.length; 11043 final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1); 11044 for (int i = 0; i < N; i++) { 11045 final VerifierInfo verifierInfo = pkgInfo.verifiers[i]; 11046 11047 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName, 11048 receivers); 11049 if (comp == null) { 11050 continue; 11051 } 11052 11053 final int verifierUid = getUidForVerifier(verifierInfo); 11054 if (verifierUid == -1) { 11055 continue; 11056 } 11057 11058 if (DEBUG_VERIFY) { 11059 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName 11060 + " with the correct signature"); 11061 } 11062 sufficientVerifiers.add(comp); 11063 verificationState.addSufficientVerifier(verifierUid); 11064 } 11065 11066 return sufficientVerifiers; 11067 } 11068 11069 private int getUidForVerifier(VerifierInfo verifierInfo) { 11070 synchronized (mPackages) { 11071 final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName); 11072 if (pkg == null) { 11073 return -1; 11074 } else if (pkg.mSignatures.length != 1) { 11075 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 11076 + " has more than one signature; ignoring"); 11077 return -1; 11078 } 11079 11080 /* 11081 * If the public key of the package's signature does not match 11082 * our expected public key, then this is a different package and 11083 * we should skip. 11084 */ 11085 11086 final byte[] expectedPublicKey; 11087 try { 11088 final Signature verifierSig = pkg.mSignatures[0]; 11089 final PublicKey publicKey = verifierSig.getPublicKey(); 11090 expectedPublicKey = publicKey.getEncoded(); 11091 } catch (CertificateException e) { 11092 return -1; 11093 } 11094 11095 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded(); 11096 11097 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) { 11098 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 11099 + " does not have the expected public key; ignoring"); 11100 return -1; 11101 } 11102 11103 return pkg.applicationInfo.uid; 11104 } 11105 } 11106 11107 @Override 11108 public void finishPackageInstall(int token) { 11109 enforceSystemOrRoot("Only the system is allowed to finish installs"); 11110 11111 if (DEBUG_INSTALL) { 11112 Slog.v(TAG, "BM finishing package install for " + token); 11113 } 11114 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token); 11115 11116 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 11117 mHandler.sendMessage(msg); 11118 } 11119 11120 /** 11121 * Get the verification agent timeout. 11122 * 11123 * @return verification timeout in milliseconds 11124 */ 11125 private long getVerificationTimeout() { 11126 return android.provider.Settings.Global.getLong(mContext.getContentResolver(), 11127 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT, 11128 DEFAULT_VERIFICATION_TIMEOUT); 11129 } 11130 11131 /** 11132 * Get the default verification agent response code. 11133 * 11134 * @return default verification response code 11135 */ 11136 private int getDefaultVerificationResponse() { 11137 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 11138 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE, 11139 DEFAULT_VERIFICATION_RESPONSE); 11140 } 11141 11142 /** 11143 * Check whether or not package verification has been enabled. 11144 * 11145 * @return true if verification should be performed 11146 */ 11147 private boolean isVerificationEnabled(int userId, int installFlags) { 11148 if (!DEFAULT_VERIFY_ENABLE) { 11149 return false; 11150 } 11151 // Ephemeral apps don't get the full verification treatment 11152 if ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) { 11153 if (DEBUG_EPHEMERAL) { 11154 Slog.d(TAG, "INSTALL_EPHEMERAL so skipping verification"); 11155 } 11156 return false; 11157 } 11158 11159 boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS); 11160 11161 // Check if installing from ADB 11162 if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) { 11163 // Do not run verification in a test harness environment 11164 if (ActivityManager.isRunningInTestHarness()) { 11165 return false; 11166 } 11167 if (ensureVerifyAppsEnabled) { 11168 return true; 11169 } 11170 // Check if the developer does not want package verification for ADB installs 11171 if (android.provider.Settings.Global.getInt(mContext.getContentResolver(), 11172 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) { 11173 return false; 11174 } 11175 } 11176 11177 if (ensureVerifyAppsEnabled) { 11178 return true; 11179 } 11180 11181 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 11182 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1; 11183 } 11184 11185 @Override 11186 public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains) 11187 throws RemoteException { 11188 mContext.enforceCallingOrSelfPermission( 11189 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 11190 "Only intentfilter verification agents can verify applications"); 11191 11192 final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED); 11193 final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse( 11194 Binder.getCallingUid(), verificationCode, failedDomains); 11195 msg.arg1 = id; 11196 msg.obj = response; 11197 mHandler.sendMessage(msg); 11198 } 11199 11200 @Override 11201 public int getIntentVerificationStatus(String packageName, int userId) { 11202 synchronized (mPackages) { 11203 return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 11204 } 11205 } 11206 11207 @Override 11208 public boolean updateIntentVerificationStatus(String packageName, int status, int userId) { 11209 mContext.enforceCallingOrSelfPermission( 11210 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 11211 11212 boolean result = false; 11213 synchronized (mPackages) { 11214 result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId); 11215 } 11216 if (result) { 11217 scheduleWritePackageRestrictionsLocked(userId); 11218 } 11219 return result; 11220 } 11221 11222 @Override 11223 public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications( 11224 String packageName) { 11225 synchronized (mPackages) { 11226 return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName)); 11227 } 11228 } 11229 11230 @Override 11231 public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) { 11232 if (TextUtils.isEmpty(packageName)) { 11233 return ParceledListSlice.emptyList(); 11234 } 11235 synchronized (mPackages) { 11236 PackageParser.Package pkg = mPackages.get(packageName); 11237 if (pkg == null || pkg.activities == null) { 11238 return ParceledListSlice.emptyList(); 11239 } 11240 final int count = pkg.activities.size(); 11241 ArrayList<IntentFilter> result = new ArrayList<>(); 11242 for (int n=0; n<count; n++) { 11243 PackageParser.Activity activity = pkg.activities.get(n); 11244 if (activity.intents != null && activity.intents.size() > 0) { 11245 result.addAll(activity.intents); 11246 } 11247 } 11248 return new ParceledListSlice<>(result); 11249 } 11250 } 11251 11252 @Override 11253 public boolean setDefaultBrowserPackageName(String packageName, int userId) { 11254 mContext.enforceCallingOrSelfPermission( 11255 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 11256 11257 synchronized (mPackages) { 11258 boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId); 11259 if (packageName != null) { 11260 result |= updateIntentVerificationStatus(packageName, 11261 PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, 11262 userId); 11263 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr( 11264 packageName, userId); 11265 } 11266 return result; 11267 } 11268 } 11269 11270 @Override 11271 public String getDefaultBrowserPackageName(int userId) { 11272 synchronized (mPackages) { 11273 return mSettings.getDefaultBrowserPackageNameLPw(userId); 11274 } 11275 } 11276 11277 /** 11278 * Get the "allow unknown sources" setting. 11279 * 11280 * @return the current "allow unknown sources" setting 11281 */ 11282 private int getUnknownSourcesSettings() { 11283 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 11284 android.provider.Settings.Global.INSTALL_NON_MARKET_APPS, 11285 -1); 11286 } 11287 11288 @Override 11289 public void setInstallerPackageName(String targetPackage, String installerPackageName) { 11290 final int uid = Binder.getCallingUid(); 11291 // writer 11292 synchronized (mPackages) { 11293 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage); 11294 if (targetPackageSetting == null) { 11295 throw new IllegalArgumentException("Unknown target package: " + targetPackage); 11296 } 11297 11298 PackageSetting installerPackageSetting; 11299 if (installerPackageName != null) { 11300 installerPackageSetting = mSettings.mPackages.get(installerPackageName); 11301 if (installerPackageSetting == null) { 11302 throw new IllegalArgumentException("Unknown installer package: " 11303 + installerPackageName); 11304 } 11305 } else { 11306 installerPackageSetting = null; 11307 } 11308 11309 Signature[] callerSignature; 11310 Object obj = mSettings.getUserIdLPr(uid); 11311 if (obj != null) { 11312 if (obj instanceof SharedUserSetting) { 11313 callerSignature = ((SharedUserSetting)obj).signatures.mSignatures; 11314 } else if (obj instanceof PackageSetting) { 11315 callerSignature = ((PackageSetting)obj).signatures.mSignatures; 11316 } else { 11317 throw new SecurityException("Bad object " + obj + " for uid " + uid); 11318 } 11319 } else { 11320 throw new SecurityException("Unknown calling UID: " + uid); 11321 } 11322 11323 // Verify: can't set installerPackageName to a package that is 11324 // not signed with the same cert as the caller. 11325 if (installerPackageSetting != null) { 11326 if (compareSignatures(callerSignature, 11327 installerPackageSetting.signatures.mSignatures) 11328 != PackageManager.SIGNATURE_MATCH) { 11329 throw new SecurityException( 11330 "Caller does not have same cert as new installer package " 11331 + installerPackageName); 11332 } 11333 } 11334 11335 // Verify: if target already has an installer package, it must 11336 // be signed with the same cert as the caller. 11337 if (targetPackageSetting.installerPackageName != null) { 11338 PackageSetting setting = mSettings.mPackages.get( 11339 targetPackageSetting.installerPackageName); 11340 // If the currently set package isn't valid, then it's always 11341 // okay to change it. 11342 if (setting != null) { 11343 if (compareSignatures(callerSignature, 11344 setting.signatures.mSignatures) 11345 != PackageManager.SIGNATURE_MATCH) { 11346 throw new SecurityException( 11347 "Caller does not have same cert as old installer package " 11348 + targetPackageSetting.installerPackageName); 11349 } 11350 } 11351 } 11352 11353 // Okay! 11354 targetPackageSetting.installerPackageName = installerPackageName; 11355 scheduleWriteSettingsLocked(); 11356 } 11357 } 11358 11359 private void processPendingInstall(final InstallArgs args, final int currentStatus) { 11360 // Queue up an async operation since the package installation may take a little while. 11361 mHandler.post(new Runnable() { 11362 public void run() { 11363 mHandler.removeCallbacks(this); 11364 // Result object to be returned 11365 PackageInstalledInfo res = new PackageInstalledInfo(); 11366 res.setReturnCode(currentStatus); 11367 res.uid = -1; 11368 res.pkg = null; 11369 res.removedInfo = null; 11370 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 11371 args.doPreInstall(res.returnCode); 11372 synchronized (mInstallLock) { 11373 installPackageTracedLI(args, res); 11374 } 11375 args.doPostInstall(res.returnCode, res.uid); 11376 } 11377 11378 // A restore should be performed at this point if (a) the install 11379 // succeeded, (b) the operation is not an update, and (c) the new 11380 // package has not opted out of backup participation. 11381 final boolean update = res.removedInfo != null 11382 && res.removedInfo.removedPackage != null; 11383 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags; 11384 boolean doRestore = !update 11385 && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0); 11386 11387 // Set up the post-install work request bookkeeping. This will be used 11388 // and cleaned up by the post-install event handling regardless of whether 11389 // there's a restore pass performed. Token values are >= 1. 11390 int token; 11391 if (mNextInstallToken < 0) mNextInstallToken = 1; 11392 token = mNextInstallToken++; 11393 11394 PostInstallData data = new PostInstallData(args, res); 11395 mRunningInstalls.put(token, data); 11396 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token); 11397 11398 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) { 11399 // Pass responsibility to the Backup Manager. It will perform a 11400 // restore if appropriate, then pass responsibility back to the 11401 // Package Manager to run the post-install observer callbacks 11402 // and broadcasts. 11403 IBackupManager bm = IBackupManager.Stub.asInterface( 11404 ServiceManager.getService(Context.BACKUP_SERVICE)); 11405 if (bm != null) { 11406 if (DEBUG_INSTALL) Log.v(TAG, "token " + token 11407 + " to BM for possible restore"); 11408 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token); 11409 try { 11410 // TODO: http://b/22388012 11411 if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) { 11412 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token); 11413 } else { 11414 doRestore = false; 11415 } 11416 } catch (RemoteException e) { 11417 // can't happen; the backup manager is local 11418 } catch (Exception e) { 11419 Slog.e(TAG, "Exception trying to enqueue restore", e); 11420 doRestore = false; 11421 } 11422 } else { 11423 Slog.e(TAG, "Backup Manager not found!"); 11424 doRestore = false; 11425 } 11426 } 11427 11428 if (!doRestore) { 11429 // No restore possible, or the Backup Manager was mysteriously not 11430 // available -- just fire the post-install work request directly. 11431 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token); 11432 11433 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token); 11434 11435 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 11436 mHandler.sendMessage(msg); 11437 } 11438 } 11439 }); 11440 } 11441 11442 private abstract class HandlerParams { 11443 private static final int MAX_RETRIES = 4; 11444 11445 /** 11446 * Number of times startCopy() has been attempted and had a non-fatal 11447 * error. 11448 */ 11449 private int mRetries = 0; 11450 11451 /** User handle for the user requesting the information or installation. */ 11452 private final UserHandle mUser; 11453 String traceMethod; 11454 int traceCookie; 11455 11456 HandlerParams(UserHandle user) { 11457 mUser = user; 11458 } 11459 11460 UserHandle getUser() { 11461 return mUser; 11462 } 11463 11464 HandlerParams setTraceMethod(String traceMethod) { 11465 this.traceMethod = traceMethod; 11466 return this; 11467 } 11468 11469 HandlerParams setTraceCookie(int traceCookie) { 11470 this.traceCookie = traceCookie; 11471 return this; 11472 } 11473 11474 final boolean startCopy() { 11475 boolean res; 11476 try { 11477 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this); 11478 11479 if (++mRetries > MAX_RETRIES) { 11480 Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up"); 11481 mHandler.sendEmptyMessage(MCS_GIVE_UP); 11482 handleServiceError(); 11483 return false; 11484 } else { 11485 handleStartCopy(); 11486 res = true; 11487 } 11488 } catch (RemoteException e) { 11489 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT"); 11490 mHandler.sendEmptyMessage(MCS_RECONNECT); 11491 res = false; 11492 } 11493 handleReturnCode(); 11494 return res; 11495 } 11496 11497 final void serviceError() { 11498 if (DEBUG_INSTALL) Slog.i(TAG, "serviceError"); 11499 handleServiceError(); 11500 handleReturnCode(); 11501 } 11502 11503 abstract void handleStartCopy() throws RemoteException; 11504 abstract void handleServiceError(); 11505 abstract void handleReturnCode(); 11506 } 11507 11508 class MeasureParams extends HandlerParams { 11509 private final PackageStats mStats; 11510 private boolean mSuccess; 11511 11512 private final IPackageStatsObserver mObserver; 11513 11514 public MeasureParams(PackageStats stats, IPackageStatsObserver observer) { 11515 super(new UserHandle(stats.userHandle)); 11516 mObserver = observer; 11517 mStats = stats; 11518 } 11519 11520 @Override 11521 public String toString() { 11522 return "MeasureParams{" 11523 + Integer.toHexString(System.identityHashCode(this)) 11524 + " " + mStats.packageName + "}"; 11525 } 11526 11527 @Override 11528 void handleStartCopy() throws RemoteException { 11529 synchronized (mInstallLock) { 11530 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats); 11531 } 11532 11533 if (mSuccess) { 11534 final boolean mounted; 11535 if (Environment.isExternalStorageEmulated()) { 11536 mounted = true; 11537 } else { 11538 final String status = Environment.getExternalStorageState(); 11539 mounted = (Environment.MEDIA_MOUNTED.equals(status) 11540 || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status)); 11541 } 11542 11543 if (mounted) { 11544 final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle); 11545 11546 mStats.externalCacheSize = calculateDirectorySize(mContainerService, 11547 userEnv.buildExternalStorageAppCacheDirs(mStats.packageName)); 11548 11549 mStats.externalDataSize = calculateDirectorySize(mContainerService, 11550 userEnv.buildExternalStorageAppDataDirs(mStats.packageName)); 11551 11552 // Always subtract cache size, since it's a subdirectory 11553 mStats.externalDataSize -= mStats.externalCacheSize; 11554 11555 mStats.externalMediaSize = calculateDirectorySize(mContainerService, 11556 userEnv.buildExternalStorageAppMediaDirs(mStats.packageName)); 11557 11558 mStats.externalObbSize = calculateDirectorySize(mContainerService, 11559 userEnv.buildExternalStorageAppObbDirs(mStats.packageName)); 11560 } 11561 } 11562 } 11563 11564 @Override 11565 void handleReturnCode() { 11566 if (mObserver != null) { 11567 try { 11568 mObserver.onGetStatsCompleted(mStats, mSuccess); 11569 } catch (RemoteException e) { 11570 Slog.i(TAG, "Observer no longer exists."); 11571 } 11572 } 11573 } 11574 11575 @Override 11576 void handleServiceError() { 11577 Slog.e(TAG, "Could not measure application " + mStats.packageName 11578 + " external storage"); 11579 } 11580 } 11581 11582 private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths) 11583 throws RemoteException { 11584 long result = 0; 11585 for (File path : paths) { 11586 result += mcs.calculateDirectorySize(path.getAbsolutePath()); 11587 } 11588 return result; 11589 } 11590 11591 private static void clearDirectory(IMediaContainerService mcs, File[] paths) { 11592 for (File path : paths) { 11593 try { 11594 mcs.clearDirectory(path.getAbsolutePath()); 11595 } catch (RemoteException e) { 11596 } 11597 } 11598 } 11599 11600 static class OriginInfo { 11601 /** 11602 * Location where install is coming from, before it has been 11603 * copied/renamed into place. This could be a single monolithic APK 11604 * file, or a cluster directory. This location may be untrusted. 11605 */ 11606 final File file; 11607 final String cid; 11608 11609 /** 11610 * Flag indicating that {@link #file} or {@link #cid} has already been 11611 * staged, meaning downstream users don't need to defensively copy the 11612 * contents. 11613 */ 11614 final boolean staged; 11615 11616 /** 11617 * Flag indicating that {@link #file} or {@link #cid} is an already 11618 * installed app that is being moved. 11619 */ 11620 final boolean existing; 11621 11622 final String resolvedPath; 11623 final File resolvedFile; 11624 11625 static OriginInfo fromNothing() { 11626 return new OriginInfo(null, null, false, false); 11627 } 11628 11629 static OriginInfo fromUntrustedFile(File file) { 11630 return new OriginInfo(file, null, false, false); 11631 } 11632 11633 static OriginInfo fromExistingFile(File file) { 11634 return new OriginInfo(file, null, false, true); 11635 } 11636 11637 static OriginInfo fromStagedFile(File file) { 11638 return new OriginInfo(file, null, true, false); 11639 } 11640 11641 static OriginInfo fromStagedContainer(String cid) { 11642 return new OriginInfo(null, cid, true, false); 11643 } 11644 11645 private OriginInfo(File file, String cid, boolean staged, boolean existing) { 11646 this.file = file; 11647 this.cid = cid; 11648 this.staged = staged; 11649 this.existing = existing; 11650 11651 if (cid != null) { 11652 resolvedPath = PackageHelper.getSdDir(cid); 11653 resolvedFile = new File(resolvedPath); 11654 } else if (file != null) { 11655 resolvedPath = file.getAbsolutePath(); 11656 resolvedFile = file; 11657 } else { 11658 resolvedPath = null; 11659 resolvedFile = null; 11660 } 11661 } 11662 } 11663 11664 static class MoveInfo { 11665 final int moveId; 11666 final String fromUuid; 11667 final String toUuid; 11668 final String packageName; 11669 final String dataAppName; 11670 final int appId; 11671 final String seinfo; 11672 final int targetSdkVersion; 11673 11674 public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName, 11675 String dataAppName, int appId, String seinfo, int targetSdkVersion) { 11676 this.moveId = moveId; 11677 this.fromUuid = fromUuid; 11678 this.toUuid = toUuid; 11679 this.packageName = packageName; 11680 this.dataAppName = dataAppName; 11681 this.appId = appId; 11682 this.seinfo = seinfo; 11683 this.targetSdkVersion = targetSdkVersion; 11684 } 11685 } 11686 11687 static class VerificationInfo { 11688 /** A constant used to indicate that a uid value is not present. */ 11689 public static final int NO_UID = -1; 11690 11691 /** URI referencing where the package was downloaded from. */ 11692 final Uri originatingUri; 11693 11694 /** HTTP referrer URI associated with the originatingURI. */ 11695 final Uri referrer; 11696 11697 /** UID of the application that the install request originated from. */ 11698 final int originatingUid; 11699 11700 /** UID of application requesting the install */ 11701 final int installerUid; 11702 11703 VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) { 11704 this.originatingUri = originatingUri; 11705 this.referrer = referrer; 11706 this.originatingUid = originatingUid; 11707 this.installerUid = installerUid; 11708 } 11709 } 11710 11711 class InstallParams extends HandlerParams { 11712 final OriginInfo origin; 11713 final MoveInfo move; 11714 final IPackageInstallObserver2 observer; 11715 int installFlags; 11716 final String installerPackageName; 11717 final String volumeUuid; 11718 private InstallArgs mArgs; 11719 private int mRet; 11720 final String packageAbiOverride; 11721 final String[] grantedRuntimePermissions; 11722 final VerificationInfo verificationInfo; 11723 11724 InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 11725 int installFlags, String installerPackageName, String volumeUuid, 11726 VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride, 11727 String[] grantedPermissions) { 11728 super(user); 11729 this.origin = origin; 11730 this.move = move; 11731 this.observer = observer; 11732 this.installFlags = installFlags; 11733 this.installerPackageName = installerPackageName; 11734 this.volumeUuid = volumeUuid; 11735 this.verificationInfo = verificationInfo; 11736 this.packageAbiOverride = packageAbiOverride; 11737 this.grantedRuntimePermissions = grantedPermissions; 11738 } 11739 11740 @Override 11741 public String toString() { 11742 return "InstallParams{" + Integer.toHexString(System.identityHashCode(this)) 11743 + " file=" + origin.file + " cid=" + origin.cid + "}"; 11744 } 11745 11746 private int installLocationPolicy(PackageInfoLite pkgLite) { 11747 String packageName = pkgLite.packageName; 11748 int installLocation = pkgLite.installLocation; 11749 boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 11750 // reader 11751 synchronized (mPackages) { 11752 // Currently installed package which the new package is attempting to replace or 11753 // null if no such package is installed. 11754 PackageParser.Package installedPkg = mPackages.get(packageName); 11755 // Package which currently owns the data which the new package will own if installed. 11756 // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg 11757 // will be null whereas dataOwnerPkg will contain information about the package 11758 // which was uninstalled while keeping its data. 11759 PackageParser.Package dataOwnerPkg = installedPkg; 11760 if (dataOwnerPkg == null) { 11761 PackageSetting ps = mSettings.mPackages.get(packageName); 11762 if (ps != null) { 11763 dataOwnerPkg = ps.pkg; 11764 } 11765 } 11766 11767 if (dataOwnerPkg != null) { 11768 // If installed, the package will get access to data left on the device by its 11769 // predecessor. As a security measure, this is permited only if this is not a 11770 // version downgrade or if the predecessor package is marked as debuggable and 11771 // a downgrade is explicitly requested. 11772 if (((dataOwnerPkg.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) 11773 || ((installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) == 0)) { 11774 try { 11775 checkDowngrade(dataOwnerPkg, pkgLite); 11776 } catch (PackageManagerException e) { 11777 Slog.w(TAG, "Downgrade detected: " + e.getMessage()); 11778 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE; 11779 } 11780 } 11781 } 11782 11783 if (installedPkg != null) { 11784 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 11785 // Check for updated system application. 11786 if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11787 if (onSd) { 11788 Slog.w(TAG, "Cannot install update to system app on sdcard"); 11789 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION; 11790 } 11791 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 11792 } else { 11793 if (onSd) { 11794 // Install flag overrides everything. 11795 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 11796 } 11797 // If current upgrade specifies particular preference 11798 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) { 11799 // Application explicitly specified internal. 11800 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 11801 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) { 11802 // App explictly prefers external. Let policy decide 11803 } else { 11804 // Prefer previous location 11805 if (isExternal(installedPkg)) { 11806 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 11807 } 11808 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 11809 } 11810 } 11811 } else { 11812 // Invalid install. Return error code 11813 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS; 11814 } 11815 } 11816 } 11817 // All the special cases have been taken care of. 11818 // Return result based on recommended install location. 11819 if (onSd) { 11820 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 11821 } 11822 return pkgLite.recommendedInstallLocation; 11823 } 11824 11825 /* 11826 * Invoke remote method to get package information and install 11827 * location values. Override install location based on default 11828 * policy if needed and then create install arguments based 11829 * on the install location. 11830 */ 11831 public void handleStartCopy() throws RemoteException { 11832 int ret = PackageManager.INSTALL_SUCCEEDED; 11833 11834 // If we're already staged, we've firmly committed to an install location 11835 if (origin.staged) { 11836 if (origin.file != null) { 11837 installFlags |= PackageManager.INSTALL_INTERNAL; 11838 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 11839 } else if (origin.cid != null) { 11840 installFlags |= PackageManager.INSTALL_EXTERNAL; 11841 installFlags &= ~PackageManager.INSTALL_INTERNAL; 11842 } else { 11843 throw new IllegalStateException("Invalid stage location"); 11844 } 11845 } 11846 11847 final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 11848 final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0; 11849 final boolean ephemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; 11850 PackageInfoLite pkgLite = null; 11851 11852 if (onInt && onSd) { 11853 // Check if both bits are set. 11854 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external"); 11855 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 11856 } else if (onSd && ephemeral) { 11857 Slog.w(TAG, "Conflicting flags specified for installing ephemeral on external"); 11858 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 11859 } else { 11860 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags, 11861 packageAbiOverride); 11862 11863 if (DEBUG_EPHEMERAL && ephemeral) { 11864 Slog.v(TAG, "pkgLite for install: " + pkgLite); 11865 } 11866 11867 /* 11868 * If we have too little free space, try to free cache 11869 * before giving up. 11870 */ 11871 if (!origin.staged && pkgLite.recommendedInstallLocation 11872 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 11873 // TODO: focus freeing disk space on the target device 11874 final StorageManager storage = StorageManager.from(mContext); 11875 final long lowThreshold = storage.getStorageLowBytes( 11876 Environment.getDataDirectory()); 11877 11878 final long sizeBytes = mContainerService.calculateInstalledSize( 11879 origin.resolvedPath, isForwardLocked(), packageAbiOverride); 11880 11881 try { 11882 mInstaller.freeCache(null, sizeBytes + lowThreshold); 11883 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, 11884 installFlags, packageAbiOverride); 11885 } catch (InstallerException e) { 11886 Slog.w(TAG, "Failed to free cache", e); 11887 } 11888 11889 /* 11890 * The cache free must have deleted the file we 11891 * downloaded to install. 11892 * 11893 * TODO: fix the "freeCache" call to not delete 11894 * the file we care about. 11895 */ 11896 if (pkgLite.recommendedInstallLocation 11897 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 11898 pkgLite.recommendedInstallLocation 11899 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE; 11900 } 11901 } 11902 } 11903 11904 if (ret == PackageManager.INSTALL_SUCCEEDED) { 11905 int loc = pkgLite.recommendedInstallLocation; 11906 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) { 11907 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 11908 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) { 11909 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 11910 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 11911 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 11912 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) { 11913 ret = PackageManager.INSTALL_FAILED_INVALID_APK; 11914 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 11915 ret = PackageManager.INSTALL_FAILED_INVALID_URI; 11916 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) { 11917 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE; 11918 } else { 11919 // Override with defaults if needed. 11920 loc = installLocationPolicy(pkgLite); 11921 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) { 11922 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 11923 } else if (!onSd && !onInt) { 11924 // Override install location with flags 11925 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) { 11926 // Set the flag to install on external media. 11927 installFlags |= PackageManager.INSTALL_EXTERNAL; 11928 installFlags &= ~PackageManager.INSTALL_INTERNAL; 11929 } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) { 11930 if (DEBUG_EPHEMERAL) { 11931 Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag"); 11932 } 11933 installFlags |= PackageManager.INSTALL_EPHEMERAL; 11934 installFlags &= ~(PackageManager.INSTALL_EXTERNAL 11935 |PackageManager.INSTALL_INTERNAL); 11936 } else { 11937 // Make sure the flag for installing on external 11938 // media is unset 11939 installFlags |= PackageManager.INSTALL_INTERNAL; 11940 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 11941 } 11942 } 11943 } 11944 } 11945 11946 final InstallArgs args = createInstallArgs(this); 11947 mArgs = args; 11948 11949 if (ret == PackageManager.INSTALL_SUCCEEDED) { 11950 // TODO: http://b/22976637 11951 // Apps installed for "all" users use the device owner to verify the app 11952 UserHandle verifierUser = getUser(); 11953 if (verifierUser == UserHandle.ALL) { 11954 verifierUser = UserHandle.SYSTEM; 11955 } 11956 11957 /* 11958 * Determine if we have any installed package verifiers. If we 11959 * do, then we'll defer to them to verify the packages. 11960 */ 11961 final int requiredUid = mRequiredVerifierPackage == null ? -1 11962 : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 11963 verifierUser.getIdentifier()); 11964 if (!origin.existing && requiredUid != -1 11965 && isVerificationEnabled(verifierUser.getIdentifier(), installFlags)) { 11966 final Intent verification = new Intent( 11967 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 11968 verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 11969 verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)), 11970 PACKAGE_MIME_TYPE); 11971 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 11972 11973 // Query all live verifiers based on current user state 11974 final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification, 11975 PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier()); 11976 11977 if (DEBUG_VERIFY) { 11978 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent " 11979 + verification.toString() + " with " + pkgLite.verifiers.length 11980 + " optional verifiers"); 11981 } 11982 11983 final int verificationId = mPendingVerificationToken++; 11984 11985 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 11986 11987 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE, 11988 installerPackageName); 11989 11990 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, 11991 installFlags); 11992 11993 verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME, 11994 pkgLite.packageName); 11995 11996 verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE, 11997 pkgLite.versionCode); 11998 11999 if (verificationInfo != null) { 12000 if (verificationInfo.originatingUri != null) { 12001 verification.putExtra(Intent.EXTRA_ORIGINATING_URI, 12002 verificationInfo.originatingUri); 12003 } 12004 if (verificationInfo.referrer != null) { 12005 verification.putExtra(Intent.EXTRA_REFERRER, 12006 verificationInfo.referrer); 12007 } 12008 if (verificationInfo.originatingUid >= 0) { 12009 verification.putExtra(Intent.EXTRA_ORIGINATING_UID, 12010 verificationInfo.originatingUid); 12011 } 12012 if (verificationInfo.installerUid >= 0) { 12013 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID, 12014 verificationInfo.installerUid); 12015 } 12016 } 12017 12018 final PackageVerificationState verificationState = new PackageVerificationState( 12019 requiredUid, args); 12020 12021 mPendingVerification.append(verificationId, verificationState); 12022 12023 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite, 12024 receivers, verificationState); 12025 12026 /* 12027 * If any sufficient verifiers were listed in the package 12028 * manifest, attempt to ask them. 12029 */ 12030 if (sufficientVerifiers != null) { 12031 final int N = sufficientVerifiers.size(); 12032 if (N == 0) { 12033 Slog.i(TAG, "Additional verifiers required, but none installed."); 12034 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 12035 } else { 12036 for (int i = 0; i < N; i++) { 12037 final ComponentName verifierComponent = sufficientVerifiers.get(i); 12038 12039 final Intent sufficientIntent = new Intent(verification); 12040 sufficientIntent.setComponent(verifierComponent); 12041 mContext.sendBroadcastAsUser(sufficientIntent, verifierUser); 12042 } 12043 } 12044 } 12045 12046 final ComponentName requiredVerifierComponent = matchComponentForVerifier( 12047 mRequiredVerifierPackage, receivers); 12048 if (ret == PackageManager.INSTALL_SUCCEEDED 12049 && mRequiredVerifierPackage != null) { 12050 Trace.asyncTraceBegin( 12051 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 12052 /* 12053 * Send the intent to the required verification agent, 12054 * but only start the verification timeout after the 12055 * target BroadcastReceivers have run. 12056 */ 12057 verification.setComponent(requiredVerifierComponent); 12058 mContext.sendOrderedBroadcastAsUser(verification, verifierUser, 12059 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 12060 new BroadcastReceiver() { 12061 @Override 12062 public void onReceive(Context context, Intent intent) { 12063 final Message msg = mHandler 12064 .obtainMessage(CHECK_PENDING_VERIFICATION); 12065 msg.arg1 = verificationId; 12066 mHandler.sendMessageDelayed(msg, getVerificationTimeout()); 12067 } 12068 }, null, 0, null, null); 12069 12070 /* 12071 * We don't want the copy to proceed until verification 12072 * succeeds, so null out this field. 12073 */ 12074 mArgs = null; 12075 } 12076 } else { 12077 /* 12078 * No package verification is enabled, so immediately start 12079 * the remote call to initiate copy using temporary file. 12080 */ 12081 ret = args.copyApk(mContainerService, true); 12082 } 12083 } 12084 12085 mRet = ret; 12086 } 12087 12088 @Override 12089 void handleReturnCode() { 12090 // If mArgs is null, then MCS couldn't be reached. When it 12091 // reconnects, it will try again to install. At that point, this 12092 // will succeed. 12093 if (mArgs != null) { 12094 processPendingInstall(mArgs, mRet); 12095 } 12096 } 12097 12098 @Override 12099 void handleServiceError() { 12100 mArgs = createInstallArgs(this); 12101 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 12102 } 12103 12104 public boolean isForwardLocked() { 12105 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 12106 } 12107 } 12108 12109 /** 12110 * Used during creation of InstallArgs 12111 * 12112 * @param installFlags package installation flags 12113 * @return true if should be installed on external storage 12114 */ 12115 private static boolean installOnExternalAsec(int installFlags) { 12116 if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) { 12117 return false; 12118 } 12119 if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) { 12120 return true; 12121 } 12122 return false; 12123 } 12124 12125 /** 12126 * Used during creation of InstallArgs 12127 * 12128 * @param installFlags package installation flags 12129 * @return true if should be installed as forward locked 12130 */ 12131 private static boolean installForwardLocked(int installFlags) { 12132 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 12133 } 12134 12135 private InstallArgs createInstallArgs(InstallParams params) { 12136 if (params.move != null) { 12137 return new MoveInstallArgs(params); 12138 } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) { 12139 return new AsecInstallArgs(params); 12140 } else { 12141 return new FileInstallArgs(params); 12142 } 12143 } 12144 12145 /** 12146 * Create args that describe an existing installed package. Typically used 12147 * when cleaning up old installs, or used as a move source. 12148 */ 12149 private InstallArgs createInstallArgsForExisting(int installFlags, String codePath, 12150 String resourcePath, String[] instructionSets) { 12151 final boolean isInAsec; 12152 if (installOnExternalAsec(installFlags)) { 12153 /* Apps on SD card are always in ASEC containers. */ 12154 isInAsec = true; 12155 } else if (installForwardLocked(installFlags) 12156 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) { 12157 /* 12158 * Forward-locked apps are only in ASEC containers if they're the 12159 * new style 12160 */ 12161 isInAsec = true; 12162 } else { 12163 isInAsec = false; 12164 } 12165 12166 if (isInAsec) { 12167 return new AsecInstallArgs(codePath, instructionSets, 12168 installOnExternalAsec(installFlags), installForwardLocked(installFlags)); 12169 } else { 12170 return new FileInstallArgs(codePath, resourcePath, instructionSets); 12171 } 12172 } 12173 12174 static abstract class InstallArgs { 12175 /** @see InstallParams#origin */ 12176 final OriginInfo origin; 12177 /** @see InstallParams#move */ 12178 final MoveInfo move; 12179 12180 final IPackageInstallObserver2 observer; 12181 // Always refers to PackageManager flags only 12182 final int installFlags; 12183 final String installerPackageName; 12184 final String volumeUuid; 12185 final UserHandle user; 12186 final String abiOverride; 12187 final String[] installGrantPermissions; 12188 /** If non-null, drop an async trace when the install completes */ 12189 final String traceMethod; 12190 final int traceCookie; 12191 12192 // The list of instruction sets supported by this app. This is currently 12193 // only used during the rmdex() phase to clean up resources. We can get rid of this 12194 // if we move dex files under the common app path. 12195 /* nullable */ String[] instructionSets; 12196 12197 InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 12198 int installFlags, String installerPackageName, String volumeUuid, 12199 UserHandle user, String[] instructionSets, 12200 String abiOverride, String[] installGrantPermissions, 12201 String traceMethod, int traceCookie) { 12202 this.origin = origin; 12203 this.move = move; 12204 this.installFlags = installFlags; 12205 this.observer = observer; 12206 this.installerPackageName = installerPackageName; 12207 this.volumeUuid = volumeUuid; 12208 this.user = user; 12209 this.instructionSets = instructionSets; 12210 this.abiOverride = abiOverride; 12211 this.installGrantPermissions = installGrantPermissions; 12212 this.traceMethod = traceMethod; 12213 this.traceCookie = traceCookie; 12214 } 12215 12216 abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException; 12217 abstract int doPreInstall(int status); 12218 12219 /** 12220 * Rename package into final resting place. All paths on the given 12221 * scanned package should be updated to reflect the rename. 12222 */ 12223 abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath); 12224 abstract int doPostInstall(int status, int uid); 12225 12226 /** @see PackageSettingBase#codePathString */ 12227 abstract String getCodePath(); 12228 /** @see PackageSettingBase#resourcePathString */ 12229 abstract String getResourcePath(); 12230 12231 // Need installer lock especially for dex file removal. 12232 abstract void cleanUpResourcesLI(); 12233 abstract boolean doPostDeleteLI(boolean delete); 12234 12235 /** 12236 * Called before the source arguments are copied. This is used mostly 12237 * for MoveParams when it needs to read the source file to put it in the 12238 * destination. 12239 */ 12240 int doPreCopy() { 12241 return PackageManager.INSTALL_SUCCEEDED; 12242 } 12243 12244 /** 12245 * Called after the source arguments are copied. This is used mostly for 12246 * MoveParams when it needs to read the source file to put it in the 12247 * destination. 12248 * 12249 * @return 12250 */ 12251 int doPostCopy(int uid) { 12252 return PackageManager.INSTALL_SUCCEEDED; 12253 } 12254 12255 protected boolean isFwdLocked() { 12256 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 12257 } 12258 12259 protected boolean isExternalAsec() { 12260 return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 12261 } 12262 12263 protected boolean isEphemeral() { 12264 return (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; 12265 } 12266 12267 UserHandle getUser() { 12268 return user; 12269 } 12270 } 12271 12272 private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) { 12273 if (!allCodePaths.isEmpty()) { 12274 if (instructionSets == null) { 12275 throw new IllegalStateException("instructionSet == null"); 12276 } 12277 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); 12278 for (String codePath : allCodePaths) { 12279 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 12280 try { 12281 mInstaller.rmdex(codePath, dexCodeInstructionSet); 12282 } catch (InstallerException ignored) { 12283 } 12284 } 12285 } 12286 } 12287 } 12288 12289 /** 12290 * Logic to handle installation of non-ASEC applications, including copying 12291 * and renaming logic. 12292 */ 12293 class FileInstallArgs extends InstallArgs { 12294 private File codeFile; 12295 private File resourceFile; 12296 12297 // Example topology: 12298 // /data/app/com.example/base.apk 12299 // /data/app/com.example/split_foo.apk 12300 // /data/app/com.example/lib/arm/libfoo.so 12301 // /data/app/com.example/lib/arm64/libfoo.so 12302 // /data/app/com.example/dalvik/arm/base.apk@classes.dex 12303 12304 /** New install */ 12305 FileInstallArgs(InstallParams params) { 12306 super(params.origin, params.move, params.observer, params.installFlags, 12307 params.installerPackageName, params.volumeUuid, 12308 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 12309 params.grantedRuntimePermissions, 12310 params.traceMethod, params.traceCookie); 12311 if (isFwdLocked()) { 12312 throw new IllegalArgumentException("Forward locking only supported in ASEC"); 12313 } 12314 } 12315 12316 /** Existing install */ 12317 FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) { 12318 super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets, 12319 null, null, null, 0); 12320 this.codeFile = (codePath != null) ? new File(codePath) : null; 12321 this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null; 12322 } 12323 12324 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 12325 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk"); 12326 try { 12327 return doCopyApk(imcs, temp); 12328 } finally { 12329 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 12330 } 12331 } 12332 12333 private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 12334 if (origin.staged) { 12335 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy"); 12336 codeFile = origin.file; 12337 resourceFile = origin.file; 12338 return PackageManager.INSTALL_SUCCEEDED; 12339 } 12340 12341 try { 12342 final boolean isEphemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; 12343 final File tempDir = 12344 mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral); 12345 codeFile = tempDir; 12346 resourceFile = tempDir; 12347 } catch (IOException e) { 12348 Slog.w(TAG, "Failed to create copy file: " + e); 12349 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 12350 } 12351 12352 final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() { 12353 @Override 12354 public ParcelFileDescriptor open(String name, int mode) throws RemoteException { 12355 if (!FileUtils.isValidExtFilename(name)) { 12356 throw new IllegalArgumentException("Invalid filename: " + name); 12357 } 12358 try { 12359 final File file = new File(codeFile, name); 12360 final FileDescriptor fd = Os.open(file.getAbsolutePath(), 12361 O_RDWR | O_CREAT, 0644); 12362 Os.chmod(file.getAbsolutePath(), 0644); 12363 return new ParcelFileDescriptor(fd); 12364 } catch (ErrnoException e) { 12365 throw new RemoteException("Failed to open: " + e.getMessage()); 12366 } 12367 } 12368 }; 12369 12370 int ret = PackageManager.INSTALL_SUCCEEDED; 12371 ret = imcs.copyPackage(origin.file.getAbsolutePath(), target); 12372 if (ret != PackageManager.INSTALL_SUCCEEDED) { 12373 Slog.e(TAG, "Failed to copy package"); 12374 return ret; 12375 } 12376 12377 final File libraryRoot = new File(codeFile, LIB_DIR_NAME); 12378 NativeLibraryHelper.Handle handle = null; 12379 try { 12380 handle = NativeLibraryHelper.Handle.create(codeFile); 12381 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot, 12382 abiOverride); 12383 } catch (IOException e) { 12384 Slog.e(TAG, "Copying native libraries failed", e); 12385 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 12386 } finally { 12387 IoUtils.closeQuietly(handle); 12388 } 12389 12390 return ret; 12391 } 12392 12393 int doPreInstall(int status) { 12394 if (status != PackageManager.INSTALL_SUCCEEDED) { 12395 cleanUp(); 12396 } 12397 return status; 12398 } 12399 12400 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 12401 if (status != PackageManager.INSTALL_SUCCEEDED) { 12402 cleanUp(); 12403 return false; 12404 } 12405 12406 final File targetDir = codeFile.getParentFile(); 12407 final File beforeCodeFile = codeFile; 12408 final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName); 12409 12410 if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile); 12411 try { 12412 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath()); 12413 } catch (ErrnoException e) { 12414 Slog.w(TAG, "Failed to rename", e); 12415 return false; 12416 } 12417 12418 if (!SELinux.restoreconRecursive(afterCodeFile)) { 12419 Slog.w(TAG, "Failed to restorecon"); 12420 return false; 12421 } 12422 12423 // Reflect the rename internally 12424 codeFile = afterCodeFile; 12425 resourceFile = afterCodeFile; 12426 12427 // Reflect the rename in scanned details 12428 pkg.setCodePath(afterCodeFile.getAbsolutePath()); 12429 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile, 12430 afterCodeFile, pkg.baseCodePath)); 12431 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile, 12432 afterCodeFile, pkg.splitCodePaths)); 12433 12434 // Reflect the rename in app info 12435 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 12436 pkg.setApplicationInfoCodePath(pkg.codePath); 12437 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 12438 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 12439 pkg.setApplicationInfoResourcePath(pkg.codePath); 12440 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 12441 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 12442 12443 return true; 12444 } 12445 12446 int doPostInstall(int status, int uid) { 12447 if (status != PackageManager.INSTALL_SUCCEEDED) { 12448 cleanUp(); 12449 } 12450 return status; 12451 } 12452 12453 @Override 12454 String getCodePath() { 12455 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 12456 } 12457 12458 @Override 12459 String getResourcePath() { 12460 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 12461 } 12462 12463 private boolean cleanUp() { 12464 if (codeFile == null || !codeFile.exists()) { 12465 return false; 12466 } 12467 12468 removeCodePathLI(codeFile); 12469 12470 if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) { 12471 resourceFile.delete(); 12472 } 12473 12474 return true; 12475 } 12476 12477 void cleanUpResourcesLI() { 12478 // Try enumerating all code paths before deleting 12479 List<String> allCodePaths = Collections.EMPTY_LIST; 12480 if (codeFile != null && codeFile.exists()) { 12481 try { 12482 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 12483 allCodePaths = pkg.getAllCodePaths(); 12484 } catch (PackageParserException e) { 12485 // Ignored; we tried our best 12486 } 12487 } 12488 12489 cleanUp(); 12490 removeDexFiles(allCodePaths, instructionSets); 12491 } 12492 12493 boolean doPostDeleteLI(boolean delete) { 12494 // XXX err, shouldn't we respect the delete flag? 12495 cleanUpResourcesLI(); 12496 return true; 12497 } 12498 } 12499 12500 private boolean isAsecExternal(String cid) { 12501 final String asecPath = PackageHelper.getSdFilesystem(cid); 12502 return !asecPath.startsWith(mAsecInternalPath); 12503 } 12504 12505 private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws 12506 PackageManagerException { 12507 if (copyRet < 0) { 12508 if (copyRet != PackageManager.NO_NATIVE_LIBRARIES && 12509 copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) { 12510 throw new PackageManagerException(copyRet, message); 12511 } 12512 } 12513 } 12514 12515 /** 12516 * Extract the MountService "container ID" from the full code path of an 12517 * .apk. 12518 */ 12519 static String cidFromCodePath(String fullCodePath) { 12520 int eidx = fullCodePath.lastIndexOf("/"); 12521 String subStr1 = fullCodePath.substring(0, eidx); 12522 int sidx = subStr1.lastIndexOf("/"); 12523 return subStr1.substring(sidx+1, eidx); 12524 } 12525 12526 /** 12527 * Logic to handle installation of ASEC applications, including copying and 12528 * renaming logic. 12529 */ 12530 class AsecInstallArgs extends InstallArgs { 12531 static final String RES_FILE_NAME = "pkg.apk"; 12532 static final String PUBLIC_RES_FILE_NAME = "res.zip"; 12533 12534 String cid; 12535 String packagePath; 12536 String resourcePath; 12537 12538 /** New install */ 12539 AsecInstallArgs(InstallParams params) { 12540 super(params.origin, params.move, params.observer, params.installFlags, 12541 params.installerPackageName, params.volumeUuid, 12542 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 12543 params.grantedRuntimePermissions, 12544 params.traceMethod, params.traceCookie); 12545 } 12546 12547 /** Existing install */ 12548 AsecInstallArgs(String fullCodePath, String[] instructionSets, 12549 boolean isExternal, boolean isForwardLocked) { 12550 super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0) 12551 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, 12552 instructionSets, null, null, null, 0); 12553 // Hackily pretend we're still looking at a full code path 12554 if (!fullCodePath.endsWith(RES_FILE_NAME)) { 12555 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath(); 12556 } 12557 12558 // Extract cid from fullCodePath 12559 int eidx = fullCodePath.lastIndexOf("/"); 12560 String subStr1 = fullCodePath.substring(0, eidx); 12561 int sidx = subStr1.lastIndexOf("/"); 12562 cid = subStr1.substring(sidx+1, eidx); 12563 setMountPath(subStr1); 12564 } 12565 12566 AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) { 12567 super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0) 12568 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, 12569 instructionSets, null, null, null, 0); 12570 this.cid = cid; 12571 setMountPath(PackageHelper.getSdDir(cid)); 12572 } 12573 12574 void createCopyFile() { 12575 cid = mInstallerService.allocateExternalStageCidLegacy(); 12576 } 12577 12578 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 12579 if (origin.staged && origin.cid != null) { 12580 if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy"); 12581 cid = origin.cid; 12582 setMountPath(PackageHelper.getSdDir(cid)); 12583 return PackageManager.INSTALL_SUCCEEDED; 12584 } 12585 12586 if (temp) { 12587 createCopyFile(); 12588 } else { 12589 /* 12590 * Pre-emptively destroy the container since it's destroyed if 12591 * copying fails due to it existing anyway. 12592 */ 12593 PackageHelper.destroySdDir(cid); 12594 } 12595 12596 final String newMountPath = imcs.copyPackageToContainer( 12597 origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(), 12598 isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */)); 12599 12600 if (newMountPath != null) { 12601 setMountPath(newMountPath); 12602 return PackageManager.INSTALL_SUCCEEDED; 12603 } else { 12604 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 12605 } 12606 } 12607 12608 @Override 12609 String getCodePath() { 12610 return packagePath; 12611 } 12612 12613 @Override 12614 String getResourcePath() { 12615 return resourcePath; 12616 } 12617 12618 int doPreInstall(int status) { 12619 if (status != PackageManager.INSTALL_SUCCEEDED) { 12620 // Destroy container 12621 PackageHelper.destroySdDir(cid); 12622 } else { 12623 boolean mounted = PackageHelper.isContainerMounted(cid); 12624 if (!mounted) { 12625 String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(), 12626 Process.SYSTEM_UID); 12627 if (newMountPath != null) { 12628 setMountPath(newMountPath); 12629 } else { 12630 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 12631 } 12632 } 12633 } 12634 return status; 12635 } 12636 12637 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 12638 String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME); 12639 String newMountPath = null; 12640 if (PackageHelper.isContainerMounted(cid)) { 12641 // Unmount the container 12642 if (!PackageHelper.unMountSdDir(cid)) { 12643 Slog.i(TAG, "Failed to unmount " + cid + " before renaming"); 12644 return false; 12645 } 12646 } 12647 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 12648 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId + 12649 " which might be stale. Will try to clean up."); 12650 // Clean up the stale container and proceed to recreate. 12651 if (!PackageHelper.destroySdDir(newCacheId)) { 12652 Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId); 12653 return false; 12654 } 12655 // Successfully cleaned up stale container. Try to rename again. 12656 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 12657 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId 12658 + " inspite of cleaning it up."); 12659 return false; 12660 } 12661 } 12662 if (!PackageHelper.isContainerMounted(newCacheId)) { 12663 Slog.w(TAG, "Mounting container " + newCacheId); 12664 newMountPath = PackageHelper.mountSdDir(newCacheId, 12665 getEncryptKey(), Process.SYSTEM_UID); 12666 } else { 12667 newMountPath = PackageHelper.getSdDir(newCacheId); 12668 } 12669 if (newMountPath == null) { 12670 Slog.w(TAG, "Failed to get cache path for " + newCacheId); 12671 return false; 12672 } 12673 Log.i(TAG, "Succesfully renamed " + cid + 12674 " to " + newCacheId + 12675 " at new path: " + newMountPath); 12676 cid = newCacheId; 12677 12678 final File beforeCodeFile = new File(packagePath); 12679 setMountPath(newMountPath); 12680 final File afterCodeFile = new File(packagePath); 12681 12682 // Reflect the rename in scanned details 12683 pkg.setCodePath(afterCodeFile.getAbsolutePath()); 12684 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile, 12685 afterCodeFile, pkg.baseCodePath)); 12686 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile, 12687 afterCodeFile, pkg.splitCodePaths)); 12688 12689 // Reflect the rename in app info 12690 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 12691 pkg.setApplicationInfoCodePath(pkg.codePath); 12692 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 12693 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 12694 pkg.setApplicationInfoResourcePath(pkg.codePath); 12695 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 12696 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 12697 12698 return true; 12699 } 12700 12701 private void setMountPath(String mountPath) { 12702 final File mountFile = new File(mountPath); 12703 12704 final File monolithicFile = new File(mountFile, RES_FILE_NAME); 12705 if (monolithicFile.exists()) { 12706 packagePath = monolithicFile.getAbsolutePath(); 12707 if (isFwdLocked()) { 12708 resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath(); 12709 } else { 12710 resourcePath = packagePath; 12711 } 12712 } else { 12713 packagePath = mountFile.getAbsolutePath(); 12714 resourcePath = packagePath; 12715 } 12716 } 12717 12718 int doPostInstall(int status, int uid) { 12719 if (status != PackageManager.INSTALL_SUCCEEDED) { 12720 cleanUp(); 12721 } else { 12722 final int groupOwner; 12723 final String protectedFile; 12724 if (isFwdLocked()) { 12725 groupOwner = UserHandle.getSharedAppGid(uid); 12726 protectedFile = RES_FILE_NAME; 12727 } else { 12728 groupOwner = -1; 12729 protectedFile = null; 12730 } 12731 12732 if (uid < Process.FIRST_APPLICATION_UID 12733 || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) { 12734 Slog.e(TAG, "Failed to finalize " + cid); 12735 PackageHelper.destroySdDir(cid); 12736 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 12737 } 12738 12739 boolean mounted = PackageHelper.isContainerMounted(cid); 12740 if (!mounted) { 12741 PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid()); 12742 } 12743 } 12744 return status; 12745 } 12746 12747 private void cleanUp() { 12748 if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp"); 12749 12750 // Destroy secure container 12751 PackageHelper.destroySdDir(cid); 12752 } 12753 12754 private List<String> getAllCodePaths() { 12755 final File codeFile = new File(getCodePath()); 12756 if (codeFile != null && codeFile.exists()) { 12757 try { 12758 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 12759 return pkg.getAllCodePaths(); 12760 } catch (PackageParserException e) { 12761 // Ignored; we tried our best 12762 } 12763 } 12764 return Collections.EMPTY_LIST; 12765 } 12766 12767 void cleanUpResourcesLI() { 12768 // Enumerate all code paths before deleting 12769 cleanUpResourcesLI(getAllCodePaths()); 12770 } 12771 12772 private void cleanUpResourcesLI(List<String> allCodePaths) { 12773 cleanUp(); 12774 removeDexFiles(allCodePaths, instructionSets); 12775 } 12776 12777 String getPackageName() { 12778 return getAsecPackageName(cid); 12779 } 12780 12781 boolean doPostDeleteLI(boolean delete) { 12782 if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete); 12783 final List<String> allCodePaths = getAllCodePaths(); 12784 boolean mounted = PackageHelper.isContainerMounted(cid); 12785 if (mounted) { 12786 // Unmount first 12787 if (PackageHelper.unMountSdDir(cid)) { 12788 mounted = false; 12789 } 12790 } 12791 if (!mounted && delete) { 12792 cleanUpResourcesLI(allCodePaths); 12793 } 12794 return !mounted; 12795 } 12796 12797 @Override 12798 int doPreCopy() { 12799 if (isFwdLocked()) { 12800 if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE, 12801 MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) { 12802 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 12803 } 12804 } 12805 12806 return PackageManager.INSTALL_SUCCEEDED; 12807 } 12808 12809 @Override 12810 int doPostCopy(int uid) { 12811 if (isFwdLocked()) { 12812 if (uid < Process.FIRST_APPLICATION_UID 12813 || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid), 12814 RES_FILE_NAME)) { 12815 Slog.e(TAG, "Failed to finalize " + cid); 12816 PackageHelper.destroySdDir(cid); 12817 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 12818 } 12819 } 12820 12821 return PackageManager.INSTALL_SUCCEEDED; 12822 } 12823 } 12824 12825 /** 12826 * Logic to handle movement of existing installed applications. 12827 */ 12828 class MoveInstallArgs extends InstallArgs { 12829 private File codeFile; 12830 private File resourceFile; 12831 12832 /** New install */ 12833 MoveInstallArgs(InstallParams params) { 12834 super(params.origin, params.move, params.observer, params.installFlags, 12835 params.installerPackageName, params.volumeUuid, 12836 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 12837 params.grantedRuntimePermissions, 12838 params.traceMethod, params.traceCookie); 12839 } 12840 12841 int copyApk(IMediaContainerService imcs, boolean temp) { 12842 if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from " 12843 + move.fromUuid + " to " + move.toUuid); 12844 synchronized (mInstaller) { 12845 try { 12846 mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName, 12847 move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion); 12848 } catch (InstallerException e) { 12849 Slog.w(TAG, "Failed to move app", e); 12850 return PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 12851 } 12852 } 12853 12854 codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName); 12855 resourceFile = codeFile; 12856 if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile); 12857 12858 return PackageManager.INSTALL_SUCCEEDED; 12859 } 12860 12861 int doPreInstall(int status) { 12862 if (status != PackageManager.INSTALL_SUCCEEDED) { 12863 cleanUp(move.toUuid); 12864 } 12865 return status; 12866 } 12867 12868 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 12869 if (status != PackageManager.INSTALL_SUCCEEDED) { 12870 cleanUp(move.toUuid); 12871 return false; 12872 } 12873 12874 // Reflect the move in app info 12875 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 12876 pkg.setApplicationInfoCodePath(pkg.codePath); 12877 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 12878 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 12879 pkg.setApplicationInfoResourcePath(pkg.codePath); 12880 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 12881 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 12882 12883 return true; 12884 } 12885 12886 int doPostInstall(int status, int uid) { 12887 if (status == PackageManager.INSTALL_SUCCEEDED) { 12888 cleanUp(move.fromUuid); 12889 } else { 12890 cleanUp(move.toUuid); 12891 } 12892 return status; 12893 } 12894 12895 @Override 12896 String getCodePath() { 12897 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 12898 } 12899 12900 @Override 12901 String getResourcePath() { 12902 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 12903 } 12904 12905 private boolean cleanUp(String volumeUuid) { 12906 final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid), 12907 move.dataAppName); 12908 Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid); 12909 synchronized (mInstallLock) { 12910 // Clean up both app data and code 12911 removeDataDirsLI(volumeUuid, move.packageName); 12912 removeCodePathLI(codeFile); 12913 } 12914 return true; 12915 } 12916 12917 void cleanUpResourcesLI() { 12918 throw new UnsupportedOperationException(); 12919 } 12920 12921 boolean doPostDeleteLI(boolean delete) { 12922 throw new UnsupportedOperationException(); 12923 } 12924 } 12925 12926 static String getAsecPackageName(String packageCid) { 12927 int idx = packageCid.lastIndexOf("-"); 12928 if (idx == -1) { 12929 return packageCid; 12930 } 12931 return packageCid.substring(0, idx); 12932 } 12933 12934 // Utility method used to create code paths based on package name and available index. 12935 private static String getNextCodePath(String oldCodePath, String prefix, String suffix) { 12936 String idxStr = ""; 12937 int idx = 1; 12938 // Fall back to default value of idx=1 if prefix is not 12939 // part of oldCodePath 12940 if (oldCodePath != null) { 12941 String subStr = oldCodePath; 12942 // Drop the suffix right away 12943 if (suffix != null && subStr.endsWith(suffix)) { 12944 subStr = subStr.substring(0, subStr.length() - suffix.length()); 12945 } 12946 // If oldCodePath already contains prefix find out the 12947 // ending index to either increment or decrement. 12948 int sidx = subStr.lastIndexOf(prefix); 12949 if (sidx != -1) { 12950 subStr = subStr.substring(sidx + prefix.length()); 12951 if (subStr != null) { 12952 if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) { 12953 subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length()); 12954 } 12955 try { 12956 idx = Integer.parseInt(subStr); 12957 if (idx <= 1) { 12958 idx++; 12959 } else { 12960 idx--; 12961 } 12962 } catch(NumberFormatException e) { 12963 } 12964 } 12965 } 12966 } 12967 idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx); 12968 return prefix + idxStr; 12969 } 12970 12971 private File getNextCodePath(File targetDir, String packageName) { 12972 int suffix = 1; 12973 File result; 12974 do { 12975 result = new File(targetDir, packageName + "-" + suffix); 12976 suffix++; 12977 } while (result.exists()); 12978 return result; 12979 } 12980 12981 // Utility method that returns the relative package path with respect 12982 // to the installation directory. Like say for /data/data/com.test-1.apk 12983 // string com.test-1 is returned. 12984 static String deriveCodePathName(String codePath) { 12985 if (codePath == null) { 12986 return null; 12987 } 12988 final File codeFile = new File(codePath); 12989 final String name = codeFile.getName(); 12990 if (codeFile.isDirectory()) { 12991 return name; 12992 } else if (name.endsWith(".apk") || name.endsWith(".tmp")) { 12993 final int lastDot = name.lastIndexOf('.'); 12994 return name.substring(0, lastDot); 12995 } else { 12996 Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK"); 12997 return null; 12998 } 12999 } 13000 13001 static class PackageInstalledInfo { 13002 String name; 13003 int uid; 13004 // The set of users that originally had this package installed. 13005 int[] origUsers; 13006 // The set of users that now have this package installed. 13007 int[] newUsers; 13008 PackageParser.Package pkg; 13009 int returnCode; 13010 String returnMsg; 13011 PackageRemovedInfo removedInfo; 13012 ArrayMap<String, PackageInstalledInfo> addedChildPackages; 13013 13014 public void setError(int code, String msg) { 13015 setReturnCode(code); 13016 setReturnMessage(msg); 13017 Slog.w(TAG, msg); 13018 } 13019 13020 public void setError(String msg, PackageParserException e) { 13021 setReturnCode(e.error); 13022 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e)); 13023 Slog.w(TAG, msg, e); 13024 } 13025 13026 public void setError(String msg, PackageManagerException e) { 13027 returnCode = e.error; 13028 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e)); 13029 Slog.w(TAG, msg, e); 13030 } 13031 13032 public void setReturnCode(int returnCode) { 13033 this.returnCode = returnCode; 13034 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0; 13035 for (int i = 0; i < childCount; i++) { 13036 addedChildPackages.valueAt(i).returnCode = returnCode; 13037 } 13038 } 13039 13040 private void setReturnMessage(String returnMsg) { 13041 this.returnMsg = returnMsg; 13042 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0; 13043 for (int i = 0; i < childCount; i++) { 13044 addedChildPackages.valueAt(i).returnMsg = returnMsg; 13045 } 13046 } 13047 13048 // In some error cases we want to convey more info back to the observer 13049 String origPackage; 13050 String origPermission; 13051 } 13052 13053 /* 13054 * Install a non-existing package. 13055 */ 13056 private void installNewPackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, 13057 UserHandle user, String installerPackageName, String volumeUuid, 13058 PackageInstalledInfo res) { 13059 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage"); 13060 13061 // Remember this for later, in case we need to rollback this install 13062 String pkgName = pkg.packageName; 13063 13064 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg); 13065 13066 synchronized(mPackages) { 13067 if (mSettings.mRenamedPackages.containsKey(pkgName)) { 13068 // A package with the same name is already installed, though 13069 // it has been renamed to an older name. The package we 13070 // are trying to install should be installed as an update to 13071 // the existing one, but that has not been requested, so bail. 13072 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 13073 + " without first uninstalling package running as " 13074 + mSettings.mRenamedPackages.get(pkgName)); 13075 return; 13076 } 13077 if (mPackages.containsKey(pkgName)) { 13078 // Don't allow installation over an existing package with the same name. 13079 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 13080 + " without first uninstalling."); 13081 return; 13082 } 13083 } 13084 13085 try { 13086 PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags, 13087 System.currentTimeMillis(), user); 13088 13089 updateSettingsLI(newPackage, installerPackageName, null, res, user); 13090 13091 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 13092 prepareAppDataAfterInstall(newPackage); 13093 13094 } else { 13095 // Remove package from internal structures, but keep around any 13096 // data that might have already existed 13097 deletePackageLI(pkgName, UserHandle.ALL, false, null, 13098 PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null); 13099 } 13100 } catch (PackageManagerException e) { 13101 res.setError("Package couldn't be installed in " + pkg.codePath, e); 13102 } 13103 13104 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13105 } 13106 13107 private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) { 13108 // Can't rotate keys during boot or if sharedUser. 13109 if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null 13110 || !oldPs.keySetData.isUsingUpgradeKeySets()) { 13111 return false; 13112 } 13113 // app is using upgradeKeySets; make sure all are valid 13114 KeySetManagerService ksms = mSettings.mKeySetManagerService; 13115 long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets(); 13116 for (int i = 0; i < upgradeKeySets.length; i++) { 13117 if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) { 13118 Slog.wtf(TAG, "Package " 13119 + (oldPs.name != null ? oldPs.name : "<null>") 13120 + " contains upgrade-key-set reference to unknown key-set: " 13121 + upgradeKeySets[i] 13122 + " reverting to signatures check."); 13123 return false; 13124 } 13125 } 13126 return true; 13127 } 13128 13129 private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) { 13130 // Upgrade keysets are being used. Determine if new package has a superset of the 13131 // required keys. 13132 long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets(); 13133 KeySetManagerService ksms = mSettings.mKeySetManagerService; 13134 for (int i = 0; i < upgradeKeySets.length; i++) { 13135 Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]); 13136 if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) { 13137 return true; 13138 } 13139 } 13140 return false; 13141 } 13142 13143 private void replacePackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, 13144 UserHandle user, String installerPackageName, PackageInstalledInfo res) { 13145 final boolean isEphemeral = (parseFlags & PackageParser.PARSE_IS_EPHEMERAL) != 0; 13146 13147 final PackageParser.Package oldPackage; 13148 final String pkgName = pkg.packageName; 13149 final int[] allUsers; 13150 13151 // First find the old package info and check signatures 13152 synchronized(mPackages) { 13153 oldPackage = mPackages.get(pkgName); 13154 final boolean oldIsEphemeral = oldPackage.applicationInfo.isEphemeralApp(); 13155 if (isEphemeral && !oldIsEphemeral) { 13156 // can't downgrade from full to ephemeral 13157 Slog.w(TAG, "Can't replace app with ephemeral: " + pkgName); 13158 res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID); 13159 return; 13160 } 13161 if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage); 13162 final PackageSetting ps = mSettings.mPackages.get(pkgName); 13163 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { 13164 if (!checkUpgradeKeySetLP(ps, pkg)) { 13165 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 13166 "New package not signed by keys specified by upgrade-keysets: " 13167 + pkgName); 13168 return; 13169 } 13170 } else { 13171 // default to original signature matching 13172 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures) 13173 != PackageManager.SIGNATURE_MATCH) { 13174 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 13175 "New package has a different signature: " + pkgName); 13176 return; 13177 } 13178 } 13179 13180 // In case of rollback, remember per-user/profile install state 13181 allUsers = sUserManager.getUserIds(); 13182 } 13183 13184 // Update what is removed 13185 res.removedInfo = new PackageRemovedInfo(); 13186 res.removedInfo.uid = oldPackage.applicationInfo.uid; 13187 res.removedInfo.removedPackage = oldPackage.packageName; 13188 res.removedInfo.isUpdate = true; 13189 final int childCount = (oldPackage.childPackages != null) 13190 ? oldPackage.childPackages.size() : 0; 13191 for (int i = 0; i < childCount; i++) { 13192 boolean childPackageUpdated = false; 13193 PackageParser.Package childPkg = oldPackage.childPackages.get(i); 13194 if (res.addedChildPackages != null) { 13195 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName); 13196 if (childRes != null) { 13197 childRes.removedInfo.uid = childPkg.applicationInfo.uid; 13198 childRes.removedInfo.removedPackage = childPkg.packageName; 13199 childRes.removedInfo.isUpdate = true; 13200 childPackageUpdated = true; 13201 } 13202 } 13203 if (!childPackageUpdated) { 13204 PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(); 13205 childRemovedRes.removedPackage = childPkg.packageName; 13206 childRemovedRes.isUpdate = false; 13207 childRemovedRes.dataRemoved = true; 13208 synchronized (mPackages) { 13209 PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName); 13210 if (childPs != null) { 13211 childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true); 13212 } 13213 } 13214 if (res.removedInfo.removedChildPackages == null) { 13215 res.removedInfo.removedChildPackages = new ArrayMap<>(); 13216 } 13217 res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes); 13218 } 13219 } 13220 13221 boolean sysPkg = (isSystemApp(oldPackage)); 13222 if (sysPkg) { 13223 replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags, 13224 user, allUsers, installerPackageName, res); 13225 } else { 13226 replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags, 13227 user, allUsers, installerPackageName, res); 13228 } 13229 } 13230 13231 public List<String> getPreviousCodePaths(String packageName) { 13232 final PackageSetting ps = mSettings.mPackages.get(packageName); 13233 final List<String> result = new ArrayList<String>(); 13234 if (ps != null && ps.oldCodePaths != null) { 13235 result.addAll(ps.oldCodePaths); 13236 } 13237 return result; 13238 } 13239 13240 private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage, 13241 PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, 13242 int[] allUsers, String installerPackageName, PackageInstalledInfo res) { 13243 if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old=" 13244 + deletedPackage); 13245 13246 String pkgName = deletedPackage.packageName; 13247 boolean deletedPkg = true; 13248 boolean addedPkg = false; 13249 boolean updatedSettings = false; 13250 final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0; 13251 final int deleteFlags = PackageManager.DELETE_KEEP_DATA 13252 | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP); 13253 13254 final long origUpdateTime = (pkg.mExtras != null) 13255 ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0; 13256 13257 // First delete the existing package while retaining the data directory 13258 if (!deletePackageLI(pkgName, null, true, allUsers, deleteFlags, 13259 res.removedInfo, true, pkg)) { 13260 // If the existing package wasn't successfully deleted 13261 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI"); 13262 deletedPkg = false; 13263 } else { 13264 // Successfully deleted the old package; proceed with replace. 13265 13266 // If deleted package lived in a container, give users a chance to 13267 // relinquish resources before killing. 13268 if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) { 13269 if (DEBUG_INSTALL) { 13270 Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE"); 13271 } 13272 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid }; 13273 final ArrayList<String> pkgList = new ArrayList<String>(1); 13274 pkgList.add(deletedPackage.applicationInfo.packageName); 13275 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null); 13276 } 13277 13278 deleteCodeCacheDirsLI(pkg); 13279 deleteProfilesLI(pkg, /*destroy*/ false); 13280 13281 try { 13282 final PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags, 13283 scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user); 13284 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user); 13285 13286 // Update the in-memory copy of the previous code paths. 13287 PackageSetting ps = mSettings.mPackages.get(pkgName); 13288 if (!killApp) { 13289 if (ps.oldCodePaths == null) { 13290 ps.oldCodePaths = new ArraySet<>(); 13291 } 13292 Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath); 13293 if (deletedPackage.splitCodePaths != null) { 13294 Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths); 13295 } 13296 } else { 13297 ps.oldCodePaths = null; 13298 } 13299 if (ps.childPackageNames != null) { 13300 for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) { 13301 final String childPkgName = ps.childPackageNames.get(i); 13302 final PackageSetting childPs = mSettings.mPackages.get(childPkgName); 13303 childPs.oldCodePaths = ps.oldCodePaths; 13304 } 13305 } 13306 prepareAppDataAfterInstall(newPackage); 13307 addedPkg = true; 13308 } catch (PackageManagerException e) { 13309 res.setError("Package couldn't be installed in " + pkg.codePath, e); 13310 } 13311 } 13312 13313 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 13314 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName); 13315 13316 // Revert all internal state mutations and added folders for the failed install 13317 if (addedPkg) { 13318 deletePackageLI(pkgName, null, true, allUsers, deleteFlags, 13319 res.removedInfo, true, null); 13320 } 13321 13322 // Restore the old package 13323 if (deletedPkg) { 13324 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage); 13325 File restoreFile = new File(deletedPackage.codePath); 13326 // Parse old package 13327 boolean oldExternal = isExternal(deletedPackage); 13328 int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY | 13329 (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) | 13330 (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0); 13331 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME; 13332 try { 13333 scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, 13334 null); 13335 } catch (PackageManagerException e) { 13336 Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: " 13337 + e.getMessage()); 13338 return; 13339 } 13340 13341 synchronized (mPackages) { 13342 // Ensure the installer package name up to date 13343 setInstallerPackageNameLPw(deletedPackage, installerPackageName); 13344 13345 // Update permissions for restored package 13346 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL); 13347 13348 mSettings.writeLPr(); 13349 } 13350 13351 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade"); 13352 } 13353 } else { 13354 synchronized (mPackages) { 13355 PackageSetting ps = mSettings.peekPackageLPr(pkg.packageName); 13356 if (ps != null) { 13357 res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null; 13358 if (res.removedInfo.removedChildPackages != null) { 13359 final int childCount = res.removedInfo.removedChildPackages.size(); 13360 // Iterate in reverse as we may modify the collection 13361 for (int i = childCount - 1; i >= 0; i--) { 13362 String childPackageName = res.removedInfo.removedChildPackages.keyAt(i); 13363 if (res.addedChildPackages.containsKey(childPackageName)) { 13364 res.removedInfo.removedChildPackages.removeAt(i); 13365 } else { 13366 PackageRemovedInfo childInfo = res.removedInfo 13367 .removedChildPackages.valueAt(i); 13368 childInfo.removedForAllUsers = mPackages.get( 13369 childInfo.removedPackage) == null; 13370 } 13371 } 13372 } 13373 } 13374 } 13375 } 13376 } 13377 13378 private void replaceSystemPackageLI(PackageParser.Package deletedPackage, 13379 PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, 13380 int[] allUsers, String installerPackageName, PackageInstalledInfo res) { 13381 if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg 13382 + ", old=" + deletedPackage); 13383 13384 final boolean disabledSystem; 13385 13386 // Set the system/privileged flags as needed 13387 parseFlags |= PackageParser.PARSE_IS_SYSTEM; 13388 if ((deletedPackage.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) 13389 != 0) { 13390 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 13391 } 13392 13393 // Kill package processes including services, providers, etc. 13394 killPackage(deletedPackage, "replace sys pkg"); 13395 13396 // Remove existing system package 13397 removePackageLI(deletedPackage, true); 13398 13399 disabledSystem = disableSystemPackageLPw(deletedPackage, pkg); 13400 if (!disabledSystem) { 13401 // We didn't need to disable the .apk as a current system package, 13402 // which means we are replacing another update that is already 13403 // installed. We need to make sure to delete the older one's .apk. 13404 res.removedInfo.args = createInstallArgsForExisting(0, 13405 deletedPackage.applicationInfo.getCodePath(), 13406 deletedPackage.applicationInfo.getResourcePath(), 13407 getAppDexInstructionSets(deletedPackage.applicationInfo)); 13408 } else { 13409 res.removedInfo.args = null; 13410 } 13411 13412 // Successfully disabled the old package. Now proceed with re-installation 13413 deleteCodeCacheDirsLI(pkg); 13414 deleteProfilesLI(pkg, /*destroy*/ false); 13415 13416 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 13417 pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP, 13418 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP); 13419 13420 PackageParser.Package newPackage = null; 13421 try { 13422 // Add the package to the internal data structures 13423 newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags, 0, user); 13424 13425 // Set the update and install times 13426 PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras; 13427 setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime, 13428 System.currentTimeMillis()); 13429 13430 // Check for shared user id changes 13431 String invalidPackageName = getParentOrChildPackageChangedSharedUser( 13432 deletedPackage, newPackage); 13433 if (invalidPackageName != null) { 13434 res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 13435 "Forbidding shared user change from " + deletedPkgSetting.sharedUser 13436 + " to " + invalidPackageName); 13437 } 13438 13439 // Update the package dynamic state if succeeded 13440 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 13441 // Now that the install succeeded make sure we remove data 13442 // directories for any child package the update removed. 13443 final int deletedChildCount = (deletedPackage.childPackages != null) 13444 ? deletedPackage.childPackages.size() : 0; 13445 final int newChildCount = (newPackage.childPackages != null) 13446 ? newPackage.childPackages.size() : 0; 13447 for (int i = 0; i < deletedChildCount; i++) { 13448 PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i); 13449 boolean childPackageDeleted = true; 13450 for (int j = 0; j < newChildCount; j++) { 13451 PackageParser.Package newChildPkg = newPackage.childPackages.get(j); 13452 if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) { 13453 childPackageDeleted = false; 13454 break; 13455 } 13456 } 13457 if (childPackageDeleted) { 13458 PackageSetting ps = mSettings.getDisabledSystemPkgLPr( 13459 deletedChildPkg.packageName); 13460 if (ps != null && res.removedInfo.removedChildPackages != null) { 13461 PackageRemovedInfo removedChildRes = res.removedInfo 13462 .removedChildPackages.get(deletedChildPkg.packageName); 13463 removePackageDataLI(ps, allUsers, removedChildRes, 0, false); 13464 removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null; 13465 } 13466 } 13467 } 13468 13469 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user); 13470 prepareAppDataAfterInstall(newPackage); 13471 } 13472 } catch (PackageManagerException e) { 13473 res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR); 13474 res.setError("Package couldn't be installed in " + pkg.codePath, e); 13475 } 13476 13477 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 13478 // Re installation failed. Restore old information 13479 // Remove new pkg information 13480 if (newPackage != null) { 13481 removeInstalledPackageLI(newPackage, true); 13482 } 13483 // Add back the old system package 13484 try { 13485 scanPackageTracedLI(deletedPackage, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user); 13486 } catch (PackageManagerException e) { 13487 Slog.e(TAG, "Failed to restore original package: " + e.getMessage()); 13488 } 13489 13490 synchronized (mPackages) { 13491 if (disabledSystem) { 13492 enableSystemPackageLPw(deletedPackage); 13493 } 13494 13495 // Ensure the installer package name up to date 13496 setInstallerPackageNameLPw(deletedPackage, installerPackageName); 13497 13498 // Update permissions for restored package 13499 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL); 13500 13501 mSettings.writeLPr(); 13502 } 13503 13504 Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName 13505 + " after failed upgrade"); 13506 } 13507 } 13508 13509 /** 13510 * Checks whether the parent or any of the child packages have a change shared 13511 * user. For a package to be a valid update the shred users of the parent and 13512 * the children should match. We may later support changing child shared users. 13513 * @param oldPkg The updated package. 13514 * @param newPkg The update package. 13515 * @return The shared user that change between the versions. 13516 */ 13517 private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg, 13518 PackageParser.Package newPkg) { 13519 // Check parent shared user 13520 if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) { 13521 return newPkg.packageName; 13522 } 13523 // Check child shared users 13524 final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0; 13525 final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0; 13526 for (int i = 0; i < newChildCount; i++) { 13527 PackageParser.Package newChildPkg = newPkg.childPackages.get(i); 13528 // If this child was present, did it have the same shared user? 13529 for (int j = 0; j < oldChildCount; j++) { 13530 PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j); 13531 if (newChildPkg.packageName.equals(oldChildPkg.packageName) 13532 && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) { 13533 return newChildPkg.packageName; 13534 } 13535 } 13536 } 13537 return null; 13538 } 13539 13540 private void removeNativeBinariesLI(PackageSetting ps) { 13541 // Remove the lib path for the parent package 13542 if (ps != null) { 13543 NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString); 13544 // Remove the lib path for the child packages 13545 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0; 13546 for (int i = 0; i < childCount; i++) { 13547 PackageSetting childPs = null; 13548 synchronized (mPackages) { 13549 childPs = mSettings.peekPackageLPr(ps.childPackageNames.get(i)); 13550 } 13551 if (childPs != null) { 13552 NativeLibraryHelper.removeNativeBinariesLI(childPs 13553 .legacyNativeLibraryPathString); 13554 } 13555 } 13556 } 13557 } 13558 13559 private void enableSystemPackageLPw(PackageParser.Package pkg) { 13560 // Enable the parent package 13561 mSettings.enableSystemPackageLPw(pkg.packageName); 13562 // Enable the child packages 13563 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 13564 for (int i = 0; i < childCount; i++) { 13565 PackageParser.Package childPkg = pkg.childPackages.get(i); 13566 mSettings.enableSystemPackageLPw(childPkg.packageName); 13567 } 13568 } 13569 13570 private boolean disableSystemPackageLPw(PackageParser.Package oldPkg, 13571 PackageParser.Package newPkg) { 13572 // Disable the parent package (parent always replaced) 13573 boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true); 13574 // Disable the child packages 13575 final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0; 13576 for (int i = 0; i < childCount; i++) { 13577 PackageParser.Package childPkg = oldPkg.childPackages.get(i); 13578 final boolean replace = newPkg.hasChildPackage(childPkg.packageName); 13579 disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace); 13580 } 13581 return disabled; 13582 } 13583 13584 private void setInstallerPackageNameLPw(PackageParser.Package pkg, 13585 String installerPackageName) { 13586 // Enable the parent package 13587 mSettings.setInstallerPackageName(pkg.packageName, installerPackageName); 13588 // Enable the child packages 13589 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 13590 for (int i = 0; i < childCount; i++) { 13591 PackageParser.Package childPkg = pkg.childPackages.get(i); 13592 mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName); 13593 } 13594 } 13595 13596 private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) { 13597 // Collect all used permissions in the UID 13598 ArraySet<String> usedPermissions = new ArraySet<>(); 13599 final int packageCount = su.packages.size(); 13600 for (int i = 0; i < packageCount; i++) { 13601 PackageSetting ps = su.packages.valueAt(i); 13602 if (ps.pkg == null) { 13603 continue; 13604 } 13605 final int requestedPermCount = ps.pkg.requestedPermissions.size(); 13606 for (int j = 0; j < requestedPermCount; j++) { 13607 String permission = ps.pkg.requestedPermissions.get(j); 13608 BasePermission bp = mSettings.mPermissions.get(permission); 13609 if (bp != null) { 13610 usedPermissions.add(permission); 13611 } 13612 } 13613 } 13614 13615 PermissionsState permissionsState = su.getPermissionsState(); 13616 // Prune install permissions 13617 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates(); 13618 final int installPermCount = installPermStates.size(); 13619 for (int i = installPermCount - 1; i >= 0; i--) { 13620 PermissionState permissionState = installPermStates.get(i); 13621 if (!usedPermissions.contains(permissionState.getName())) { 13622 BasePermission bp = mSettings.mPermissions.get(permissionState.getName()); 13623 if (bp != null) { 13624 permissionsState.revokeInstallPermission(bp); 13625 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 13626 PackageManager.MASK_PERMISSION_FLAGS, 0); 13627 } 13628 } 13629 } 13630 13631 int[] runtimePermissionChangedUserIds = EmptyArray.INT; 13632 13633 // Prune runtime permissions 13634 for (int userId : allUserIds) { 13635 List<PermissionState> runtimePermStates = permissionsState 13636 .getRuntimePermissionStates(userId); 13637 final int runtimePermCount = runtimePermStates.size(); 13638 for (int i = runtimePermCount - 1; i >= 0; i--) { 13639 PermissionState permissionState = runtimePermStates.get(i); 13640 if (!usedPermissions.contains(permissionState.getName())) { 13641 BasePermission bp = mSettings.mPermissions.get(permissionState.getName()); 13642 if (bp != null) { 13643 permissionsState.revokeRuntimePermission(bp, userId); 13644 permissionsState.updatePermissionFlags(bp, userId, 13645 PackageManager.MASK_PERMISSION_FLAGS, 0); 13646 runtimePermissionChangedUserIds = ArrayUtils.appendInt( 13647 runtimePermissionChangedUserIds, userId); 13648 } 13649 } 13650 } 13651 } 13652 13653 return runtimePermissionChangedUserIds; 13654 } 13655 13656 private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, 13657 int[] allUsers, PackageInstalledInfo res, UserHandle user) { 13658 // Update the parent package setting 13659 updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers, 13660 res, user); 13661 // Update the child packages setting 13662 final int childCount = (newPackage.childPackages != null) 13663 ? newPackage.childPackages.size() : 0; 13664 for (int i = 0; i < childCount; i++) { 13665 PackageParser.Package childPackage = newPackage.childPackages.get(i); 13666 PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName); 13667 updateSettingsInternalLI(childPackage, installerPackageName, allUsers, 13668 childRes.origUsers, childRes, user); 13669 } 13670 } 13671 13672 private void updateSettingsInternalLI(PackageParser.Package newPackage, 13673 String installerPackageName, int[] allUsers, int[] installedForUsers, 13674 PackageInstalledInfo res, UserHandle user) { 13675 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 13676 13677 String pkgName = newPackage.packageName; 13678 synchronized (mPackages) { 13679 //write settings. the installStatus will be incomplete at this stage. 13680 //note that the new package setting would have already been 13681 //added to mPackages. It hasn't been persisted yet. 13682 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE); 13683 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings"); 13684 mSettings.writeLPr(); 13685 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13686 } 13687 13688 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath); 13689 synchronized (mPackages) { 13690 updatePermissionsLPw(newPackage.packageName, newPackage, 13691 UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0 13692 ? UPDATE_PERMISSIONS_ALL : 0)); 13693 // For system-bundled packages, we assume that installing an upgraded version 13694 // of the package implies that the user actually wants to run that new code, 13695 // so we enable the package. 13696 PackageSetting ps = mSettings.mPackages.get(pkgName); 13697 final int userId = user.getIdentifier(); 13698 if (ps != null) { 13699 if (isSystemApp(newPackage)) { 13700 if (DEBUG_INSTALL) { 13701 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName); 13702 } 13703 // Enable system package for requested users 13704 if (res.origUsers != null) { 13705 for (int origUserId : res.origUsers) { 13706 if (userId == UserHandle.USER_ALL || userId == origUserId) { 13707 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 13708 origUserId, installerPackageName); 13709 } 13710 } 13711 } 13712 // Also convey the prior install/uninstall state 13713 if (allUsers != null && installedForUsers != null) { 13714 for (int currentUserId : allUsers) { 13715 final boolean installed = ArrayUtils.contains( 13716 installedForUsers, currentUserId); 13717 if (DEBUG_INSTALL) { 13718 Slog.d(TAG, " user " + currentUserId + " => " + installed); 13719 } 13720 ps.setInstalled(installed, currentUserId); 13721 } 13722 // these install state changes will be persisted in the 13723 // upcoming call to mSettings.writeLPr(). 13724 } 13725 } 13726 // It's implied that when a user requests installation, they want the app to be 13727 // installed and enabled. 13728 if (userId != UserHandle.USER_ALL) { 13729 ps.setInstalled(true, userId); 13730 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName); 13731 } 13732 } 13733 res.name = pkgName; 13734 res.uid = newPackage.applicationInfo.uid; 13735 res.pkg = newPackage; 13736 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE); 13737 mSettings.setInstallerPackageName(pkgName, installerPackageName); 13738 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 13739 //to update install status 13740 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings"); 13741 mSettings.writeLPr(); 13742 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13743 } 13744 13745 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13746 } 13747 13748 private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) { 13749 try { 13750 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage"); 13751 installPackageLI(args, res); 13752 } finally { 13753 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13754 } 13755 } 13756 13757 private void installPackageLI(InstallArgs args, PackageInstalledInfo res) { 13758 final int installFlags = args.installFlags; 13759 final String installerPackageName = args.installerPackageName; 13760 final String volumeUuid = args.volumeUuid; 13761 final File tmpPackageFile = new File(args.getCodePath()); 13762 final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0); 13763 final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) 13764 || (args.volumeUuid != null)); 13765 final boolean ephemeral = ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0); 13766 boolean replace = false; 13767 int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE; 13768 if (args.move != null) { 13769 // moving a complete application; perform an initial scan on the new install location 13770 scanFlags |= SCAN_INITIAL; 13771 } 13772 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) { 13773 scanFlags |= SCAN_DONT_KILL_APP; 13774 } 13775 13776 // Result object to be returned 13777 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 13778 13779 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile); 13780 13781 // Sanity check 13782 if (ephemeral && (forwardLocked || onExternal)) { 13783 Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked 13784 + " external=" + onExternal); 13785 res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID); 13786 return; 13787 } 13788 13789 // Retrieve PackageSettings and parse package 13790 final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY 13791 | PackageParser.PARSE_ENFORCE_CODE 13792 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) 13793 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0) 13794 | (ephemeral ? PackageParser.PARSE_IS_EPHEMERAL : 0); 13795 PackageParser pp = new PackageParser(); 13796 pp.setSeparateProcesses(mSeparateProcesses); 13797 pp.setDisplayMetrics(mMetrics); 13798 13799 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage"); 13800 final PackageParser.Package pkg; 13801 try { 13802 pkg = pp.parsePackage(tmpPackageFile, parseFlags); 13803 } catch (PackageParserException e) { 13804 res.setError("Failed parse during installPackageLI", e); 13805 return; 13806 } finally { 13807 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13808 } 13809 13810 // If we are installing a clustered package add results for the children 13811 if (pkg.childPackages != null) { 13812 synchronized (mPackages) { 13813 final int childCount = pkg.childPackages.size(); 13814 for (int i = 0; i < childCount; i++) { 13815 PackageParser.Package childPkg = pkg.childPackages.get(i); 13816 PackageInstalledInfo childRes = new PackageInstalledInfo(); 13817 childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 13818 childRes.pkg = childPkg; 13819 childRes.name = childPkg.packageName; 13820 PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName); 13821 if (childPs != null) { 13822 childRes.origUsers = childPs.queryInstalledUsers( 13823 sUserManager.getUserIds(), true); 13824 } 13825 if ((mPackages.containsKey(childPkg.packageName))) { 13826 childRes.removedInfo = new PackageRemovedInfo(); 13827 childRes.removedInfo.removedPackage = childPkg.packageName; 13828 } 13829 if (res.addedChildPackages == null) { 13830 res.addedChildPackages = new ArrayMap<>(); 13831 } 13832 res.addedChildPackages.put(childPkg.packageName, childRes); 13833 } 13834 } 13835 } 13836 13837 // If package doesn't declare API override, mark that we have an install 13838 // time CPU ABI override. 13839 if (TextUtils.isEmpty(pkg.cpuAbiOverride)) { 13840 pkg.cpuAbiOverride = args.abiOverride; 13841 } 13842 13843 String pkgName = res.name = pkg.packageName; 13844 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) { 13845 if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) { 13846 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI"); 13847 return; 13848 } 13849 } 13850 13851 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates"); 13852 try { 13853 PackageParser.collectCertificates(pkg, parseFlags); 13854 } catch (PackageParserException e) { 13855 res.setError("Failed collect during installPackageLI", e); 13856 return; 13857 } finally { 13858 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13859 } 13860 13861 // Get rid of all references to package scan path via parser. 13862 pp = null; 13863 String oldCodePath = null; 13864 boolean systemApp = false; 13865 synchronized (mPackages) { 13866 // Check if installing already existing package 13867 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 13868 String oldName = mSettings.mRenamedPackages.get(pkgName); 13869 if (pkg.mOriginalPackages != null 13870 && pkg.mOriginalPackages.contains(oldName) 13871 && mPackages.containsKey(oldName)) { 13872 // This package is derived from an original package, 13873 // and this device has been updating from that original 13874 // name. We must continue using the original name, so 13875 // rename the new package here. 13876 pkg.setPackageName(oldName); 13877 pkgName = pkg.packageName; 13878 replace = true; 13879 if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName=" 13880 + oldName + " pkgName=" + pkgName); 13881 } else if (mPackages.containsKey(pkgName)) { 13882 // This package, under its official name, already exists 13883 // on the device; we should replace it. 13884 replace = true; 13885 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName); 13886 } 13887 13888 // Child packages are installed through the parent package 13889 if (pkg.parentPackage != null) { 13890 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME, 13891 "Package " + pkg.packageName + " is child of package " 13892 + pkg.parentPackage.parentPackage + ". Child packages " 13893 + "can be updated only through the parent package."); 13894 return; 13895 } 13896 13897 if (replace) { 13898 // Prevent apps opting out from runtime permissions 13899 PackageParser.Package oldPackage = mPackages.get(pkgName); 13900 final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion; 13901 final int newTargetSdk = pkg.applicationInfo.targetSdkVersion; 13902 if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1 13903 && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) { 13904 res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE, 13905 "Package " + pkg.packageName + " new target SDK " + newTargetSdk 13906 + " doesn't support runtime permissions but the old" 13907 + " target SDK " + oldTargetSdk + " does."); 13908 return; 13909 } 13910 13911 // Prevent installing of child packages 13912 if (oldPackage.parentPackage != null) { 13913 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME, 13914 "Package " + pkg.packageName + " is child of package " 13915 + oldPackage.parentPackage + ". Child packages " 13916 + "can be updated only through the parent package."); 13917 return; 13918 } 13919 } 13920 } 13921 13922 PackageSetting ps = mSettings.mPackages.get(pkgName); 13923 if (ps != null) { 13924 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps); 13925 13926 // Quick sanity check that we're signed correctly if updating; 13927 // we'll check this again later when scanning, but we want to 13928 // bail early here before tripping over redefined permissions. 13929 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { 13930 if (!checkUpgradeKeySetLP(ps, pkg)) { 13931 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 13932 + pkg.packageName + " upgrade keys do not match the " 13933 + "previously installed version"); 13934 return; 13935 } 13936 } else { 13937 try { 13938 verifySignaturesLP(ps, pkg); 13939 } catch (PackageManagerException e) { 13940 res.setError(e.error, e.getMessage()); 13941 return; 13942 } 13943 } 13944 13945 oldCodePath = mSettings.mPackages.get(pkgName).codePathString; 13946 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 13947 systemApp = (ps.pkg.applicationInfo.flags & 13948 ApplicationInfo.FLAG_SYSTEM) != 0; 13949 } 13950 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 13951 } 13952 13953 // Check whether the newly-scanned package wants to define an already-defined perm 13954 int N = pkg.permissions.size(); 13955 for (int i = N-1; i >= 0; i--) { 13956 PackageParser.Permission perm = pkg.permissions.get(i); 13957 BasePermission bp = mSettings.mPermissions.get(perm.info.name); 13958 if (bp != null) { 13959 // If the defining package is signed with our cert, it's okay. This 13960 // also includes the "updating the same package" case, of course. 13961 // "updating same package" could also involve key-rotation. 13962 final boolean sigsOk; 13963 if (bp.sourcePackage.equals(pkg.packageName) 13964 && (bp.packageSetting instanceof PackageSetting) 13965 && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting, 13966 scanFlags))) { 13967 sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg); 13968 } else { 13969 sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures, 13970 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 13971 } 13972 if (!sigsOk) { 13973 // If the owning package is the system itself, we log but allow 13974 // install to proceed; we fail the install on all other permission 13975 // redefinitions. 13976 if (!bp.sourcePackage.equals("android")) { 13977 res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package " 13978 + pkg.packageName + " attempting to redeclare permission " 13979 + perm.info.name + " already owned by " + bp.sourcePackage); 13980 res.origPermission = perm.info.name; 13981 res.origPackage = bp.sourcePackage; 13982 return; 13983 } else { 13984 Slog.w(TAG, "Package " + pkg.packageName 13985 + " attempting to redeclare system permission " 13986 + perm.info.name + "; ignoring new declaration"); 13987 pkg.permissions.remove(i); 13988 } 13989 } 13990 } 13991 } 13992 } 13993 13994 if (systemApp) { 13995 if (onExternal) { 13996 // Abort update; system app can't be replaced with app on sdcard 13997 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION, 13998 "Cannot install updates to system apps on sdcard"); 13999 return; 14000 } else if (ephemeral) { 14001 // Abort update; system app can't be replaced with an ephemeral app 14002 res.setError(INSTALL_FAILED_EPHEMERAL_INVALID, 14003 "Cannot update a system app with an ephemeral app"); 14004 return; 14005 } 14006 } 14007 14008 if (args.move != null) { 14009 // We did an in-place move, so dex is ready to roll 14010 scanFlags |= SCAN_NO_DEX; 14011 scanFlags |= SCAN_MOVE; 14012 14013 synchronized (mPackages) { 14014 final PackageSetting ps = mSettings.mPackages.get(pkgName); 14015 if (ps == null) { 14016 res.setError(INSTALL_FAILED_INTERNAL_ERROR, 14017 "Missing settings for moved package " + pkgName); 14018 } 14019 14020 // We moved the entire application as-is, so bring over the 14021 // previously derived ABI information. 14022 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString; 14023 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString; 14024 } 14025 14026 } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) { 14027 // Enable SCAN_NO_DEX flag to skip dexopt at a later stage 14028 scanFlags |= SCAN_NO_DEX; 14029 14030 try { 14031 String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ? 14032 args.abiOverride : pkg.cpuAbiOverride); 14033 derivePackageAbi(pkg, new File(pkg.codePath), abiOverride, 14034 true /* extract libs */); 14035 } catch (PackageManagerException pme) { 14036 Slog.e(TAG, "Error deriving application ABI", pme); 14037 res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI"); 14038 return; 14039 } 14040 14041 14042 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 14043 // Do not run PackageDexOptimizer through the local performDexOpt 14044 // method because `pkg` is not in `mPackages` yet. 14045 int result = mPackageDexOptimizer.performDexOpt(pkg, null /* instructionSets */, 14046 false /* checkProfiles */, getCompilerFilterForReason(REASON_INSTALL)); 14047 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14048 if (result == PackageDexOptimizer.DEX_OPT_FAILED) { 14049 String msg = "Extracking package failed for " + pkgName; 14050 res.setError(INSTALL_FAILED_DEXOPT, msg); 14051 return; 14052 } 14053 } 14054 14055 if (!args.doRename(res.returnCode, pkg, oldCodePath)) { 14056 res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename"); 14057 return; 14058 } 14059 14060 startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg); 14061 14062 if (replace) { 14063 replacePackageLI(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user, 14064 installerPackageName, res); 14065 } else { 14066 installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES, 14067 args.user, installerPackageName, volumeUuid, res); 14068 } 14069 synchronized (mPackages) { 14070 final PackageSetting ps = mSettings.mPackages.get(pkgName); 14071 if (ps != null) { 14072 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 14073 } 14074 14075 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 14076 for (int i = 0; i < childCount; i++) { 14077 PackageParser.Package childPkg = pkg.childPackages.get(i); 14078 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName); 14079 PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName); 14080 if (childPs != null) { 14081 childRes.newUsers = childPs.queryInstalledUsers( 14082 sUserManager.getUserIds(), true); 14083 } 14084 } 14085 } 14086 } 14087 14088 private void startIntentFilterVerifications(int userId, boolean replacing, 14089 PackageParser.Package pkg) { 14090 if (mIntentFilterVerifierComponent == null) { 14091 Slog.w(TAG, "No IntentFilter verification will not be done as " 14092 + "there is no IntentFilterVerifier available!"); 14093 return; 14094 } 14095 14096 final int verifierUid = getPackageUid( 14097 mIntentFilterVerifierComponent.getPackageName(), 14098 MATCH_DEBUG_TRIAGED_MISSING, 14099 (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId); 14100 14101 Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 14102 msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid); 14103 mHandler.sendMessage(msg); 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 msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 14109 msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid); 14110 mHandler.sendMessage(msg); 14111 } 14112 } 14113 14114 private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing, 14115 PackageParser.Package pkg) { 14116 int size = pkg.activities.size(); 14117 if (size == 0) { 14118 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 14119 "No activity, so no need to verify any IntentFilter!"); 14120 return; 14121 } 14122 14123 final boolean hasDomainURLs = hasDomainURLs(pkg); 14124 if (!hasDomainURLs) { 14125 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 14126 "No domain URLs, so no need to verify any IntentFilter!"); 14127 return; 14128 } 14129 14130 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId 14131 + " if any IntentFilter from the " + size 14132 + " Activities needs verification ..."); 14133 14134 int count = 0; 14135 final String packageName = pkg.packageName; 14136 14137 synchronized (mPackages) { 14138 // If this is a new install and we see that we've already run verification for this 14139 // package, we have nothing to do: it means the state was restored from backup. 14140 if (!replacing) { 14141 IntentFilterVerificationInfo ivi = 14142 mSettings.getIntentFilterVerificationLPr(packageName); 14143 if (ivi != null) { 14144 if (DEBUG_DOMAIN_VERIFICATION) { 14145 Slog.i(TAG, "Package " + packageName+ " already verified: status=" 14146 + ivi.getStatusString()); 14147 } 14148 return; 14149 } 14150 } 14151 14152 // If any filters need to be verified, then all need to be. 14153 boolean needToVerify = false; 14154 for (PackageParser.Activity a : pkg.activities) { 14155 for (ActivityIntentInfo filter : a.intents) { 14156 if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) { 14157 if (DEBUG_DOMAIN_VERIFICATION) { 14158 Slog.d(TAG, "Intent filter needs verification, so processing all filters"); 14159 } 14160 needToVerify = true; 14161 break; 14162 } 14163 } 14164 } 14165 14166 if (needToVerify) { 14167 final int verificationId = mIntentFilterVerificationToken++; 14168 for (PackageParser.Activity a : pkg.activities) { 14169 for (ActivityIntentInfo filter : a.intents) { 14170 if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) { 14171 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 14172 "Verification needed for IntentFilter:" + filter.toString()); 14173 mIntentFilterVerifier.addOneIntentFilterVerification( 14174 verifierUid, userId, verificationId, filter, packageName); 14175 count++; 14176 } 14177 } 14178 } 14179 } 14180 } 14181 14182 if (count > 0) { 14183 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count 14184 + " IntentFilter verification" + (count > 1 ? "s" : "") 14185 + " for userId:" + userId); 14186 mIntentFilterVerifier.startVerifications(userId); 14187 } else { 14188 if (DEBUG_DOMAIN_VERIFICATION) { 14189 Slog.d(TAG, "No filters or not all autoVerify for " + packageName); 14190 } 14191 } 14192 } 14193 14194 private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) { 14195 final ComponentName cn = filter.activity.getComponentName(); 14196 final String packageName = cn.getPackageName(); 14197 14198 IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr( 14199 packageName); 14200 if (ivi == null) { 14201 return true; 14202 } 14203 int status = ivi.getStatus(); 14204 switch (status) { 14205 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 14206 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 14207 return true; 14208 14209 default: 14210 // Nothing to do 14211 return false; 14212 } 14213 } 14214 14215 private static boolean isMultiArch(ApplicationInfo info) { 14216 return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0; 14217 } 14218 14219 private static boolean isExternal(PackageParser.Package pkg) { 14220 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 14221 } 14222 14223 private static boolean isExternal(PackageSetting ps) { 14224 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 14225 } 14226 14227 private static boolean isEphemeral(PackageParser.Package pkg) { 14228 return pkg.applicationInfo.isEphemeralApp(); 14229 } 14230 14231 private static boolean isEphemeral(PackageSetting ps) { 14232 return ps.pkg != null && isEphemeral(ps.pkg); 14233 } 14234 14235 private static boolean isSystemApp(PackageParser.Package pkg) { 14236 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 14237 } 14238 14239 private static boolean isPrivilegedApp(PackageParser.Package pkg) { 14240 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; 14241 } 14242 14243 private static boolean hasDomainURLs(PackageParser.Package pkg) { 14244 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0; 14245 } 14246 14247 private static boolean isSystemApp(PackageSetting ps) { 14248 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0; 14249 } 14250 14251 private static boolean isUpdatedSystemApp(PackageSetting ps) { 14252 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; 14253 } 14254 14255 private int packageFlagsToInstallFlags(PackageSetting ps) { 14256 int installFlags = 0; 14257 if (isEphemeral(ps)) { 14258 installFlags |= PackageManager.INSTALL_EPHEMERAL; 14259 } 14260 if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) { 14261 // This existing package was an external ASEC install when we have 14262 // the external flag without a UUID 14263 installFlags |= PackageManager.INSTALL_EXTERNAL; 14264 } 14265 if (ps.isForwardLocked()) { 14266 installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 14267 } 14268 return installFlags; 14269 } 14270 14271 private String getVolumeUuidForPackage(PackageParser.Package pkg) { 14272 if (isExternal(pkg)) { 14273 if (TextUtils.isEmpty(pkg.volumeUuid)) { 14274 return StorageManager.UUID_PRIMARY_PHYSICAL; 14275 } else { 14276 return pkg.volumeUuid; 14277 } 14278 } else { 14279 return StorageManager.UUID_PRIVATE_INTERNAL; 14280 } 14281 } 14282 14283 private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) { 14284 if (isExternal(pkg)) { 14285 if (TextUtils.isEmpty(pkg.volumeUuid)) { 14286 return mSettings.getExternalVersion(); 14287 } else { 14288 return mSettings.findOrCreateVersion(pkg.volumeUuid); 14289 } 14290 } else { 14291 return mSettings.getInternalVersion(); 14292 } 14293 } 14294 14295 private void deleteTempPackageFiles() { 14296 final FilenameFilter filter = new FilenameFilter() { 14297 public boolean accept(File dir, String name) { 14298 return name.startsWith("vmdl") && name.endsWith(".tmp"); 14299 } 14300 }; 14301 for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) { 14302 file.delete(); 14303 } 14304 } 14305 14306 @Override 14307 public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId, 14308 int flags) { 14309 deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId, 14310 flags); 14311 } 14312 14313 @Override 14314 public void deletePackage(final String packageName, 14315 final IPackageDeleteObserver2 observer, final int userId, final int flags) { 14316 mContext.enforceCallingOrSelfPermission( 14317 android.Manifest.permission.DELETE_PACKAGES, null); 14318 Preconditions.checkNotNull(packageName); 14319 Preconditions.checkNotNull(observer); 14320 final int uid = Binder.getCallingUid(); 14321 final boolean deleteAllUsers = (flags & PackageManager.DELETE_ALL_USERS) != 0; 14322 final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId }; 14323 if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) { 14324 mContext.enforceCallingOrSelfPermission( 14325 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 14326 "deletePackage for user " + userId); 14327 } 14328 14329 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) { 14330 try { 14331 observer.onPackageDeleted(packageName, 14332 PackageManager.DELETE_FAILED_USER_RESTRICTED, null); 14333 } catch (RemoteException re) { 14334 } 14335 return; 14336 } 14337 14338 if (!deleteAllUsers && getBlockUninstallForUser(packageName, userId)) { 14339 try { 14340 observer.onPackageDeleted(packageName, 14341 PackageManager.DELETE_FAILED_OWNER_BLOCKED, null); 14342 } catch (RemoteException re) { 14343 } 14344 return; 14345 } 14346 14347 if (DEBUG_REMOVE) { 14348 Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId 14349 + " deleteAllUsers: " + deleteAllUsers ); 14350 } 14351 // Queue up an async operation since the package deletion may take a little while. 14352 mHandler.post(new Runnable() { 14353 public void run() { 14354 mHandler.removeCallbacks(this); 14355 int returnCode; 14356 if (!deleteAllUsers) { 14357 returnCode = deletePackageX(packageName, userId, flags); 14358 } else { 14359 int[] blockUninstallUserIds = getBlockUninstallForUsers(packageName, users); 14360 // If nobody is blocking uninstall, proceed with delete for all users 14361 if (ArrayUtils.isEmpty(blockUninstallUserIds)) { 14362 returnCode = deletePackageX(packageName, userId, flags); 14363 } else { 14364 // Otherwise uninstall individually for users with blockUninstalls=false 14365 final int userFlags = flags & ~PackageManager.DELETE_ALL_USERS; 14366 for (int userId : users) { 14367 if (!ArrayUtils.contains(blockUninstallUserIds, userId)) { 14368 returnCode = deletePackageX(packageName, userId, userFlags); 14369 if (returnCode != PackageManager.DELETE_SUCCEEDED) { 14370 Slog.w(TAG, "Package delete failed for user " + userId 14371 + ", returnCode " + returnCode); 14372 } 14373 } 14374 } 14375 // The app has only been marked uninstalled for certain users. 14376 // We still need to report that delete was blocked 14377 returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED; 14378 } 14379 } 14380 try { 14381 observer.onPackageDeleted(packageName, returnCode, null); 14382 } catch (RemoteException e) { 14383 Log.i(TAG, "Observer no longer exists."); 14384 } //end catch 14385 } //end run 14386 }); 14387 } 14388 14389 private int[] getBlockUninstallForUsers(String packageName, int[] userIds) { 14390 int[] result = EMPTY_INT_ARRAY; 14391 for (int userId : userIds) { 14392 if (getBlockUninstallForUser(packageName, userId)) { 14393 result = ArrayUtils.appendInt(result, userId); 14394 } 14395 } 14396 return result; 14397 } 14398 14399 @Override 14400 public boolean isPackageDeviceAdminOnAnyUser(String packageName) { 14401 return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL); 14402 } 14403 14404 private boolean isPackageDeviceAdmin(String packageName, int userId) { 14405 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface( 14406 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); 14407 try { 14408 if (dpm != null) { 14409 final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent( 14410 /* callingUserOnly =*/ false); 14411 final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null 14412 : deviceOwnerComponentName.getPackageName(); 14413 // Does the package contains the device owner? 14414 // TODO Do we have to do it even if userId != UserHandle.USER_ALL? Otherwise, 14415 // this check is probably not needed, since DO should be registered as a device 14416 // admin on some user too. (Original bug for this: b/17657954) 14417 if (packageName.equals(deviceOwnerPackageName)) { 14418 return true; 14419 } 14420 // Does it contain a device admin for any user? 14421 int[] users; 14422 if (userId == UserHandle.USER_ALL) { 14423 users = sUserManager.getUserIds(); 14424 } else { 14425 users = new int[]{userId}; 14426 } 14427 for (int i = 0; i < users.length; ++i) { 14428 if (dpm.packageHasActiveAdmins(packageName, users[i])) { 14429 return true; 14430 } 14431 } 14432 } 14433 } catch (RemoteException e) { 14434 } 14435 return false; 14436 } 14437 14438 private boolean shouldKeepUninstalledPackageLPr(String packageName) { 14439 return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName); 14440 } 14441 14442 /** 14443 * This method is an internal method that could be get invoked either 14444 * to delete an installed package or to clean up a failed installation. 14445 * After deleting an installed package, a broadcast is sent to notify any 14446 * listeners that the package has been installed. For cleaning up a failed 14447 * installation, the broadcast is not necessary since the package's 14448 * installation wouldn't have sent the initial broadcast either 14449 * The key steps in deleting a package are 14450 * deleting the package information in internal structures like mPackages, 14451 * deleting the packages base directories through installd 14452 * updating mSettings to reflect current status 14453 * persisting settings for later use 14454 * sending a broadcast if necessary 14455 */ 14456 private int deletePackageX(String packageName, int userId, int flags) { 14457 final PackageRemovedInfo info = new PackageRemovedInfo(); 14458 final boolean res; 14459 14460 final UserHandle removeForUser = (flags & PackageManager.DELETE_ALL_USERS) != 0 14461 ? UserHandle.ALL : new UserHandle(userId); 14462 14463 if (isPackageDeviceAdmin(packageName, removeForUser.getIdentifier())) { 14464 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin"); 14465 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER; 14466 } 14467 14468 PackageSetting uninstalledPs = null; 14469 14470 // for the uninstall-updates case and restricted profiles, remember the per- 14471 // user handle installed state 14472 int[] allUsers; 14473 synchronized (mPackages) { 14474 uninstalledPs = mSettings.mPackages.get(packageName); 14475 if (uninstalledPs == null) { 14476 Slog.w(TAG, "Not removing non-existent package " + packageName); 14477 return PackageManager.DELETE_FAILED_INTERNAL_ERROR; 14478 } 14479 allUsers = sUserManager.getUserIds(); 14480 info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true); 14481 } 14482 14483 synchronized (mInstallLock) { 14484 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId); 14485 res = deletePackageLI(packageName, removeForUser, true, allUsers, 14486 flags | REMOVE_CHATTY, info, true, null); 14487 synchronized (mPackages) { 14488 if (res) { 14489 mEphemeralApplicationRegistry.onPackageUninstalledLPw(uninstalledPs.pkg); 14490 } 14491 } 14492 } 14493 14494 if (res) { 14495 final boolean killApp = (flags & PackageManager.INSTALL_DONT_KILL_APP) == 0; 14496 info.sendPackageRemovedBroadcasts(killApp); 14497 info.sendSystemPackageUpdatedBroadcasts(); 14498 info.sendSystemPackageAppearedBroadcasts(); 14499 } 14500 // Force a gc here. 14501 Runtime.getRuntime().gc(); 14502 // Delete the resources here after sending the broadcast to let 14503 // other processes clean up before deleting resources. 14504 if (info.args != null) { 14505 synchronized (mInstallLock) { 14506 info.args.doPostDeleteLI(true); 14507 } 14508 } 14509 14510 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR; 14511 } 14512 14513 class PackageRemovedInfo { 14514 String removedPackage; 14515 int uid = -1; 14516 int removedAppId = -1; 14517 int[] origUsers; 14518 int[] removedUsers = null; 14519 boolean isRemovedPackageSystemUpdate = false; 14520 boolean isUpdate; 14521 boolean dataRemoved; 14522 boolean removedForAllUsers; 14523 // Clean up resources deleted packages. 14524 InstallArgs args = null; 14525 ArrayMap<String, PackageRemovedInfo> removedChildPackages; 14526 ArrayMap<String, PackageInstalledInfo> appearedChildPackages; 14527 14528 void sendPackageRemovedBroadcasts(boolean killApp) { 14529 sendPackageRemovedBroadcastInternal(killApp); 14530 final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0; 14531 for (int i = 0; i < childCount; i++) { 14532 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i); 14533 childInfo.sendPackageRemovedBroadcastInternal(killApp); 14534 } 14535 } 14536 14537 void sendSystemPackageUpdatedBroadcasts() { 14538 if (isRemovedPackageSystemUpdate) { 14539 sendSystemPackageUpdatedBroadcastsInternal(); 14540 final int childCount = (removedChildPackages != null) 14541 ? removedChildPackages.size() : 0; 14542 for (int i = 0; i < childCount; i++) { 14543 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i); 14544 if (childInfo.isRemovedPackageSystemUpdate) { 14545 childInfo.sendSystemPackageUpdatedBroadcastsInternal(); 14546 } 14547 } 14548 } 14549 } 14550 14551 void sendSystemPackageAppearedBroadcasts() { 14552 final int packageCount = (appearedChildPackages != null) 14553 ? appearedChildPackages.size() : 0; 14554 for (int i = 0; i < packageCount; i++) { 14555 PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i); 14556 for (int userId : installedInfo.newUsers) { 14557 sendPackageAddedForUser(installedInfo.name, true, 14558 UserHandle.getAppId(installedInfo.uid), userId); 14559 } 14560 } 14561 } 14562 14563 private void sendSystemPackageUpdatedBroadcastsInternal() { 14564 Bundle extras = new Bundle(2); 14565 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 14566 extras.putBoolean(Intent.EXTRA_REPLACING, true); 14567 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, removedPackage, 14568 extras, 0, null, null, null); 14569 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, removedPackage, 14570 extras, 0, null, null, null); 14571 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null, 14572 null, 0, removedPackage, null, null); 14573 } 14574 14575 private void sendPackageRemovedBroadcastInternal(boolean killApp) { 14576 Bundle extras = new Bundle(2); 14577 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 14578 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved); 14579 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp); 14580 if (isUpdate || isRemovedPackageSystemUpdate) { 14581 extras.putBoolean(Intent.EXTRA_REPLACING, true); 14582 } 14583 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers); 14584 if (removedPackage != null) { 14585 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, 14586 extras, 0, null, null, removedUsers); 14587 if (dataRemoved && !isRemovedPackageSystemUpdate) { 14588 sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, 14589 removedPackage, extras, 0, null, null, removedUsers); 14590 } 14591 } 14592 if (removedAppId >= 0) { 14593 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, 0, null, null, 14594 removedUsers); 14595 } 14596 } 14597 } 14598 14599 /* 14600 * This method deletes the package from internal data structures. If the DONT_DELETE_DATA 14601 * flag is not set, the data directory is removed as well. 14602 * make sure this flag is set for partially installed apps. If not its meaningless to 14603 * delete a partially installed application. 14604 */ 14605 private void removePackageDataLI(PackageSetting ps, int[] allUserHandles, 14606 PackageRemovedInfo outInfo, int flags, boolean writeSettings) { 14607 String packageName = ps.name; 14608 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps); 14609 removePackageLI(ps, (flags&REMOVE_CHATTY) != 0); 14610 // Retrieve object to delete permissions for shared user later on 14611 final PackageSetting deletedPs; 14612 // reader 14613 synchronized (mPackages) { 14614 deletedPs = mSettings.mPackages.get(packageName); 14615 if (outInfo != null) { 14616 outInfo.removedPackage = packageName; 14617 outInfo.removedUsers = deletedPs != null 14618 ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true) 14619 : null; 14620 } 14621 } 14622 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 14623 removeDataDirsLI(ps.volumeUuid, packageName); 14624 if (outInfo != null) { 14625 outInfo.dataRemoved = true; 14626 } 14627 schedulePackageCleaning(packageName, UserHandle.USER_ALL, true); 14628 } 14629 // writer 14630 synchronized (mPackages) { 14631 if (deletedPs != null) { 14632 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 14633 clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL); 14634 clearDefaultBrowserIfNeeded(packageName); 14635 if (outInfo != null) { 14636 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName); 14637 outInfo.removedAppId = mSettings.removePackageLPw(packageName); 14638 } 14639 updatePermissionsLPw(deletedPs.name, null, 0); 14640 if (deletedPs.sharedUser != null) { 14641 // Remove permissions associated with package. Since runtime 14642 // permissions are per user we have to kill the removed package 14643 // or packages running under the shared user of the removed 14644 // package if revoking the permissions requested only by the removed 14645 // package is successful and this causes a change in gids. 14646 for (int userId : UserManagerService.getInstance().getUserIds()) { 14647 final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs, 14648 userId); 14649 if (userIdToKill == UserHandle.USER_ALL 14650 || userIdToKill >= UserHandle.USER_SYSTEM) { 14651 // If gids changed for this user, kill all affected packages. 14652 mHandler.post(new Runnable() { 14653 @Override 14654 public void run() { 14655 // This has to happen with no lock held. 14656 killApplication(deletedPs.name, deletedPs.appId, 14657 KILL_APP_REASON_GIDS_CHANGED); 14658 } 14659 }); 14660 break; 14661 } 14662 } 14663 } 14664 clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL); 14665 } 14666 // make sure to preserve per-user disabled state if this removal was just 14667 // a downgrade of a system app to the factory package 14668 if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) { 14669 if (DEBUG_REMOVE) { 14670 Slog.d(TAG, "Propagating install state across downgrade"); 14671 } 14672 for (int userId : allUserHandles) { 14673 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId); 14674 if (DEBUG_REMOVE) { 14675 Slog.d(TAG, " user " + userId + " => " + installed); 14676 } 14677 ps.setInstalled(installed, userId); 14678 } 14679 } 14680 } 14681 // can downgrade to reader 14682 if (writeSettings) { 14683 // Save settings now 14684 mSettings.writeLPr(); 14685 } 14686 } 14687 if (outInfo != null) { 14688 // A user ID was deleted here. Go through all users and remove it 14689 // from KeyStore. 14690 removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId); 14691 } 14692 } 14693 14694 static boolean locationIsPrivileged(File path) { 14695 try { 14696 final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app") 14697 .getCanonicalPath(); 14698 return path.getCanonicalPath().startsWith(privilegedAppDir); 14699 } catch (IOException e) { 14700 Slog.e(TAG, "Unable to access code path " + path); 14701 } 14702 return false; 14703 } 14704 14705 /* 14706 * Tries to delete system package. 14707 */ 14708 private boolean deleteSystemPackageLI(PackageParser.Package deletedPkg, 14709 PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo, 14710 boolean writeSettings) { 14711 if (deletedPs.parentPackageName != null) { 14712 Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName); 14713 return false; 14714 } 14715 14716 final boolean applyUserRestrictions 14717 = (allUserHandles != null) && (outInfo.origUsers != null); 14718 final PackageSetting disabledPs; 14719 // Confirm if the system package has been updated 14720 // An updated system app can be deleted. This will also have to restore 14721 // the system pkg from system partition 14722 // reader 14723 synchronized (mPackages) { 14724 disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name); 14725 } 14726 14727 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName 14728 + " disabledPs=" + disabledPs); 14729 14730 if (disabledPs == null) { 14731 Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName); 14732 return false; 14733 } else if (DEBUG_REMOVE) { 14734 Slog.d(TAG, "Deleting system pkg from data partition"); 14735 } 14736 14737 if (DEBUG_REMOVE) { 14738 if (applyUserRestrictions) { 14739 Slog.d(TAG, "Remembering install states:"); 14740 for (int userId : allUserHandles) { 14741 final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId); 14742 Slog.d(TAG, " u=" + userId + " inst=" + finstalled); 14743 } 14744 } 14745 } 14746 14747 // Delete the updated package 14748 outInfo.isRemovedPackageSystemUpdate = true; 14749 if (outInfo.removedChildPackages != null) { 14750 final int childCount = (deletedPs.childPackageNames != null) 14751 ? deletedPs.childPackageNames.size() : 0; 14752 for (int i = 0; i < childCount; i++) { 14753 String childPackageName = deletedPs.childPackageNames.get(i); 14754 if (disabledPs.childPackageNames != null && disabledPs.childPackageNames 14755 .contains(childPackageName)) { 14756 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get( 14757 childPackageName); 14758 if (childInfo != null) { 14759 childInfo.isRemovedPackageSystemUpdate = true; 14760 } 14761 } 14762 } 14763 } 14764 14765 if (disabledPs.versionCode < deletedPs.versionCode) { 14766 // Delete data for downgrades 14767 flags &= ~PackageManager.DELETE_KEEP_DATA; 14768 } else { 14769 // Preserve data by setting flag 14770 flags |= PackageManager.DELETE_KEEP_DATA; 14771 } 14772 14773 boolean ret = deleteInstalledPackageLI(deletedPs, true, flags, allUserHandles, 14774 outInfo, writeSettings, disabledPs.pkg); 14775 if (!ret) { 14776 return false; 14777 } 14778 14779 // writer 14780 synchronized (mPackages) { 14781 // Reinstate the old system package 14782 enableSystemPackageLPw(disabledPs.pkg); 14783 // Remove any native libraries from the upgraded package. 14784 removeNativeBinariesLI(deletedPs); 14785 } 14786 14787 // Install the system package 14788 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs); 14789 int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM; 14790 if (locationIsPrivileged(disabledPs.codePath)) { 14791 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 14792 } 14793 14794 final PackageParser.Package newPkg; 14795 try { 14796 newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null); 14797 } catch (PackageManagerException e) { 14798 Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": " 14799 + e.getMessage()); 14800 return false; 14801 } 14802 14803 prepareAppDataAfterInstall(newPkg); 14804 14805 // writer 14806 synchronized (mPackages) { 14807 PackageSetting ps = mSettings.mPackages.get(newPkg.packageName); 14808 14809 // Propagate the permissions state as we do not want to drop on the floor 14810 // runtime permissions. The update permissions method below will take 14811 // care of removing obsolete permissions and grant install permissions. 14812 ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState()); 14813 updatePermissionsLPw(newPkg.packageName, newPkg, 14814 UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG); 14815 14816 if (applyUserRestrictions) { 14817 if (DEBUG_REMOVE) { 14818 Slog.d(TAG, "Propagating install state across reinstall"); 14819 } 14820 for (int userId : allUserHandles) { 14821 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId); 14822 if (DEBUG_REMOVE) { 14823 Slog.d(TAG, " user " + userId + " => " + installed); 14824 } 14825 ps.setInstalled(installed, userId); 14826 14827 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 14828 } 14829 // Regardless of writeSettings we need to ensure that this restriction 14830 // state propagation is persisted 14831 mSettings.writeAllUsersPackageRestrictionsLPr(); 14832 } 14833 // can downgrade to reader here 14834 if (writeSettings) { 14835 mSettings.writeLPr(); 14836 } 14837 } 14838 return true; 14839 } 14840 14841 private boolean deleteInstalledPackageLI(PackageSetting ps, 14842 boolean deleteCodeAndResources, int flags, int[] allUserHandles, 14843 PackageRemovedInfo outInfo, boolean writeSettings, 14844 PackageParser.Package replacingPackage) { 14845 synchronized (mPackages) { 14846 if (outInfo != null) { 14847 outInfo.uid = ps.appId; 14848 } 14849 14850 if (outInfo != null && outInfo.removedChildPackages != null) { 14851 final int childCount = (ps.childPackageNames != null) 14852 ? ps.childPackageNames.size() : 0; 14853 for (int i = 0; i < childCount; i++) { 14854 String childPackageName = ps.childPackageNames.get(i); 14855 PackageSetting childPs = mSettings.mPackages.get(childPackageName); 14856 if (childPs == null) { 14857 return false; 14858 } 14859 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get( 14860 childPackageName); 14861 if (childInfo != null) { 14862 childInfo.uid = childPs.appId; 14863 } 14864 } 14865 } 14866 } 14867 14868 // Delete package data from internal structures and also remove data if flag is set 14869 removePackageDataLI(ps, allUserHandles, outInfo, flags, writeSettings); 14870 14871 // Delete the child packages data 14872 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0; 14873 for (int i = 0; i < childCount; i++) { 14874 PackageSetting childPs; 14875 synchronized (mPackages) { 14876 childPs = mSettings.peekPackageLPr(ps.childPackageNames.get(i)); 14877 } 14878 if (childPs != null) { 14879 PackageRemovedInfo childOutInfo = (outInfo != null 14880 && outInfo.removedChildPackages != null) 14881 ? outInfo.removedChildPackages.get(childPs.name) : null; 14882 final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0 14883 && (replacingPackage != null 14884 && !replacingPackage.hasChildPackage(childPs.name)) 14885 ? flags & ~DELETE_KEEP_DATA : flags; 14886 removePackageDataLI(childPs, allUserHandles, childOutInfo, 14887 deleteFlags, writeSettings); 14888 } 14889 } 14890 14891 // Delete application code and resources only for parent packages 14892 if (ps.parentPackageName == null) { 14893 if (deleteCodeAndResources && (outInfo != null)) { 14894 outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 14895 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 14896 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args); 14897 } 14898 } 14899 14900 return true; 14901 } 14902 14903 @Override 14904 public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall, 14905 int userId) { 14906 mContext.enforceCallingOrSelfPermission( 14907 android.Manifest.permission.DELETE_PACKAGES, null); 14908 synchronized (mPackages) { 14909 PackageSetting ps = mSettings.mPackages.get(packageName); 14910 if (ps == null) { 14911 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName); 14912 return false; 14913 } 14914 if (!ps.getInstalled(userId)) { 14915 // Can't block uninstall for an app that is not installed or enabled. 14916 Log.i(TAG, "Package not installed in set block uninstall " + packageName); 14917 return false; 14918 } 14919 ps.setBlockUninstall(blockUninstall, userId); 14920 mSettings.writePackageRestrictionsLPr(userId); 14921 } 14922 return true; 14923 } 14924 14925 @Override 14926 public boolean getBlockUninstallForUser(String packageName, int userId) { 14927 synchronized (mPackages) { 14928 PackageSetting ps = mSettings.mPackages.get(packageName); 14929 if (ps == null) { 14930 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName); 14931 return false; 14932 } 14933 return ps.getBlockUninstall(userId); 14934 } 14935 } 14936 14937 @Override 14938 public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) { 14939 int callingUid = Binder.getCallingUid(); 14940 if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) { 14941 throw new SecurityException( 14942 "setRequiredForSystemUser can only be run by the system or root"); 14943 } 14944 synchronized (mPackages) { 14945 PackageSetting ps = mSettings.mPackages.get(packageName); 14946 if (ps == null) { 14947 Log.w(TAG, "Package doesn't exist: " + packageName); 14948 return false; 14949 } 14950 if (systemUserApp) { 14951 ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER; 14952 } else { 14953 ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER; 14954 } 14955 mSettings.writeLPr(); 14956 } 14957 return true; 14958 } 14959 14960 /* 14961 * This method handles package deletion in general 14962 */ 14963 private boolean deletePackageLI(String packageName, UserHandle user, 14964 boolean deleteCodeAndResources, int[] allUserHandles, int flags, 14965 PackageRemovedInfo outInfo, boolean writeSettings, 14966 PackageParser.Package replacingPackage) { 14967 if (packageName == null) { 14968 Slog.w(TAG, "Attempt to delete null packageName."); 14969 return false; 14970 } 14971 14972 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user); 14973 14974 PackageSetting ps; 14975 14976 synchronized (mPackages) { 14977 ps = mSettings.mPackages.get(packageName); 14978 if (ps == null) { 14979 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 14980 return false; 14981 } 14982 14983 if (ps.parentPackageName != null && (!isSystemApp(ps) 14984 || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) { 14985 if (DEBUG_REMOVE) { 14986 Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:" 14987 + ((user == null) ? UserHandle.USER_ALL : user)); 14988 } 14989 final int removedUserId = (user != null) ? user.getIdentifier() 14990 : UserHandle.USER_ALL; 14991 if (!clearPackageStateForUser(ps, removedUserId, outInfo)) { 14992 return false; 14993 } 14994 markPackageUninstalledForUserLPw(ps, user); 14995 scheduleWritePackageRestrictionsLocked(user); 14996 return true; 14997 } 14998 } 14999 15000 if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null 15001 && user.getIdentifier() != UserHandle.USER_ALL)) { 15002 // The caller is asking that the package only be deleted for a single 15003 // user. To do this, we just mark its uninstalled state and delete 15004 // its data. If this is a system app, we only allow this to happen if 15005 // they have set the special DELETE_SYSTEM_APP which requests different 15006 // semantics than normal for uninstalling system apps. 15007 markPackageUninstalledForUserLPw(ps, user); 15008 15009 if (!isSystemApp(ps)) { 15010 // Do not uninstall the APK if an app should be cached 15011 boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName); 15012 if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) { 15013 // Other user still have this package installed, so all 15014 // we need to do is clear this user's data and save that 15015 // it is uninstalled. 15016 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users"); 15017 if (!clearPackageStateForUser(ps, user.getIdentifier(), outInfo)) { 15018 return false; 15019 } 15020 scheduleWritePackageRestrictionsLocked(user); 15021 return true; 15022 } else { 15023 // We need to set it back to 'installed' so the uninstall 15024 // broadcasts will be sent correctly. 15025 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete"); 15026 ps.setInstalled(true, user.getIdentifier()); 15027 } 15028 } else { 15029 // This is a system app, so we assume that the 15030 // other users still have this package installed, so all 15031 // we need to do is clear this user's data and save that 15032 // it is uninstalled. 15033 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app"); 15034 if (!clearPackageStateForUser(ps, user.getIdentifier(), outInfo)) { 15035 return false; 15036 } 15037 scheduleWritePackageRestrictionsLocked(user); 15038 return true; 15039 } 15040 } 15041 15042 // If we are deleting a composite package for all users, keep track 15043 // of result for each child. 15044 if (ps.childPackageNames != null && outInfo != null) { 15045 synchronized (mPackages) { 15046 final int childCount = ps.childPackageNames.size(); 15047 outInfo.removedChildPackages = new ArrayMap<>(childCount); 15048 for (int i = 0; i < childCount; i++) { 15049 String childPackageName = ps.childPackageNames.get(i); 15050 PackageRemovedInfo childInfo = new PackageRemovedInfo(); 15051 childInfo.removedPackage = childPackageName; 15052 outInfo.removedChildPackages.put(childPackageName, childInfo); 15053 PackageSetting childPs = mSettings.peekPackageLPr(childPackageName); 15054 if (childPs != null) { 15055 childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true); 15056 } 15057 } 15058 } 15059 } 15060 15061 boolean ret = false; 15062 if (isSystemApp(ps)) { 15063 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name); 15064 // When an updated system application is deleted we delete the existing resources 15065 // as well and fall back to existing code in system partition 15066 ret = deleteSystemPackageLI(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings); 15067 } else { 15068 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name); 15069 // Kill application pre-emptively especially for apps on sd. 15070 final boolean killApp = (flags & PackageManager.DELETE_DONT_KILL_APP) == 0; 15071 if (killApp) { 15072 killApplication(packageName, ps.appId, "uninstall pkg"); 15073 } 15074 ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags, allUserHandles, 15075 outInfo, writeSettings, replacingPackage); 15076 } 15077 15078 // Take a note whether we deleted the package for all users 15079 if (outInfo != null) { 15080 outInfo.removedForAllUsers = mPackages.get(ps.name) == null; 15081 if (outInfo.removedChildPackages != null) { 15082 synchronized (mPackages) { 15083 final int childCount = outInfo.removedChildPackages.size(); 15084 for (int i = 0; i < childCount; i++) { 15085 PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i); 15086 if (childInfo != null) { 15087 childInfo.removedForAllUsers = mPackages.get( 15088 childInfo.removedPackage) == null; 15089 } 15090 } 15091 } 15092 } 15093 // If we uninstalled an update to a system app there may be some 15094 // child packages that appeared as they are declared in the system 15095 // app but were not declared in the update. 15096 if (isSystemApp(ps)) { 15097 synchronized (mPackages) { 15098 PackageSetting updatedPs = mSettings.peekPackageLPr(ps.name); 15099 final int childCount = (updatedPs.childPackageNames != null) 15100 ? updatedPs.childPackageNames.size() : 0; 15101 for (int i = 0; i < childCount; i++) { 15102 String childPackageName = updatedPs.childPackageNames.get(i); 15103 if (outInfo.removedChildPackages == null 15104 || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) { 15105 PackageSetting childPs = mSettings.peekPackageLPr(childPackageName); 15106 if (childPs == null) { 15107 continue; 15108 } 15109 PackageInstalledInfo installRes = new PackageInstalledInfo(); 15110 installRes.name = childPackageName; 15111 installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true); 15112 installRes.pkg = mPackages.get(childPackageName); 15113 installRes.uid = childPs.pkg.applicationInfo.uid; 15114 if (outInfo.appearedChildPackages == null) { 15115 outInfo.appearedChildPackages = new ArrayMap<>(); 15116 } 15117 outInfo.appearedChildPackages.put(childPackageName, installRes); 15118 } 15119 } 15120 } 15121 } 15122 } 15123 15124 return ret; 15125 } 15126 15127 private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) { 15128 final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL) 15129 ? sUserManager.getUserIds() : new int[] {user.getIdentifier()}; 15130 for (int nextUserId : userIds) { 15131 if (DEBUG_REMOVE) { 15132 Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId); 15133 } 15134 ps.setUserState(nextUserId, COMPONENT_ENABLED_STATE_DEFAULT, 15135 false /*installed*/, true /*stopped*/, true /*notLaunched*/, 15136 false /*hidden*/, false /*suspended*/, null, null, null, 15137 false /*blockUninstall*/, 15138 ps.readUserState(nextUserId).domainVerificationStatus, 0); 15139 } 15140 } 15141 15142 private boolean clearPackageStateForUser(PackageSetting ps, int userId, 15143 PackageRemovedInfo outInfo) { 15144 final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() 15145 : new int[] {userId}; 15146 for (int nextUserId : userIds) { 15147 if (DEBUG_REMOVE) { 15148 Slog.d(TAG, "Updating package:" + ps.name + " install state for user:" 15149 + nextUserId); 15150 } 15151 final int flags = StorageManager.FLAG_STORAGE_CE| StorageManager.FLAG_STORAGE_DE; 15152 try { 15153 mInstaller.destroyAppData(ps.volumeUuid, ps.name, nextUserId, flags); 15154 } catch (InstallerException e) { 15155 Slog.w(TAG, "Couldn't remove cache files for package " + ps.name, e); 15156 return false; 15157 } 15158 removeKeystoreDataIfNeeded(nextUserId, ps.appId); 15159 schedulePackageCleaning(ps.name, nextUserId, false); 15160 synchronized (mPackages) { 15161 if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) { 15162 scheduleWritePackageRestrictionsLocked(nextUserId); 15163 } 15164 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId); 15165 } 15166 } 15167 15168 if (outInfo != null) { 15169 outInfo.removedPackage = ps.name; 15170 outInfo.removedAppId = ps.appId; 15171 outInfo.removedUsers = userIds; 15172 } 15173 15174 return true; 15175 } 15176 15177 private final class ClearStorageConnection implements ServiceConnection { 15178 IMediaContainerService mContainerService; 15179 15180 @Override 15181 public void onServiceConnected(ComponentName name, IBinder service) { 15182 synchronized (this) { 15183 mContainerService = IMediaContainerService.Stub.asInterface(service); 15184 notifyAll(); 15185 } 15186 } 15187 15188 @Override 15189 public void onServiceDisconnected(ComponentName name) { 15190 } 15191 } 15192 15193 private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) { 15194 final boolean mounted; 15195 if (Environment.isExternalStorageEmulated()) { 15196 mounted = true; 15197 } else { 15198 final String status = Environment.getExternalStorageState(); 15199 15200 mounted = status.equals(Environment.MEDIA_MOUNTED) 15201 || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY); 15202 } 15203 15204 if (!mounted) { 15205 return; 15206 } 15207 15208 final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 15209 int[] users; 15210 if (userId == UserHandle.USER_ALL) { 15211 users = sUserManager.getUserIds(); 15212 } else { 15213 users = new int[] { userId }; 15214 } 15215 final ClearStorageConnection conn = new ClearStorageConnection(); 15216 if (mContext.bindServiceAsUser( 15217 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) { 15218 try { 15219 for (int curUser : users) { 15220 long timeout = SystemClock.uptimeMillis() + 5000; 15221 synchronized (conn) { 15222 long now = SystemClock.uptimeMillis(); 15223 while (conn.mContainerService == null && now < timeout) { 15224 try { 15225 conn.wait(timeout - now); 15226 } catch (InterruptedException e) { 15227 } 15228 } 15229 } 15230 if (conn.mContainerService == null) { 15231 return; 15232 } 15233 15234 final UserEnvironment userEnv = new UserEnvironment(curUser); 15235 clearDirectory(conn.mContainerService, 15236 userEnv.buildExternalStorageAppCacheDirs(packageName)); 15237 if (allData) { 15238 clearDirectory(conn.mContainerService, 15239 userEnv.buildExternalStorageAppDataDirs(packageName)); 15240 clearDirectory(conn.mContainerService, 15241 userEnv.buildExternalStorageAppMediaDirs(packageName)); 15242 } 15243 } 15244 } finally { 15245 mContext.unbindService(conn); 15246 } 15247 } 15248 } 15249 15250 @Override 15251 public void clearApplicationProfileData(String packageName) { 15252 enforceSystemOrRoot("Only the system can clear all profile data"); 15253 try { 15254 mInstaller.clearAppProfiles(packageName); 15255 } catch (InstallerException ex) { 15256 Log.e(TAG, "Could not clear profile data of package " + packageName); 15257 } 15258 } 15259 15260 @Override 15261 public void clearApplicationUserData(final String packageName, 15262 final IPackageDataObserver observer, final int userId) { 15263 mContext.enforceCallingOrSelfPermission( 15264 android.Manifest.permission.CLEAR_APP_USER_DATA, null); 15265 15266 enforceCrossUserPermission(Binder.getCallingUid(), userId, 15267 true /* requireFullPermission */, false /* checkShell */, "clear application data"); 15268 15269 final DevicePolicyManagerInternal dpmi = LocalServices 15270 .getService(DevicePolicyManagerInternal.class); 15271 if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) { 15272 throw new SecurityException("Cannot clear data for a device owner or a profile owner"); 15273 } 15274 // Queue up an async operation since the package deletion may take a little while. 15275 mHandler.post(new Runnable() { 15276 public void run() { 15277 mHandler.removeCallbacks(this); 15278 final boolean succeeded; 15279 synchronized (mInstallLock) { 15280 succeeded = clearApplicationUserDataLI(packageName, userId); 15281 } 15282 clearExternalStorageDataSync(packageName, userId, true); 15283 if (succeeded) { 15284 // invoke DeviceStorageMonitor's update method to clear any notifications 15285 DeviceStorageMonitorInternal dsm = LocalServices 15286 .getService(DeviceStorageMonitorInternal.class); 15287 if (dsm != null) { 15288 dsm.checkMemory(); 15289 } 15290 } 15291 if(observer != null) { 15292 try { 15293 observer.onRemoveCompleted(packageName, succeeded); 15294 } catch (RemoteException e) { 15295 Log.i(TAG, "Observer no longer exists."); 15296 } 15297 } //end if observer 15298 } //end run 15299 }); 15300 } 15301 15302 private boolean clearApplicationUserDataLI(String packageName, int userId) { 15303 if (packageName == null) { 15304 Slog.w(TAG, "Attempt to delete null packageName."); 15305 return false; 15306 } 15307 15308 // Try finding details about the requested package 15309 PackageParser.Package pkg; 15310 synchronized (mPackages) { 15311 pkg = mPackages.get(packageName); 15312 if (pkg == null) { 15313 final PackageSetting ps = mSettings.mPackages.get(packageName); 15314 if (ps != null) { 15315 pkg = ps.pkg; 15316 } 15317 } 15318 15319 if (pkg == null) { 15320 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 15321 return false; 15322 } 15323 15324 PackageSetting ps = (PackageSetting) pkg.mExtras; 15325 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 15326 } 15327 15328 // Always delete data directories for package, even if we found no other 15329 // record of app. This helps users recover from UID mismatches without 15330 // resorting to a full data wipe. 15331 // TODO: triage flags as part of 26466827 15332 final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE; 15333 try { 15334 mInstaller.clearAppData(pkg.volumeUuid, packageName, userId, flags); 15335 } catch (InstallerException e) { 15336 Slog.w(TAG, "Couldn't remove cache files for package " + packageName, e); 15337 return false; 15338 } 15339 15340 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); 15341 removeKeystoreDataIfNeeded(userId, appId); 15342 15343 // Create a native library symlink only if we have native libraries 15344 // and if the native libraries are 32 bit libraries. We do not provide 15345 // this symlink for 64 bit libraries. 15346 if (pkg.applicationInfo.primaryCpuAbi != null && 15347 !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) { 15348 final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir; 15349 try { 15350 mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName, 15351 nativeLibPath, userId); 15352 } catch (InstallerException e) { 15353 Slog.w(TAG, "Failed linking native library dir", e); 15354 return false; 15355 } 15356 } 15357 15358 return true; 15359 } 15360 15361 /** 15362 * Reverts user permission state changes (permissions and flags) in 15363 * all packages for a given user. 15364 * 15365 * @param userId The device user for which to do a reset. 15366 */ 15367 private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) { 15368 final int packageCount = mPackages.size(); 15369 for (int i = 0; i < packageCount; i++) { 15370 PackageParser.Package pkg = mPackages.valueAt(i); 15371 PackageSetting ps = (PackageSetting) pkg.mExtras; 15372 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 15373 } 15374 } 15375 15376 /** 15377 * Reverts user permission state changes (permissions and flags). 15378 * 15379 * @param ps The package for which to reset. 15380 * @param userId The device user for which to do a reset. 15381 */ 15382 private void resetUserChangesToRuntimePermissionsAndFlagsLPw( 15383 final PackageSetting ps, final int userId) { 15384 if (ps.pkg == null) { 15385 return; 15386 } 15387 15388 // These are flags that can change base on user actions. 15389 final int userSettableMask = FLAG_PERMISSION_USER_SET 15390 | FLAG_PERMISSION_USER_FIXED 15391 | FLAG_PERMISSION_REVOKE_ON_UPGRADE 15392 | FLAG_PERMISSION_REVIEW_REQUIRED; 15393 15394 final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED 15395 | FLAG_PERMISSION_POLICY_FIXED; 15396 15397 boolean writeInstallPermissions = false; 15398 boolean writeRuntimePermissions = false; 15399 15400 final int permissionCount = ps.pkg.requestedPermissions.size(); 15401 for (int i = 0; i < permissionCount; i++) { 15402 String permission = ps.pkg.requestedPermissions.get(i); 15403 15404 BasePermission bp = mSettings.mPermissions.get(permission); 15405 if (bp == null) { 15406 continue; 15407 } 15408 15409 // If shared user we just reset the state to which only this app contributed. 15410 if (ps.sharedUser != null) { 15411 boolean used = false; 15412 final int packageCount = ps.sharedUser.packages.size(); 15413 for (int j = 0; j < packageCount; j++) { 15414 PackageSetting pkg = ps.sharedUser.packages.valueAt(j); 15415 if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName) 15416 && pkg.pkg.requestedPermissions.contains(permission)) { 15417 used = true; 15418 break; 15419 } 15420 } 15421 if (used) { 15422 continue; 15423 } 15424 } 15425 15426 PermissionsState permissionsState = ps.getPermissionsState(); 15427 15428 final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId); 15429 15430 // Always clear the user settable flags. 15431 final boolean hasInstallState = permissionsState.getInstallPermissionState( 15432 bp.name) != null; 15433 // If permission review is enabled and this is a legacy app, mark the 15434 // permission as requiring a review as this is the initial state. 15435 int flags = 0; 15436 if (Build.PERMISSIONS_REVIEW_REQUIRED 15437 && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 15438 flags |= FLAG_PERMISSION_REVIEW_REQUIRED; 15439 } 15440 if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) { 15441 if (hasInstallState) { 15442 writeInstallPermissions = true; 15443 } else { 15444 writeRuntimePermissions = true; 15445 } 15446 } 15447 15448 // Below is only runtime permission handling. 15449 if (!bp.isRuntime()) { 15450 continue; 15451 } 15452 15453 // Never clobber system or policy. 15454 if ((oldFlags & policyOrSystemFlags) != 0) { 15455 continue; 15456 } 15457 15458 // If this permission was granted by default, make sure it is. 15459 if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) { 15460 if (permissionsState.grantRuntimePermission(bp, userId) 15461 != PERMISSION_OPERATION_FAILURE) { 15462 writeRuntimePermissions = true; 15463 } 15464 // If permission review is enabled the permissions for a legacy apps 15465 // are represented as constantly granted runtime ones, so don't revoke. 15466 } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) { 15467 // Otherwise, reset the permission. 15468 final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId); 15469 switch (revokeResult) { 15470 case PERMISSION_OPERATION_SUCCESS: { 15471 writeRuntimePermissions = true; 15472 } break; 15473 15474 case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 15475 writeRuntimePermissions = true; 15476 final int appId = ps.appId; 15477 mHandler.post(new Runnable() { 15478 @Override 15479 public void run() { 15480 killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED); 15481 } 15482 }); 15483 } break; 15484 } 15485 } 15486 } 15487 15488 // Synchronously write as we are taking permissions away. 15489 if (writeRuntimePermissions) { 15490 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 15491 } 15492 15493 // Synchronously write as we are taking permissions away. 15494 if (writeInstallPermissions) { 15495 mSettings.writeLPr(); 15496 } 15497 } 15498 15499 /** 15500 * Remove entries from the keystore daemon. Will only remove it if the 15501 * {@code appId} is valid. 15502 */ 15503 private static void removeKeystoreDataIfNeeded(int userId, int appId) { 15504 if (appId < 0) { 15505 return; 15506 } 15507 15508 final KeyStore keyStore = KeyStore.getInstance(); 15509 if (keyStore != null) { 15510 if (userId == UserHandle.USER_ALL) { 15511 for (final int individual : sUserManager.getUserIds()) { 15512 keyStore.clearUid(UserHandle.getUid(individual, appId)); 15513 } 15514 } else { 15515 keyStore.clearUid(UserHandle.getUid(userId, appId)); 15516 } 15517 } else { 15518 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId); 15519 } 15520 } 15521 15522 @Override 15523 public void deleteApplicationCacheFiles(final String packageName, 15524 final IPackageDataObserver observer) { 15525 mContext.enforceCallingOrSelfPermission( 15526 android.Manifest.permission.DELETE_CACHE_FILES, null); 15527 // Queue up an async operation since the package deletion may take a little while. 15528 final int userId = UserHandle.getCallingUserId(); 15529 mHandler.post(new Runnable() { 15530 public void run() { 15531 mHandler.removeCallbacks(this); 15532 final boolean succeded; 15533 synchronized (mInstallLock) { 15534 succeded = deleteApplicationCacheFilesLI(packageName, userId); 15535 } 15536 clearExternalStorageDataSync(packageName, userId, false); 15537 if (observer != null) { 15538 try { 15539 observer.onRemoveCompleted(packageName, succeded); 15540 } catch (RemoteException e) { 15541 Log.i(TAG, "Observer no longer exists."); 15542 } 15543 } //end if observer 15544 } //end run 15545 }); 15546 } 15547 15548 private boolean deleteApplicationCacheFilesLI(String packageName, int userId) { 15549 if (packageName == null) { 15550 Slog.w(TAG, "Attempt to delete null packageName."); 15551 return false; 15552 } 15553 PackageParser.Package p; 15554 synchronized (mPackages) { 15555 p = mPackages.get(packageName); 15556 } 15557 if (p == null) { 15558 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 15559 return false; 15560 } 15561 final ApplicationInfo applicationInfo = p.applicationInfo; 15562 if (applicationInfo == null) { 15563 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 15564 return false; 15565 } 15566 // TODO: triage flags as part of 26466827 15567 final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE; 15568 try { 15569 mInstaller.clearAppData(p.volumeUuid, packageName, userId, 15570 flags | Installer.FLAG_CLEAR_CACHE_ONLY); 15571 } catch (InstallerException e) { 15572 Slog.w(TAG, "Couldn't remove cache files for package " 15573 + packageName + " u" + userId, e); 15574 return false; 15575 } 15576 return true; 15577 } 15578 15579 @Override 15580 public void getPackageSizeInfo(final String packageName, int userHandle, 15581 final IPackageStatsObserver observer) { 15582 mContext.enforceCallingOrSelfPermission( 15583 android.Manifest.permission.GET_PACKAGE_SIZE, null); 15584 if (packageName == null) { 15585 throw new IllegalArgumentException("Attempt to get size of null packageName"); 15586 } 15587 15588 PackageStats stats = new PackageStats(packageName, userHandle); 15589 15590 /* 15591 * Queue up an async operation since the package measurement may take a 15592 * little while. 15593 */ 15594 Message msg = mHandler.obtainMessage(INIT_COPY); 15595 msg.obj = new MeasureParams(stats, observer); 15596 mHandler.sendMessage(msg); 15597 } 15598 15599 private boolean getPackageSizeInfoLI(String packageName, int userHandle, 15600 PackageStats pStats) { 15601 if (packageName == null) { 15602 Slog.w(TAG, "Attempt to get size of null packageName."); 15603 return false; 15604 } 15605 PackageParser.Package p; 15606 boolean dataOnly = false; 15607 String libDirRoot = null; 15608 String asecPath = null; 15609 PackageSetting ps = null; 15610 synchronized (mPackages) { 15611 p = mPackages.get(packageName); 15612 ps = mSettings.mPackages.get(packageName); 15613 if(p == null) { 15614 dataOnly = true; 15615 if((ps == null) || (ps.pkg == null)) { 15616 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 15617 return false; 15618 } 15619 p = ps.pkg; 15620 } 15621 if (ps != null) { 15622 libDirRoot = ps.legacyNativeLibraryPathString; 15623 } 15624 if (p != null && (p.isForwardLocked() || p.applicationInfo.isExternalAsec())) { 15625 final long token = Binder.clearCallingIdentity(); 15626 try { 15627 String secureContainerId = cidFromCodePath(p.applicationInfo.getBaseCodePath()); 15628 if (secureContainerId != null) { 15629 asecPath = PackageHelper.getSdFilesystem(secureContainerId); 15630 } 15631 } finally { 15632 Binder.restoreCallingIdentity(token); 15633 } 15634 } 15635 } 15636 String publicSrcDir = null; 15637 if(!dataOnly) { 15638 final ApplicationInfo applicationInfo = p.applicationInfo; 15639 if (applicationInfo == null) { 15640 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 15641 return false; 15642 } 15643 if (p.isForwardLocked()) { 15644 publicSrcDir = applicationInfo.getBaseResourcePath(); 15645 } 15646 } 15647 // TODO: extend to measure size of split APKs 15648 // TODO(multiArch): Extend getSizeInfo to look at the full subdirectory tree, 15649 // not just the first level. 15650 // TODO(multiArch): Extend getSizeInfo to look at *all* instruction sets, not 15651 // just the primary. 15652 String[] dexCodeInstructionSets = getDexCodeInstructionSets(getAppDexInstructionSets(ps)); 15653 15654 String apkPath; 15655 File packageDir = new File(p.codePath); 15656 15657 if (packageDir.isDirectory() && p.canHaveOatDir()) { 15658 apkPath = packageDir.getAbsolutePath(); 15659 // If libDirRoot is inside a package dir, set it to null to avoid it being counted twice 15660 if (libDirRoot != null && libDirRoot.startsWith(apkPath)) { 15661 libDirRoot = null; 15662 } 15663 } else { 15664 apkPath = p.baseCodePath; 15665 } 15666 15667 // TODO: triage flags as part of 26466827 15668 final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE; 15669 try { 15670 mInstaller.getAppSize(p.volumeUuid, packageName, userHandle, flags, apkPath, 15671 libDirRoot, publicSrcDir, asecPath, dexCodeInstructionSets, pStats); 15672 } catch (InstallerException e) { 15673 return false; 15674 } 15675 15676 // Fix-up for forward-locked applications in ASEC containers. 15677 if (!isExternal(p)) { 15678 pStats.codeSize += pStats.externalCodeSize; 15679 pStats.externalCodeSize = 0L; 15680 } 15681 15682 return true; 15683 } 15684 15685 private int getUidTargetSdkVersionLockedLPr(int uid) { 15686 Object obj = mSettings.getUserIdLPr(uid); 15687 if (obj instanceof SharedUserSetting) { 15688 final SharedUserSetting sus = (SharedUserSetting) obj; 15689 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT; 15690 final Iterator<PackageSetting> it = sus.packages.iterator(); 15691 while (it.hasNext()) { 15692 final PackageSetting ps = it.next(); 15693 if (ps.pkg != null) { 15694 int v = ps.pkg.applicationInfo.targetSdkVersion; 15695 if (v < vers) vers = v; 15696 } 15697 } 15698 return vers; 15699 } else if (obj instanceof PackageSetting) { 15700 final PackageSetting ps = (PackageSetting) obj; 15701 if (ps.pkg != null) { 15702 return ps.pkg.applicationInfo.targetSdkVersion; 15703 } 15704 } 15705 return Build.VERSION_CODES.CUR_DEVELOPMENT; 15706 } 15707 15708 @Override 15709 public void addPreferredActivity(IntentFilter filter, int match, 15710 ComponentName[] set, ComponentName activity, int userId) { 15711 addPreferredActivityInternal(filter, match, set, activity, true, userId, 15712 "Adding preferred"); 15713 } 15714 15715 private void addPreferredActivityInternal(IntentFilter filter, int match, 15716 ComponentName[] set, ComponentName activity, boolean always, int userId, 15717 String opname) { 15718 // writer 15719 int callingUid = Binder.getCallingUid(); 15720 enforceCrossUserPermission(callingUid, userId, 15721 true /* requireFullPermission */, false /* checkShell */, "add preferred activity"); 15722 if (filter.countActions() == 0) { 15723 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 15724 return; 15725 } 15726 synchronized (mPackages) { 15727 if (mContext.checkCallingOrSelfPermission( 15728 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 15729 != PackageManager.PERMISSION_GRANTED) { 15730 if (getUidTargetSdkVersionLockedLPr(callingUid) 15731 < Build.VERSION_CODES.FROYO) { 15732 Slog.w(TAG, "Ignoring addPreferredActivity() from uid " 15733 + callingUid); 15734 return; 15735 } 15736 mContext.enforceCallingOrSelfPermission( 15737 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 15738 } 15739 15740 PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId); 15741 Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user " 15742 + userId + ":"); 15743 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 15744 pir.addFilter(new PreferredActivity(filter, match, set, activity, always)); 15745 scheduleWritePackageRestrictionsLocked(userId); 15746 } 15747 } 15748 15749 @Override 15750 public void replacePreferredActivity(IntentFilter filter, int match, 15751 ComponentName[] set, ComponentName activity, int userId) { 15752 if (filter.countActions() != 1) { 15753 throw new IllegalArgumentException( 15754 "replacePreferredActivity expects filter to have only 1 action."); 15755 } 15756 if (filter.countDataAuthorities() != 0 15757 || filter.countDataPaths() != 0 15758 || filter.countDataSchemes() > 1 15759 || filter.countDataTypes() != 0) { 15760 throw new IllegalArgumentException( 15761 "replacePreferredActivity expects filter to have no data authorities, " + 15762 "paths, or types; and at most one scheme."); 15763 } 15764 15765 final int callingUid = Binder.getCallingUid(); 15766 enforceCrossUserPermission(callingUid, userId, 15767 true /* requireFullPermission */, false /* checkShell */, 15768 "replace preferred activity"); 15769 synchronized (mPackages) { 15770 if (mContext.checkCallingOrSelfPermission( 15771 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 15772 != PackageManager.PERMISSION_GRANTED) { 15773 if (getUidTargetSdkVersionLockedLPr(callingUid) 15774 < Build.VERSION_CODES.FROYO) { 15775 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid " 15776 + Binder.getCallingUid()); 15777 return; 15778 } 15779 mContext.enforceCallingOrSelfPermission( 15780 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 15781 } 15782 15783 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 15784 if (pir != null) { 15785 // Get all of the existing entries that exactly match this filter. 15786 ArrayList<PreferredActivity> existing = pir.findFilters(filter); 15787 if (existing != null && existing.size() == 1) { 15788 PreferredActivity cur = existing.get(0); 15789 if (DEBUG_PREFERRED) { 15790 Slog.i(TAG, "Checking replace of preferred:"); 15791 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 15792 if (!cur.mPref.mAlways) { 15793 Slog.i(TAG, " -- CUR; not mAlways!"); 15794 } else { 15795 Slog.i(TAG, " -- CUR: mMatch=" + cur.mPref.mMatch); 15796 Slog.i(TAG, " -- CUR: mSet=" 15797 + Arrays.toString(cur.mPref.mSetComponents)); 15798 Slog.i(TAG, " -- CUR: mComponent=" + cur.mPref.mShortComponent); 15799 Slog.i(TAG, " -- NEW: mMatch=" 15800 + (match&IntentFilter.MATCH_CATEGORY_MASK)); 15801 Slog.i(TAG, " -- CUR: mSet=" + Arrays.toString(set)); 15802 Slog.i(TAG, " -- CUR: mComponent=" + activity.flattenToShortString()); 15803 } 15804 } 15805 if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity) 15806 && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK) 15807 && cur.mPref.sameSet(set)) { 15808 // Setting the preferred activity to what it happens to be already 15809 if (DEBUG_PREFERRED) { 15810 Slog.i(TAG, "Replacing with same preferred activity " 15811 + cur.mPref.mShortComponent + " for user " 15812 + userId + ":"); 15813 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 15814 } 15815 return; 15816 } 15817 } 15818 15819 if (existing != null) { 15820 if (DEBUG_PREFERRED) { 15821 Slog.i(TAG, existing.size() + " existing preferred matches for:"); 15822 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 15823 } 15824 for (int i = 0; i < existing.size(); i++) { 15825 PreferredActivity pa = existing.get(i); 15826 if (DEBUG_PREFERRED) { 15827 Slog.i(TAG, "Removing existing preferred activity " 15828 + pa.mPref.mComponent + ":"); 15829 pa.dump(new LogPrinter(Log.INFO, TAG), " "); 15830 } 15831 pir.removeFilter(pa); 15832 } 15833 } 15834 } 15835 addPreferredActivityInternal(filter, match, set, activity, true, userId, 15836 "Replacing preferred"); 15837 } 15838 } 15839 15840 @Override 15841 public void clearPackagePreferredActivities(String packageName) { 15842 final int uid = Binder.getCallingUid(); 15843 // writer 15844 synchronized (mPackages) { 15845 PackageParser.Package pkg = mPackages.get(packageName); 15846 if (pkg == null || pkg.applicationInfo.uid != uid) { 15847 if (mContext.checkCallingOrSelfPermission( 15848 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 15849 != PackageManager.PERMISSION_GRANTED) { 15850 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid()) 15851 < Build.VERSION_CODES.FROYO) { 15852 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid " 15853 + Binder.getCallingUid()); 15854 return; 15855 } 15856 mContext.enforceCallingOrSelfPermission( 15857 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 15858 } 15859 } 15860 15861 int user = UserHandle.getCallingUserId(); 15862 if (clearPackagePreferredActivitiesLPw(packageName, user)) { 15863 scheduleWritePackageRestrictionsLocked(user); 15864 } 15865 } 15866 } 15867 15868 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 15869 boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) { 15870 ArrayList<PreferredActivity> removed = null; 15871 boolean changed = false; 15872 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 15873 final int thisUserId = mSettings.mPreferredActivities.keyAt(i); 15874 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 15875 if (userId != UserHandle.USER_ALL && userId != thisUserId) { 15876 continue; 15877 } 15878 Iterator<PreferredActivity> it = pir.filterIterator(); 15879 while (it.hasNext()) { 15880 PreferredActivity pa = it.next(); 15881 // Mark entry for removal only if it matches the package name 15882 // and the entry is of type "always". 15883 if (packageName == null || 15884 (pa.mPref.mComponent.getPackageName().equals(packageName) 15885 && pa.mPref.mAlways)) { 15886 if (removed == null) { 15887 removed = new ArrayList<PreferredActivity>(); 15888 } 15889 removed.add(pa); 15890 } 15891 } 15892 if (removed != null) { 15893 for (int j=0; j<removed.size(); j++) { 15894 PreferredActivity pa = removed.get(j); 15895 pir.removeFilter(pa); 15896 } 15897 changed = true; 15898 } 15899 } 15900 return changed; 15901 } 15902 15903 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 15904 private void clearIntentFilterVerificationsLPw(int userId) { 15905 final int packageCount = mPackages.size(); 15906 for (int i = 0; i < packageCount; i++) { 15907 PackageParser.Package pkg = mPackages.valueAt(i); 15908 clearIntentFilterVerificationsLPw(pkg.packageName, userId); 15909 } 15910 } 15911 15912 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 15913 void clearIntentFilterVerificationsLPw(String packageName, int userId) { 15914 if (userId == UserHandle.USER_ALL) { 15915 if (mSettings.removeIntentFilterVerificationLPw(packageName, 15916 sUserManager.getUserIds())) { 15917 for (int oneUserId : sUserManager.getUserIds()) { 15918 scheduleWritePackageRestrictionsLocked(oneUserId); 15919 } 15920 } 15921 } else { 15922 if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) { 15923 scheduleWritePackageRestrictionsLocked(userId); 15924 } 15925 } 15926 } 15927 15928 void clearDefaultBrowserIfNeeded(String packageName) { 15929 for (int oneUserId : sUserManager.getUserIds()) { 15930 String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId); 15931 if (TextUtils.isEmpty(defaultBrowserPackageName)) continue; 15932 if (packageName.equals(defaultBrowserPackageName)) { 15933 setDefaultBrowserPackageName(null, oneUserId); 15934 } 15935 } 15936 } 15937 15938 @Override 15939 public void resetApplicationPreferences(int userId) { 15940 mContext.enforceCallingOrSelfPermission( 15941 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 15942 // writer 15943 synchronized (mPackages) { 15944 final long identity = Binder.clearCallingIdentity(); 15945 try { 15946 clearPackagePreferredActivitiesLPw(null, userId); 15947 mSettings.applyDefaultPreferredAppsLPw(this, userId); 15948 // TODO: We have to reset the default SMS and Phone. This requires 15949 // significant refactoring to keep all default apps in the package 15950 // manager (cleaner but more work) or have the services provide 15951 // callbacks to the package manager to request a default app reset. 15952 applyFactoryDefaultBrowserLPw(userId); 15953 clearIntentFilterVerificationsLPw(userId); 15954 primeDomainVerificationsLPw(userId); 15955 resetUserChangesToRuntimePermissionsAndFlagsLPw(userId); 15956 scheduleWritePackageRestrictionsLocked(userId); 15957 } finally { 15958 Binder.restoreCallingIdentity(identity); 15959 } 15960 } 15961 } 15962 15963 @Override 15964 public int getPreferredActivities(List<IntentFilter> outFilters, 15965 List<ComponentName> outActivities, String packageName) { 15966 15967 int num = 0; 15968 final int userId = UserHandle.getCallingUserId(); 15969 // reader 15970 synchronized (mPackages) { 15971 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 15972 if (pir != null) { 15973 final Iterator<PreferredActivity> it = pir.filterIterator(); 15974 while (it.hasNext()) { 15975 final PreferredActivity pa = it.next(); 15976 if (packageName == null 15977 || (pa.mPref.mComponent.getPackageName().equals(packageName) 15978 && pa.mPref.mAlways)) { 15979 if (outFilters != null) { 15980 outFilters.add(new IntentFilter(pa)); 15981 } 15982 if (outActivities != null) { 15983 outActivities.add(pa.mPref.mComponent); 15984 } 15985 } 15986 } 15987 } 15988 } 15989 15990 return num; 15991 } 15992 15993 @Override 15994 public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity, 15995 int userId) { 15996 int callingUid = Binder.getCallingUid(); 15997 if (callingUid != Process.SYSTEM_UID) { 15998 throw new SecurityException( 15999 "addPersistentPreferredActivity can only be run by the system"); 16000 } 16001 if (filter.countActions() == 0) { 16002 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 16003 return; 16004 } 16005 synchronized (mPackages) { 16006 Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId + 16007 ":"); 16008 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 16009 mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter( 16010 new PersistentPreferredActivity(filter, activity)); 16011 scheduleWritePackageRestrictionsLocked(userId); 16012 } 16013 } 16014 16015 @Override 16016 public void clearPackagePersistentPreferredActivities(String packageName, int userId) { 16017 int callingUid = Binder.getCallingUid(); 16018 if (callingUid != Process.SYSTEM_UID) { 16019 throw new SecurityException( 16020 "clearPackagePersistentPreferredActivities can only be run by the system"); 16021 } 16022 ArrayList<PersistentPreferredActivity> removed = null; 16023 boolean changed = false; 16024 synchronized (mPackages) { 16025 for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) { 16026 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i); 16027 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 16028 .valueAt(i); 16029 if (userId != thisUserId) { 16030 continue; 16031 } 16032 Iterator<PersistentPreferredActivity> it = ppir.filterIterator(); 16033 while (it.hasNext()) { 16034 PersistentPreferredActivity ppa = it.next(); 16035 // Mark entry for removal only if it matches the package name. 16036 if (ppa.mComponent.getPackageName().equals(packageName)) { 16037 if (removed == null) { 16038 removed = new ArrayList<PersistentPreferredActivity>(); 16039 } 16040 removed.add(ppa); 16041 } 16042 } 16043 if (removed != null) { 16044 for (int j=0; j<removed.size(); j++) { 16045 PersistentPreferredActivity ppa = removed.get(j); 16046 ppir.removeFilter(ppa); 16047 } 16048 changed = true; 16049 } 16050 } 16051 16052 if (changed) { 16053 scheduleWritePackageRestrictionsLocked(userId); 16054 } 16055 } 16056 } 16057 16058 /** 16059 * Common machinery for picking apart a restored XML blob and passing 16060 * it to a caller-supplied functor to be applied to the running system. 16061 */ 16062 private void restoreFromXml(XmlPullParser parser, int userId, 16063 String expectedStartTag, BlobXmlRestorer functor) 16064 throws IOException, XmlPullParserException { 16065 int type; 16066 while ((type = parser.next()) != XmlPullParser.START_TAG 16067 && type != XmlPullParser.END_DOCUMENT) { 16068 } 16069 if (type != XmlPullParser.START_TAG) { 16070 // oops didn't find a start tag?! 16071 if (DEBUG_BACKUP) { 16072 Slog.e(TAG, "Didn't find start tag during restore"); 16073 } 16074 return; 16075 } 16076Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName()); 16077 // this is supposed to be TAG_PREFERRED_BACKUP 16078 if (!expectedStartTag.equals(parser.getName())) { 16079 if (DEBUG_BACKUP) { 16080 Slog.e(TAG, "Found unexpected tag " + parser.getName()); 16081 } 16082 return; 16083 } 16084 16085 // skip interfering stuff, then we're aligned with the backing implementation 16086 while ((type = parser.next()) == XmlPullParser.TEXT) { } 16087Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); 16088 functor.apply(parser, userId); 16089 } 16090 16091 private interface BlobXmlRestorer { 16092 public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException; 16093 } 16094 16095 /** 16096 * Non-Binder method, support for the backup/restore mechanism: write the 16097 * full set of preferred activities in its canonical XML format. Returns the 16098 * XML output as a byte array, or null if there is none. 16099 */ 16100 @Override 16101 public byte[] getPreferredActivityBackup(int userId) { 16102 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16103 throw new SecurityException("Only the system may call getPreferredActivityBackup()"); 16104 } 16105 16106 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 16107 try { 16108 final XmlSerializer serializer = new FastXmlSerializer(); 16109 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 16110 serializer.startDocument(null, true); 16111 serializer.startTag(null, TAG_PREFERRED_BACKUP); 16112 16113 synchronized (mPackages) { 16114 mSettings.writePreferredActivitiesLPr(serializer, userId, true); 16115 } 16116 16117 serializer.endTag(null, TAG_PREFERRED_BACKUP); 16118 serializer.endDocument(); 16119 serializer.flush(); 16120 } catch (Exception e) { 16121 if (DEBUG_BACKUP) { 16122 Slog.e(TAG, "Unable to write preferred activities for backup", e); 16123 } 16124 return null; 16125 } 16126 16127 return dataStream.toByteArray(); 16128 } 16129 16130 @Override 16131 public void restorePreferredActivities(byte[] backup, int userId) { 16132 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16133 throw new SecurityException("Only the system may call restorePreferredActivities()"); 16134 } 16135 16136 try { 16137 final XmlPullParser parser = Xml.newPullParser(); 16138 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 16139 restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP, 16140 new BlobXmlRestorer() { 16141 @Override 16142 public void apply(XmlPullParser parser, int userId) 16143 throws XmlPullParserException, IOException { 16144 synchronized (mPackages) { 16145 mSettings.readPreferredActivitiesLPw(parser, userId); 16146 } 16147 } 16148 } ); 16149 } catch (Exception e) { 16150 if (DEBUG_BACKUP) { 16151 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 16152 } 16153 } 16154 } 16155 16156 /** 16157 * Non-Binder method, support for the backup/restore mechanism: write the 16158 * default browser (etc) settings in its canonical XML format. Returns the default 16159 * browser XML representation as a byte array, or null if there is none. 16160 */ 16161 @Override 16162 public byte[] getDefaultAppsBackup(int userId) { 16163 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16164 throw new SecurityException("Only the system may call getDefaultAppsBackup()"); 16165 } 16166 16167 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 16168 try { 16169 final XmlSerializer serializer = new FastXmlSerializer(); 16170 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 16171 serializer.startDocument(null, true); 16172 serializer.startTag(null, TAG_DEFAULT_APPS); 16173 16174 synchronized (mPackages) { 16175 mSettings.writeDefaultAppsLPr(serializer, userId); 16176 } 16177 16178 serializer.endTag(null, TAG_DEFAULT_APPS); 16179 serializer.endDocument(); 16180 serializer.flush(); 16181 } catch (Exception e) { 16182 if (DEBUG_BACKUP) { 16183 Slog.e(TAG, "Unable to write default apps for backup", e); 16184 } 16185 return null; 16186 } 16187 16188 return dataStream.toByteArray(); 16189 } 16190 16191 @Override 16192 public void restoreDefaultApps(byte[] backup, int userId) { 16193 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16194 throw new SecurityException("Only the system may call restoreDefaultApps()"); 16195 } 16196 16197 try { 16198 final XmlPullParser parser = Xml.newPullParser(); 16199 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 16200 restoreFromXml(parser, userId, TAG_DEFAULT_APPS, 16201 new BlobXmlRestorer() { 16202 @Override 16203 public void apply(XmlPullParser parser, int userId) 16204 throws XmlPullParserException, IOException { 16205 synchronized (mPackages) { 16206 mSettings.readDefaultAppsLPw(parser, userId); 16207 } 16208 } 16209 } ); 16210 } catch (Exception e) { 16211 if (DEBUG_BACKUP) { 16212 Slog.e(TAG, "Exception restoring default apps: " + e.getMessage()); 16213 } 16214 } 16215 } 16216 16217 @Override 16218 public byte[] getIntentFilterVerificationBackup(int userId) { 16219 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16220 throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()"); 16221 } 16222 16223 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 16224 try { 16225 final XmlSerializer serializer = new FastXmlSerializer(); 16226 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 16227 serializer.startDocument(null, true); 16228 serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION); 16229 16230 synchronized (mPackages) { 16231 mSettings.writeAllDomainVerificationsLPr(serializer, userId); 16232 } 16233 16234 serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION); 16235 serializer.endDocument(); 16236 serializer.flush(); 16237 } catch (Exception e) { 16238 if (DEBUG_BACKUP) { 16239 Slog.e(TAG, "Unable to write default apps for backup", e); 16240 } 16241 return null; 16242 } 16243 16244 return dataStream.toByteArray(); 16245 } 16246 16247 @Override 16248 public void restoreIntentFilterVerification(byte[] backup, int userId) { 16249 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16250 throw new SecurityException("Only the system may call restorePreferredActivities()"); 16251 } 16252 16253 try { 16254 final XmlPullParser parser = Xml.newPullParser(); 16255 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 16256 restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION, 16257 new BlobXmlRestorer() { 16258 @Override 16259 public void apply(XmlPullParser parser, int userId) 16260 throws XmlPullParserException, IOException { 16261 synchronized (mPackages) { 16262 mSettings.readAllDomainVerificationsLPr(parser, userId); 16263 mSettings.writeLPr(); 16264 } 16265 } 16266 } ); 16267 } catch (Exception e) { 16268 if (DEBUG_BACKUP) { 16269 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 16270 } 16271 } 16272 } 16273 16274 @Override 16275 public byte[] getPermissionGrantBackup(int userId) { 16276 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16277 throw new SecurityException("Only the system may call getPermissionGrantBackup()"); 16278 } 16279 16280 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 16281 try { 16282 final XmlSerializer serializer = new FastXmlSerializer(); 16283 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 16284 serializer.startDocument(null, true); 16285 serializer.startTag(null, TAG_PERMISSION_BACKUP); 16286 16287 synchronized (mPackages) { 16288 serializeRuntimePermissionGrantsLPr(serializer, userId); 16289 } 16290 16291 serializer.endTag(null, TAG_PERMISSION_BACKUP); 16292 serializer.endDocument(); 16293 serializer.flush(); 16294 } catch (Exception e) { 16295 if (DEBUG_BACKUP) { 16296 Slog.e(TAG, "Unable to write default apps for backup", e); 16297 } 16298 return null; 16299 } 16300 16301 return dataStream.toByteArray(); 16302 } 16303 16304 @Override 16305 public void restorePermissionGrants(byte[] backup, int userId) { 16306 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16307 throw new SecurityException("Only the system may call restorePermissionGrants()"); 16308 } 16309 16310 try { 16311 final XmlPullParser parser = Xml.newPullParser(); 16312 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 16313 restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP, 16314 new BlobXmlRestorer() { 16315 @Override 16316 public void apply(XmlPullParser parser, int userId) 16317 throws XmlPullParserException, IOException { 16318 synchronized (mPackages) { 16319 processRestoredPermissionGrantsLPr(parser, userId); 16320 } 16321 } 16322 } ); 16323 } catch (Exception e) { 16324 if (DEBUG_BACKUP) { 16325 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 16326 } 16327 } 16328 } 16329 16330 private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId) 16331 throws IOException { 16332 serializer.startTag(null, TAG_ALL_GRANTS); 16333 16334 final int N = mSettings.mPackages.size(); 16335 for (int i = 0; i < N; i++) { 16336 final PackageSetting ps = mSettings.mPackages.valueAt(i); 16337 boolean pkgGrantsKnown = false; 16338 16339 PermissionsState packagePerms = ps.getPermissionsState(); 16340 16341 for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) { 16342 final int grantFlags = state.getFlags(); 16343 // only look at grants that are not system/policy fixed 16344 if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) { 16345 final boolean isGranted = state.isGranted(); 16346 // And only back up the user-twiddled state bits 16347 if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) { 16348 final String packageName = mSettings.mPackages.keyAt(i); 16349 if (!pkgGrantsKnown) { 16350 serializer.startTag(null, TAG_GRANT); 16351 serializer.attribute(null, ATTR_PACKAGE_NAME, packageName); 16352 pkgGrantsKnown = true; 16353 } 16354 16355 final boolean userSet = 16356 (grantFlags & FLAG_PERMISSION_USER_SET) != 0; 16357 final boolean userFixed = 16358 (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0; 16359 final boolean revoke = 16360 (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0; 16361 16362 serializer.startTag(null, TAG_PERMISSION); 16363 serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName()); 16364 if (isGranted) { 16365 serializer.attribute(null, ATTR_IS_GRANTED, "true"); 16366 } 16367 if (userSet) { 16368 serializer.attribute(null, ATTR_USER_SET, "true"); 16369 } 16370 if (userFixed) { 16371 serializer.attribute(null, ATTR_USER_FIXED, "true"); 16372 } 16373 if (revoke) { 16374 serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true"); 16375 } 16376 serializer.endTag(null, TAG_PERMISSION); 16377 } 16378 } 16379 } 16380 16381 if (pkgGrantsKnown) { 16382 serializer.endTag(null, TAG_GRANT); 16383 } 16384 } 16385 16386 serializer.endTag(null, TAG_ALL_GRANTS); 16387 } 16388 16389 private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId) 16390 throws XmlPullParserException, IOException { 16391 String pkgName = null; 16392 int outerDepth = parser.getDepth(); 16393 int type; 16394 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 16395 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 16396 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 16397 continue; 16398 } 16399 16400 final String tagName = parser.getName(); 16401 if (tagName.equals(TAG_GRANT)) { 16402 pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME); 16403 if (DEBUG_BACKUP) { 16404 Slog.v(TAG, "+++ Restoring grants for package " + pkgName); 16405 } 16406 } else if (tagName.equals(TAG_PERMISSION)) { 16407 16408 final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED)); 16409 final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME); 16410 16411 int newFlagSet = 0; 16412 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) { 16413 newFlagSet |= FLAG_PERMISSION_USER_SET; 16414 } 16415 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) { 16416 newFlagSet |= FLAG_PERMISSION_USER_FIXED; 16417 } 16418 if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) { 16419 newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE; 16420 } 16421 if (DEBUG_BACKUP) { 16422 Slog.v(TAG, " + Restoring grant: pkg=" + pkgName + " perm=" + permName 16423 + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet)); 16424 } 16425 final PackageSetting ps = mSettings.mPackages.get(pkgName); 16426 if (ps != null) { 16427 // Already installed so we apply the grant immediately 16428 if (DEBUG_BACKUP) { 16429 Slog.v(TAG, " + already installed; applying"); 16430 } 16431 PermissionsState perms = ps.getPermissionsState(); 16432 BasePermission bp = mSettings.mPermissions.get(permName); 16433 if (bp != null) { 16434 if (isGranted) { 16435 perms.grantRuntimePermission(bp, userId); 16436 } 16437 if (newFlagSet != 0) { 16438 perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet); 16439 } 16440 } 16441 } else { 16442 // Need to wait for post-restore install to apply the grant 16443 if (DEBUG_BACKUP) { 16444 Slog.v(TAG, " - not yet installed; saving for later"); 16445 } 16446 mSettings.processRestoredPermissionGrantLPr(pkgName, permName, 16447 isGranted, newFlagSet, userId); 16448 } 16449 } else { 16450 PackageManagerService.reportSettingsProblem(Log.WARN, 16451 "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName); 16452 XmlUtils.skipCurrentTag(parser); 16453 } 16454 } 16455 16456 scheduleWriteSettingsLocked(); 16457 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 16458 } 16459 16460 @Override 16461 public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage, 16462 int sourceUserId, int targetUserId, int flags) { 16463 mContext.enforceCallingOrSelfPermission( 16464 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 16465 int callingUid = Binder.getCallingUid(); 16466 enforceOwnerRights(ownerPackage, callingUid); 16467 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 16468 if (intentFilter.countActions() == 0) { 16469 Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions"); 16470 return; 16471 } 16472 synchronized (mPackages) { 16473 CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter, 16474 ownerPackage, targetUserId, flags); 16475 CrossProfileIntentResolver resolver = 16476 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 16477 ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter); 16478 // We have all those whose filter is equal. Now checking if the rest is equal as well. 16479 if (existing != null) { 16480 int size = existing.size(); 16481 for (int i = 0; i < size; i++) { 16482 if (newFilter.equalsIgnoreFilter(existing.get(i))) { 16483 return; 16484 } 16485 } 16486 } 16487 resolver.addFilter(newFilter); 16488 scheduleWritePackageRestrictionsLocked(sourceUserId); 16489 } 16490 } 16491 16492 @Override 16493 public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) { 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 synchronized (mPackages) { 16500 CrossProfileIntentResolver resolver = 16501 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 16502 ArraySet<CrossProfileIntentFilter> set = 16503 new ArraySet<CrossProfileIntentFilter>(resolver.filterSet()); 16504 for (CrossProfileIntentFilter filter : set) { 16505 if (filter.getOwnerPackage().equals(ownerPackage)) { 16506 resolver.removeFilter(filter); 16507 } 16508 } 16509 scheduleWritePackageRestrictionsLocked(sourceUserId); 16510 } 16511 } 16512 16513 // Enforcing that callingUid is owning pkg on userId 16514 private void enforceOwnerRights(String pkg, int callingUid) { 16515 // The system owns everything. 16516 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) { 16517 return; 16518 } 16519 int callingUserId = UserHandle.getUserId(callingUid); 16520 PackageInfo pi = getPackageInfo(pkg, 0, callingUserId); 16521 if (pi == null) { 16522 throw new IllegalArgumentException("Unknown package " + pkg + " on user " 16523 + callingUserId); 16524 } 16525 if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) { 16526 throw new SecurityException("Calling uid " + callingUid 16527 + " does not own package " + pkg); 16528 } 16529 } 16530 16531 @Override 16532 public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) { 16533 return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId()); 16534 } 16535 16536 private Intent getHomeIntent() { 16537 Intent intent = new Intent(Intent.ACTION_MAIN); 16538 intent.addCategory(Intent.CATEGORY_HOME); 16539 return intent; 16540 } 16541 16542 private IntentFilter getHomeFilter() { 16543 IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN); 16544 filter.addCategory(Intent.CATEGORY_HOME); 16545 filter.addCategory(Intent.CATEGORY_DEFAULT); 16546 return filter; 16547 } 16548 16549 ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, 16550 int userId) { 16551 Intent intent = getHomeIntent(); 16552 List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null, 16553 PackageManager.GET_META_DATA, userId); 16554 ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0, 16555 true, false, false, userId); 16556 16557 allHomeCandidates.clear(); 16558 if (list != null) { 16559 for (ResolveInfo ri : list) { 16560 allHomeCandidates.add(ri); 16561 } 16562 } 16563 return (preferred == null || preferred.activityInfo == null) 16564 ? null 16565 : new ComponentName(preferred.activityInfo.packageName, 16566 preferred.activityInfo.name); 16567 } 16568 16569 @Override 16570 public void setHomeActivity(ComponentName comp, int userId) { 16571 ArrayList<ResolveInfo> homeActivities = new ArrayList<>(); 16572 getHomeActivitiesAsUser(homeActivities, userId); 16573 16574 boolean found = false; 16575 16576 final int size = homeActivities.size(); 16577 final ComponentName[] set = new ComponentName[size]; 16578 for (int i = 0; i < size; i++) { 16579 final ResolveInfo candidate = homeActivities.get(i); 16580 final ActivityInfo info = candidate.activityInfo; 16581 final ComponentName activityName = new ComponentName(info.packageName, info.name); 16582 set[i] = activityName; 16583 if (!found && activityName.equals(comp)) { 16584 found = true; 16585 } 16586 } 16587 if (!found) { 16588 throw new IllegalArgumentException("Component " + comp + " cannot be home on user " 16589 + userId); 16590 } 16591 replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY, 16592 set, comp, userId); 16593 } 16594 16595 @Override 16596 public void setApplicationEnabledSetting(String appPackageName, 16597 int newState, int flags, int userId, String callingPackage) { 16598 if (!sUserManager.exists(userId)) return; 16599 if (callingPackage == null) { 16600 callingPackage = Integer.toString(Binder.getCallingUid()); 16601 } 16602 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage); 16603 } 16604 16605 @Override 16606 public void setComponentEnabledSetting(ComponentName componentName, 16607 int newState, int flags, int userId) { 16608 if (!sUserManager.exists(userId)) return; 16609 setEnabledSetting(componentName.getPackageName(), 16610 componentName.getClassName(), newState, flags, userId, null); 16611 } 16612 16613 private void setEnabledSetting(final String packageName, String className, int newState, 16614 final int flags, int userId, String callingPackage) { 16615 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT 16616 || newState == COMPONENT_ENABLED_STATE_ENABLED 16617 || newState == COMPONENT_ENABLED_STATE_DISABLED 16618 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER 16619 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) { 16620 throw new IllegalArgumentException("Invalid new component state: " 16621 + newState); 16622 } 16623 PackageSetting pkgSetting; 16624 final int uid = Binder.getCallingUid(); 16625 final int permission = mContext.checkCallingOrSelfPermission( 16626 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 16627 enforceCrossUserPermission(uid, userId, 16628 false /* requireFullPermission */, true /* checkShell */, "set enabled"); 16629 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 16630 boolean sendNow = false; 16631 boolean isApp = (className == null); 16632 String componentName = isApp ? packageName : className; 16633 int packageUid = -1; 16634 ArrayList<String> components; 16635 16636 // writer 16637 synchronized (mPackages) { 16638 pkgSetting = mSettings.mPackages.get(packageName); 16639 if (pkgSetting == null) { 16640 if (className == null) { 16641 throw new IllegalArgumentException("Unknown package: " + packageName); 16642 } 16643 throw new IllegalArgumentException( 16644 "Unknown component: " + packageName + "/" + className); 16645 } 16646 // Allow root and verify that userId is not being specified by a different user 16647 if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) { 16648 throw new SecurityException( 16649 "Permission Denial: attempt to change component state from pid=" 16650 + Binder.getCallingPid() 16651 + ", uid=" + uid + ", package uid=" + pkgSetting.appId); 16652 } 16653 if (className == null) { 16654 // We're dealing with an application/package level state change 16655 if (pkgSetting.getEnabled(userId) == newState) { 16656 // Nothing to do 16657 return; 16658 } 16659 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT 16660 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { 16661 // Don't care about who enables an app. 16662 callingPackage = null; 16663 } 16664 pkgSetting.setEnabled(newState, userId, callingPackage); 16665 // pkgSetting.pkg.mSetEnabled = newState; 16666 } else { 16667 // We're dealing with a component level state change 16668 // First, verify that this is a valid class name. 16669 PackageParser.Package pkg = pkgSetting.pkg; 16670 if (pkg == null || !pkg.hasComponentClassName(className)) { 16671 if (pkg != null && 16672 pkg.applicationInfo.targetSdkVersion >= 16673 Build.VERSION_CODES.JELLY_BEAN) { 16674 throw new IllegalArgumentException("Component class " + className 16675 + " does not exist in " + packageName); 16676 } else { 16677 Slog.w(TAG, "Failed setComponentEnabledSetting: component class " 16678 + className + " does not exist in " + packageName); 16679 } 16680 } 16681 switch (newState) { 16682 case COMPONENT_ENABLED_STATE_ENABLED: 16683 if (!pkgSetting.enableComponentLPw(className, userId)) { 16684 return; 16685 } 16686 break; 16687 case COMPONENT_ENABLED_STATE_DISABLED: 16688 if (!pkgSetting.disableComponentLPw(className, userId)) { 16689 return; 16690 } 16691 break; 16692 case COMPONENT_ENABLED_STATE_DEFAULT: 16693 if (!pkgSetting.restoreComponentLPw(className, userId)) { 16694 return; 16695 } 16696 break; 16697 default: 16698 Slog.e(TAG, "Invalid new component state: " + newState); 16699 return; 16700 } 16701 } 16702 scheduleWritePackageRestrictionsLocked(userId); 16703 components = mPendingBroadcasts.get(userId, packageName); 16704 final boolean newPackage = components == null; 16705 if (newPackage) { 16706 components = new ArrayList<String>(); 16707 } 16708 if (!components.contains(componentName)) { 16709 components.add(componentName); 16710 } 16711 if ((flags&PackageManager.DONT_KILL_APP) == 0) { 16712 sendNow = true; 16713 // Purge entry from pending broadcast list if another one exists already 16714 // since we are sending one right away. 16715 mPendingBroadcasts.remove(userId, packageName); 16716 } else { 16717 if (newPackage) { 16718 mPendingBroadcasts.put(userId, packageName, components); 16719 } 16720 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) { 16721 // Schedule a message 16722 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY); 16723 } 16724 } 16725 } 16726 16727 long callingId = Binder.clearCallingIdentity(); 16728 try { 16729 if (sendNow) { 16730 packageUid = UserHandle.getUid(userId, pkgSetting.appId); 16731 sendPackageChangedBroadcast(packageName, 16732 (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid); 16733 } 16734 } finally { 16735 Binder.restoreCallingIdentity(callingId); 16736 } 16737 } 16738 16739 @Override 16740 public void flushPackageRestrictionsAsUser(int userId) { 16741 if (!sUserManager.exists(userId)) { 16742 return; 16743 } 16744 enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/, 16745 false /* checkShell */, "flushPackageRestrictions"); 16746 synchronized (mPackages) { 16747 mSettings.writePackageRestrictionsLPr(userId); 16748 mDirtyUsers.remove(userId); 16749 if (mDirtyUsers.isEmpty()) { 16750 mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS); 16751 } 16752 } 16753 } 16754 16755 private void sendPackageChangedBroadcast(String packageName, 16756 boolean killFlag, ArrayList<String> componentNames, int packageUid) { 16757 if (DEBUG_INSTALL) 16758 Log.v(TAG, "Sending package changed: package=" + packageName + " components=" 16759 + componentNames); 16760 Bundle extras = new Bundle(4); 16761 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0)); 16762 String nameList[] = new String[componentNames.size()]; 16763 componentNames.toArray(nameList); 16764 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList); 16765 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag); 16766 extras.putInt(Intent.EXTRA_UID, packageUid); 16767 // If this is not reporting a change of the overall package, then only send it 16768 // to registered receivers. We don't want to launch a swath of apps for every 16769 // little component state change. 16770 final int flags = !componentNames.contains(packageName) 16771 ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0; 16772 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, flags, null, null, 16773 new int[] {UserHandle.getUserId(packageUid)}); 16774 } 16775 16776 @Override 16777 public void setPackageStoppedState(String packageName, boolean stopped, int userId) { 16778 if (!sUserManager.exists(userId)) return; 16779 final int uid = Binder.getCallingUid(); 16780 final int permission = mContext.checkCallingOrSelfPermission( 16781 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 16782 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 16783 enforceCrossUserPermission(uid, userId, 16784 true /* requireFullPermission */, true /* checkShell */, "stop package"); 16785 // writer 16786 synchronized (mPackages) { 16787 if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped, 16788 allowedByPermission, uid, userId)) { 16789 scheduleWritePackageRestrictionsLocked(userId); 16790 } 16791 } 16792 } 16793 16794 @Override 16795 public String getInstallerPackageName(String packageName) { 16796 // reader 16797 synchronized (mPackages) { 16798 return mSettings.getInstallerPackageNameLPr(packageName); 16799 } 16800 } 16801 16802 @Override 16803 public int getApplicationEnabledSetting(String packageName, int userId) { 16804 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 16805 int uid = Binder.getCallingUid(); 16806 enforceCrossUserPermission(uid, userId, 16807 false /* requireFullPermission */, false /* checkShell */, "get enabled"); 16808 // reader 16809 synchronized (mPackages) { 16810 return mSettings.getApplicationEnabledSettingLPr(packageName, userId); 16811 } 16812 } 16813 16814 @Override 16815 public int getComponentEnabledSetting(ComponentName componentName, int userId) { 16816 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 16817 int uid = Binder.getCallingUid(); 16818 enforceCrossUserPermission(uid, userId, 16819 false /* requireFullPermission */, false /* checkShell */, "get component enabled"); 16820 // reader 16821 synchronized (mPackages) { 16822 return mSettings.getComponentEnabledSettingLPr(componentName, userId); 16823 } 16824 } 16825 16826 @Override 16827 public void enterSafeMode() { 16828 enforceSystemOrRoot("Only the system can request entering safe mode"); 16829 16830 if (!mSystemReady) { 16831 mSafeMode = true; 16832 } 16833 } 16834 16835 @Override 16836 public void systemReady() { 16837 mSystemReady = true; 16838 16839 // Read the compatibilty setting when the system is ready. 16840 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt( 16841 mContext.getContentResolver(), 16842 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1; 16843 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled); 16844 if (DEBUG_SETTINGS) { 16845 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled); 16846 } 16847 16848 int[] grantPermissionsUserIds = EMPTY_INT_ARRAY; 16849 16850 synchronized (mPackages) { 16851 // Verify that all of the preferred activity components actually 16852 // exist. It is possible for applications to be updated and at 16853 // that point remove a previously declared activity component that 16854 // had been set as a preferred activity. We try to clean this up 16855 // the next time we encounter that preferred activity, but it is 16856 // possible for the user flow to never be able to return to that 16857 // situation so here we do a sanity check to make sure we haven't 16858 // left any junk around. 16859 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>(); 16860 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 16861 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 16862 removed.clear(); 16863 for (PreferredActivity pa : pir.filterSet()) { 16864 if (mActivities.mActivities.get(pa.mPref.mComponent) == null) { 16865 removed.add(pa); 16866 } 16867 } 16868 if (removed.size() > 0) { 16869 for (int r=0; r<removed.size(); r++) { 16870 PreferredActivity pa = removed.get(r); 16871 Slog.w(TAG, "Removing dangling preferred activity: " 16872 + pa.mPref.mComponent); 16873 pir.removeFilter(pa); 16874 } 16875 mSettings.writePackageRestrictionsLPr( 16876 mSettings.mPreferredActivities.keyAt(i)); 16877 } 16878 } 16879 16880 for (int userId : UserManagerService.getInstance().getUserIds()) { 16881 if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) { 16882 grantPermissionsUserIds = ArrayUtils.appendInt( 16883 grantPermissionsUserIds, userId); 16884 } 16885 } 16886 } 16887 sUserManager.systemReady(); 16888 16889 // If we upgraded grant all default permissions before kicking off. 16890 for (int userId : grantPermissionsUserIds) { 16891 mDefaultPermissionPolicy.grantDefaultPermissions(userId); 16892 } 16893 16894 // Kick off any messages waiting for system ready 16895 if (mPostSystemReadyMessages != null) { 16896 for (Message msg : mPostSystemReadyMessages) { 16897 msg.sendToTarget(); 16898 } 16899 mPostSystemReadyMessages = null; 16900 } 16901 16902 // Watch for external volumes that come and go over time 16903 final StorageManager storage = mContext.getSystemService(StorageManager.class); 16904 storage.registerListener(mStorageListener); 16905 16906 mInstallerService.systemReady(); 16907 mPackageDexOptimizer.systemReady(); 16908 16909 MountServiceInternal mountServiceInternal = LocalServices.getService( 16910 MountServiceInternal.class); 16911 mountServiceInternal.addExternalStoragePolicy( 16912 new MountServiceInternal.ExternalStorageMountPolicy() { 16913 @Override 16914 public int getMountMode(int uid, String packageName) { 16915 if (Process.isIsolated(uid)) { 16916 return Zygote.MOUNT_EXTERNAL_NONE; 16917 } 16918 if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) { 16919 return Zygote.MOUNT_EXTERNAL_DEFAULT; 16920 } 16921 if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { 16922 return Zygote.MOUNT_EXTERNAL_DEFAULT; 16923 } 16924 if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { 16925 return Zygote.MOUNT_EXTERNAL_READ; 16926 } 16927 return Zygote.MOUNT_EXTERNAL_WRITE; 16928 } 16929 16930 @Override 16931 public boolean hasExternalStorage(int uid, String packageName) { 16932 return true; 16933 } 16934 }); 16935 } 16936 16937 @Override 16938 public boolean isSafeMode() { 16939 return mSafeMode; 16940 } 16941 16942 @Override 16943 public boolean hasSystemUidErrors() { 16944 return mHasSystemUidErrors; 16945 } 16946 16947 static String arrayToString(int[] array) { 16948 StringBuffer buf = new StringBuffer(128); 16949 buf.append('['); 16950 if (array != null) { 16951 for (int i=0; i<array.length; i++) { 16952 if (i > 0) buf.append(", "); 16953 buf.append(array[i]); 16954 } 16955 } 16956 buf.append(']'); 16957 return buf.toString(); 16958 } 16959 16960 static class DumpState { 16961 public static final int DUMP_LIBS = 1 << 0; 16962 public static final int DUMP_FEATURES = 1 << 1; 16963 public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2; 16964 public static final int DUMP_SERVICE_RESOLVERS = 1 << 3; 16965 public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4; 16966 public static final int DUMP_CONTENT_RESOLVERS = 1 << 5; 16967 public static final int DUMP_PERMISSIONS = 1 << 6; 16968 public static final int DUMP_PACKAGES = 1 << 7; 16969 public static final int DUMP_SHARED_USERS = 1 << 8; 16970 public static final int DUMP_MESSAGES = 1 << 9; 16971 public static final int DUMP_PROVIDERS = 1 << 10; 16972 public static final int DUMP_VERIFIERS = 1 << 11; 16973 public static final int DUMP_PREFERRED = 1 << 12; 16974 public static final int DUMP_PREFERRED_XML = 1 << 13; 16975 public static final int DUMP_KEYSETS = 1 << 14; 16976 public static final int DUMP_VERSION = 1 << 15; 16977 public static final int DUMP_INSTALLS = 1 << 16; 16978 public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17; 16979 public static final int DUMP_DOMAIN_PREFERRED = 1 << 18; 16980 16981 public static final int OPTION_SHOW_FILTERS = 1 << 0; 16982 16983 private int mTypes; 16984 16985 private int mOptions; 16986 16987 private boolean mTitlePrinted; 16988 16989 private SharedUserSetting mSharedUser; 16990 16991 public boolean isDumping(int type) { 16992 if (mTypes == 0 && type != DUMP_PREFERRED_XML) { 16993 return true; 16994 } 16995 16996 return (mTypes & type) != 0; 16997 } 16998 16999 public void setDump(int type) { 17000 mTypes |= type; 17001 } 17002 17003 public boolean isOptionEnabled(int option) { 17004 return (mOptions & option) != 0; 17005 } 17006 17007 public void setOptionEnabled(int option) { 17008 mOptions |= option; 17009 } 17010 17011 public boolean onTitlePrinted() { 17012 final boolean printed = mTitlePrinted; 17013 mTitlePrinted = true; 17014 return printed; 17015 } 17016 17017 public boolean getTitlePrinted() { 17018 return mTitlePrinted; 17019 } 17020 17021 public void setTitlePrinted(boolean enabled) { 17022 mTitlePrinted = enabled; 17023 } 17024 17025 public SharedUserSetting getSharedUser() { 17026 return mSharedUser; 17027 } 17028 17029 public void setSharedUser(SharedUserSetting user) { 17030 mSharedUser = user; 17031 } 17032 } 17033 17034 @Override 17035 public void onShellCommand(FileDescriptor in, FileDescriptor out, 17036 FileDescriptor err, String[] args, ResultReceiver resultReceiver) { 17037 (new PackageManagerShellCommand(this)).exec( 17038 this, in, out, err, args, resultReceiver); 17039 } 17040 17041 @Override 17042 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 17043 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 17044 != PackageManager.PERMISSION_GRANTED) { 17045 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 17046 + Binder.getCallingPid() 17047 + ", uid=" + Binder.getCallingUid() 17048 + " without permission " 17049 + android.Manifest.permission.DUMP); 17050 return; 17051 } 17052 17053 DumpState dumpState = new DumpState(); 17054 boolean fullPreferred = false; 17055 boolean checkin = false; 17056 17057 String packageName = null; 17058 ArraySet<String> permissionNames = null; 17059 17060 int opti = 0; 17061 while (opti < args.length) { 17062 String opt = args[opti]; 17063 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 17064 break; 17065 } 17066 opti++; 17067 17068 if ("-a".equals(opt)) { 17069 // Right now we only know how to print all. 17070 } else if ("-h".equals(opt)) { 17071 pw.println("Package manager dump options:"); 17072 pw.println(" [-h] [-f] [--checkin] [cmd] ..."); 17073 pw.println(" --checkin: dump for a checkin"); 17074 pw.println(" -f: print details of intent filters"); 17075 pw.println(" -h: print this help"); 17076 pw.println(" cmd may be one of:"); 17077 pw.println(" l[ibraries]: list known shared libraries"); 17078 pw.println(" f[eatures]: list device features"); 17079 pw.println(" k[eysets]: print known keysets"); 17080 pw.println(" r[esolvers] [activity|service|receiver|content]: dump intent resolvers"); 17081 pw.println(" perm[issions]: dump permissions"); 17082 pw.println(" permission [name ...]: dump declaration and use of given permission"); 17083 pw.println(" pref[erred]: print preferred package settings"); 17084 pw.println(" preferred-xml [--full]: print preferred package settings as xml"); 17085 pw.println(" prov[iders]: dump content providers"); 17086 pw.println(" p[ackages]: dump installed packages"); 17087 pw.println(" s[hared-users]: dump shared user IDs"); 17088 pw.println(" m[essages]: print collected runtime messages"); 17089 pw.println(" v[erifiers]: print package verifier info"); 17090 pw.println(" d[omain-preferred-apps]: print domains preferred apps"); 17091 pw.println(" i[ntent-filter-verifiers]|ifv: print intent filter verifier info"); 17092 pw.println(" version: print database version info"); 17093 pw.println(" write: write current settings now"); 17094 pw.println(" installs: details about install sessions"); 17095 pw.println(" check-permission <permission> <package> [<user>]: does pkg hold perm?"); 17096 pw.println(" <package.name>: info about given package"); 17097 return; 17098 } else if ("--checkin".equals(opt)) { 17099 checkin = true; 17100 } else if ("-f".equals(opt)) { 17101 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 17102 } else { 17103 pw.println("Unknown argument: " + opt + "; use -h for help"); 17104 } 17105 } 17106 17107 // Is the caller requesting to dump a particular piece of data? 17108 if (opti < args.length) { 17109 String cmd = args[opti]; 17110 opti++; 17111 // Is this a package name? 17112 if ("android".equals(cmd) || cmd.contains(".")) { 17113 packageName = cmd; 17114 // When dumping a single package, we always dump all of its 17115 // filter information since the amount of data will be reasonable. 17116 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 17117 } else if ("check-permission".equals(cmd)) { 17118 if (opti >= args.length) { 17119 pw.println("Error: check-permission missing permission argument"); 17120 return; 17121 } 17122 String perm = args[opti]; 17123 opti++; 17124 if (opti >= args.length) { 17125 pw.println("Error: check-permission missing package argument"); 17126 return; 17127 } 17128 String pkg = args[opti]; 17129 opti++; 17130 int user = UserHandle.getUserId(Binder.getCallingUid()); 17131 if (opti < args.length) { 17132 try { 17133 user = Integer.parseInt(args[opti]); 17134 } catch (NumberFormatException e) { 17135 pw.println("Error: check-permission user argument is not a number: " 17136 + args[opti]); 17137 return; 17138 } 17139 } 17140 pw.println(checkPermission(perm, pkg, user)); 17141 return; 17142 } else if ("l".equals(cmd) || "libraries".equals(cmd)) { 17143 dumpState.setDump(DumpState.DUMP_LIBS); 17144 } else if ("f".equals(cmd) || "features".equals(cmd)) { 17145 dumpState.setDump(DumpState.DUMP_FEATURES); 17146 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) { 17147 if (opti >= args.length) { 17148 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS 17149 | DumpState.DUMP_SERVICE_RESOLVERS 17150 | DumpState.DUMP_RECEIVER_RESOLVERS 17151 | DumpState.DUMP_CONTENT_RESOLVERS); 17152 } else { 17153 while (opti < args.length) { 17154 String name = args[opti]; 17155 if ("a".equals(name) || "activity".equals(name)) { 17156 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS); 17157 } else if ("s".equals(name) || "service".equals(name)) { 17158 dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS); 17159 } else if ("r".equals(name) || "receiver".equals(name)) { 17160 dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS); 17161 } else if ("c".equals(name) || "content".equals(name)) { 17162 dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS); 17163 } else { 17164 pw.println("Error: unknown resolver table type: " + name); 17165 return; 17166 } 17167 opti++; 17168 } 17169 } 17170 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) { 17171 dumpState.setDump(DumpState.DUMP_PERMISSIONS); 17172 } else if ("permission".equals(cmd)) { 17173 if (opti >= args.length) { 17174 pw.println("Error: permission requires permission name"); 17175 return; 17176 } 17177 permissionNames = new ArraySet<>(); 17178 while (opti < args.length) { 17179 permissionNames.add(args[opti]); 17180 opti++; 17181 } 17182 dumpState.setDump(DumpState.DUMP_PERMISSIONS 17183 | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS); 17184 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) { 17185 dumpState.setDump(DumpState.DUMP_PREFERRED); 17186 } else if ("preferred-xml".equals(cmd)) { 17187 dumpState.setDump(DumpState.DUMP_PREFERRED_XML); 17188 if (opti < args.length && "--full".equals(args[opti])) { 17189 fullPreferred = true; 17190 opti++; 17191 } 17192 } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) { 17193 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED); 17194 } else if ("p".equals(cmd) || "packages".equals(cmd)) { 17195 dumpState.setDump(DumpState.DUMP_PACKAGES); 17196 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) { 17197 dumpState.setDump(DumpState.DUMP_SHARED_USERS); 17198 } else if ("prov".equals(cmd) || "providers".equals(cmd)) { 17199 dumpState.setDump(DumpState.DUMP_PROVIDERS); 17200 } else if ("m".equals(cmd) || "messages".equals(cmd)) { 17201 dumpState.setDump(DumpState.DUMP_MESSAGES); 17202 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) { 17203 dumpState.setDump(DumpState.DUMP_VERIFIERS); 17204 } else if ("i".equals(cmd) || "ifv".equals(cmd) 17205 || "intent-filter-verifiers".equals(cmd)) { 17206 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS); 17207 } else if ("version".equals(cmd)) { 17208 dumpState.setDump(DumpState.DUMP_VERSION); 17209 } else if ("k".equals(cmd) || "keysets".equals(cmd)) { 17210 dumpState.setDump(DumpState.DUMP_KEYSETS); 17211 } else if ("installs".equals(cmd)) { 17212 dumpState.setDump(DumpState.DUMP_INSTALLS); 17213 } else if ("write".equals(cmd)) { 17214 synchronized (mPackages) { 17215 mSettings.writeLPr(); 17216 pw.println("Settings written."); 17217 return; 17218 } 17219 } 17220 } 17221 17222 if (checkin) { 17223 pw.println("vers,1"); 17224 } 17225 17226 // reader 17227 synchronized (mPackages) { 17228 if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) { 17229 if (!checkin) { 17230 if (dumpState.onTitlePrinted()) 17231 pw.println(); 17232 pw.println("Database versions:"); 17233 mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, " ")); 17234 } 17235 } 17236 17237 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) { 17238 if (!checkin) { 17239 if (dumpState.onTitlePrinted()) 17240 pw.println(); 17241 pw.println("Verifiers:"); 17242 pw.print(" Required: "); 17243 pw.print(mRequiredVerifierPackage); 17244 pw.print(" (uid="); 17245 pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 17246 UserHandle.USER_SYSTEM)); 17247 pw.println(")"); 17248 } else if (mRequiredVerifierPackage != null) { 17249 pw.print("vrfy,"); pw.print(mRequiredVerifierPackage); 17250 pw.print(","); 17251 pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 17252 UserHandle.USER_SYSTEM)); 17253 } 17254 } 17255 17256 if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) && 17257 packageName == null) { 17258 if (mIntentFilterVerifierComponent != null) { 17259 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName(); 17260 if (!checkin) { 17261 if (dumpState.onTitlePrinted()) 17262 pw.println(); 17263 pw.println("Intent Filter Verifier:"); 17264 pw.print(" Using: "); 17265 pw.print(verifierPackageName); 17266 pw.print(" (uid="); 17267 pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING, 17268 UserHandle.USER_SYSTEM)); 17269 pw.println(")"); 17270 } else if (verifierPackageName != null) { 17271 pw.print("ifv,"); pw.print(verifierPackageName); 17272 pw.print(","); 17273 pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING, 17274 UserHandle.USER_SYSTEM)); 17275 } 17276 } else { 17277 pw.println(); 17278 pw.println("No Intent Filter Verifier available!"); 17279 } 17280 } 17281 17282 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) { 17283 boolean printedHeader = false; 17284 final Iterator<String> it = mSharedLibraries.keySet().iterator(); 17285 while (it.hasNext()) { 17286 String name = it.next(); 17287 SharedLibraryEntry ent = mSharedLibraries.get(name); 17288 if (!checkin) { 17289 if (!printedHeader) { 17290 if (dumpState.onTitlePrinted()) 17291 pw.println(); 17292 pw.println("Libraries:"); 17293 printedHeader = true; 17294 } 17295 pw.print(" "); 17296 } else { 17297 pw.print("lib,"); 17298 } 17299 pw.print(name); 17300 if (!checkin) { 17301 pw.print(" -> "); 17302 } 17303 if (ent.path != null) { 17304 if (!checkin) { 17305 pw.print("(jar) "); 17306 pw.print(ent.path); 17307 } else { 17308 pw.print(",jar,"); 17309 pw.print(ent.path); 17310 } 17311 } else { 17312 if (!checkin) { 17313 pw.print("(apk) "); 17314 pw.print(ent.apk); 17315 } else { 17316 pw.print(",apk,"); 17317 pw.print(ent.apk); 17318 } 17319 } 17320 pw.println(); 17321 } 17322 } 17323 17324 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) { 17325 if (dumpState.onTitlePrinted()) 17326 pw.println(); 17327 if (!checkin) { 17328 pw.println("Features:"); 17329 } 17330 17331 for (FeatureInfo feat : mAvailableFeatures.values()) { 17332 if (checkin) { 17333 pw.print("feat,"); 17334 pw.print(feat.name); 17335 pw.print(","); 17336 pw.println(feat.version); 17337 } else { 17338 pw.print(" "); 17339 pw.print(feat.name); 17340 if (feat.version > 0) { 17341 pw.print(" version="); 17342 pw.print(feat.version); 17343 } 17344 pw.println(); 17345 } 17346 } 17347 } 17348 17349 if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) { 17350 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:" 17351 : "Activity Resolver Table:", " ", packageName, 17352 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 17353 dumpState.setTitlePrinted(true); 17354 } 17355 } 17356 if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) { 17357 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:" 17358 : "Receiver Resolver Table:", " ", packageName, 17359 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 17360 dumpState.setTitlePrinted(true); 17361 } 17362 } 17363 if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) { 17364 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:" 17365 : "Service Resolver Table:", " ", packageName, 17366 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 17367 dumpState.setTitlePrinted(true); 17368 } 17369 } 17370 if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) { 17371 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:" 17372 : "Provider Resolver Table:", " ", packageName, 17373 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 17374 dumpState.setTitlePrinted(true); 17375 } 17376 } 17377 17378 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) { 17379 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 17380 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 17381 int user = mSettings.mPreferredActivities.keyAt(i); 17382 if (pir.dump(pw, 17383 dumpState.getTitlePrinted() 17384 ? "\nPreferred Activities User " + user + ":" 17385 : "Preferred Activities User " + user + ":", " ", 17386 packageName, true, false)) { 17387 dumpState.setTitlePrinted(true); 17388 } 17389 } 17390 } 17391 17392 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) { 17393 pw.flush(); 17394 FileOutputStream fout = new FileOutputStream(fd); 17395 BufferedOutputStream str = new BufferedOutputStream(fout); 17396 XmlSerializer serializer = new FastXmlSerializer(); 17397 try { 17398 serializer.setOutput(str, StandardCharsets.UTF_8.name()); 17399 serializer.startDocument(null, true); 17400 serializer.setFeature( 17401 "http://xmlpull.org/v1/doc/features.html#indent-output", true); 17402 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred); 17403 serializer.endDocument(); 17404 serializer.flush(); 17405 } catch (IllegalArgumentException e) { 17406 pw.println("Failed writing: " + e); 17407 } catch (IllegalStateException e) { 17408 pw.println("Failed writing: " + e); 17409 } catch (IOException e) { 17410 pw.println("Failed writing: " + e); 17411 } 17412 } 17413 17414 if (!checkin 17415 && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED) 17416 && packageName == null) { 17417 pw.println(); 17418 int count = mSettings.mPackages.size(); 17419 if (count == 0) { 17420 pw.println("No applications!"); 17421 pw.println(); 17422 } else { 17423 final String prefix = " "; 17424 Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values(); 17425 if (allPackageSettings.size() == 0) { 17426 pw.println("No domain preferred apps!"); 17427 pw.println(); 17428 } else { 17429 pw.println("App verification status:"); 17430 pw.println(); 17431 count = 0; 17432 for (PackageSetting ps : allPackageSettings) { 17433 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo(); 17434 if (ivi == null || ivi.getPackageName() == null) continue; 17435 pw.println(prefix + "Package: " + ivi.getPackageName()); 17436 pw.println(prefix + "Domains: " + ivi.getDomainsString()); 17437 pw.println(prefix + "Status: " + ivi.getStatusString()); 17438 pw.println(); 17439 count++; 17440 } 17441 if (count == 0) { 17442 pw.println(prefix + "No app verification established."); 17443 pw.println(); 17444 } 17445 for (int userId : sUserManager.getUserIds()) { 17446 pw.println("App linkages for user " + userId + ":"); 17447 pw.println(); 17448 count = 0; 17449 for (PackageSetting ps : allPackageSettings) { 17450 final long status = ps.getDomainVerificationStatusForUser(userId); 17451 if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 17452 continue; 17453 } 17454 pw.println(prefix + "Package: " + ps.name); 17455 pw.println(prefix + "Domains: " + dumpDomainString(ps.name)); 17456 String statusStr = IntentFilterVerificationInfo. 17457 getStatusStringFromValue(status); 17458 pw.println(prefix + "Status: " + statusStr); 17459 pw.println(); 17460 count++; 17461 } 17462 if (count == 0) { 17463 pw.println(prefix + "No configured app linkages."); 17464 pw.println(); 17465 } 17466 } 17467 } 17468 } 17469 } 17470 17471 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) { 17472 mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState); 17473 if (packageName == null && permissionNames == null) { 17474 for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) { 17475 if (iperm == 0) { 17476 if (dumpState.onTitlePrinted()) 17477 pw.println(); 17478 pw.println("AppOp Permissions:"); 17479 } 17480 pw.print(" AppOp Permission "); 17481 pw.print(mAppOpPermissionPackages.keyAt(iperm)); 17482 pw.println(":"); 17483 ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm); 17484 for (int ipkg=0; ipkg<pkgs.size(); ipkg++) { 17485 pw.print(" "); pw.println(pkgs.valueAt(ipkg)); 17486 } 17487 } 17488 } 17489 } 17490 17491 if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) { 17492 boolean printedSomething = false; 17493 for (PackageParser.Provider p : mProviders.mProviders.values()) { 17494 if (packageName != null && !packageName.equals(p.info.packageName)) { 17495 continue; 17496 } 17497 if (!printedSomething) { 17498 if (dumpState.onTitlePrinted()) 17499 pw.println(); 17500 pw.println("Registered ContentProviders:"); 17501 printedSomething = true; 17502 } 17503 pw.print(" "); p.printComponentShortName(pw); pw.println(":"); 17504 pw.print(" "); pw.println(p.toString()); 17505 } 17506 printedSomething = false; 17507 for (Map.Entry<String, PackageParser.Provider> entry : 17508 mProvidersByAuthority.entrySet()) { 17509 PackageParser.Provider p = entry.getValue(); 17510 if (packageName != null && !packageName.equals(p.info.packageName)) { 17511 continue; 17512 } 17513 if (!printedSomething) { 17514 if (dumpState.onTitlePrinted()) 17515 pw.println(); 17516 pw.println("ContentProvider Authorities:"); 17517 printedSomething = true; 17518 } 17519 pw.print(" ["); pw.print(entry.getKey()); pw.println("]:"); 17520 pw.print(" "); pw.println(p.toString()); 17521 if (p.info != null && p.info.applicationInfo != null) { 17522 final String appInfo = p.info.applicationInfo.toString(); 17523 pw.print(" applicationInfo="); pw.println(appInfo); 17524 } 17525 } 17526 } 17527 17528 if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) { 17529 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState); 17530 } 17531 17532 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) { 17533 mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin); 17534 } 17535 17536 if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) { 17537 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin); 17538 } 17539 17540 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) { 17541 mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState); 17542 } 17543 17544 if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) { 17545 // XXX should handle packageName != null by dumping only install data that 17546 // the given package is involved with. 17547 if (dumpState.onTitlePrinted()) pw.println(); 17548 mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120)); 17549 } 17550 17551 if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) { 17552 if (dumpState.onTitlePrinted()) pw.println(); 17553 mSettings.dumpReadMessagesLPr(pw, dumpState); 17554 17555 pw.println(); 17556 pw.println("Package warning messages:"); 17557 BufferedReader in = null; 17558 String line = null; 17559 try { 17560 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 17561 while ((line = in.readLine()) != null) { 17562 if (line.contains("ignored: updated version")) continue; 17563 pw.println(line); 17564 } 17565 } catch (IOException ignored) { 17566 } finally { 17567 IoUtils.closeQuietly(in); 17568 } 17569 } 17570 17571 if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) { 17572 BufferedReader in = null; 17573 String line = null; 17574 try { 17575 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 17576 while ((line = in.readLine()) != null) { 17577 if (line.contains("ignored: updated version")) continue; 17578 pw.print("msg,"); 17579 pw.println(line); 17580 } 17581 } catch (IOException ignored) { 17582 } finally { 17583 IoUtils.closeQuietly(in); 17584 } 17585 } 17586 } 17587 } 17588 17589 private String dumpDomainString(String packageName) { 17590 List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName) 17591 .getList(); 17592 List<IntentFilter> filters = getAllIntentFilters(packageName).getList(); 17593 17594 ArraySet<String> result = new ArraySet<>(); 17595 if (iviList.size() > 0) { 17596 for (IntentFilterVerificationInfo ivi : iviList) { 17597 for (String host : ivi.getDomains()) { 17598 result.add(host); 17599 } 17600 } 17601 } 17602 if (filters != null && filters.size() > 0) { 17603 for (IntentFilter filter : filters) { 17604 if (filter.hasCategory(Intent.CATEGORY_BROWSABLE) 17605 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 17606 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) { 17607 result.addAll(filter.getHostsList()); 17608 } 17609 } 17610 } 17611 17612 StringBuilder sb = new StringBuilder(result.size() * 16); 17613 for (String domain : result) { 17614 if (sb.length() > 0) sb.append(" "); 17615 sb.append(domain); 17616 } 17617 return sb.toString(); 17618 } 17619 17620 // ------- apps on sdcard specific code ------- 17621 static final boolean DEBUG_SD_INSTALL = false; 17622 17623 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD"; 17624 17625 private static final String SD_ENCRYPTION_ALGORITHM = "AES"; 17626 17627 private boolean mMediaMounted = false; 17628 17629 static String getEncryptKey() { 17630 try { 17631 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString( 17632 SD_ENCRYPTION_KEYSTORE_NAME); 17633 if (sdEncKey == null) { 17634 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128, 17635 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME); 17636 if (sdEncKey == null) { 17637 Slog.e(TAG, "Failed to create encryption keys"); 17638 return null; 17639 } 17640 } 17641 return sdEncKey; 17642 } catch (NoSuchAlgorithmException nsae) { 17643 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae); 17644 return null; 17645 } catch (IOException ioe) { 17646 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe); 17647 return null; 17648 } 17649 } 17650 17651 /* 17652 * Update media status on PackageManager. 17653 */ 17654 @Override 17655 public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) { 17656 int callingUid = Binder.getCallingUid(); 17657 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 17658 throw new SecurityException("Media status can only be updated by the system"); 17659 } 17660 // reader; this apparently protects mMediaMounted, but should probably 17661 // be a different lock in that case. 17662 synchronized (mPackages) { 17663 Log.i(TAG, "Updating external media status from " 17664 + (mMediaMounted ? "mounted" : "unmounted") + " to " 17665 + (mediaStatus ? "mounted" : "unmounted")); 17666 if (DEBUG_SD_INSTALL) 17667 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus 17668 + ", mMediaMounted=" + mMediaMounted); 17669 if (mediaStatus == mMediaMounted) { 17670 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 17671 : 0, -1); 17672 mHandler.sendMessage(msg); 17673 return; 17674 } 17675 mMediaMounted = mediaStatus; 17676 } 17677 // Queue up an async operation since the package installation may take a 17678 // little while. 17679 mHandler.post(new Runnable() { 17680 public void run() { 17681 updateExternalMediaStatusInner(mediaStatus, reportStatus, true); 17682 } 17683 }); 17684 } 17685 17686 /** 17687 * Called by MountService when the initial ASECs to scan are available. 17688 * Should block until all the ASEC containers are finished being scanned. 17689 */ 17690 public void scanAvailableAsecs() { 17691 updateExternalMediaStatusInner(true, false, false); 17692 } 17693 17694 /* 17695 * Collect information of applications on external media, map them against 17696 * existing containers and update information based on current mount status. 17697 * Please note that we always have to report status if reportStatus has been 17698 * set to true especially when unloading packages. 17699 */ 17700 private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus, 17701 boolean externalStorage) { 17702 ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>(); 17703 int[] uidArr = EmptyArray.INT; 17704 17705 final String[] list = PackageHelper.getSecureContainerList(); 17706 if (ArrayUtils.isEmpty(list)) { 17707 Log.i(TAG, "No secure containers found"); 17708 } else { 17709 // Process list of secure containers and categorize them 17710 // as active or stale based on their package internal state. 17711 17712 // reader 17713 synchronized (mPackages) { 17714 for (String cid : list) { 17715 // Leave stages untouched for now; installer service owns them 17716 if (PackageInstallerService.isStageName(cid)) continue; 17717 17718 if (DEBUG_SD_INSTALL) 17719 Log.i(TAG, "Processing container " + cid); 17720 String pkgName = getAsecPackageName(cid); 17721 if (pkgName == null) { 17722 Slog.i(TAG, "Found stale container " + cid + " with no package name"); 17723 continue; 17724 } 17725 if (DEBUG_SD_INSTALL) 17726 Log.i(TAG, "Looking for pkg : " + pkgName); 17727 17728 final PackageSetting ps = mSettings.mPackages.get(pkgName); 17729 if (ps == null) { 17730 Slog.i(TAG, "Found stale container " + cid + " with no matching settings"); 17731 continue; 17732 } 17733 17734 /* 17735 * Skip packages that are not external if we're unmounting 17736 * external storage. 17737 */ 17738 if (externalStorage && !isMounted && !isExternal(ps)) { 17739 continue; 17740 } 17741 17742 final AsecInstallArgs args = new AsecInstallArgs(cid, 17743 getAppDexInstructionSets(ps), ps.isForwardLocked()); 17744 // The package status is changed only if the code path 17745 // matches between settings and the container id. 17746 if (ps.codePathString != null 17747 && ps.codePathString.startsWith(args.getCodePath())) { 17748 if (DEBUG_SD_INSTALL) { 17749 Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName 17750 + " at code path: " + ps.codePathString); 17751 } 17752 17753 // We do have a valid package installed on sdcard 17754 processCids.put(args, ps.codePathString); 17755 final int uid = ps.appId; 17756 if (uid != -1) { 17757 uidArr = ArrayUtils.appendInt(uidArr, uid); 17758 } 17759 } else { 17760 Slog.i(TAG, "Found stale container " + cid + ": expected codePath=" 17761 + ps.codePathString); 17762 } 17763 } 17764 } 17765 17766 Arrays.sort(uidArr); 17767 } 17768 17769 // Process packages with valid entries. 17770 if (isMounted) { 17771 if (DEBUG_SD_INSTALL) 17772 Log.i(TAG, "Loading packages"); 17773 loadMediaPackages(processCids, uidArr, externalStorage); 17774 startCleaningPackages(); 17775 mInstallerService.onSecureContainersAvailable(); 17776 } else { 17777 if (DEBUG_SD_INSTALL) 17778 Log.i(TAG, "Unloading packages"); 17779 unloadMediaPackages(processCids, uidArr, reportStatus); 17780 } 17781 } 17782 17783 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 17784 ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) { 17785 final int size = infos.size(); 17786 final String[] packageNames = new String[size]; 17787 final int[] packageUids = new int[size]; 17788 for (int i = 0; i < size; i++) { 17789 final ApplicationInfo info = infos.get(i); 17790 packageNames[i] = info.packageName; 17791 packageUids[i] = info.uid; 17792 } 17793 sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids, 17794 finishedReceiver); 17795 } 17796 17797 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 17798 ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 17799 sendResourcesChangedBroadcast(mediaStatus, replacing, 17800 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver); 17801 } 17802 17803 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 17804 String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 17805 int size = pkgList.length; 17806 if (size > 0) { 17807 // Send broadcasts here 17808 Bundle extras = new Bundle(); 17809 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 17810 if (uidArr != null) { 17811 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr); 17812 } 17813 if (replacing) { 17814 extras.putBoolean(Intent.EXTRA_REPLACING, replacing); 17815 } 17816 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE 17817 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE; 17818 sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null); 17819 } 17820 } 17821 17822 /* 17823 * Look at potentially valid container ids from processCids If package 17824 * information doesn't match the one on record or package scanning fails, 17825 * the cid is added to list of removeCids. We currently don't delete stale 17826 * containers. 17827 */ 17828 private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr, 17829 boolean externalStorage) { 17830 ArrayList<String> pkgList = new ArrayList<String>(); 17831 Set<AsecInstallArgs> keys = processCids.keySet(); 17832 17833 for (AsecInstallArgs args : keys) { 17834 String codePath = processCids.get(args); 17835 if (DEBUG_SD_INSTALL) 17836 Log.i(TAG, "Loading container : " + args.cid); 17837 int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 17838 try { 17839 // Make sure there are no container errors first. 17840 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) { 17841 Slog.e(TAG, "Failed to mount cid : " + args.cid 17842 + " when installing from sdcard"); 17843 continue; 17844 } 17845 // Check code path here. 17846 if (codePath == null || !codePath.startsWith(args.getCodePath())) { 17847 Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath() 17848 + " does not match one in settings " + codePath); 17849 continue; 17850 } 17851 // Parse package 17852 int parseFlags = mDefParseFlags; 17853 if (args.isExternalAsec()) { 17854 parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE; 17855 } 17856 if (args.isFwdLocked()) { 17857 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 17858 } 17859 17860 synchronized (mInstallLock) { 17861 PackageParser.Package pkg = null; 17862 try { 17863 pkg = scanPackageTracedLI(new File(codePath), parseFlags, 0, 0, null); 17864 } catch (PackageManagerException e) { 17865 Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage()); 17866 } 17867 // Scan the package 17868 if (pkg != null) { 17869 /* 17870 * TODO why is the lock being held? doPostInstall is 17871 * called in other places without the lock. This needs 17872 * to be straightened out. 17873 */ 17874 // writer 17875 synchronized (mPackages) { 17876 retCode = PackageManager.INSTALL_SUCCEEDED; 17877 pkgList.add(pkg.packageName); 17878 // Post process args 17879 args.doPostInstall(PackageManager.INSTALL_SUCCEEDED, 17880 pkg.applicationInfo.uid); 17881 } 17882 } else { 17883 Slog.i(TAG, "Failed to install pkg from " + codePath + " from sdcard"); 17884 } 17885 } 17886 17887 } finally { 17888 if (retCode != PackageManager.INSTALL_SUCCEEDED) { 17889 Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode); 17890 } 17891 } 17892 } 17893 // writer 17894 synchronized (mPackages) { 17895 // If the platform SDK has changed since the last time we booted, 17896 // we need to re-grant app permission to catch any new ones that 17897 // appear. This is really a hack, and means that apps can in some 17898 // cases get permissions that the user didn't initially explicitly 17899 // allow... it would be nice to have some better way to handle 17900 // this situation. 17901 final VersionInfo ver = externalStorage ? mSettings.getExternalVersion() 17902 : mSettings.getInternalVersion(); 17903 final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL 17904 : StorageManager.UUID_PRIVATE_INTERNAL; 17905 17906 int updateFlags = UPDATE_PERMISSIONS_ALL; 17907 if (ver.sdkVersion != mSdkVersion) { 17908 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " 17909 + mSdkVersion + "; regranting permissions for external"); 17910 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 17911 } 17912 updatePermissionsLPw(null, null, volumeUuid, updateFlags); 17913 17914 // Yay, everything is now upgraded 17915 ver.forceCurrent(); 17916 17917 // can downgrade to reader 17918 // Persist settings 17919 mSettings.writeLPr(); 17920 } 17921 // Send a broadcast to let everyone know we are done processing 17922 if (pkgList.size() > 0) { 17923 sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null); 17924 } 17925 } 17926 17927 /* 17928 * Utility method to unload a list of specified containers 17929 */ 17930 private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) { 17931 // Just unmount all valid containers. 17932 for (AsecInstallArgs arg : cidArgs) { 17933 synchronized (mInstallLock) { 17934 arg.doPostDeleteLI(false); 17935 } 17936 } 17937 } 17938 17939 /* 17940 * Unload packages mounted on external media. This involves deleting package 17941 * data from internal structures, sending broadcasts about disabled packages, 17942 * gc'ing to free up references, unmounting all secure containers 17943 * corresponding to packages on external media, and posting a 17944 * UPDATED_MEDIA_STATUS message if status has been requested. Please note 17945 * that we always have to post this message if status has been requested no 17946 * matter what. 17947 */ 17948 private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[], 17949 final boolean reportStatus) { 17950 if (DEBUG_SD_INSTALL) 17951 Log.i(TAG, "unloading media packages"); 17952 ArrayList<String> pkgList = new ArrayList<String>(); 17953 ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>(); 17954 final Set<AsecInstallArgs> keys = processCids.keySet(); 17955 for (AsecInstallArgs args : keys) { 17956 String pkgName = args.getPackageName(); 17957 if (DEBUG_SD_INSTALL) 17958 Log.i(TAG, "Trying to unload pkg : " + pkgName); 17959 // Delete package internally 17960 PackageRemovedInfo outInfo = new PackageRemovedInfo(); 17961 synchronized (mInstallLock) { 17962 boolean res = deletePackageLI(pkgName, null, false, null, 17963 PackageManager.DELETE_KEEP_DATA, outInfo, false, null); 17964 if (res) { 17965 pkgList.add(pkgName); 17966 } else { 17967 Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName); 17968 failedList.add(args); 17969 } 17970 } 17971 } 17972 17973 // reader 17974 synchronized (mPackages) { 17975 // We didn't update the settings after removing each package; 17976 // write them now for all packages. 17977 mSettings.writeLPr(); 17978 } 17979 17980 // We have to absolutely send UPDATED_MEDIA_STATUS only 17981 // after confirming that all the receivers processed the ordered 17982 // broadcast when packages get disabled, force a gc to clean things up. 17983 // and unload all the containers. 17984 if (pkgList.size() > 0) { 17985 sendResourcesChangedBroadcast(false, false, pkgList, uidArr, 17986 new IIntentReceiver.Stub() { 17987 public void performReceive(Intent intent, int resultCode, String data, 17988 Bundle extras, boolean ordered, boolean sticky, 17989 int sendingUser) throws RemoteException { 17990 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, 17991 reportStatus ? 1 : 0, 1, keys); 17992 mHandler.sendMessage(msg); 17993 } 17994 }); 17995 } else { 17996 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1, 17997 keys); 17998 mHandler.sendMessage(msg); 17999 } 18000 } 18001 18002 private void loadPrivatePackages(final VolumeInfo vol) { 18003 mHandler.post(new Runnable() { 18004 @Override 18005 public void run() { 18006 loadPrivatePackagesInner(vol); 18007 } 18008 }); 18009 } 18010 18011 private void loadPrivatePackagesInner(VolumeInfo vol) { 18012 final String volumeUuid = vol.fsUuid; 18013 if (TextUtils.isEmpty(volumeUuid)) { 18014 Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring"); 18015 return; 18016 } 18017 18018 final ArrayList<ApplicationInfo> loaded = new ArrayList<>(); 18019 final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE; 18020 18021 final VersionInfo ver; 18022 final List<PackageSetting> packages; 18023 synchronized (mPackages) { 18024 ver = mSettings.findOrCreateVersion(volumeUuid); 18025 packages = mSettings.getVolumePackagesLPr(volumeUuid); 18026 } 18027 18028 // TODO: introduce a new concept similar to "frozen" to prevent these 18029 // apps from being launched until after data has been fully reconciled 18030 for (PackageSetting ps : packages) { 18031 synchronized (mInstallLock) { 18032 final PackageParser.Package pkg; 18033 try { 18034 pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null); 18035 loaded.add(pkg.applicationInfo); 18036 18037 } catch (PackageManagerException e) { 18038 Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage()); 18039 } 18040 18041 if (!Build.FINGERPRINT.equals(ver.fingerprint)) { 18042 deleteCodeCacheDirsLI(ps.volumeUuid, ps.name); 18043 } 18044 } 18045 } 18046 18047 // Reconcile app data for all started/unlocked users 18048 final StorageManager sm = mContext.getSystemService(StorageManager.class); 18049 final UserManager um = mContext.getSystemService(UserManager.class); 18050 for (UserInfo user : um.getUsers()) { 18051 final int flags; 18052 if (um.isUserUnlocked(user.id)) { 18053 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 18054 } else if (um.isUserRunning(user.id)) { 18055 flags = StorageManager.FLAG_STORAGE_DE; 18056 } else { 18057 continue; 18058 } 18059 18060 sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags); 18061 reconcileAppsData(volumeUuid, user.id, flags); 18062 } 18063 18064 synchronized (mPackages) { 18065 int updateFlags = UPDATE_PERMISSIONS_ALL; 18066 if (ver.sdkVersion != mSdkVersion) { 18067 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " 18068 + mSdkVersion + "; regranting permissions for " + volumeUuid); 18069 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 18070 } 18071 updatePermissionsLPw(null, null, volumeUuid, updateFlags); 18072 18073 // Yay, everything is now upgraded 18074 ver.forceCurrent(); 18075 18076 mSettings.writeLPr(); 18077 } 18078 18079 if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded); 18080 sendResourcesChangedBroadcast(true, false, loaded, null); 18081 } 18082 18083 private void unloadPrivatePackages(final VolumeInfo vol) { 18084 mHandler.post(new Runnable() { 18085 @Override 18086 public void run() { 18087 unloadPrivatePackagesInner(vol); 18088 } 18089 }); 18090 } 18091 18092 private void unloadPrivatePackagesInner(VolumeInfo vol) { 18093 final String volumeUuid = vol.fsUuid; 18094 if (TextUtils.isEmpty(volumeUuid)) { 18095 Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring"); 18096 return; 18097 } 18098 18099 final ArrayList<ApplicationInfo> unloaded = new ArrayList<>(); 18100 synchronized (mInstallLock) { 18101 synchronized (mPackages) { 18102 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid); 18103 for (PackageSetting ps : packages) { 18104 if (ps.pkg == null) continue; 18105 18106 final ApplicationInfo info = ps.pkg.applicationInfo; 18107 final PackageRemovedInfo outInfo = new PackageRemovedInfo(); 18108 if (deletePackageLI(ps.name, null, false, null, 18109 PackageManager.DELETE_KEEP_DATA, outInfo, false, null)) { 18110 unloaded.add(info); 18111 } else { 18112 Slog.w(TAG, "Failed to unload " + ps.codePath); 18113 } 18114 } 18115 18116 mSettings.writeLPr(); 18117 } 18118 } 18119 18120 if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded); 18121 sendResourcesChangedBroadcast(false, false, unloaded, null); 18122 } 18123 18124 /** 18125 * Examine all users present on given mounted volume, and destroy data 18126 * belonging to users that are no longer valid, or whose user ID has been 18127 * recycled. 18128 */ 18129 private void reconcileUsers(String volumeUuid) { 18130 // TODO: also reconcile DE directories 18131 final File[] files = FileUtils 18132 .listFilesOrEmpty(Environment.getDataUserCeDirectory(volumeUuid)); 18133 for (File file : files) { 18134 if (!file.isDirectory()) continue; 18135 18136 final int userId; 18137 final UserInfo info; 18138 try { 18139 userId = Integer.parseInt(file.getName()); 18140 info = sUserManager.getUserInfo(userId); 18141 } catch (NumberFormatException e) { 18142 Slog.w(TAG, "Invalid user directory " + file); 18143 continue; 18144 } 18145 18146 boolean destroyUser = false; 18147 if (info == null) { 18148 logCriticalInfo(Log.WARN, "Destroying user directory " + file 18149 + " because no matching user was found"); 18150 destroyUser = true; 18151 } else { 18152 try { 18153 UserManagerService.enforceSerialNumber(file, info.serialNumber); 18154 } catch (IOException e) { 18155 logCriticalInfo(Log.WARN, "Destroying user directory " + file 18156 + " because we failed to enforce serial number: " + e); 18157 destroyUser = true; 18158 } 18159 } 18160 18161 if (destroyUser) { 18162 synchronized (mInstallLock) { 18163 try { 18164 mInstaller.removeUserDataDirs(volumeUuid, userId); 18165 } catch (InstallerException e) { 18166 Slog.w(TAG, "Failed to clean up user dirs", e); 18167 } 18168 } 18169 } 18170 } 18171 } 18172 18173 private void assertPackageKnown(String volumeUuid, String packageName) 18174 throws PackageManagerException { 18175 synchronized (mPackages) { 18176 final PackageSetting ps = mSettings.mPackages.get(packageName); 18177 if (ps == null) { 18178 throw new PackageManagerException("Package " + packageName + " is unknown"); 18179 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) { 18180 throw new PackageManagerException( 18181 "Package " + packageName + " found on unknown volume " + volumeUuid 18182 + "; expected volume " + ps.volumeUuid); 18183 } 18184 } 18185 } 18186 18187 private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId) 18188 throws PackageManagerException { 18189 synchronized (mPackages) { 18190 final PackageSetting ps = mSettings.mPackages.get(packageName); 18191 if (ps == null) { 18192 throw new PackageManagerException("Package " + packageName + " is unknown"); 18193 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) { 18194 throw new PackageManagerException( 18195 "Package " + packageName + " found on unknown volume " + volumeUuid 18196 + "; expected volume " + ps.volumeUuid); 18197 } else if (!ps.getInstalled(userId)) { 18198 throw new PackageManagerException( 18199 "Package " + packageName + " not installed for user " + userId); 18200 } 18201 } 18202 } 18203 18204 /** 18205 * Examine all apps present on given mounted volume, and destroy apps that 18206 * aren't expected, either due to uninstallation or reinstallation on 18207 * another volume. 18208 */ 18209 private void reconcileApps(String volumeUuid) { 18210 final File[] files = FileUtils 18211 .listFilesOrEmpty(Environment.getDataAppDirectory(volumeUuid)); 18212 for (File file : files) { 18213 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 18214 && !PackageInstallerService.isStageName(file.getName()); 18215 if (!isPackage) { 18216 // Ignore entries which are not packages 18217 continue; 18218 } 18219 18220 try { 18221 final PackageLite pkg = PackageParser.parsePackageLite(file, 18222 PackageParser.PARSE_MUST_BE_APK); 18223 assertPackageKnown(volumeUuid, pkg.packageName); 18224 18225 } catch (PackageParserException | PackageManagerException e) { 18226 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 18227 synchronized (mInstallLock) { 18228 removeCodePathLI(file); 18229 } 18230 } 18231 } 18232 } 18233 18234 /** 18235 * Reconcile all app data for the given user. 18236 * <p> 18237 * Verifies that directories exist and that ownership and labeling is 18238 * correct for all installed apps on all mounted volumes. 18239 */ 18240 void reconcileAppsData(int userId, int flags) { 18241 final StorageManager storage = mContext.getSystemService(StorageManager.class); 18242 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 18243 final String volumeUuid = vol.getFsUuid(); 18244 reconcileAppsData(volumeUuid, userId, flags); 18245 } 18246 } 18247 18248 /** 18249 * Reconcile all app data on given mounted volume. 18250 * <p> 18251 * Destroys app data that isn't expected, either due to uninstallation or 18252 * reinstallation on another volume. 18253 * <p> 18254 * Verifies that directories exist and that ownership and labeling is 18255 * correct for all installed apps. 18256 */ 18257 private void reconcileAppsData(String volumeUuid, int userId, int flags) { 18258 Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x" 18259 + Integer.toHexString(flags)); 18260 18261 final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId); 18262 final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId); 18263 18264 boolean restoreconNeeded = false; 18265 18266 // First look for stale data that doesn't belong, and check if things 18267 // have changed since we did our last restorecon 18268 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 18269 if (!isUserKeyUnlocked(userId)) { 18270 throw new RuntimeException( 18271 "Yikes, someone asked us to reconcile CE storage while " + userId 18272 + " was still locked; this would have caused massive data loss!"); 18273 } 18274 18275 restoreconNeeded |= SELinuxMMAC.isRestoreconNeeded(ceDir); 18276 18277 final File[] files = FileUtils.listFilesOrEmpty(ceDir); 18278 for (File file : files) { 18279 final String packageName = file.getName(); 18280 try { 18281 assertPackageKnownAndInstalled(volumeUuid, packageName, userId); 18282 } catch (PackageManagerException e) { 18283 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 18284 synchronized (mInstallLock) { 18285 destroyAppDataLI(volumeUuid, packageName, userId, 18286 StorageManager.FLAG_STORAGE_CE); 18287 } 18288 } 18289 } 18290 } 18291 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) { 18292 restoreconNeeded |= SELinuxMMAC.isRestoreconNeeded(deDir); 18293 18294 final File[] files = FileUtils.listFilesOrEmpty(deDir); 18295 for (File file : files) { 18296 final String packageName = file.getName(); 18297 try { 18298 assertPackageKnownAndInstalled(volumeUuid, packageName, userId); 18299 } catch (PackageManagerException e) { 18300 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 18301 synchronized (mInstallLock) { 18302 destroyAppDataLI(volumeUuid, packageName, userId, 18303 StorageManager.FLAG_STORAGE_DE); 18304 } 18305 } 18306 } 18307 } 18308 18309 // Ensure that data directories are ready to roll for all packages 18310 // installed for this volume and user 18311 final List<PackageSetting> packages; 18312 synchronized (mPackages) { 18313 packages = mSettings.getVolumePackagesLPr(volumeUuid); 18314 } 18315 int preparedCount = 0; 18316 for (PackageSetting ps : packages) { 18317 final String packageName = ps.name; 18318 if (ps.pkg == null) { 18319 Slog.w(TAG, "Odd, missing scanned package " + packageName); 18320 // TODO: might be due to legacy ASEC apps; we should circle back 18321 // and reconcile again once they're scanned 18322 continue; 18323 } 18324 18325 if (ps.getInstalled(userId)) { 18326 prepareAppData(volumeUuid, userId, flags, ps.pkg, restoreconNeeded); 18327 18328 if (maybeMigrateAppData(volumeUuid, userId, ps.pkg)) { 18329 // We may have just shuffled around app data directories, so 18330 // prepare them one more time 18331 prepareAppData(volumeUuid, userId, flags, ps.pkg, restoreconNeeded); 18332 } 18333 18334 preparedCount++; 18335 } 18336 } 18337 18338 if (restoreconNeeded) { 18339 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 18340 SELinuxMMAC.setRestoreconDone(ceDir); 18341 } 18342 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) { 18343 SELinuxMMAC.setRestoreconDone(deDir); 18344 } 18345 } 18346 18347 Slog.v(TAG, "reconcileAppsData finished " + preparedCount 18348 + " packages; restoreconNeeded was " + restoreconNeeded); 18349 } 18350 18351 /** 18352 * Prepare app data for the given app just after it was installed or 18353 * upgraded. This method carefully only touches users that it's installed 18354 * for, and it forces a restorecon to handle any seinfo changes. 18355 * <p> 18356 * Verifies that directories exist and that ownership and labeling is 18357 * correct for all installed apps. If there is an ownership mismatch, it 18358 * will try recovering system apps by wiping data; third-party app data is 18359 * left intact. 18360 * <p> 18361 * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em> 18362 */ 18363 private void prepareAppDataAfterInstall(PackageParser.Package pkg) { 18364 prepareAppDataAfterInstallInternal(pkg); 18365 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 18366 for (int i = 0; i < childCount; i++) { 18367 PackageParser.Package childPackage = pkg.childPackages.get(i); 18368 prepareAppDataAfterInstallInternal(childPackage); 18369 } 18370 } 18371 18372 private void prepareAppDataAfterInstallInternal(PackageParser.Package pkg) { 18373 final PackageSetting ps; 18374 synchronized (mPackages) { 18375 ps = mSettings.mPackages.get(pkg.packageName); 18376 mSettings.writeKernelMappingLPr(ps); 18377 } 18378 18379 final UserManager um = mContext.getSystemService(UserManager.class); 18380 for (UserInfo user : um.getUsers()) { 18381 final int flags; 18382 if (um.isUserUnlocked(user.id)) { 18383 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 18384 } else if (um.isUserRunning(user.id)) { 18385 flags = StorageManager.FLAG_STORAGE_DE; 18386 } else { 18387 continue; 18388 } 18389 18390 if (ps.getInstalled(user.id)) { 18391 // Whenever an app changes, force a restorecon of its data 18392 // TODO: when user data is locked, mark that we're still dirty 18393 prepareAppData(pkg.volumeUuid, user.id, flags, pkg, true); 18394 } 18395 } 18396 } 18397 18398 /** 18399 * Prepare app data for the given app. 18400 * <p> 18401 * Verifies that directories exist and that ownership and labeling is 18402 * correct for all installed apps. If there is an ownership mismatch, this 18403 * will try recovering system apps by wiping data; third-party app data is 18404 * left intact. 18405 */ 18406 private void prepareAppData(String volumeUuid, int userId, int flags, 18407 PackageParser.Package pkg, boolean restoreconNeeded) { 18408 if (DEBUG_APP_DATA) { 18409 Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x" 18410 + Integer.toHexString(flags) + (restoreconNeeded ? " restoreconNeeded" : "")); 18411 } 18412 18413 final String packageName = pkg.packageName; 18414 final ApplicationInfo app = pkg.applicationInfo; 18415 final int appId = UserHandle.getAppId(app.uid); 18416 18417 Preconditions.checkNotNull(app.seinfo); 18418 18419 synchronized (mInstallLock) { 18420 try { 18421 mInstaller.createAppData(volumeUuid, packageName, userId, flags, 18422 appId, app.seinfo, app.targetSdkVersion); 18423 } catch (InstallerException e) { 18424 if (app.isSystemApp()) { 18425 logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName 18426 + ", but trying to recover: " + e); 18427 destroyAppDataLI(volumeUuid, packageName, userId, flags); 18428 try { 18429 mInstaller.createAppData(volumeUuid, packageName, userId, flags, 18430 appId, app.seinfo, app.targetSdkVersion); 18431 logCriticalInfo(Log.DEBUG, "Recovery succeeded!"); 18432 } catch (InstallerException e2) { 18433 logCriticalInfo(Log.DEBUG, "Recovery failed!"); 18434 } 18435 } else { 18436 Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e); 18437 } 18438 } 18439 18440 if (restoreconNeeded) { 18441 restoreconAppDataLI(volumeUuid, packageName, userId, flags, appId, app.seinfo); 18442 } 18443 18444 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 18445 // Create a native library symlink only if we have native libraries 18446 // and if the native libraries are 32 bit libraries. We do not provide 18447 // this symlink for 64 bit libraries. 18448 if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) { 18449 final String nativeLibPath = app.nativeLibraryDir; 18450 try { 18451 mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName, 18452 nativeLibPath, userId); 18453 } catch (InstallerException e) { 18454 Slog.e(TAG, "Failed to link native for " + packageName + ": " + e); 18455 } 18456 } 18457 } 18458 } 18459 } 18460 18461 /** 18462 * For system apps on non-FBE devices, this method migrates any existing 18463 * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag 18464 * requested by the app. 18465 */ 18466 private boolean maybeMigrateAppData(String volumeUuid, int userId, PackageParser.Package pkg) { 18467 if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated() 18468 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) { 18469 final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage() 18470 ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE; 18471 synchronized (mInstallLock) { 18472 try { 18473 mInstaller.migrateAppData(volumeUuid, pkg.packageName, userId, storageTarget); 18474 } catch (InstallerException e) { 18475 logCriticalInfo(Log.WARN, 18476 "Failed to migrate " + pkg.packageName + ": " + e.getMessage()); 18477 } 18478 } 18479 return true; 18480 } else { 18481 return false; 18482 } 18483 } 18484 18485 private void unfreezePackage(String packageName) { 18486 synchronized (mPackages) { 18487 final PackageSetting ps = mSettings.mPackages.get(packageName); 18488 if (ps != null) { 18489 ps.frozen = false; 18490 } 18491 } 18492 } 18493 18494 @Override 18495 public int movePackage(final String packageName, final String volumeUuid) { 18496 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 18497 18498 final int moveId = mNextMoveId.getAndIncrement(); 18499 mHandler.post(new Runnable() { 18500 @Override 18501 public void run() { 18502 try { 18503 movePackageInternal(packageName, volumeUuid, moveId); 18504 } catch (PackageManagerException e) { 18505 Slog.w(TAG, "Failed to move " + packageName, e); 18506 mMoveCallbacks.notifyStatusChanged(moveId, 18507 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 18508 } 18509 } 18510 }); 18511 return moveId; 18512 } 18513 18514 private void movePackageInternal(final String packageName, final String volumeUuid, 18515 final int moveId) throws PackageManagerException { 18516 final UserHandle user = new UserHandle(UserHandle.getCallingUserId()); 18517 final StorageManager storage = mContext.getSystemService(StorageManager.class); 18518 final PackageManager pm = mContext.getPackageManager(); 18519 18520 final boolean currentAsec; 18521 final String currentVolumeUuid; 18522 final File codeFile; 18523 final String installerPackageName; 18524 final String packageAbiOverride; 18525 final int appId; 18526 final String seinfo; 18527 final String label; 18528 final int targetSdkVersion; 18529 18530 // reader 18531 synchronized (mPackages) { 18532 final PackageParser.Package pkg = mPackages.get(packageName); 18533 final PackageSetting ps = mSettings.mPackages.get(packageName); 18534 if (pkg == null || ps == null) { 18535 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package"); 18536 } 18537 18538 if (pkg.applicationInfo.isSystemApp()) { 18539 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE, 18540 "Cannot move system application"); 18541 } 18542 18543 if (pkg.applicationInfo.isExternalAsec()) { 18544 currentAsec = true; 18545 currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL; 18546 } else if (pkg.applicationInfo.isForwardLocked()) { 18547 currentAsec = true; 18548 currentVolumeUuid = "forward_locked"; 18549 } else { 18550 currentAsec = false; 18551 currentVolumeUuid = ps.volumeUuid; 18552 18553 final File probe = new File(pkg.codePath); 18554 final File probeOat = new File(probe, "oat"); 18555 if (!probe.isDirectory() || !probeOat.isDirectory()) { 18556 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 18557 "Move only supported for modern cluster style installs"); 18558 } 18559 } 18560 18561 if (Objects.equals(currentVolumeUuid, volumeUuid)) { 18562 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 18563 "Package already moved to " + volumeUuid); 18564 } 18565 if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) { 18566 throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN, 18567 "Device admin cannot be moved"); 18568 } 18569 18570 if (ps.frozen) { 18571 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING, 18572 "Failed to move already frozen package"); 18573 } 18574 ps.frozen = true; 18575 18576 codeFile = new File(pkg.codePath); 18577 installerPackageName = ps.installerPackageName; 18578 packageAbiOverride = ps.cpuAbiOverrideString; 18579 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 18580 seinfo = pkg.applicationInfo.seinfo; 18581 label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo)); 18582 targetSdkVersion = pkg.applicationInfo.targetSdkVersion; 18583 } 18584 18585 // Now that we're guarded by frozen state, kill app during move 18586 final long token = Binder.clearCallingIdentity(); 18587 try { 18588 killApplication(packageName, appId, "move pkg"); 18589 } finally { 18590 Binder.restoreCallingIdentity(token); 18591 } 18592 18593 final Bundle extras = new Bundle(); 18594 extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName); 18595 extras.putString(Intent.EXTRA_TITLE, label); 18596 mMoveCallbacks.notifyCreated(moveId, extras); 18597 18598 int installFlags; 18599 final boolean moveCompleteApp; 18600 final File measurePath; 18601 18602 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) { 18603 installFlags = INSTALL_INTERNAL; 18604 moveCompleteApp = !currentAsec; 18605 measurePath = Environment.getDataAppDirectory(volumeUuid); 18606 } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) { 18607 installFlags = INSTALL_EXTERNAL; 18608 moveCompleteApp = false; 18609 measurePath = storage.getPrimaryPhysicalVolume().getPath(); 18610 } else { 18611 final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid); 18612 if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE 18613 || !volume.isMountedWritable()) { 18614 unfreezePackage(packageName); 18615 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 18616 "Move location not mounted private volume"); 18617 } 18618 18619 Preconditions.checkState(!currentAsec); 18620 18621 installFlags = INSTALL_INTERNAL; 18622 moveCompleteApp = true; 18623 measurePath = Environment.getDataAppDirectory(volumeUuid); 18624 } 18625 18626 final PackageStats stats = new PackageStats(null, -1); 18627 synchronized (mInstaller) { 18628 if (!getPackageSizeInfoLI(packageName, -1, stats)) { 18629 unfreezePackage(packageName); 18630 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 18631 "Failed to measure package size"); 18632 } 18633 } 18634 18635 if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size " 18636 + stats.dataSize); 18637 18638 final long startFreeBytes = measurePath.getFreeSpace(); 18639 final long sizeBytes; 18640 if (moveCompleteApp) { 18641 sizeBytes = stats.codeSize + stats.dataSize; 18642 } else { 18643 sizeBytes = stats.codeSize; 18644 } 18645 18646 if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) { 18647 unfreezePackage(packageName); 18648 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 18649 "Not enough free space to move"); 18650 } 18651 18652 mMoveCallbacks.notifyStatusChanged(moveId, 10); 18653 18654 final CountDownLatch installedLatch = new CountDownLatch(1); 18655 final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() { 18656 @Override 18657 public void onUserActionRequired(Intent intent) throws RemoteException { 18658 throw new IllegalStateException(); 18659 } 18660 18661 @Override 18662 public void onPackageInstalled(String basePackageName, int returnCode, String msg, 18663 Bundle extras) throws RemoteException { 18664 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: " 18665 + PackageManager.installStatusToString(returnCode, msg)); 18666 18667 installedLatch.countDown(); 18668 18669 // Regardless of success or failure of the move operation, 18670 // always unfreeze the package 18671 unfreezePackage(packageName); 18672 18673 final int status = PackageManager.installStatusToPublicStatus(returnCode); 18674 switch (status) { 18675 case PackageInstaller.STATUS_SUCCESS: 18676 mMoveCallbacks.notifyStatusChanged(moveId, 18677 PackageManager.MOVE_SUCCEEDED); 18678 break; 18679 case PackageInstaller.STATUS_FAILURE_STORAGE: 18680 mMoveCallbacks.notifyStatusChanged(moveId, 18681 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE); 18682 break; 18683 default: 18684 mMoveCallbacks.notifyStatusChanged(moveId, 18685 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 18686 break; 18687 } 18688 } 18689 }; 18690 18691 final MoveInfo move; 18692 if (moveCompleteApp) { 18693 // Kick off a thread to report progress estimates 18694 new Thread() { 18695 @Override 18696 public void run() { 18697 while (true) { 18698 try { 18699 if (installedLatch.await(1, TimeUnit.SECONDS)) { 18700 break; 18701 } 18702 } catch (InterruptedException ignored) { 18703 } 18704 18705 final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace(); 18706 final int progress = 10 + (int) MathUtils.constrain( 18707 ((deltaFreeBytes * 80) / sizeBytes), 0, 80); 18708 mMoveCallbacks.notifyStatusChanged(moveId, progress); 18709 } 18710 } 18711 }.start(); 18712 18713 final String dataAppName = codeFile.getName(); 18714 move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName, 18715 dataAppName, appId, seinfo, targetSdkVersion); 18716 } else { 18717 move = null; 18718 } 18719 18720 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 18721 18722 final Message msg = mHandler.obtainMessage(INIT_COPY); 18723 final OriginInfo origin = OriginInfo.fromExistingFile(codeFile); 18724 final InstallParams params = new InstallParams(origin, move, installObserver, installFlags, 18725 installerPackageName, volumeUuid, null /*verificationInfo*/, user, 18726 packageAbiOverride, null); 18727 params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params)); 18728 msg.obj = params; 18729 18730 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage", 18731 System.identityHashCode(msg.obj)); 18732 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 18733 System.identityHashCode(msg.obj)); 18734 18735 mHandler.sendMessage(msg); 18736 } 18737 18738 @Override 18739 public int movePrimaryStorage(String volumeUuid) throws RemoteException { 18740 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 18741 18742 final int realMoveId = mNextMoveId.getAndIncrement(); 18743 final Bundle extras = new Bundle(); 18744 extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid); 18745 mMoveCallbacks.notifyCreated(realMoveId, extras); 18746 18747 final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() { 18748 @Override 18749 public void onCreated(int moveId, Bundle extras) { 18750 // Ignored 18751 } 18752 18753 @Override 18754 public void onStatusChanged(int moveId, int status, long estMillis) { 18755 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis); 18756 } 18757 }; 18758 18759 final StorageManager storage = mContext.getSystemService(StorageManager.class); 18760 storage.setPrimaryStorageUuid(volumeUuid, callback); 18761 return realMoveId; 18762 } 18763 18764 @Override 18765 public int getMoveStatus(int moveId) { 18766 mContext.enforceCallingOrSelfPermission( 18767 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 18768 return mMoveCallbacks.mLastStatus.get(moveId); 18769 } 18770 18771 @Override 18772 public void registerMoveCallback(IPackageMoveObserver callback) { 18773 mContext.enforceCallingOrSelfPermission( 18774 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 18775 mMoveCallbacks.register(callback); 18776 } 18777 18778 @Override 18779 public void unregisterMoveCallback(IPackageMoveObserver callback) { 18780 mContext.enforceCallingOrSelfPermission( 18781 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 18782 mMoveCallbacks.unregister(callback); 18783 } 18784 18785 @Override 18786 public boolean setInstallLocation(int loc) { 18787 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, 18788 null); 18789 if (getInstallLocation() == loc) { 18790 return true; 18791 } 18792 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL 18793 || loc == PackageHelper.APP_INSTALL_EXTERNAL) { 18794 android.provider.Settings.Global.putInt(mContext.getContentResolver(), 18795 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc); 18796 return true; 18797 } 18798 return false; 18799 } 18800 18801 @Override 18802 public int getInstallLocation() { 18803 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 18804 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, 18805 PackageHelper.APP_INSTALL_AUTO); 18806 } 18807 18808 /** Called by UserManagerService */ 18809 void cleanUpUser(UserManagerService userManager, int userHandle) { 18810 synchronized (mPackages) { 18811 mDirtyUsers.remove(userHandle); 18812 mUserNeedsBadging.delete(userHandle); 18813 mSettings.removeUserLPw(userHandle); 18814 mPendingBroadcasts.remove(userHandle); 18815 mEphemeralApplicationRegistry.onUserRemovedLPw(userHandle); 18816 } 18817 synchronized (mInstallLock) { 18818 final StorageManager storage = mContext.getSystemService(StorageManager.class); 18819 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 18820 final String volumeUuid = vol.getFsUuid(); 18821 if (DEBUG_INSTALL) Slog.d(TAG, "Removing user data on volume " + volumeUuid); 18822 try { 18823 mInstaller.removeUserDataDirs(volumeUuid, userHandle); 18824 } catch (InstallerException e) { 18825 Slog.w(TAG, "Failed to remove user data", e); 18826 } 18827 } 18828 synchronized (mPackages) { 18829 removeUnusedPackagesLILPw(userManager, userHandle); 18830 } 18831 } 18832 } 18833 18834 /** 18835 * We're removing userHandle and would like to remove any downloaded packages 18836 * that are no longer in use by any other user. 18837 * @param userHandle the user being removed 18838 */ 18839 private void removeUnusedPackagesLILPw(UserManagerService userManager, final int userHandle) { 18840 final boolean DEBUG_CLEAN_APKS = false; 18841 int [] users = userManager.getUserIds(); 18842 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 18843 while (psit.hasNext()) { 18844 PackageSetting ps = psit.next(); 18845 if (ps.pkg == null) { 18846 continue; 18847 } 18848 final String packageName = ps.pkg.packageName; 18849 // Skip over if system app 18850 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) { 18851 continue; 18852 } 18853 if (DEBUG_CLEAN_APKS) { 18854 Slog.i(TAG, "Checking package " + packageName); 18855 } 18856 boolean keep = shouldKeepUninstalledPackageLPr(packageName); 18857 if (keep) { 18858 if (DEBUG_CLEAN_APKS) { 18859 Slog.i(TAG, " Keeping package " + packageName + " - requested by DO"); 18860 } 18861 } else { 18862 for (int i = 0; i < users.length; i++) { 18863 if (users[i] != userHandle && ps.getInstalled(users[i])) { 18864 keep = true; 18865 if (DEBUG_CLEAN_APKS) { 18866 Slog.i(TAG, " Keeping package " + packageName + " for user " 18867 + users[i]); 18868 } 18869 break; 18870 } 18871 } 18872 } 18873 if (!keep) { 18874 if (DEBUG_CLEAN_APKS) { 18875 Slog.i(TAG, " Removing package " + packageName); 18876 } 18877 mHandler.post(new Runnable() { 18878 public void run() { 18879 deletePackageX(packageName, userHandle, 0); 18880 } //end run 18881 }); 18882 } 18883 } 18884 } 18885 18886 /** Called by UserManagerService */ 18887 void createNewUser(int userHandle) { 18888 synchronized (mInstallLock) { 18889 try { 18890 mInstaller.createUserConfig(userHandle); 18891 } catch (InstallerException e) { 18892 Slog.w(TAG, "Failed to create user config", e); 18893 } 18894 mSettings.createNewUserLI(this, mInstaller, userHandle); 18895 } 18896 synchronized (mPackages) { 18897 applyFactoryDefaultBrowserLPw(userHandle); 18898 primeDomainVerificationsLPw(userHandle); 18899 } 18900 } 18901 18902 void newUserCreated(final int userHandle) { 18903 mDefaultPermissionPolicy.grantDefaultPermissions(userHandle); 18904 // If permission review for legacy apps is required, we represent 18905 // dagerous permissions for such apps as always granted runtime 18906 // permissions to keep per user flag state whether review is needed. 18907 // Hence, if a new user is added we have to propagate dangerous 18908 // permission grants for these legacy apps. 18909 if (Build.PERMISSIONS_REVIEW_REQUIRED) { 18910 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL 18911 | UPDATE_PERMISSIONS_REPLACE_ALL); 18912 } 18913 } 18914 18915 @Override 18916 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException { 18917 mContext.enforceCallingOrSelfPermission( 18918 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 18919 "Only package verification agents can read the verifier device identity"); 18920 18921 synchronized (mPackages) { 18922 return mSettings.getVerifierDeviceIdentityLPw(); 18923 } 18924 } 18925 18926 @Override 18927 public void setPermissionEnforced(String permission, boolean enforced) { 18928 // TODO: Now that we no longer change GID for storage, this should to away. 18929 mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 18930 "setPermissionEnforced"); 18931 if (READ_EXTERNAL_STORAGE.equals(permission)) { 18932 synchronized (mPackages) { 18933 if (mSettings.mReadExternalStorageEnforced == null 18934 || mSettings.mReadExternalStorageEnforced != enforced) { 18935 mSettings.mReadExternalStorageEnforced = enforced; 18936 mSettings.writeLPr(); 18937 } 18938 } 18939 // kill any non-foreground processes so we restart them and 18940 // grant/revoke the GID. 18941 final IActivityManager am = ActivityManagerNative.getDefault(); 18942 if (am != null) { 18943 final long token = Binder.clearCallingIdentity(); 18944 try { 18945 am.killProcessesBelowForeground("setPermissionEnforcement"); 18946 } catch (RemoteException e) { 18947 } finally { 18948 Binder.restoreCallingIdentity(token); 18949 } 18950 } 18951 } else { 18952 throw new IllegalArgumentException("No selective enforcement for " + permission); 18953 } 18954 } 18955 18956 @Override 18957 @Deprecated 18958 public boolean isPermissionEnforced(String permission) { 18959 return true; 18960 } 18961 18962 @Override 18963 public boolean isStorageLow() { 18964 final long token = Binder.clearCallingIdentity(); 18965 try { 18966 final DeviceStorageMonitorInternal 18967 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 18968 if (dsm != null) { 18969 return dsm.isMemoryLow(); 18970 } else { 18971 return false; 18972 } 18973 } finally { 18974 Binder.restoreCallingIdentity(token); 18975 } 18976 } 18977 18978 @Override 18979 public IPackageInstaller getPackageInstaller() { 18980 return mInstallerService; 18981 } 18982 18983 private boolean userNeedsBadging(int userId) { 18984 int index = mUserNeedsBadging.indexOfKey(userId); 18985 if (index < 0) { 18986 final UserInfo userInfo; 18987 final long token = Binder.clearCallingIdentity(); 18988 try { 18989 userInfo = sUserManager.getUserInfo(userId); 18990 } finally { 18991 Binder.restoreCallingIdentity(token); 18992 } 18993 final boolean b; 18994 if (userInfo != null && userInfo.isManagedProfile()) { 18995 b = true; 18996 } else { 18997 b = false; 18998 } 18999 mUserNeedsBadging.put(userId, b); 19000 return b; 19001 } 19002 return mUserNeedsBadging.valueAt(index); 19003 } 19004 19005 @Override 19006 public KeySet getKeySetByAlias(String packageName, String alias) { 19007 if (packageName == null || alias == null) { 19008 return null; 19009 } 19010 synchronized(mPackages) { 19011 final PackageParser.Package pkg = mPackages.get(packageName); 19012 if (pkg == null) { 19013 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 19014 throw new IllegalArgumentException("Unknown package: " + packageName); 19015 } 19016 KeySetManagerService ksms = mSettings.mKeySetManagerService; 19017 return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias)); 19018 } 19019 } 19020 19021 @Override 19022 public KeySet getSigningKeySet(String packageName) { 19023 if (packageName == null) { 19024 return null; 19025 } 19026 synchronized(mPackages) { 19027 final PackageParser.Package pkg = mPackages.get(packageName); 19028 if (pkg == null) { 19029 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 19030 throw new IllegalArgumentException("Unknown package: " + packageName); 19031 } 19032 if (pkg.applicationInfo.uid != Binder.getCallingUid() 19033 && Process.SYSTEM_UID != Binder.getCallingUid()) { 19034 throw new SecurityException("May not access signing KeySet of other apps."); 19035 } 19036 KeySetManagerService ksms = mSettings.mKeySetManagerService; 19037 return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName)); 19038 } 19039 } 19040 19041 @Override 19042 public boolean isPackageSignedByKeySet(String packageName, KeySet ks) { 19043 if (packageName == null || ks == null) { 19044 return false; 19045 } 19046 synchronized(mPackages) { 19047 final PackageParser.Package pkg = mPackages.get(packageName); 19048 if (pkg == null) { 19049 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 19050 throw new IllegalArgumentException("Unknown package: " + packageName); 19051 } 19052 IBinder ksh = ks.getToken(); 19053 if (ksh instanceof KeySetHandle) { 19054 KeySetManagerService ksms = mSettings.mKeySetManagerService; 19055 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh); 19056 } 19057 return false; 19058 } 19059 } 19060 19061 @Override 19062 public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) { 19063 if (packageName == null || ks == null) { 19064 return false; 19065 } 19066 synchronized(mPackages) { 19067 final PackageParser.Package pkg = mPackages.get(packageName); 19068 if (pkg == null) { 19069 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 19070 throw new IllegalArgumentException("Unknown package: " + packageName); 19071 } 19072 IBinder ksh = ks.getToken(); 19073 if (ksh instanceof KeySetHandle) { 19074 KeySetManagerService ksms = mSettings.mKeySetManagerService; 19075 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh); 19076 } 19077 return false; 19078 } 19079 } 19080 19081 private void deletePackageIfUnusedLPr(final String packageName) { 19082 PackageSetting ps = mSettings.mPackages.get(packageName); 19083 if (ps == null) { 19084 return; 19085 } 19086 if (!ps.isAnyInstalled(sUserManager.getUserIds())) { 19087 // TODO Implement atomic delete if package is unused 19088 // It is currently possible that the package will be deleted even if it is installed 19089 // after this method returns. 19090 mHandler.post(new Runnable() { 19091 public void run() { 19092 deletePackageX(packageName, 0, PackageManager.DELETE_ALL_USERS); 19093 } 19094 }); 19095 } 19096 } 19097 19098 /** 19099 * Check and throw if the given before/after packages would be considered a 19100 * downgrade. 19101 */ 19102 private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after) 19103 throws PackageManagerException { 19104 if (after.versionCode < before.mVersionCode) { 19105 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 19106 "Update version code " + after.versionCode + " is older than current " 19107 + before.mVersionCode); 19108 } else if (after.versionCode == before.mVersionCode) { 19109 if (after.baseRevisionCode < before.baseRevisionCode) { 19110 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 19111 "Update base revision code " + after.baseRevisionCode 19112 + " is older than current " + before.baseRevisionCode); 19113 } 19114 19115 if (!ArrayUtils.isEmpty(after.splitNames)) { 19116 for (int i = 0; i < after.splitNames.length; i++) { 19117 final String splitName = after.splitNames[i]; 19118 final int j = ArrayUtils.indexOf(before.splitNames, splitName); 19119 if (j != -1) { 19120 if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) { 19121 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 19122 "Update split " + splitName + " revision code " 19123 + after.splitRevisionCodes[i] + " is older than current " 19124 + before.splitRevisionCodes[j]); 19125 } 19126 } 19127 } 19128 } 19129 } 19130 } 19131 19132 private static class MoveCallbacks extends Handler { 19133 private static final int MSG_CREATED = 1; 19134 private static final int MSG_STATUS_CHANGED = 2; 19135 19136 private final RemoteCallbackList<IPackageMoveObserver> 19137 mCallbacks = new RemoteCallbackList<>(); 19138 19139 private final SparseIntArray mLastStatus = new SparseIntArray(); 19140 19141 public MoveCallbacks(Looper looper) { 19142 super(looper); 19143 } 19144 19145 public void register(IPackageMoveObserver callback) { 19146 mCallbacks.register(callback); 19147 } 19148 19149 public void unregister(IPackageMoveObserver callback) { 19150 mCallbacks.unregister(callback); 19151 } 19152 19153 @Override 19154 public void handleMessage(Message msg) { 19155 final SomeArgs args = (SomeArgs) msg.obj; 19156 final int n = mCallbacks.beginBroadcast(); 19157 for (int i = 0; i < n; i++) { 19158 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i); 19159 try { 19160 invokeCallback(callback, msg.what, args); 19161 } catch (RemoteException ignored) { 19162 } 19163 } 19164 mCallbacks.finishBroadcast(); 19165 args.recycle(); 19166 } 19167 19168 private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args) 19169 throws RemoteException { 19170 switch (what) { 19171 case MSG_CREATED: { 19172 callback.onCreated(args.argi1, (Bundle) args.arg2); 19173 break; 19174 } 19175 case MSG_STATUS_CHANGED: { 19176 callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3); 19177 break; 19178 } 19179 } 19180 } 19181 19182 private void notifyCreated(int moveId, Bundle extras) { 19183 Slog.v(TAG, "Move " + moveId + " created " + extras.toString()); 19184 19185 final SomeArgs args = SomeArgs.obtain(); 19186 args.argi1 = moveId; 19187 args.arg2 = extras; 19188 obtainMessage(MSG_CREATED, args).sendToTarget(); 19189 } 19190 19191 private void notifyStatusChanged(int moveId, int status) { 19192 notifyStatusChanged(moveId, status, -1); 19193 } 19194 19195 private void notifyStatusChanged(int moveId, int status, long estMillis) { 19196 Slog.v(TAG, "Move " + moveId + " status " + status); 19197 19198 final SomeArgs args = SomeArgs.obtain(); 19199 args.argi1 = moveId; 19200 args.argi2 = status; 19201 args.arg3 = estMillis; 19202 obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget(); 19203 19204 synchronized (mLastStatus) { 19205 mLastStatus.put(moveId, status); 19206 } 19207 } 19208 } 19209 19210 private final static class OnPermissionChangeListeners extends Handler { 19211 private static final int MSG_ON_PERMISSIONS_CHANGED = 1; 19212 19213 private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners = 19214 new RemoteCallbackList<>(); 19215 19216 public OnPermissionChangeListeners(Looper looper) { 19217 super(looper); 19218 } 19219 19220 @Override 19221 public void handleMessage(Message msg) { 19222 switch (msg.what) { 19223 case MSG_ON_PERMISSIONS_CHANGED: { 19224 final int uid = msg.arg1; 19225 handleOnPermissionsChanged(uid); 19226 } break; 19227 } 19228 } 19229 19230 public void addListenerLocked(IOnPermissionsChangeListener listener) { 19231 mPermissionListeners.register(listener); 19232 19233 } 19234 19235 public void removeListenerLocked(IOnPermissionsChangeListener listener) { 19236 mPermissionListeners.unregister(listener); 19237 } 19238 19239 public void onPermissionsChanged(int uid) { 19240 if (mPermissionListeners.getRegisteredCallbackCount() > 0) { 19241 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget(); 19242 } 19243 } 19244 19245 private void handleOnPermissionsChanged(int uid) { 19246 final int count = mPermissionListeners.beginBroadcast(); 19247 try { 19248 for (int i = 0; i < count; i++) { 19249 IOnPermissionsChangeListener callback = mPermissionListeners 19250 .getBroadcastItem(i); 19251 try { 19252 callback.onPermissionsChanged(uid); 19253 } catch (RemoteException e) { 19254 Log.e(TAG, "Permission listener is dead", e); 19255 } 19256 } 19257 } finally { 19258 mPermissionListeners.finishBroadcast(); 19259 } 19260 } 19261 } 19262 19263 private class PackageManagerInternalImpl extends PackageManagerInternal { 19264 @Override 19265 public void setLocationPackagesProvider(PackagesProvider provider) { 19266 synchronized (mPackages) { 19267 mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider); 19268 } 19269 } 19270 19271 @Override 19272 public void setVoiceInteractionPackagesProvider(PackagesProvider provider) { 19273 synchronized (mPackages) { 19274 mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider); 19275 } 19276 } 19277 19278 @Override 19279 public void setSmsAppPackagesProvider(PackagesProvider provider) { 19280 synchronized (mPackages) { 19281 mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider); 19282 } 19283 } 19284 19285 @Override 19286 public void setDialerAppPackagesProvider(PackagesProvider provider) { 19287 synchronized (mPackages) { 19288 mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider); 19289 } 19290 } 19291 19292 @Override 19293 public void setSimCallManagerPackagesProvider(PackagesProvider provider) { 19294 synchronized (mPackages) { 19295 mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider); 19296 } 19297 } 19298 19299 @Override 19300 public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) { 19301 synchronized (mPackages) { 19302 mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider); 19303 } 19304 } 19305 19306 @Override 19307 public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) { 19308 synchronized (mPackages) { 19309 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr( 19310 packageName, userId); 19311 } 19312 } 19313 19314 @Override 19315 public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) { 19316 synchronized (mPackages) { 19317 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr( 19318 packageName, userId); 19319 } 19320 } 19321 19322 @Override 19323 public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) { 19324 synchronized (mPackages) { 19325 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr( 19326 packageName, userId); 19327 } 19328 } 19329 19330 @Override 19331 public void setKeepUninstalledPackages(final List<String> packageList) { 19332 Preconditions.checkNotNull(packageList); 19333 List<String> removedFromList = null; 19334 synchronized (mPackages) { 19335 if (mKeepUninstalledPackages != null) { 19336 final int packagesCount = mKeepUninstalledPackages.size(); 19337 for (int i = 0; i < packagesCount; i++) { 19338 String oldPackage = mKeepUninstalledPackages.get(i); 19339 if (packageList != null && packageList.contains(oldPackage)) { 19340 continue; 19341 } 19342 if (removedFromList == null) { 19343 removedFromList = new ArrayList<>(); 19344 } 19345 removedFromList.add(oldPackage); 19346 } 19347 } 19348 mKeepUninstalledPackages = new ArrayList<>(packageList); 19349 if (removedFromList != null) { 19350 final int removedCount = removedFromList.size(); 19351 for (int i = 0; i < removedCount; i++) { 19352 deletePackageIfUnusedLPr(removedFromList.get(i)); 19353 } 19354 } 19355 } 19356 } 19357 19358 @Override 19359 public boolean isPermissionsReviewRequired(String packageName, int userId) { 19360 synchronized (mPackages) { 19361 // If we do not support permission review, done. 19362 if (!Build.PERMISSIONS_REVIEW_REQUIRED) { 19363 return false; 19364 } 19365 19366 PackageSetting packageSetting = mSettings.mPackages.get(packageName); 19367 if (packageSetting == null) { 19368 return false; 19369 } 19370 19371 // Permission review applies only to apps not supporting the new permission model. 19372 if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) { 19373 return false; 19374 } 19375 19376 // Legacy apps have the permission and get user consent on launch. 19377 PermissionsState permissionsState = packageSetting.getPermissionsState(); 19378 return permissionsState.isPermissionReviewRequired(userId); 19379 } 19380 } 19381 19382 @Override 19383 public ApplicationInfo getApplicationInfo(String packageName, int userId) { 19384 return PackageManagerService.this.getApplicationInfo(packageName, 0 /*flags*/, userId); 19385 } 19386 19387 @Override 19388 public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, 19389 int userId) { 19390 return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId); 19391 } 19392 } 19393 19394 @Override 19395 public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) { 19396 enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps"); 19397 synchronized (mPackages) { 19398 final long identity = Binder.clearCallingIdentity(); 19399 try { 19400 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr( 19401 packageNames, userId); 19402 } finally { 19403 Binder.restoreCallingIdentity(identity); 19404 } 19405 } 19406 } 19407 19408 private static void enforceSystemOrPhoneCaller(String tag) { 19409 int callingUid = Binder.getCallingUid(); 19410 if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) { 19411 throw new SecurityException( 19412 "Cannot call " + tag + " from UID " + callingUid); 19413 } 19414 } 19415 19416 boolean isHistoricalPackageUsageAvailable() { 19417 return mPackageUsage.isHistoricalPackageUsageAvailable(); 19418 } 19419 19420 /** 19421 * Return a <b>copy</b> of the collection of packages known to the package manager. 19422 * @return A copy of the values of mPackages. 19423 */ 19424 Collection<PackageParser.Package> getPackages() { 19425 synchronized (mPackages) { 19426 return new ArrayList<>(mPackages.values()); 19427 } 19428 } 19429} 19430