PackageManagerService.java revision 39bfee5e3674faea992c32204abc1c03429b8cda
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_DISABLED_COMPONENTS; 65import static android.content.pm.PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE; 66import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY; 67import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES; 68import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN; 69import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST; 70import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR; 71import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING; 72import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE; 73import static android.content.pm.PackageManager.PERMISSION_DENIED; 74import static android.content.pm.PackageManager.PERMISSION_GRANTED; 75import static android.content.pm.PackageParser.PARSE_IS_PRIVILEGED; 76import static android.content.pm.PackageParser.isApkFile; 77import static android.os.Process.PACKAGE_INFO_GID; 78import static android.os.Process.SYSTEM_UID; 79import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; 80import static android.system.OsConstants.O_CREAT; 81import static android.system.OsConstants.O_RDWR; 82 83import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE; 84import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT; 85import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME; 86import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME; 87import static com.android.internal.util.ArrayUtils.appendInt; 88import static com.android.server.pm.Installer.DEXOPT_PUBLIC; 89import static com.android.server.pm.InstructionSets.getAppDexInstructionSets; 90import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet; 91import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets; 92import static com.android.server.pm.InstructionSets.getPreferredInstructionSet; 93import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet; 94import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE; 95import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS; 96import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED; 97 98import android.Manifest; 99import android.annotation.NonNull; 100import android.annotation.Nullable; 101import android.app.ActivityManager; 102import android.app.ActivityManagerNative; 103import android.app.IActivityManager; 104import android.app.admin.IDevicePolicyManager; 105import android.app.backup.IBackupManager; 106import android.content.BroadcastReceiver; 107import android.content.ComponentName; 108import android.content.Context; 109import android.content.IIntentReceiver; 110import android.content.Intent; 111import android.content.IntentFilter; 112import android.content.IntentSender; 113import android.content.IntentSender.SendIntentException; 114import android.content.ServiceConnection; 115import android.content.pm.ActivityInfo; 116import android.content.pm.ApplicationInfo; 117import android.content.pm.AppsQueryHelper; 118import android.content.pm.ComponentInfo; 119import android.content.pm.EphemeralApplicationInfo; 120import android.content.pm.EphemeralResolveInfo; 121import android.content.pm.EphemeralResolveInfo.EphemeralResolveIntentInfo; 122import android.content.pm.FeatureInfo; 123import android.content.pm.IOnPermissionsChangeListener; 124import android.content.pm.IPackageDataObserver; 125import android.content.pm.IPackageDeleteObserver; 126import android.content.pm.IPackageDeleteObserver2; 127import android.content.pm.IPackageInstallObserver2; 128import android.content.pm.IPackageInstaller; 129import android.content.pm.IPackageManager; 130import android.content.pm.IPackageMoveObserver; 131import android.content.pm.IPackageStatsObserver; 132import android.content.pm.InstrumentationInfo; 133import android.content.pm.IntentFilterVerificationInfo; 134import android.content.pm.KeySet; 135import android.content.pm.PackageCleanItem; 136import android.content.pm.PackageInfo; 137import android.content.pm.PackageInfoLite; 138import android.content.pm.PackageInstaller; 139import android.content.pm.PackageManager; 140import android.content.pm.PackageManager.LegacyPackageDeleteObserver; 141import android.content.pm.PackageManagerInternal; 142import android.content.pm.PackageParser; 143import android.content.pm.PackageParser.ActivityIntentInfo; 144import android.content.pm.PackageParser.PackageLite; 145import android.content.pm.PackageParser.PackageParserException; 146import android.content.pm.PackageStats; 147import android.content.pm.PackageUserState; 148import android.content.pm.ParceledListSlice; 149import android.content.pm.PermissionGroupInfo; 150import android.content.pm.PermissionInfo; 151import android.content.pm.ProviderInfo; 152import android.content.pm.ResolveInfo; 153import android.content.pm.ServiceInfo; 154import android.content.pm.Signature; 155import android.content.pm.UserInfo; 156import android.content.pm.VerifierDeviceIdentity; 157import android.content.pm.VerifierInfo; 158import android.content.res.Resources; 159import android.graphics.Bitmap; 160import android.hardware.display.DisplayManager; 161import android.net.Uri; 162import android.os.Binder; 163import android.os.Build; 164import android.os.Bundle; 165import android.os.Debug; 166import android.os.Environment; 167import android.os.Environment.UserEnvironment; 168import android.os.FileUtils; 169import android.os.Handler; 170import android.os.IBinder; 171import android.os.Looper; 172import android.os.Message; 173import android.os.Parcel; 174import android.os.ParcelFileDescriptor; 175import android.os.Parcelable; 176import android.os.Process; 177import android.os.RemoteCallbackList; 178import android.os.RemoteException; 179import android.os.ResultReceiver; 180import android.os.SELinux; 181import android.os.ServiceManager; 182import android.os.SystemClock; 183import android.os.SystemProperties; 184import android.os.Trace; 185import android.os.UserHandle; 186import android.os.UserManager; 187import android.os.storage.IMountService; 188import android.os.storage.MountServiceInternal; 189import android.os.storage.StorageEventListener; 190import android.os.storage.StorageManager; 191import android.os.storage.VolumeInfo; 192import android.os.storage.VolumeRecord; 193import android.security.KeyStore; 194import android.security.SystemKeyStore; 195import android.system.ErrnoException; 196import android.system.Os; 197import android.text.TextUtils; 198import android.text.format.DateUtils; 199import android.util.ArrayMap; 200import android.util.ArraySet; 201import android.util.AtomicFile; 202import android.util.DisplayMetrics; 203import android.util.EventLog; 204import android.util.ExceptionUtils; 205import android.util.Log; 206import android.util.LogPrinter; 207import android.util.MathUtils; 208import android.util.PrintStreamPrinter; 209import android.util.Slog; 210import android.util.SparseArray; 211import android.util.SparseBooleanArray; 212import android.util.SparseIntArray; 213import android.util.Xml; 214import android.view.Display; 215 216import com.android.internal.R; 217import com.android.internal.annotations.GuardedBy; 218import com.android.internal.app.IMediaContainerService; 219import com.android.internal.app.ResolverActivity; 220import com.android.internal.content.NativeLibraryHelper; 221import com.android.internal.content.PackageHelper; 222import com.android.internal.os.IParcelFileDescriptorFactory; 223import com.android.internal.os.InstallerConnection.InstallerException; 224import com.android.internal.os.SomeArgs; 225import com.android.internal.os.Zygote; 226import com.android.internal.util.ArrayUtils; 227import com.android.internal.util.FastPrintWriter; 228import com.android.internal.util.FastXmlSerializer; 229import com.android.internal.util.IndentingPrintWriter; 230import com.android.internal.util.Preconditions; 231import com.android.internal.util.XmlUtils; 232import com.android.server.EventLogTags; 233import com.android.server.FgThread; 234import com.android.server.IntentResolver; 235import com.android.server.LocalServices; 236import com.android.server.ServiceThread; 237import com.android.server.SystemConfig; 238import com.android.server.Watchdog; 239import com.android.server.pm.PermissionsState.PermissionState; 240import com.android.server.pm.Settings.DatabaseVersion; 241import com.android.server.pm.Settings.VersionInfo; 242import com.android.server.storage.DeviceStorageMonitorInternal; 243 244import dalvik.system.DexFile; 245import dalvik.system.VMRuntime; 246 247import libcore.io.IoUtils; 248import libcore.util.EmptyArray; 249 250import org.xmlpull.v1.XmlPullParser; 251import org.xmlpull.v1.XmlPullParserException; 252import org.xmlpull.v1.XmlSerializer; 253 254import java.io.BufferedInputStream; 255import java.io.BufferedOutputStream; 256import java.io.BufferedReader; 257import java.io.ByteArrayInputStream; 258import java.io.ByteArrayOutputStream; 259import java.io.File; 260import java.io.FileDescriptor; 261import java.io.FileNotFoundException; 262import java.io.FileOutputStream; 263import java.io.FileReader; 264import java.io.FilenameFilter; 265import java.io.IOException; 266import java.io.InputStream; 267import java.io.PrintWriter; 268import java.nio.charset.StandardCharsets; 269import java.security.MessageDigest; 270import java.security.NoSuchAlgorithmException; 271import java.security.PublicKey; 272import java.security.cert.CertificateEncodingException; 273import java.security.cert.CertificateException; 274import java.text.SimpleDateFormat; 275import java.util.ArrayList; 276import java.util.Arrays; 277import java.util.Collection; 278import java.util.Collections; 279import java.util.Comparator; 280import java.util.Date; 281import java.util.HashSet; 282import java.util.Iterator; 283import java.util.List; 284import java.util.Map; 285import java.util.Objects; 286import java.util.Set; 287import java.util.concurrent.CountDownLatch; 288import java.util.concurrent.TimeUnit; 289import java.util.concurrent.atomic.AtomicBoolean; 290import java.util.concurrent.atomic.AtomicInteger; 291import java.util.concurrent.atomic.AtomicLong; 292 293/** 294 * Keep track of all those .apks everywhere. 295 * 296 * This is very central to the platform's security; please run the unit 297 * tests whenever making modifications here: 298 * 299runtest -c android.content.pm.PackageManagerTests frameworks-core 300 * 301 * {@hide} 302 */ 303public class PackageManagerService extends IPackageManager.Stub { 304 static final String TAG = "PackageManager"; 305 static final boolean DEBUG_SETTINGS = false; 306 static final boolean DEBUG_PREFERRED = false; 307 static final boolean DEBUG_UPGRADE = false; 308 static final boolean DEBUG_DOMAIN_VERIFICATION = false; 309 private static final boolean DEBUG_BACKUP = false; 310 private static final boolean DEBUG_INSTALL = false; 311 private static final boolean DEBUG_REMOVE = false; 312 private static final boolean DEBUG_BROADCASTS = false; 313 private static final boolean DEBUG_SHOW_INFO = false; 314 private static final boolean DEBUG_PACKAGE_INFO = false; 315 private static final boolean DEBUG_INTENT_MATCHING = false; 316 private static final boolean DEBUG_PACKAGE_SCANNING = false; 317 private static final boolean DEBUG_VERIFY = false; 318 319 // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService 320 // and PackageDexOptimizer. All these classes have their own flag to allow switching a single 321 // user, but by default initialize to this. 322 static final boolean DEBUG_DEXOPT = false; 323 324 private static final boolean DEBUG_ABI_SELECTION = false; 325 private static final boolean DEBUG_EPHEMERAL = false; 326 private static final boolean DEBUG_TRIAGED_MISSING = false; 327 private static final boolean DEBUG_APP_DATA = false; 328 329 static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false; 330 331 private static final boolean DISABLE_EPHEMERAL_APPS = true; 332 333 private static final int RADIO_UID = Process.PHONE_UID; 334 private static final int LOG_UID = Process.LOG_UID; 335 private static final int NFC_UID = Process.NFC_UID; 336 private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID; 337 private static final int SHELL_UID = Process.SHELL_UID; 338 339 // Cap the size of permission trees that 3rd party apps can define 340 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768; // characters of text 341 342 // Suffix used during package installation when copying/moving 343 // package apks to install directory. 344 private static final String INSTALL_PACKAGE_SUFFIX = "-"; 345 346 static final int SCAN_NO_DEX = 1<<1; 347 static final int SCAN_FORCE_DEX = 1<<2; 348 static final int SCAN_UPDATE_SIGNATURE = 1<<3; 349 static final int SCAN_NEW_INSTALL = 1<<4; 350 static final int SCAN_NO_PATHS = 1<<5; 351 static final int SCAN_UPDATE_TIME = 1<<6; 352 static final int SCAN_DEFER_DEX = 1<<7; 353 static final int SCAN_BOOTING = 1<<8; 354 static final int SCAN_TRUSTED_OVERLAY = 1<<9; 355 static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10; 356 static final int SCAN_REPLACING = 1<<11; 357 static final int SCAN_REQUIRE_KNOWN = 1<<12; 358 static final int SCAN_MOVE = 1<<13; 359 static final int SCAN_INITIAL = 1<<14; 360 static final int SCAN_CHECK_ONLY = 1<<15; 361 static final int SCAN_DONT_KILL_APP = 1<<17; 362 363 static final int REMOVE_CHATTY = 1<<16; 364 365 private static final int[] EMPTY_INT_ARRAY = new int[0]; 366 367 /** 368 * Timeout (in milliseconds) after which the watchdog should declare that 369 * our handler thread is wedged. The usual default for such things is one 370 * minute but we sometimes do very lengthy I/O operations on this thread, 371 * such as installing multi-gigabyte applications, so ours needs to be longer. 372 */ 373 private static final long WATCHDOG_TIMEOUT = 1000*60*10; // ten minutes 374 375 /** 376 * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim 377 * be run on this device. We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL 378 * settings entry if available, otherwise we use the hardcoded default. If it's been 379 * more than this long since the last fstrim, we force one during the boot sequence. 380 * 381 * This backstops other fstrim scheduling: if the device is alive at midnight+idle, 382 * one gets run at the next available charging+idle time. This final mandatory 383 * no-fstrim check kicks in only of the other scheduling criteria is never met. 384 */ 385 private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS; 386 387 /** 388 * Whether verification is enabled by default. 389 */ 390 private static final boolean DEFAULT_VERIFY_ENABLE = true; 391 392 /** 393 * The default maximum time to wait for the verification agent to return in 394 * milliseconds. 395 */ 396 private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000; 397 398 /** 399 * The default response for package verification timeout. 400 * 401 * This can be either PackageManager.VERIFICATION_ALLOW or 402 * PackageManager.VERIFICATION_REJECT. 403 */ 404 private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW; 405 406 static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer"; 407 408 static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName( 409 DEFAULT_CONTAINER_PACKAGE, 410 "com.android.defcontainer.DefaultContainerService"); 411 412 private static final String KILL_APP_REASON_GIDS_CHANGED = 413 "permission grant or revoke changed gids"; 414 415 private static final String KILL_APP_REASON_PERMISSIONS_REVOKED = 416 "permissions revoked"; 417 418 private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive"; 419 420 private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay"; 421 422 /** Permission grant: not grant the permission. */ 423 private static final int GRANT_DENIED = 1; 424 425 /** Permission grant: grant the permission as an install permission. */ 426 private static final int GRANT_INSTALL = 2; 427 428 /** Permission grant: grant the permission as a runtime one. */ 429 private static final int GRANT_RUNTIME = 3; 430 431 /** Permission grant: grant as runtime a permission that was granted as an install time one. */ 432 private static final int GRANT_UPGRADE = 4; 433 434 /** Canonical intent used to identify what counts as a "web browser" app */ 435 private static final Intent sBrowserIntent; 436 static { 437 sBrowserIntent = new Intent(); 438 sBrowserIntent.setAction(Intent.ACTION_VIEW); 439 sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE); 440 sBrowserIntent.setData(Uri.parse("http:")); 441 } 442 443 final ServiceThread mHandlerThread; 444 445 final PackageHandler mHandler; 446 447 /** 448 * Messages for {@link #mHandler} that need to wait for system ready before 449 * being dispatched. 450 */ 451 private ArrayList<Message> mPostSystemReadyMessages; 452 453 final int mSdkVersion = Build.VERSION.SDK_INT; 454 455 final Context mContext; 456 final boolean mFactoryTest; 457 final boolean mOnlyCore; 458 final DisplayMetrics mMetrics; 459 final int mDefParseFlags; 460 final String[] mSeparateProcesses; 461 final boolean mIsUpgrade; 462 463 /** The location for ASEC container files on internal storage. */ 464 final String mAsecInternalPath; 465 466 // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages 467 // LOCK HELD. Can be called with mInstallLock held. 468 @GuardedBy("mInstallLock") 469 final Installer mInstaller; 470 471 /** Directory where installed third-party apps stored */ 472 final File mAppInstallDir; 473 final File mEphemeralInstallDir; 474 475 /** 476 * Directory to which applications installed internally have their 477 * 32 bit native libraries copied. 478 */ 479 private File mAppLib32InstallDir; 480 481 // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked 482 // apps. 483 final File mDrmAppPrivateInstallDir; 484 485 // ---------------------------------------------------------------- 486 487 // Lock for state used when installing and doing other long running 488 // operations. Methods that must be called with this lock held have 489 // the suffix "LI". 490 final Object mInstallLock = new Object(); 491 492 // ---------------------------------------------------------------- 493 494 // Keys are String (package name), values are Package. This also serves 495 // as the lock for the global state. Methods that must be called with 496 // this lock held have the prefix "LP". 497 @GuardedBy("mPackages") 498 final ArrayMap<String, PackageParser.Package> mPackages = 499 new ArrayMap<String, PackageParser.Package>(); 500 501 final ArrayMap<String, Set<String>> mKnownCodebase = 502 new ArrayMap<String, Set<String>>(); 503 504 // Tracks available target package names -> overlay package paths. 505 final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays = 506 new ArrayMap<String, ArrayMap<String, PackageParser.Package>>(); 507 508 /** 509 * Tracks new system packages [received in an OTA] that we expect to 510 * find updated user-installed versions. Keys are package name, values 511 * are package location. 512 */ 513 final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>(); 514 515 /** 516 * Tracks existing system packages prior to receiving an OTA. Keys are package name. 517 */ 518 final private ArraySet<String> mExistingSystemPackages = new ArraySet<>(); 519 /** 520 * Whether or not system app permissions should be promoted from install to runtime. 521 */ 522 boolean mPromoteSystemApps; 523 524 final Settings mSettings; 525 boolean mRestoredSettings; 526 527 // System configuration read by SystemConfig. 528 final int[] mGlobalGids; 529 final SparseArray<ArraySet<String>> mSystemPermissions; 530 final ArrayMap<String, FeatureInfo> mAvailableFeatures; 531 532 // If mac_permissions.xml was found for seinfo labeling. 533 boolean mFoundPolicyFile; 534 535 private final EphemeralApplicationRegistry mEphemeralApplicationRegistry; 536 537 public static final class SharedLibraryEntry { 538 public final String path; 539 public final String apk; 540 541 SharedLibraryEntry(String _path, String _apk) { 542 path = _path; 543 apk = _apk; 544 } 545 } 546 547 // Currently known shared libraries. 548 final ArrayMap<String, SharedLibraryEntry> mSharedLibraries = 549 new ArrayMap<String, SharedLibraryEntry>(); 550 551 // All available activities, for your resolving pleasure. 552 final ActivityIntentResolver mActivities = 553 new ActivityIntentResolver(); 554 555 // All available receivers, for your resolving pleasure. 556 final ActivityIntentResolver mReceivers = 557 new ActivityIntentResolver(); 558 559 // All available services, for your resolving pleasure. 560 final ServiceIntentResolver mServices = new ServiceIntentResolver(); 561 562 // All available providers, for your resolving pleasure. 563 final ProviderIntentResolver mProviders = new ProviderIntentResolver(); 564 565 // Mapping from provider base names (first directory in content URI codePath) 566 // to the provider information. 567 final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority = 568 new ArrayMap<String, PackageParser.Provider>(); 569 570 // Mapping from instrumentation class names to info about them. 571 final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation = 572 new ArrayMap<ComponentName, PackageParser.Instrumentation>(); 573 574 // Mapping from permission names to info about them. 575 final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups = 576 new ArrayMap<String, PackageParser.PermissionGroup>(); 577 578 // Packages whose data we have transfered into another package, thus 579 // should no longer exist. 580 final ArraySet<String> mTransferedPackages = new ArraySet<String>(); 581 582 // Broadcast actions that are only available to the system. 583 final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>(); 584 585 /** List of packages waiting for verification. */ 586 final SparseArray<PackageVerificationState> mPendingVerification 587 = new SparseArray<PackageVerificationState>(); 588 589 /** Set of packages associated with each app op permission. */ 590 final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>(); 591 592 final PackageInstallerService mInstallerService; 593 594 private final PackageDexOptimizer mPackageDexOptimizer; 595 596 private AtomicInteger mNextMoveId = new AtomicInteger(); 597 private final MoveCallbacks mMoveCallbacks; 598 599 private final OnPermissionChangeListeners mOnPermissionChangeListeners; 600 601 // Cache of users who need badging. 602 SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray(); 603 604 /** Token for keys in mPendingVerification. */ 605 private int mPendingVerificationToken = 0; 606 607 volatile boolean mSystemReady; 608 volatile boolean mSafeMode; 609 volatile boolean mHasSystemUidErrors; 610 611 ApplicationInfo mAndroidApplication; 612 final ActivityInfo mResolveActivity = new ActivityInfo(); 613 final ResolveInfo mResolveInfo = new ResolveInfo(); 614 ComponentName mResolveComponentName; 615 PackageParser.Package mPlatformPackage; 616 ComponentName mCustomResolverComponentName; 617 618 boolean mResolverReplaced = false; 619 620 private final @Nullable ComponentName mIntentFilterVerifierComponent; 621 private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier; 622 623 private int mIntentFilterVerificationToken = 0; 624 625 /** Component that knows whether or not an ephemeral application exists */ 626 final ComponentName mEphemeralResolverComponent; 627 /** The service connection to the ephemeral resolver */ 628 final EphemeralResolverConnection mEphemeralResolverConnection; 629 630 /** Component used to install ephemeral applications */ 631 final ComponentName mEphemeralInstallerComponent; 632 final ActivityInfo mEphemeralInstallerActivity = new ActivityInfo(); 633 final ResolveInfo mEphemeralInstallerInfo = new ResolveInfo(); 634 635 final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates 636 = new SparseArray<IntentFilterVerificationState>(); 637 638 final DefaultPermissionGrantPolicy mDefaultPermissionPolicy = 639 new DefaultPermissionGrantPolicy(this); 640 641 // List of packages names to keep cached, even if they are uninstalled for all users 642 private List<String> mKeepUninstalledPackages; 643 644 private boolean mUseJitProfiles = 645 SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false); 646 647 private static class IFVerificationParams { 648 PackageParser.Package pkg; 649 boolean replacing; 650 int userId; 651 int verifierUid; 652 653 public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing, 654 int _userId, int _verifierUid) { 655 pkg = _pkg; 656 replacing = _replacing; 657 userId = _userId; 658 replacing = _replacing; 659 verifierUid = _verifierUid; 660 } 661 } 662 663 private interface IntentFilterVerifier<T extends IntentFilter> { 664 boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId, 665 T filter, String packageName); 666 void startVerifications(int userId); 667 void receiveVerificationResponse(int verificationId); 668 } 669 670 private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> { 671 private Context mContext; 672 private ComponentName mIntentFilterVerifierComponent; 673 private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>(); 674 675 public IntentVerifierProxy(Context context, ComponentName verifierComponent) { 676 mContext = context; 677 mIntentFilterVerifierComponent = verifierComponent; 678 } 679 680 private String getDefaultScheme() { 681 return IntentFilter.SCHEME_HTTPS; 682 } 683 684 @Override 685 public void startVerifications(int userId) { 686 // Launch verifications requests 687 int count = mCurrentIntentFilterVerifications.size(); 688 for (int n=0; n<count; n++) { 689 int verificationId = mCurrentIntentFilterVerifications.get(n); 690 final IntentFilterVerificationState ivs = 691 mIntentFilterVerificationStates.get(verificationId); 692 693 String packageName = ivs.getPackageName(); 694 695 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 696 final int filterCount = filters.size(); 697 ArraySet<String> domainsSet = new ArraySet<>(); 698 for (int m=0; m<filterCount; m++) { 699 PackageParser.ActivityIntentInfo filter = filters.get(m); 700 domainsSet.addAll(filter.getHostsList()); 701 } 702 ArrayList<String> domainsList = new ArrayList<>(domainsSet); 703 synchronized (mPackages) { 704 if (mSettings.createIntentFilterVerificationIfNeededLPw( 705 packageName, domainsList) != null) { 706 scheduleWriteSettingsLocked(); 707 } 708 } 709 sendVerificationRequest(userId, verificationId, ivs); 710 } 711 mCurrentIntentFilterVerifications.clear(); 712 } 713 714 private void sendVerificationRequest(int userId, int verificationId, 715 IntentFilterVerificationState ivs) { 716 717 Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 718 verificationIntent.putExtra( 719 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID, 720 verificationId); 721 verificationIntent.putExtra( 722 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME, 723 getDefaultScheme()); 724 verificationIntent.putExtra( 725 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS, 726 ivs.getHostsString()); 727 verificationIntent.putExtra( 728 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME, 729 ivs.getPackageName()); 730 verificationIntent.setComponent(mIntentFilterVerifierComponent); 731 verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 732 733 UserHandle user = new UserHandle(userId); 734 mContext.sendBroadcastAsUser(verificationIntent, user); 735 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 736 "Sending IntentFilter verification broadcast"); 737 } 738 739 public void receiveVerificationResponse(int verificationId) { 740 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 741 742 final boolean verified = ivs.isVerified(); 743 744 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 745 final int count = filters.size(); 746 if (DEBUG_DOMAIN_VERIFICATION) { 747 Slog.i(TAG, "Received verification response " + verificationId 748 + " for " + count + " filters, verified=" + verified); 749 } 750 for (int n=0; n<count; n++) { 751 PackageParser.ActivityIntentInfo filter = filters.get(n); 752 filter.setVerified(verified); 753 754 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString() 755 + " verified with result:" + verified + " and hosts:" 756 + ivs.getHostsString()); 757 } 758 759 mIntentFilterVerificationStates.remove(verificationId); 760 761 final String packageName = ivs.getPackageName(); 762 IntentFilterVerificationInfo ivi = null; 763 764 synchronized (mPackages) { 765 ivi = mSettings.getIntentFilterVerificationLPr(packageName); 766 } 767 if (ivi == null) { 768 Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:" 769 + verificationId + " packageName:" + packageName); 770 return; 771 } 772 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 773 "Updating IntentFilterVerificationInfo for package " + packageName 774 +" verificationId:" + verificationId); 775 776 synchronized (mPackages) { 777 if (verified) { 778 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS); 779 } else { 780 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK); 781 } 782 scheduleWriteSettingsLocked(); 783 784 final int userId = ivs.getUserId(); 785 if (userId != UserHandle.USER_ALL) { 786 final int userStatus = 787 mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 788 789 int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 790 boolean needUpdate = false; 791 792 // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have 793 // already been set by the User thru the Disambiguation dialog 794 switch (userStatus) { 795 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 796 if (verified) { 797 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 798 } else { 799 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 800 } 801 needUpdate = true; 802 break; 803 804 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 805 if (verified) { 806 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 807 needUpdate = true; 808 } 809 break; 810 811 default: 812 // Nothing to do 813 } 814 815 if (needUpdate) { 816 mSettings.updateIntentFilterVerificationStatusLPw( 817 packageName, updatedStatus, userId); 818 scheduleWritePackageRestrictionsLocked(userId); 819 } 820 } 821 } 822 } 823 824 @Override 825 public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId, 826 ActivityIntentInfo filter, String packageName) { 827 if (!hasValidDomains(filter)) { 828 return false; 829 } 830 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 831 if (ivs == null) { 832 ivs = createDomainVerificationState(verifierUid, userId, verificationId, 833 packageName); 834 } 835 if (DEBUG_DOMAIN_VERIFICATION) { 836 Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter); 837 } 838 ivs.addFilter(filter); 839 return true; 840 } 841 842 private IntentFilterVerificationState createDomainVerificationState(int verifierUid, 843 int userId, int verificationId, String packageName) { 844 IntentFilterVerificationState ivs = new IntentFilterVerificationState( 845 verifierUid, userId, packageName); 846 ivs.setPendingState(); 847 synchronized (mPackages) { 848 mIntentFilterVerificationStates.append(verificationId, ivs); 849 mCurrentIntentFilterVerifications.add(verificationId); 850 } 851 return ivs; 852 } 853 } 854 855 private static boolean hasValidDomains(ActivityIntentInfo filter) { 856 return filter.hasCategory(Intent.CATEGORY_BROWSABLE) 857 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 858 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS)); 859 } 860 861 // Set of pending broadcasts for aggregating enable/disable of components. 862 static class PendingPackageBroadcasts { 863 // for each user id, a map of <package name -> components within that package> 864 final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap; 865 866 public PendingPackageBroadcasts() { 867 mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2); 868 } 869 870 public ArrayList<String> get(int userId, String packageName) { 871 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 872 return packages.get(packageName); 873 } 874 875 public void put(int userId, String packageName, ArrayList<String> components) { 876 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 877 packages.put(packageName, components); 878 } 879 880 public void remove(int userId, String packageName) { 881 ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId); 882 if (packages != null) { 883 packages.remove(packageName); 884 } 885 } 886 887 public void remove(int userId) { 888 mUidMap.remove(userId); 889 } 890 891 public int userIdCount() { 892 return mUidMap.size(); 893 } 894 895 public int userIdAt(int n) { 896 return mUidMap.keyAt(n); 897 } 898 899 public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) { 900 return mUidMap.get(userId); 901 } 902 903 public int size() { 904 // total number of pending broadcast entries across all userIds 905 int num = 0; 906 for (int i = 0; i< mUidMap.size(); i++) { 907 num += mUidMap.valueAt(i).size(); 908 } 909 return num; 910 } 911 912 public void clear() { 913 mUidMap.clear(); 914 } 915 916 private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) { 917 ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId); 918 if (map == null) { 919 map = new ArrayMap<String, ArrayList<String>>(); 920 mUidMap.put(userId, map); 921 } 922 return map; 923 } 924 } 925 final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts(); 926 927 // Service Connection to remote media container service to copy 928 // package uri's from external media onto secure containers 929 // or internal storage. 930 private IMediaContainerService mContainerService = null; 931 932 static final int SEND_PENDING_BROADCAST = 1; 933 static final int MCS_BOUND = 3; 934 static final int END_COPY = 4; 935 static final int INIT_COPY = 5; 936 static final int MCS_UNBIND = 6; 937 static final int START_CLEANING_PACKAGE = 7; 938 static final int FIND_INSTALL_LOC = 8; 939 static final int POST_INSTALL = 9; 940 static final int MCS_RECONNECT = 10; 941 static final int MCS_GIVE_UP = 11; 942 static final int UPDATED_MEDIA_STATUS = 12; 943 static final int WRITE_SETTINGS = 13; 944 static final int WRITE_PACKAGE_RESTRICTIONS = 14; 945 static final int PACKAGE_VERIFIED = 15; 946 static final int CHECK_PENDING_VERIFICATION = 16; 947 static final int START_INTENT_FILTER_VERIFICATIONS = 17; 948 static final int INTENT_FILTER_VERIFIED = 18; 949 950 static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds 951 952 // Delay time in millisecs 953 static final int BROADCAST_DELAY = 10 * 1000; 954 955 static UserManagerService sUserManager; 956 957 // Stores a list of users whose package restrictions file needs to be updated 958 private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>(); 959 960 final private DefaultContainerConnection mDefContainerConn = 961 new DefaultContainerConnection(); 962 class DefaultContainerConnection implements ServiceConnection { 963 public void onServiceConnected(ComponentName name, IBinder service) { 964 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected"); 965 IMediaContainerService imcs = 966 IMediaContainerService.Stub.asInterface(service); 967 mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs)); 968 } 969 970 public void onServiceDisconnected(ComponentName name) { 971 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected"); 972 } 973 } 974 975 // Recordkeeping of restore-after-install operations that are currently in flight 976 // between the Package Manager and the Backup Manager 977 static class PostInstallData { 978 public InstallArgs args; 979 public PackageInstalledInfo res; 980 981 PostInstallData(InstallArgs _a, PackageInstalledInfo _r) { 982 args = _a; 983 res = _r; 984 } 985 } 986 987 final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>(); 988 int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows 989 990 // XML tags for backup/restore of various bits of state 991 private static final String TAG_PREFERRED_BACKUP = "pa"; 992 private static final String TAG_DEFAULT_APPS = "da"; 993 private static final String TAG_INTENT_FILTER_VERIFICATION = "iv"; 994 995 private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup"; 996 private static final String TAG_ALL_GRANTS = "rt-grants"; 997 private static final String TAG_GRANT = "grant"; 998 private static final String ATTR_PACKAGE_NAME = "pkg"; 999 1000 private static final String TAG_PERMISSION = "perm"; 1001 private static final String ATTR_PERMISSION_NAME = "name"; 1002 private static final String ATTR_IS_GRANTED = "g"; 1003 private static final String ATTR_USER_SET = "set"; 1004 private static final String ATTR_USER_FIXED = "fixed"; 1005 private static final String ATTR_REVOKE_ON_UPGRADE = "rou"; 1006 1007 // System/policy permission grants are not backed up 1008 private static final int SYSTEM_RUNTIME_GRANT_MASK = 1009 FLAG_PERMISSION_POLICY_FIXED 1010 | FLAG_PERMISSION_SYSTEM_FIXED 1011 | FLAG_PERMISSION_GRANTED_BY_DEFAULT; 1012 1013 // And we back up these user-adjusted states 1014 private static final int USER_RUNTIME_GRANT_MASK = 1015 FLAG_PERMISSION_USER_SET 1016 | FLAG_PERMISSION_USER_FIXED 1017 | FLAG_PERMISSION_REVOKE_ON_UPGRADE; 1018 1019 final @Nullable String mRequiredVerifierPackage; 1020 final @Nullable String mRequiredInstallerPackage; 1021 1022 private final PackageUsage mPackageUsage = new PackageUsage(); 1023 1024 private class PackageUsage { 1025 private static final int WRITE_INTERVAL 1026 = (DEBUG_DEXOPT) ? 0 : 30*60*1000; // 30m in ms 1027 1028 private final Object mFileLock = new Object(); 1029 private final AtomicLong mLastWritten = new AtomicLong(0); 1030 private final AtomicBoolean mBackgroundWriteRunning = new AtomicBoolean(false); 1031 1032 private boolean mIsHistoricalPackageUsageAvailable = true; 1033 1034 boolean isHistoricalPackageUsageAvailable() { 1035 return mIsHistoricalPackageUsageAvailable; 1036 } 1037 1038 void write(boolean force) { 1039 if (force) { 1040 writeInternal(); 1041 return; 1042 } 1043 if (SystemClock.elapsedRealtime() - mLastWritten.get() < WRITE_INTERVAL 1044 && !DEBUG_DEXOPT) { 1045 return; 1046 } 1047 if (mBackgroundWriteRunning.compareAndSet(false, true)) { 1048 new Thread("PackageUsage_DiskWriter") { 1049 @Override 1050 public void run() { 1051 try { 1052 writeInternal(); 1053 } finally { 1054 mBackgroundWriteRunning.set(false); 1055 } 1056 } 1057 }.start(); 1058 } 1059 } 1060 1061 private void writeInternal() { 1062 synchronized (mPackages) { 1063 synchronized (mFileLock) { 1064 AtomicFile file = getFile(); 1065 FileOutputStream f = null; 1066 try { 1067 f = file.startWrite(); 1068 BufferedOutputStream out = new BufferedOutputStream(f); 1069 FileUtils.setPermissions(file.getBaseFile().getPath(), 0640, SYSTEM_UID, PACKAGE_INFO_GID); 1070 StringBuilder sb = new StringBuilder(); 1071 for (PackageParser.Package pkg : mPackages.values()) { 1072 if (pkg.mLastPackageUsageTimeInMills == 0) { 1073 continue; 1074 } 1075 sb.setLength(0); 1076 sb.append(pkg.packageName); 1077 sb.append(' '); 1078 sb.append((long)pkg.mLastPackageUsageTimeInMills); 1079 sb.append('\n'); 1080 out.write(sb.toString().getBytes(StandardCharsets.US_ASCII)); 1081 } 1082 out.flush(); 1083 file.finishWrite(f); 1084 } catch (IOException e) { 1085 if (f != null) { 1086 file.failWrite(f); 1087 } 1088 Log.e(TAG, "Failed to write package usage times", e); 1089 } 1090 } 1091 } 1092 mLastWritten.set(SystemClock.elapsedRealtime()); 1093 } 1094 1095 void readLP() { 1096 synchronized (mFileLock) { 1097 AtomicFile file = getFile(); 1098 BufferedInputStream in = null; 1099 try { 1100 in = new BufferedInputStream(file.openRead()); 1101 StringBuffer sb = new StringBuffer(); 1102 while (true) { 1103 String packageName = readToken(in, sb, ' '); 1104 if (packageName == null) { 1105 break; 1106 } 1107 String timeInMillisString = readToken(in, sb, '\n'); 1108 if (timeInMillisString == null) { 1109 throw new IOException("Failed to find last usage time for package " 1110 + packageName); 1111 } 1112 PackageParser.Package pkg = mPackages.get(packageName); 1113 if (pkg == null) { 1114 continue; 1115 } 1116 long timeInMillis; 1117 try { 1118 timeInMillis = Long.parseLong(timeInMillisString); 1119 } catch (NumberFormatException e) { 1120 throw new IOException("Failed to parse " + timeInMillisString 1121 + " as a long.", e); 1122 } 1123 pkg.mLastPackageUsageTimeInMills = timeInMillis; 1124 } 1125 } catch (FileNotFoundException expected) { 1126 mIsHistoricalPackageUsageAvailable = false; 1127 } catch (IOException e) { 1128 Log.w(TAG, "Failed to read package usage times", e); 1129 } finally { 1130 IoUtils.closeQuietly(in); 1131 } 1132 } 1133 mLastWritten.set(SystemClock.elapsedRealtime()); 1134 } 1135 1136 private String readToken(InputStream in, StringBuffer sb, char endOfToken) 1137 throws IOException { 1138 sb.setLength(0); 1139 while (true) { 1140 int ch = in.read(); 1141 if (ch == -1) { 1142 if (sb.length() == 0) { 1143 return null; 1144 } 1145 throw new IOException("Unexpected EOF"); 1146 } 1147 if (ch == endOfToken) { 1148 return sb.toString(); 1149 } 1150 sb.append((char)ch); 1151 } 1152 } 1153 1154 private AtomicFile getFile() { 1155 File dataDir = Environment.getDataDirectory(); 1156 File systemDir = new File(dataDir, "system"); 1157 File fname = new File(systemDir, "package-usage.list"); 1158 return new AtomicFile(fname); 1159 } 1160 } 1161 1162 class PackageHandler extends Handler { 1163 private boolean mBound = false; 1164 final ArrayList<HandlerParams> mPendingInstalls = 1165 new ArrayList<HandlerParams>(); 1166 1167 private boolean connectToService() { 1168 if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" + 1169 " DefaultContainerService"); 1170 Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 1171 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1172 if (mContext.bindServiceAsUser(service, mDefContainerConn, 1173 Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) { 1174 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1175 mBound = true; 1176 return true; 1177 } 1178 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1179 return false; 1180 } 1181 1182 private void disconnectService() { 1183 mContainerService = null; 1184 mBound = false; 1185 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1186 mContext.unbindService(mDefContainerConn); 1187 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1188 } 1189 1190 PackageHandler(Looper looper) { 1191 super(looper); 1192 } 1193 1194 public void handleMessage(Message msg) { 1195 try { 1196 doHandleMessage(msg); 1197 } finally { 1198 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1199 } 1200 } 1201 1202 void doHandleMessage(Message msg) { 1203 switch (msg.what) { 1204 case INIT_COPY: { 1205 HandlerParams params = (HandlerParams) msg.obj; 1206 int idx = mPendingInstalls.size(); 1207 if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params); 1208 // If a bind was already initiated we dont really 1209 // need to do anything. The pending install 1210 // will be processed later on. 1211 if (!mBound) { 1212 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1213 System.identityHashCode(mHandler)); 1214 // If this is the only one pending we might 1215 // have to bind to the service again. 1216 if (!connectToService()) { 1217 Slog.e(TAG, "Failed to bind to media container service"); 1218 params.serviceError(); 1219 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1220 System.identityHashCode(mHandler)); 1221 if (params.traceMethod != null) { 1222 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod, 1223 params.traceCookie); 1224 } 1225 return; 1226 } else { 1227 // Once we bind to the service, the first 1228 // pending request will be processed. 1229 mPendingInstalls.add(idx, params); 1230 } 1231 } else { 1232 mPendingInstalls.add(idx, params); 1233 // Already bound to the service. Just make 1234 // sure we trigger off processing the first request. 1235 if (idx == 0) { 1236 mHandler.sendEmptyMessage(MCS_BOUND); 1237 } 1238 } 1239 break; 1240 } 1241 case MCS_BOUND: { 1242 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound"); 1243 if (msg.obj != null) { 1244 mContainerService = (IMediaContainerService) msg.obj; 1245 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1246 System.identityHashCode(mHandler)); 1247 } 1248 if (mContainerService == null) { 1249 if (!mBound) { 1250 // Something seriously wrong since we are not bound and we are not 1251 // waiting for connection. Bail out. 1252 Slog.e(TAG, "Cannot bind to media container service"); 1253 for (HandlerParams params : mPendingInstalls) { 1254 // Indicate service bind error 1255 params.serviceError(); 1256 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1257 System.identityHashCode(params)); 1258 if (params.traceMethod != null) { 1259 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, 1260 params.traceMethod, params.traceCookie); 1261 } 1262 return; 1263 } 1264 mPendingInstalls.clear(); 1265 } else { 1266 Slog.w(TAG, "Waiting to connect to media container service"); 1267 } 1268 } else if (mPendingInstalls.size() > 0) { 1269 HandlerParams params = mPendingInstalls.get(0); 1270 if (params != null) { 1271 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1272 System.identityHashCode(params)); 1273 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy"); 1274 if (params.startCopy()) { 1275 // We are done... look for more work or to 1276 // go idle. 1277 if (DEBUG_SD_INSTALL) Log.i(TAG, 1278 "Checking for more work or unbind..."); 1279 // Delete pending install 1280 if (mPendingInstalls.size() > 0) { 1281 mPendingInstalls.remove(0); 1282 } 1283 if (mPendingInstalls.size() == 0) { 1284 if (mBound) { 1285 if (DEBUG_SD_INSTALL) Log.i(TAG, 1286 "Posting delayed MCS_UNBIND"); 1287 removeMessages(MCS_UNBIND); 1288 Message ubmsg = obtainMessage(MCS_UNBIND); 1289 // Unbind after a little delay, to avoid 1290 // continual thrashing. 1291 sendMessageDelayed(ubmsg, 10000); 1292 } 1293 } else { 1294 // There are more pending requests in queue. 1295 // Just post MCS_BOUND message to trigger processing 1296 // of next pending install. 1297 if (DEBUG_SD_INSTALL) Log.i(TAG, 1298 "Posting MCS_BOUND for next work"); 1299 mHandler.sendEmptyMessage(MCS_BOUND); 1300 } 1301 } 1302 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 1303 } 1304 } else { 1305 // Should never happen ideally. 1306 Slog.w(TAG, "Empty queue"); 1307 } 1308 break; 1309 } 1310 case MCS_RECONNECT: { 1311 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect"); 1312 if (mPendingInstalls.size() > 0) { 1313 if (mBound) { 1314 disconnectService(); 1315 } 1316 if (!connectToService()) { 1317 Slog.e(TAG, "Failed to bind to media container service"); 1318 for (HandlerParams params : mPendingInstalls) { 1319 // Indicate service bind error 1320 params.serviceError(); 1321 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1322 System.identityHashCode(params)); 1323 } 1324 mPendingInstalls.clear(); 1325 } 1326 } 1327 break; 1328 } 1329 case MCS_UNBIND: { 1330 // If there is no actual work left, then time to unbind. 1331 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind"); 1332 1333 if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) { 1334 if (mBound) { 1335 if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()"); 1336 1337 disconnectService(); 1338 } 1339 } else if (mPendingInstalls.size() > 0) { 1340 // There are more pending requests in queue. 1341 // Just post MCS_BOUND message to trigger processing 1342 // of next pending install. 1343 mHandler.sendEmptyMessage(MCS_BOUND); 1344 } 1345 1346 break; 1347 } 1348 case MCS_GIVE_UP: { 1349 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries"); 1350 HandlerParams params = mPendingInstalls.remove(0); 1351 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1352 System.identityHashCode(params)); 1353 break; 1354 } 1355 case SEND_PENDING_BROADCAST: { 1356 String packages[]; 1357 ArrayList<String> components[]; 1358 int size = 0; 1359 int uids[]; 1360 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1361 synchronized (mPackages) { 1362 if (mPendingBroadcasts == null) { 1363 return; 1364 } 1365 size = mPendingBroadcasts.size(); 1366 if (size <= 0) { 1367 // Nothing to be done. Just return 1368 return; 1369 } 1370 packages = new String[size]; 1371 components = new ArrayList[size]; 1372 uids = new int[size]; 1373 int i = 0; // filling out the above arrays 1374 1375 for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) { 1376 int packageUserId = mPendingBroadcasts.userIdAt(n); 1377 Iterator<Map.Entry<String, ArrayList<String>>> it 1378 = mPendingBroadcasts.packagesForUserId(packageUserId) 1379 .entrySet().iterator(); 1380 while (it.hasNext() && i < size) { 1381 Map.Entry<String, ArrayList<String>> ent = it.next(); 1382 packages[i] = ent.getKey(); 1383 components[i] = ent.getValue(); 1384 PackageSetting ps = mSettings.mPackages.get(ent.getKey()); 1385 uids[i] = (ps != null) 1386 ? UserHandle.getUid(packageUserId, ps.appId) 1387 : -1; 1388 i++; 1389 } 1390 } 1391 size = i; 1392 mPendingBroadcasts.clear(); 1393 } 1394 // Send broadcasts 1395 for (int i = 0; i < size; i++) { 1396 sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]); 1397 } 1398 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1399 break; 1400 } 1401 case START_CLEANING_PACKAGE: { 1402 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1403 final String packageName = (String)msg.obj; 1404 final int userId = msg.arg1; 1405 final boolean andCode = msg.arg2 != 0; 1406 synchronized (mPackages) { 1407 if (userId == UserHandle.USER_ALL) { 1408 int[] users = sUserManager.getUserIds(); 1409 for (int user : users) { 1410 mSettings.addPackageToCleanLPw( 1411 new PackageCleanItem(user, packageName, andCode)); 1412 } 1413 } else { 1414 mSettings.addPackageToCleanLPw( 1415 new PackageCleanItem(userId, packageName, andCode)); 1416 } 1417 } 1418 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1419 startCleaningPackages(); 1420 } break; 1421 case POST_INSTALL: { 1422 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1); 1423 1424 PostInstallData data = mRunningInstalls.get(msg.arg1); 1425 mRunningInstalls.delete(msg.arg1); 1426 1427 if (data != null) { 1428 InstallArgs args = data.args; 1429 PackageInstalledInfo parentRes = data.res; 1430 1431 final boolean grantPermissions = (args.installFlags 1432 & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0; 1433 final boolean killApp = (args.installFlags 1434 & PackageManager.INSTALL_DONT_KILL_APP) == 0; 1435 final String[] grantedPermissions = args.installGrantPermissions; 1436 1437 // Handle the parent package 1438 handlePackagePostInstall(parentRes, grantPermissions, killApp, 1439 grantedPermissions, args.observer); 1440 1441 // Handle the child packages 1442 final int childCount = (parentRes.addedChildPackages != null) 1443 ? parentRes.addedChildPackages.size() : 0; 1444 for (int i = 0; i < childCount; i++) { 1445 PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i); 1446 handlePackagePostInstall(childRes, grantPermissions, killApp, 1447 grantedPermissions, args.observer); 1448 } 1449 1450 // Log tracing if needed 1451 if (args.traceMethod != null) { 1452 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod, 1453 args.traceCookie); 1454 } 1455 } else { 1456 Slog.e(TAG, "Bogus post-install token " + msg.arg1); 1457 } 1458 1459 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1); 1460 } break; 1461 case UPDATED_MEDIA_STATUS: { 1462 if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS"); 1463 boolean reportStatus = msg.arg1 == 1; 1464 boolean doGc = msg.arg2 == 1; 1465 if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc); 1466 if (doGc) { 1467 // Force a gc to clear up stale containers. 1468 Runtime.getRuntime().gc(); 1469 } 1470 if (msg.obj != null) { 1471 @SuppressWarnings("unchecked") 1472 Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj; 1473 if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers"); 1474 // Unload containers 1475 unloadAllContainers(args); 1476 } 1477 if (reportStatus) { 1478 try { 1479 if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back"); 1480 PackageHelper.getMountService().finishMediaUpdate(); 1481 } catch (RemoteException e) { 1482 Log.e(TAG, "MountService not running?"); 1483 } 1484 } 1485 } break; 1486 case WRITE_SETTINGS: { 1487 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1488 synchronized (mPackages) { 1489 removeMessages(WRITE_SETTINGS); 1490 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1491 mSettings.writeLPr(); 1492 mDirtyUsers.clear(); 1493 } 1494 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1495 } break; 1496 case WRITE_PACKAGE_RESTRICTIONS: { 1497 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1498 synchronized (mPackages) { 1499 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1500 for (int userId : mDirtyUsers) { 1501 mSettings.writePackageRestrictionsLPr(userId); 1502 } 1503 mDirtyUsers.clear(); 1504 } 1505 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1506 } break; 1507 case CHECK_PENDING_VERIFICATION: { 1508 final int verificationId = msg.arg1; 1509 final PackageVerificationState state = mPendingVerification.get(verificationId); 1510 1511 if ((state != null) && !state.timeoutExtended()) { 1512 final InstallArgs args = state.getInstallArgs(); 1513 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1514 1515 Slog.i(TAG, "Verification timed out for " + originUri); 1516 mPendingVerification.remove(verificationId); 1517 1518 int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1519 1520 if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) { 1521 Slog.i(TAG, "Continuing with installation of " + originUri); 1522 state.setVerifierResponse(Binder.getCallingUid(), 1523 PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT); 1524 broadcastPackageVerified(verificationId, originUri, 1525 PackageManager.VERIFICATION_ALLOW, 1526 state.getInstallArgs().getUser()); 1527 try { 1528 ret = args.copyApk(mContainerService, true); 1529 } catch (RemoteException e) { 1530 Slog.e(TAG, "Could not contact the ContainerService"); 1531 } 1532 } else { 1533 broadcastPackageVerified(verificationId, originUri, 1534 PackageManager.VERIFICATION_REJECT, 1535 state.getInstallArgs().getUser()); 1536 } 1537 1538 Trace.asyncTraceEnd( 1539 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 1540 1541 processPendingInstall(args, ret); 1542 mHandler.sendEmptyMessage(MCS_UNBIND); 1543 } 1544 break; 1545 } 1546 case PACKAGE_VERIFIED: { 1547 final int verificationId = msg.arg1; 1548 1549 final PackageVerificationState state = mPendingVerification.get(verificationId); 1550 if (state == null) { 1551 Slog.w(TAG, "Invalid verification token " + verificationId + " received"); 1552 break; 1553 } 1554 1555 final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj; 1556 1557 state.setVerifierResponse(response.callerUid, response.code); 1558 1559 if (state.isVerificationComplete()) { 1560 mPendingVerification.remove(verificationId); 1561 1562 final InstallArgs args = state.getInstallArgs(); 1563 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1564 1565 int ret; 1566 if (state.isInstallAllowed()) { 1567 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 1568 broadcastPackageVerified(verificationId, originUri, 1569 response.code, state.getInstallArgs().getUser()); 1570 try { 1571 ret = args.copyApk(mContainerService, true); 1572 } catch (RemoteException e) { 1573 Slog.e(TAG, "Could not contact the ContainerService"); 1574 } 1575 } else { 1576 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1577 } 1578 1579 Trace.asyncTraceEnd( 1580 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 1581 1582 processPendingInstall(args, ret); 1583 mHandler.sendEmptyMessage(MCS_UNBIND); 1584 } 1585 1586 break; 1587 } 1588 case START_INTENT_FILTER_VERIFICATIONS: { 1589 IFVerificationParams params = (IFVerificationParams) msg.obj; 1590 verifyIntentFiltersIfNeeded(params.userId, params.verifierUid, 1591 params.replacing, params.pkg); 1592 break; 1593 } 1594 case INTENT_FILTER_VERIFIED: { 1595 final int verificationId = msg.arg1; 1596 1597 final IntentFilterVerificationState state = mIntentFilterVerificationStates.get( 1598 verificationId); 1599 if (state == null) { 1600 Slog.w(TAG, "Invalid IntentFilter verification token " 1601 + verificationId + " received"); 1602 break; 1603 } 1604 1605 final int userId = state.getUserId(); 1606 1607 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1608 "Processing IntentFilter verification with token:" 1609 + verificationId + " and userId:" + userId); 1610 1611 final IntentFilterVerificationResponse response = 1612 (IntentFilterVerificationResponse) msg.obj; 1613 1614 state.setVerifierResponse(response.callerUid, response.code); 1615 1616 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1617 "IntentFilter verification with token:" + verificationId 1618 + " and userId:" + userId 1619 + " is settings verifier response with response code:" 1620 + response.code); 1621 1622 if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) { 1623 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: " 1624 + response.getFailedDomainsString()); 1625 } 1626 1627 if (state.isVerificationComplete()) { 1628 mIntentFilterVerifier.receiveVerificationResponse(verificationId); 1629 } else { 1630 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1631 "IntentFilter verification with token:" + verificationId 1632 + " was not said to be complete"); 1633 } 1634 1635 break; 1636 } 1637 } 1638 } 1639 } 1640 1641 private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions, 1642 boolean killApp, String[] grantedPermissions, 1643 IPackageInstallObserver2 installObserver) { 1644 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 1645 // Send the removed broadcasts 1646 if (res.removedInfo != null) { 1647 res.removedInfo.sendPackageRemovedBroadcasts(killApp); 1648 } 1649 1650 // Now that we successfully installed the package, grant runtime 1651 // permissions if requested before broadcasting the install. 1652 if (grantPermissions && res.pkg.applicationInfo.targetSdkVersion 1653 >= Build.VERSION_CODES.M) { 1654 grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions); 1655 } 1656 1657 final boolean update = res.removedInfo != null 1658 && res.removedInfo.removedPackage != null; 1659 1660 // If this is the first time we have child packages for a disabled privileged 1661 // app that had no children, we grant requested runtime permissions to the new 1662 // children if the parent on the system image had them already granted. 1663 if (res.pkg.parentPackage != null) { 1664 synchronized (mPackages) { 1665 grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg); 1666 } 1667 } 1668 1669 synchronized (mPackages) { 1670 mEphemeralApplicationRegistry.onPackageInstalledLPw(res.pkg); 1671 } 1672 1673 final String packageName = res.pkg.applicationInfo.packageName; 1674 Bundle extras = new Bundle(1); 1675 extras.putInt(Intent.EXTRA_UID, res.uid); 1676 1677 // Determine the set of users who are adding this package for 1678 // the first time vs. those who are seeing an update. 1679 int[] firstUsers = EMPTY_INT_ARRAY; 1680 int[] updateUsers = EMPTY_INT_ARRAY; 1681 if (res.origUsers == null || res.origUsers.length == 0) { 1682 firstUsers = res.newUsers; 1683 } else { 1684 for (int newUser : res.newUsers) { 1685 boolean isNew = true; 1686 for (int origUser : res.origUsers) { 1687 if (origUser == newUser) { 1688 isNew = false; 1689 break; 1690 } 1691 } 1692 if (isNew) { 1693 firstUsers = ArrayUtils.appendInt(firstUsers, newUser); 1694 } else { 1695 updateUsers = ArrayUtils.appendInt(updateUsers, newUser); 1696 } 1697 } 1698 } 1699 1700 // Send installed broadcasts if the install/update is not ephemeral 1701 if (!isEphemeral(res.pkg)) { 1702 // Send added for users that see the package for the first time 1703 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, 1704 extras, 0 /*flags*/, null /*targetPackage*/, 1705 null /*finishedReceiver*/, firstUsers); 1706 1707 // Send added for users that don't see the package for the first time 1708 if (update) { 1709 extras.putBoolean(Intent.EXTRA_REPLACING, true); 1710 } 1711 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, 1712 extras, 0 /*flags*/, null /*targetPackage*/, 1713 null /*finishedReceiver*/, updateUsers); 1714 1715 // Send replaced for users that don't see the package for the first time 1716 if (update) { 1717 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, 1718 packageName, extras, 0 /*flags*/, 1719 null /*targetPackage*/, null /*finishedReceiver*/, 1720 updateUsers); 1721 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, 1722 null /*package*/, null /*extras*/, 0 /*flags*/, 1723 packageName /*targetPackage*/, 1724 null /*finishedReceiver*/, updateUsers); 1725 } 1726 1727 // Send broadcast package appeared if forward locked/external for all users 1728 // treat asec-hosted packages like removable media on upgrade 1729 if (res.pkg.isForwardLocked() || isExternal(res.pkg)) { 1730 if (DEBUG_INSTALL) { 1731 Slog.i(TAG, "upgrading pkg " + res.pkg 1732 + " is ASEC-hosted -> AVAILABLE"); 1733 } 1734 final int[] uidArray = new int[]{res.pkg.applicationInfo.uid}; 1735 ArrayList<String> pkgList = new ArrayList<>(1); 1736 pkgList.add(packageName); 1737 sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null); 1738 } 1739 } 1740 1741 // Work that needs to happen on first install within each user 1742 if (firstUsers != null && firstUsers.length > 0) { 1743 synchronized (mPackages) { 1744 for (int userId : firstUsers) { 1745 // If this app is a browser and it's newly-installed for some 1746 // users, clear any default-browser state in those users. The 1747 // app's nature doesn't depend on the user, so we can just check 1748 // its browser nature in any user and generalize. 1749 if (packageIsBrowser(packageName, userId)) { 1750 mSettings.setDefaultBrowserPackageNameLPw(null, userId); 1751 } 1752 1753 // We may also need to apply pending (restored) runtime 1754 // permission grants within these users. 1755 mSettings.applyPendingPermissionGrantsLPw(packageName, userId); 1756 } 1757 } 1758 } 1759 1760 // Log current value of "unknown sources" setting 1761 EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED, 1762 getUnknownSourcesSettings()); 1763 1764 // Force a gc to clear up things 1765 Runtime.getRuntime().gc(); 1766 1767 // Remove the replaced package's older resources safely now 1768 // We delete after a gc for applications on sdcard. 1769 if (res.removedInfo != null && res.removedInfo.args != null) { 1770 synchronized (mInstallLock) { 1771 res.removedInfo.args.doPostDeleteLI(true); 1772 } 1773 } 1774 } 1775 1776 // If someone is watching installs - notify them 1777 if (installObserver != null) { 1778 try { 1779 Bundle extras = extrasForInstallResult(res); 1780 installObserver.onPackageInstalled(res.name, res.returnCode, 1781 res.returnMsg, extras); 1782 } catch (RemoteException e) { 1783 Slog.i(TAG, "Observer no longer exists."); 1784 } 1785 } 1786 } 1787 1788 private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw( 1789 PackageParser.Package pkg) { 1790 if (pkg.parentPackage == null) { 1791 return; 1792 } 1793 if (pkg.requestedPermissions == null) { 1794 return; 1795 } 1796 final PackageSetting disabledSysParentPs = mSettings 1797 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName); 1798 if (disabledSysParentPs == null || disabledSysParentPs.pkg == null 1799 || !disabledSysParentPs.isPrivileged() 1800 || (disabledSysParentPs.childPackageNames != null 1801 && !disabledSysParentPs.childPackageNames.isEmpty())) { 1802 return; 1803 } 1804 final int[] allUserIds = sUserManager.getUserIds(); 1805 final int permCount = pkg.requestedPermissions.size(); 1806 for (int i = 0; i < permCount; i++) { 1807 String permission = pkg.requestedPermissions.get(i); 1808 BasePermission bp = mSettings.mPermissions.get(permission); 1809 if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) { 1810 continue; 1811 } 1812 for (int userId : allUserIds) { 1813 if (disabledSysParentPs.getPermissionsState().hasRuntimePermission( 1814 permission, userId)) { 1815 grantRuntimePermission(pkg.packageName, permission, userId); 1816 } 1817 } 1818 } 1819 } 1820 1821 private StorageEventListener mStorageListener = new StorageEventListener() { 1822 @Override 1823 public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) { 1824 if (vol.type == VolumeInfo.TYPE_PRIVATE) { 1825 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1826 final String volumeUuid = vol.getFsUuid(); 1827 1828 // Clean up any users or apps that were removed or recreated 1829 // while this volume was missing 1830 reconcileUsers(volumeUuid); 1831 reconcileApps(volumeUuid); 1832 1833 // Clean up any install sessions that expired or were 1834 // cancelled while this volume was missing 1835 mInstallerService.onPrivateVolumeMounted(volumeUuid); 1836 1837 loadPrivatePackages(vol); 1838 1839 } else if (vol.state == VolumeInfo.STATE_EJECTING) { 1840 unloadPrivatePackages(vol); 1841 } 1842 } 1843 1844 if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) { 1845 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1846 updateExternalMediaStatus(true, false); 1847 } else if (vol.state == VolumeInfo.STATE_EJECTING) { 1848 updateExternalMediaStatus(false, false); 1849 } 1850 } 1851 } 1852 1853 @Override 1854 public void onVolumeForgotten(String fsUuid) { 1855 if (TextUtils.isEmpty(fsUuid)) { 1856 Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring"); 1857 return; 1858 } 1859 1860 // Remove any apps installed on the forgotten volume 1861 synchronized (mPackages) { 1862 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid); 1863 for (PackageSetting ps : packages) { 1864 Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten"); 1865 deletePackage(ps.name, new LegacyPackageDeleteObserver(null).getBinder(), 1866 UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS); 1867 } 1868 1869 mSettings.onVolumeForgotten(fsUuid); 1870 mSettings.writeLPr(); 1871 } 1872 } 1873 }; 1874 1875 private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds, 1876 String[] grantedPermissions) { 1877 for (int userId : userIds) { 1878 grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions); 1879 } 1880 1881 // We could have touched GID membership, so flush out packages.list 1882 synchronized (mPackages) { 1883 mSettings.writePackageListLPr(); 1884 } 1885 } 1886 1887 private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId, 1888 String[] grantedPermissions) { 1889 SettingBase sb = (SettingBase) pkg.mExtras; 1890 if (sb == null) { 1891 return; 1892 } 1893 1894 PermissionsState permissionsState = sb.getPermissionsState(); 1895 1896 final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 1897 | PackageManager.FLAG_PERMISSION_POLICY_FIXED; 1898 1899 synchronized (mPackages) { 1900 for (String permission : pkg.requestedPermissions) { 1901 BasePermission bp = mSettings.mPermissions.get(permission); 1902 if (bp != null && (bp.isRuntime() || bp.isDevelopment()) 1903 && (grantedPermissions == null 1904 || ArrayUtils.contains(grantedPermissions, permission))) { 1905 final int flags = permissionsState.getPermissionFlags(permission, userId); 1906 // Installer cannot change immutable permissions. 1907 if ((flags & immutableFlags) == 0) { 1908 grantRuntimePermission(pkg.packageName, permission, userId); 1909 } 1910 } 1911 } 1912 } 1913 } 1914 1915 Bundle extrasForInstallResult(PackageInstalledInfo res) { 1916 Bundle extras = null; 1917 switch (res.returnCode) { 1918 case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: { 1919 extras = new Bundle(); 1920 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION, 1921 res.origPermission); 1922 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE, 1923 res.origPackage); 1924 break; 1925 } 1926 case PackageManager.INSTALL_SUCCEEDED: { 1927 extras = new Bundle(); 1928 extras.putBoolean(Intent.EXTRA_REPLACING, 1929 res.removedInfo != null && res.removedInfo.removedPackage != null); 1930 break; 1931 } 1932 } 1933 return extras; 1934 } 1935 1936 void scheduleWriteSettingsLocked() { 1937 if (!mHandler.hasMessages(WRITE_SETTINGS)) { 1938 mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY); 1939 } 1940 } 1941 1942 void scheduleWritePackageRestrictionsLocked(UserHandle user) { 1943 final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier(); 1944 scheduleWritePackageRestrictionsLocked(userId); 1945 } 1946 1947 void scheduleWritePackageRestrictionsLocked(int userId) { 1948 final int[] userIds = (userId == UserHandle.USER_ALL) 1949 ? sUserManager.getUserIds() : new int[]{userId}; 1950 for (int nextUserId : userIds) { 1951 if (!sUserManager.exists(nextUserId)) return; 1952 mDirtyUsers.add(nextUserId); 1953 if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) { 1954 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY); 1955 } 1956 } 1957 } 1958 1959 public static PackageManagerService main(Context context, Installer installer, 1960 boolean factoryTest, boolean onlyCore) { 1961 PackageManagerService m = new PackageManagerService(context, installer, 1962 factoryTest, onlyCore); 1963 m.enableSystemUserPackages(); 1964 ServiceManager.addService("package", m); 1965 return m; 1966 } 1967 1968 private void enableSystemUserPackages() { 1969 if (!UserManager.isSplitSystemUser()) { 1970 return; 1971 } 1972 // For system user, enable apps based on the following conditions: 1973 // - app is whitelisted or belong to one of these groups: 1974 // -- system app which has no launcher icons 1975 // -- system app which has INTERACT_ACROSS_USERS permission 1976 // -- system IME app 1977 // - app is not in the blacklist 1978 AppsQueryHelper queryHelper = new AppsQueryHelper(this); 1979 Set<String> enableApps = new ArraySet<>(); 1980 enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS 1981 | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM 1982 | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM)); 1983 ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps(); 1984 enableApps.addAll(wlApps); 1985 enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER, 1986 /* systemAppsOnly */ false, UserHandle.SYSTEM)); 1987 ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps(); 1988 enableApps.removeAll(blApps); 1989 Log.i(TAG, "Applications installed for system user: " + enableApps); 1990 List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false, 1991 UserHandle.SYSTEM); 1992 final int allAppsSize = allAps.size(); 1993 synchronized (mPackages) { 1994 for (int i = 0; i < allAppsSize; i++) { 1995 String pName = allAps.get(i); 1996 PackageSetting pkgSetting = mSettings.mPackages.get(pName); 1997 // Should not happen, but we shouldn't be failing if it does 1998 if (pkgSetting == null) { 1999 continue; 2000 } 2001 boolean install = enableApps.contains(pName); 2002 if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) { 2003 Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName 2004 + " for system user"); 2005 pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM); 2006 } 2007 } 2008 } 2009 } 2010 2011 private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) { 2012 DisplayManager displayManager = (DisplayManager) context.getSystemService( 2013 Context.DISPLAY_SERVICE); 2014 displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics); 2015 } 2016 2017 public PackageManagerService(Context context, Installer installer, 2018 boolean factoryTest, boolean onlyCore) { 2019 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START, 2020 SystemClock.uptimeMillis()); 2021 2022 if (mSdkVersion <= 0) { 2023 Slog.w(TAG, "**** ro.build.version.sdk not set!"); 2024 } 2025 2026 mContext = context; 2027 mFactoryTest = factoryTest; 2028 mOnlyCore = onlyCore; 2029 mMetrics = new DisplayMetrics(); 2030 mSettings = new Settings(mPackages); 2031 mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID, 2032 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2033 mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, 2034 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2035 mSettings.addSharedUserLPw("android.uid.log", LOG_UID, 2036 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2037 mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, 2038 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2039 mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID, 2040 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2041 mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID, 2042 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2043 2044 String separateProcesses = SystemProperties.get("debug.separate_processes"); 2045 if (separateProcesses != null && separateProcesses.length() > 0) { 2046 if ("*".equals(separateProcesses)) { 2047 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES; 2048 mSeparateProcesses = null; 2049 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)"); 2050 } else { 2051 mDefParseFlags = 0; 2052 mSeparateProcesses = separateProcesses.split(","); 2053 Slog.w(TAG, "Running with debug.separate_processes: " 2054 + separateProcesses); 2055 } 2056 } else { 2057 mDefParseFlags = 0; 2058 mSeparateProcesses = null; 2059 } 2060 2061 mInstaller = installer; 2062 mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context, 2063 "*dexopt*"); 2064 mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper()); 2065 2066 mOnPermissionChangeListeners = new OnPermissionChangeListeners( 2067 FgThread.get().getLooper()); 2068 2069 getDefaultDisplayMetrics(context, mMetrics); 2070 2071 SystemConfig systemConfig = SystemConfig.getInstance(); 2072 mGlobalGids = systemConfig.getGlobalGids(); 2073 mSystemPermissions = systemConfig.getSystemPermissions(); 2074 mAvailableFeatures = systemConfig.getAvailableFeatures(); 2075 2076 synchronized (mInstallLock) { 2077 // writer 2078 synchronized (mPackages) { 2079 mHandlerThread = new ServiceThread(TAG, 2080 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/); 2081 mHandlerThread.start(); 2082 mHandler = new PackageHandler(mHandlerThread.getLooper()); 2083 Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT); 2084 2085 File dataDir = Environment.getDataDirectory(); 2086 mAppInstallDir = new File(dataDir, "app"); 2087 mAppLib32InstallDir = new File(dataDir, "app-lib"); 2088 mEphemeralInstallDir = new File(dataDir, "app-ephemeral"); 2089 mAsecInternalPath = new File(dataDir, "app-asec").getPath(); 2090 mDrmAppPrivateInstallDir = new File(dataDir, "app-private"); 2091 2092 sUserManager = new UserManagerService(context, this, mPackages); 2093 2094 // Propagate permission configuration in to package manager. 2095 ArrayMap<String, SystemConfig.PermissionEntry> permConfig 2096 = systemConfig.getPermissions(); 2097 for (int i=0; i<permConfig.size(); i++) { 2098 SystemConfig.PermissionEntry perm = permConfig.valueAt(i); 2099 BasePermission bp = mSettings.mPermissions.get(perm.name); 2100 if (bp == null) { 2101 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN); 2102 mSettings.mPermissions.put(perm.name, bp); 2103 } 2104 if (perm.gids != null) { 2105 bp.setGids(perm.gids, perm.perUser); 2106 } 2107 } 2108 2109 ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries(); 2110 for (int i=0; i<libConfig.size(); i++) { 2111 mSharedLibraries.put(libConfig.keyAt(i), 2112 new SharedLibraryEntry(libConfig.valueAt(i), null)); 2113 } 2114 2115 mFoundPolicyFile = SELinuxMMAC.readInstallPolicy(); 2116 2117 mRestoredSettings = mSettings.readLPw(sUserManager.getUsers(false)); 2118 2119 String customResolverActivity = Resources.getSystem().getString( 2120 R.string.config_customResolverActivity); 2121 if (TextUtils.isEmpty(customResolverActivity)) { 2122 customResolverActivity = null; 2123 } else { 2124 mCustomResolverComponentName = ComponentName.unflattenFromString( 2125 customResolverActivity); 2126 } 2127 2128 long startTime = SystemClock.uptimeMillis(); 2129 2130 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START, 2131 startTime); 2132 2133 // Set flag to monitor and not change apk file paths when 2134 // scanning install directories. 2135 final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING | SCAN_INITIAL; 2136 2137 final String bootClassPath = System.getenv("BOOTCLASSPATH"); 2138 final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH"); 2139 2140 if (bootClassPath == null) { 2141 Slog.w(TAG, "No BOOTCLASSPATH found!"); 2142 } 2143 2144 if (systemServerClassPath == null) { 2145 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!"); 2146 } 2147 2148 final List<String> allInstructionSets = InstructionSets.getAllInstructionSets(); 2149 final String[] dexCodeInstructionSets = 2150 getDexCodeInstructionSets( 2151 allInstructionSets.toArray(new String[allInstructionSets.size()])); 2152 2153 /** 2154 * Ensure all external libraries have had dexopt run on them. 2155 */ 2156 if (mSharedLibraries.size() > 0) { 2157 // NOTE: For now, we're compiling these system "shared libraries" 2158 // (and framework jars) into all available architectures. It's possible 2159 // to compile them only when we come across an app that uses them (there's 2160 // already logic for that in scanPackageLI) but that adds some complexity. 2161 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 2162 for (SharedLibraryEntry libEntry : mSharedLibraries.values()) { 2163 final String lib = libEntry.path; 2164 if (lib == null) { 2165 continue; 2166 } 2167 2168 try { 2169 int dexoptNeeded = DexFile.getDexOptNeeded(lib, null, dexCodeInstructionSet, false); 2170 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { 2171 // Shared libraries do not have profiles so we perform a full 2172 // AOT compilation. 2173 mInstaller.dexopt(lib, Process.SYSTEM_UID, dexCodeInstructionSet, 2174 dexoptNeeded, DEXOPT_PUBLIC /*dexFlags*/, 2175 StorageManager.UUID_PRIVATE_INTERNAL, 2176 false /*useProfiles*/); 2177 } 2178 } catch (FileNotFoundException e) { 2179 Slog.w(TAG, "Library not found: " + lib); 2180 } catch (IOException | InstallerException e) { 2181 Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? " 2182 + e.getMessage()); 2183 } 2184 } 2185 } 2186 } 2187 2188 File frameworkDir = new File(Environment.getRootDirectory(), "framework"); 2189 2190 final VersionInfo ver = mSettings.getInternalVersion(); 2191 mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint); 2192 // when upgrading from pre-M, promote system app permissions from install to runtime 2193 mPromoteSystemApps = 2194 mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1; 2195 2196 // save off the names of pre-existing system packages prior to scanning; we don't 2197 // want to automatically grant runtime permissions for new system apps 2198 if (mPromoteSystemApps) { 2199 Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator(); 2200 while (pkgSettingIter.hasNext()) { 2201 PackageSetting ps = pkgSettingIter.next(); 2202 if (isSystemApp(ps)) { 2203 mExistingSystemPackages.add(ps.name); 2204 } 2205 } 2206 } 2207 2208 // Collect vendor overlay packages. 2209 // (Do this before scanning any apps.) 2210 // For security and version matching reason, only consider 2211 // overlay packages if they reside in VENDOR_OVERLAY_DIR. 2212 File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR); 2213 scanDirTracedLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM 2214 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0); 2215 2216 // Find base frameworks (resource packages without code). 2217 scanDirTracedLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM 2218 | PackageParser.PARSE_IS_SYSTEM_DIR 2219 | PackageParser.PARSE_IS_PRIVILEGED, 2220 scanFlags | SCAN_NO_DEX, 0); 2221 2222 // Collected privileged system packages. 2223 final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app"); 2224 scanDirTracedLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM 2225 | PackageParser.PARSE_IS_SYSTEM_DIR 2226 | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0); 2227 2228 // Collect ordinary system packages. 2229 final File systemAppDir = new File(Environment.getRootDirectory(), "app"); 2230 scanDirTracedLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM 2231 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2232 2233 // Collect all vendor packages. 2234 File vendorAppDir = new File("/vendor/app"); 2235 try { 2236 vendorAppDir = vendorAppDir.getCanonicalFile(); 2237 } catch (IOException e) { 2238 // failed to look up canonical path, continue with original one 2239 } 2240 scanDirTracedLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM 2241 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2242 2243 // Collect all OEM packages. 2244 final File oemAppDir = new File(Environment.getOemDirectory(), "app"); 2245 scanDirTracedLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM 2246 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2247 2248 // Prune any system packages that no longer exist. 2249 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>(); 2250 if (!mOnlyCore) { 2251 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 2252 while (psit.hasNext()) { 2253 PackageSetting ps = psit.next(); 2254 2255 /* 2256 * If this is not a system app, it can't be a 2257 * disable system app. 2258 */ 2259 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) { 2260 continue; 2261 } 2262 2263 /* 2264 * If the package is scanned, it's not erased. 2265 */ 2266 final PackageParser.Package scannedPkg = mPackages.get(ps.name); 2267 if (scannedPkg != null) { 2268 /* 2269 * If the system app is both scanned and in the 2270 * disabled packages list, then it must have been 2271 * added via OTA. Remove it from the currently 2272 * scanned package so the previously user-installed 2273 * application can be scanned. 2274 */ 2275 if (mSettings.isDisabledSystemPackageLPr(ps.name)) { 2276 logCriticalInfo(Log.WARN, "Expecting better updated system app for " 2277 + ps.name + "; removing system app. Last known codePath=" 2278 + ps.codePathString + ", installStatus=" + ps.installStatus 2279 + ", versionCode=" + ps.versionCode + "; scanned versionCode=" 2280 + scannedPkg.mVersionCode); 2281 removePackageLI(scannedPkg, true); 2282 mExpectingBetter.put(ps.name, ps.codePath); 2283 } 2284 2285 continue; 2286 } 2287 2288 if (!mSettings.isDisabledSystemPackageLPr(ps.name)) { 2289 psit.remove(); 2290 logCriticalInfo(Log.WARN, "System package " + ps.name 2291 + " no longer exists; wiping its data"); 2292 removeDataDirsLI(null, ps.name); 2293 } else { 2294 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name); 2295 if (disabledPs.codePath == null || !disabledPs.codePath.exists()) { 2296 possiblyDeletedUpdatedSystemApps.add(ps.name); 2297 } 2298 } 2299 } 2300 } 2301 2302 //look for any incomplete package installations 2303 ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr(); 2304 //clean up list 2305 for(int i = 0; i < deletePkgsList.size(); i++) { 2306 //clean up here 2307 cleanupInstallFailedPackage(deletePkgsList.get(i)); 2308 } 2309 //delete tmp files 2310 deleteTempPackageFiles(); 2311 2312 // Remove any shared userIDs that have no associated packages 2313 mSettings.pruneSharedUsersLPw(); 2314 2315 if (!mOnlyCore) { 2316 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START, 2317 SystemClock.uptimeMillis()); 2318 scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0); 2319 2320 scanDirTracedLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK, 2321 scanFlags | SCAN_REQUIRE_KNOWN, 0); 2322 2323 scanDirLI(mEphemeralInstallDir, PackageParser.PARSE_IS_EPHEMERAL, 2324 scanFlags | SCAN_REQUIRE_KNOWN, 0); 2325 2326 /** 2327 * Remove disable package settings for any updated system 2328 * apps that were removed via an OTA. If they're not a 2329 * previously-updated app, remove them completely. 2330 * Otherwise, just revoke their system-level permissions. 2331 */ 2332 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) { 2333 PackageParser.Package deletedPkg = mPackages.get(deletedAppName); 2334 mSettings.removeDisabledSystemPackageLPw(deletedAppName); 2335 2336 String msg; 2337 if (deletedPkg == null) { 2338 msg = "Updated system package " + deletedAppName 2339 + " no longer exists; wiping its data"; 2340 removeDataDirsLI(null, deletedAppName); 2341 } else { 2342 msg = "Updated system app + " + deletedAppName 2343 + " no longer present; removing system privileges for " 2344 + deletedAppName; 2345 2346 deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM; 2347 2348 PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName); 2349 deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM; 2350 } 2351 logCriticalInfo(Log.WARN, msg); 2352 } 2353 2354 /** 2355 * Make sure all system apps that we expected to appear on 2356 * the userdata partition actually showed up. If they never 2357 * appeared, crawl back and revive the system version. 2358 */ 2359 for (int i = 0; i < mExpectingBetter.size(); i++) { 2360 final String packageName = mExpectingBetter.keyAt(i); 2361 if (!mPackages.containsKey(packageName)) { 2362 final File scanFile = mExpectingBetter.valueAt(i); 2363 2364 logCriticalInfo(Log.WARN, "Expected better " + packageName 2365 + " but never showed up; reverting to system"); 2366 2367 final int reparseFlags; 2368 if (FileUtils.contains(privilegedAppDir, scanFile)) { 2369 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2370 | PackageParser.PARSE_IS_SYSTEM_DIR 2371 | PackageParser.PARSE_IS_PRIVILEGED; 2372 } else if (FileUtils.contains(systemAppDir, scanFile)) { 2373 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2374 | PackageParser.PARSE_IS_SYSTEM_DIR; 2375 } else if (FileUtils.contains(vendorAppDir, scanFile)) { 2376 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2377 | PackageParser.PARSE_IS_SYSTEM_DIR; 2378 } else if (FileUtils.contains(oemAppDir, scanFile)) { 2379 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2380 | PackageParser.PARSE_IS_SYSTEM_DIR; 2381 } else { 2382 Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile); 2383 continue; 2384 } 2385 2386 mSettings.enableSystemPackageLPw(packageName); 2387 2388 try { 2389 scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null); 2390 } catch (PackageManagerException e) { 2391 Slog.e(TAG, "Failed to parse original system package: " 2392 + e.getMessage()); 2393 } 2394 } 2395 } 2396 } 2397 mExpectingBetter.clear(); 2398 2399 // Now that we know all of the shared libraries, update all clients to have 2400 // the correct library paths. 2401 updateAllSharedLibrariesLPw(); 2402 2403 for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) { 2404 // NOTE: We ignore potential failures here during a system scan (like 2405 // the rest of the commands above) because there's precious little we 2406 // can do about it. A settings error is reported, though. 2407 adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */, 2408 false /* boot complete */); 2409 } 2410 2411 // Now that we know all the packages we are keeping, 2412 // read and update their last usage times. 2413 mPackageUsage.readLP(); 2414 2415 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END, 2416 SystemClock.uptimeMillis()); 2417 Slog.i(TAG, "Time to scan packages: " 2418 + ((SystemClock.uptimeMillis()-startTime)/1000f) 2419 + " seconds"); 2420 2421 // If the platform SDK has changed since the last time we booted, 2422 // we need to re-grant app permission to catch any new ones that 2423 // appear. This is really a hack, and means that apps can in some 2424 // cases get permissions that the user didn't initially explicitly 2425 // allow... it would be nice to have some better way to handle 2426 // this situation. 2427 int updateFlags = UPDATE_PERMISSIONS_ALL; 2428 if (ver.sdkVersion != mSdkVersion) { 2429 Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to " 2430 + mSdkVersion + "; regranting permissions for internal storage"); 2431 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 2432 } 2433 updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags); 2434 ver.sdkVersion = mSdkVersion; 2435 2436 // If this is the first boot or an update from pre-M, and it is a normal 2437 // boot, then we need to initialize the default preferred apps across 2438 // all defined users. 2439 if (!onlyCore && (mPromoteSystemApps || !mRestoredSettings)) { 2440 for (UserInfo user : sUserManager.getUsers(true)) { 2441 mSettings.applyDefaultPreferredAppsLPw(this, user.id); 2442 applyFactoryDefaultBrowserLPw(user.id); 2443 primeDomainVerificationsLPw(user.id); 2444 } 2445 } 2446 2447 // Prepare storage for system user really early during boot, 2448 // since core system apps like SettingsProvider and SystemUI 2449 // can't wait for user to start 2450 final int storageFlags; 2451 if (StorageManager.isFileBasedEncryptionEnabled()) { 2452 storageFlags = StorageManager.FLAG_STORAGE_DE; 2453 } else { 2454 storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 2455 } 2456 reconcileAppsData(StorageManager.UUID_PRIVATE_INTERNAL, UserHandle.USER_SYSTEM, 2457 storageFlags); 2458 2459 // If this is first boot after an OTA, and a normal boot, then 2460 // we need to clear code cache directories. 2461 if (mIsUpgrade && !onlyCore) { 2462 Slog.i(TAG, "Build fingerprint changed; clearing code caches"); 2463 for (int i = 0; i < mSettings.mPackages.size(); i++) { 2464 final PackageSetting ps = mSettings.mPackages.valueAt(i); 2465 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) { 2466 deleteCodeCacheDirsLI(ps.volumeUuid, ps.name); 2467 } 2468 } 2469 ver.fingerprint = Build.FINGERPRINT; 2470 } 2471 2472 checkDefaultBrowser(); 2473 2474 // clear only after permissions and other defaults have been updated 2475 mExistingSystemPackages.clear(); 2476 mPromoteSystemApps = false; 2477 2478 // All the changes are done during package scanning. 2479 ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION; 2480 2481 // can downgrade to reader 2482 mSettings.writeLPr(); 2483 2484 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY, 2485 SystemClock.uptimeMillis()); 2486 2487 if (!mOnlyCore) { 2488 mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr(); 2489 mRequiredInstallerPackage = getRequiredInstallerLPr(); 2490 mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr(); 2491 mIntentFilterVerifier = new IntentVerifierProxy(mContext, 2492 mIntentFilterVerifierComponent); 2493 } else { 2494 mRequiredVerifierPackage = null; 2495 mRequiredInstallerPackage = null; 2496 mIntentFilterVerifierComponent = null; 2497 mIntentFilterVerifier = null; 2498 } 2499 2500 mInstallerService = new PackageInstallerService(context, this); 2501 2502 final ComponentName ephemeralResolverComponent = getEphemeralResolverLPr(); 2503 final ComponentName ephemeralInstallerComponent = getEphemeralInstallerLPr(); 2504 // both the installer and resolver must be present to enable ephemeral 2505 if (ephemeralInstallerComponent != null && ephemeralResolverComponent != null) { 2506 if (DEBUG_EPHEMERAL) { 2507 Slog.i(TAG, "Ephemeral activated; resolver: " + ephemeralResolverComponent 2508 + " installer:" + ephemeralInstallerComponent); 2509 } 2510 mEphemeralResolverComponent = ephemeralResolverComponent; 2511 mEphemeralInstallerComponent = ephemeralInstallerComponent; 2512 setUpEphemeralInstallerActivityLP(mEphemeralInstallerComponent); 2513 mEphemeralResolverConnection = 2514 new EphemeralResolverConnection(mContext, mEphemeralResolverComponent); 2515 } else { 2516 if (DEBUG_EPHEMERAL) { 2517 final String missingComponent = 2518 (ephemeralResolverComponent == null) 2519 ? (ephemeralInstallerComponent == null) 2520 ? "resolver and installer" 2521 : "resolver" 2522 : "installer"; 2523 Slog.i(TAG, "Ephemeral deactivated; missing " + missingComponent); 2524 } 2525 mEphemeralResolverComponent = null; 2526 mEphemeralInstallerComponent = null; 2527 mEphemeralResolverConnection = null; 2528 } 2529 2530 mEphemeralApplicationRegistry = new EphemeralApplicationRegistry(this); 2531 } // synchronized (mPackages) 2532 } // synchronized (mInstallLock) 2533 2534 // Now after opening every single application zip, make sure they 2535 // are all flushed. Not really needed, but keeps things nice and 2536 // tidy. 2537 Runtime.getRuntime().gc(); 2538 2539 // The initial scanning above does many calls into installd while 2540 // holding the mPackages lock, but we're mostly interested in yelling 2541 // once we have a booted system. 2542 mInstaller.setWarnIfHeld(mPackages); 2543 2544 // Expose private service for system components to use. 2545 LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl()); 2546 } 2547 2548 @Override 2549 public boolean isFirstBoot() { 2550 return !mRestoredSettings; 2551 } 2552 2553 @Override 2554 public boolean isOnlyCoreApps() { 2555 return mOnlyCore; 2556 } 2557 2558 @Override 2559 public boolean isUpgrade() { 2560 return mIsUpgrade; 2561 } 2562 2563 private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() { 2564 final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 2565 2566 final List<ResolveInfo> matches = queryIntentReceivers(intent, PACKAGE_MIME_TYPE, 2567 MATCH_SYSTEM_ONLY | MATCH_ENCRYPTION_AWARE_AND_UNAWARE, UserHandle.USER_SYSTEM); 2568 if (matches.size() == 1) { 2569 return matches.get(0).getComponentInfo().packageName; 2570 } else { 2571 Log.e(TAG, "There should probably be exactly one verifier; found " + matches); 2572 return null; 2573 } 2574 } 2575 2576 private @NonNull String getRequiredInstallerLPr() { 2577 final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE); 2578 intent.addCategory(Intent.CATEGORY_DEFAULT); 2579 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE); 2580 2581 final List<ResolveInfo> matches = queryIntentActivities(intent, PACKAGE_MIME_TYPE, 2582 MATCH_SYSTEM_ONLY | MATCH_ENCRYPTION_AWARE_AND_UNAWARE, UserHandle.USER_SYSTEM); 2583 if (matches.size() == 1) { 2584 return matches.get(0).getComponentInfo().packageName; 2585 } else { 2586 throw new RuntimeException("There must be exactly one installer; found " + matches); 2587 } 2588 } 2589 2590 private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() { 2591 final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 2592 2593 final List<ResolveInfo> matches = queryIntentReceivers(intent, PACKAGE_MIME_TYPE, 2594 MATCH_SYSTEM_ONLY | MATCH_ENCRYPTION_AWARE_AND_UNAWARE, UserHandle.USER_SYSTEM); 2595 ResolveInfo best = null; 2596 final int N = matches.size(); 2597 for (int i = 0; i < N; i++) { 2598 final ResolveInfo cur = matches.get(i); 2599 final String packageName = cur.getComponentInfo().packageName; 2600 if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 2601 packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) { 2602 continue; 2603 } 2604 2605 if (best == null || cur.priority > best.priority) { 2606 best = cur; 2607 } 2608 } 2609 2610 if (best != null) { 2611 return best.getComponentInfo().getComponentName(); 2612 } else { 2613 throw new RuntimeException("There must be at least one intent filter verifier"); 2614 } 2615 } 2616 2617 private @Nullable ComponentName getEphemeralResolverLPr() { 2618 final String[] packageArray = 2619 mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage); 2620 if (packageArray.length == 0) { 2621 if (DEBUG_EPHEMERAL) { 2622 Slog.d(TAG, "Ephemeral resolver NOT found; empty package list"); 2623 } 2624 return null; 2625 } 2626 2627 final Intent resolverIntent = new Intent(Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE); 2628 final List<ResolveInfo> resolvers = queryIntentServices(resolverIntent, null, 2629 MATCH_SYSTEM_ONLY | MATCH_ENCRYPTION_AWARE_AND_UNAWARE, UserHandle.USER_SYSTEM); 2630 2631 final int N = resolvers.size(); 2632 if (N == 0) { 2633 if (DEBUG_EPHEMERAL) { 2634 Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters"); 2635 } 2636 return null; 2637 } 2638 2639 final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray)); 2640 for (int i = 0; i < N; i++) { 2641 final ResolveInfo info = resolvers.get(i); 2642 2643 if (info.serviceInfo == null) { 2644 continue; 2645 } 2646 2647 final String packageName = info.serviceInfo.packageName; 2648 if (!possiblePackages.contains(packageName)) { 2649 if (DEBUG_EPHEMERAL) { 2650 Slog.d(TAG, "Ephemeral resolver not in allowed package list;" 2651 + " pkg: " + packageName + ", info:" + info); 2652 } 2653 continue; 2654 } 2655 2656 if (DEBUG_EPHEMERAL) { 2657 Slog.v(TAG, "Ephemeral resolver found;" 2658 + " pkg: " + packageName + ", info:" + info); 2659 } 2660 return new ComponentName(packageName, info.serviceInfo.name); 2661 } 2662 if (DEBUG_EPHEMERAL) { 2663 Slog.v(TAG, "Ephemeral resolver NOT found"); 2664 } 2665 return null; 2666 } 2667 2668 private @Nullable ComponentName getEphemeralInstallerLPr() { 2669 final Intent intent = new Intent(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE); 2670 intent.addCategory(Intent.CATEGORY_DEFAULT); 2671 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE); 2672 2673 final List<ResolveInfo> matches = queryIntentActivities(intent, PACKAGE_MIME_TYPE, 2674 MATCH_SYSTEM_ONLY | MATCH_ENCRYPTION_AWARE_AND_UNAWARE, UserHandle.USER_SYSTEM); 2675 if (matches.size() == 0) { 2676 return null; 2677 } else if (matches.size() == 1) { 2678 return matches.get(0).getComponentInfo().getComponentName(); 2679 } else { 2680 throw new RuntimeException( 2681 "There must be at most one ephemeral installer; found " + matches); 2682 } 2683 } 2684 2685 private void primeDomainVerificationsLPw(int userId) { 2686 if (DEBUG_DOMAIN_VERIFICATION) { 2687 Slog.d(TAG, "Priming domain verifications in user " + userId); 2688 } 2689 2690 SystemConfig systemConfig = SystemConfig.getInstance(); 2691 ArraySet<String> packages = systemConfig.getLinkedApps(); 2692 ArraySet<String> domains = new ArraySet<String>(); 2693 2694 for (String packageName : packages) { 2695 PackageParser.Package pkg = mPackages.get(packageName); 2696 if (pkg != null) { 2697 if (!pkg.isSystemApp()) { 2698 Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>"); 2699 continue; 2700 } 2701 2702 domains.clear(); 2703 for (PackageParser.Activity a : pkg.activities) { 2704 for (ActivityIntentInfo filter : a.intents) { 2705 if (hasValidDomains(filter)) { 2706 domains.addAll(filter.getHostsList()); 2707 } 2708 } 2709 } 2710 2711 if (domains.size() > 0) { 2712 if (DEBUG_DOMAIN_VERIFICATION) { 2713 Slog.v(TAG, " + " + packageName); 2714 } 2715 // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual 2716 // state w.r.t. the formal app-linkage "no verification attempted" state; 2717 // and then 'always' in the per-user state actually used for intent resolution. 2718 final IntentFilterVerificationInfo ivi; 2719 ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, 2720 new ArrayList<String>(domains)); 2721 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED); 2722 mSettings.updateIntentFilterVerificationStatusLPw(packageName, 2723 INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId); 2724 } else { 2725 Slog.w(TAG, "Sysconfig <app-link> package '" + packageName 2726 + "' does not handle web links"); 2727 } 2728 } else { 2729 Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>"); 2730 } 2731 } 2732 2733 scheduleWritePackageRestrictionsLocked(userId); 2734 scheduleWriteSettingsLocked(); 2735 } 2736 2737 private void applyFactoryDefaultBrowserLPw(int userId) { 2738 // The default browser app's package name is stored in a string resource, 2739 // with a product-specific overlay used for vendor customization. 2740 String browserPkg = mContext.getResources().getString( 2741 com.android.internal.R.string.default_browser); 2742 if (!TextUtils.isEmpty(browserPkg)) { 2743 // non-empty string => required to be a known package 2744 PackageSetting ps = mSettings.mPackages.get(browserPkg); 2745 if (ps == null) { 2746 Slog.e(TAG, "Product default browser app does not exist: " + browserPkg); 2747 browserPkg = null; 2748 } else { 2749 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId); 2750 } 2751 } 2752 2753 // Nothing valid explicitly set? Make the factory-installed browser the explicit 2754 // default. If there's more than one, just leave everything alone. 2755 if (browserPkg == null) { 2756 calculateDefaultBrowserLPw(userId); 2757 } 2758 } 2759 2760 private void calculateDefaultBrowserLPw(int userId) { 2761 List<String> allBrowsers = resolveAllBrowserApps(userId); 2762 final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null; 2763 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId); 2764 } 2765 2766 private List<String> resolveAllBrowserApps(int userId) { 2767 // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set 2768 List<ResolveInfo> list = queryIntentActivities(sBrowserIntent, null, 2769 PackageManager.MATCH_ALL, userId); 2770 2771 final int count = list.size(); 2772 List<String> result = new ArrayList<String>(count); 2773 for (int i=0; i<count; i++) { 2774 ResolveInfo info = list.get(i); 2775 if (info.activityInfo == null 2776 || !info.handleAllWebDataURI 2777 || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0 2778 || result.contains(info.activityInfo.packageName)) { 2779 continue; 2780 } 2781 result.add(info.activityInfo.packageName); 2782 } 2783 2784 return result; 2785 } 2786 2787 private boolean packageIsBrowser(String packageName, int userId) { 2788 List<ResolveInfo> list = queryIntentActivities(sBrowserIntent, null, 2789 PackageManager.MATCH_ALL, userId); 2790 final int N = list.size(); 2791 for (int i = 0; i < N; i++) { 2792 ResolveInfo info = list.get(i); 2793 if (packageName.equals(info.activityInfo.packageName)) { 2794 return true; 2795 } 2796 } 2797 return false; 2798 } 2799 2800 private void checkDefaultBrowser() { 2801 final int myUserId = UserHandle.myUserId(); 2802 final String packageName = getDefaultBrowserPackageName(myUserId); 2803 if (packageName != null) { 2804 PackageInfo info = getPackageInfo(packageName, 0, myUserId); 2805 if (info == null) { 2806 Slog.w(TAG, "Default browser no longer installed: " + packageName); 2807 synchronized (mPackages) { 2808 applyFactoryDefaultBrowserLPw(myUserId); // leaves ambiguous when > 1 2809 } 2810 } 2811 } 2812 } 2813 2814 @Override 2815 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2816 throws RemoteException { 2817 try { 2818 return super.onTransact(code, data, reply, flags); 2819 } catch (RuntimeException e) { 2820 if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) { 2821 Slog.wtf(TAG, "Package Manager Crash", e); 2822 } 2823 throw e; 2824 } 2825 } 2826 2827 void cleanupInstallFailedPackage(PackageSetting ps) { 2828 logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + ps.name); 2829 2830 removeDataDirsLI(ps.volumeUuid, ps.name); 2831 if (ps.codePath != null) { 2832 removeCodePathLI(ps.codePath); 2833 } 2834 if (ps.resourcePath != null && !ps.resourcePath.equals(ps.codePath)) { 2835 if (ps.resourcePath.isDirectory()) { 2836 FileUtils.deleteContents(ps.resourcePath); 2837 } 2838 ps.resourcePath.delete(); 2839 } 2840 mSettings.removePackageLPw(ps.name); 2841 } 2842 2843 static int[] appendInts(int[] cur, int[] add) { 2844 if (add == null) return cur; 2845 if (cur == null) return add; 2846 final int N = add.length; 2847 for (int i=0; i<N; i++) { 2848 cur = appendInt(cur, add[i]); 2849 } 2850 return cur; 2851 } 2852 2853 PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) { 2854 if (!sUserManager.exists(userId)) return null; 2855 final PackageSetting ps = (PackageSetting) p.mExtras; 2856 if (ps == null) { 2857 return null; 2858 } 2859 2860 final PermissionsState permissionsState = ps.getPermissionsState(); 2861 2862 final int[] gids = permissionsState.computeGids(userId); 2863 final Set<String> permissions = permissionsState.getPermissions(userId); 2864 final PackageUserState state = ps.readUserState(userId); 2865 2866 return PackageParser.generatePackageInfo(p, gids, flags, 2867 ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId); 2868 } 2869 2870 @Override 2871 public void checkPackageStartable(String packageName, int userId) { 2872 final boolean userKeyUnlocked = isUserKeyUnlocked(userId); 2873 2874 synchronized (mPackages) { 2875 final PackageSetting ps = mSettings.mPackages.get(packageName); 2876 if (ps == null) { 2877 throw new SecurityException("Package " + packageName + " was not found!"); 2878 } 2879 2880 if (mSafeMode && !ps.isSystem()) { 2881 throw new SecurityException("Package " + packageName + " not a system app!"); 2882 } 2883 2884 if (ps.frozen) { 2885 throw new SecurityException("Package " + packageName + " is currently frozen!"); 2886 } 2887 2888 if (!userKeyUnlocked && !(ps.pkg.applicationInfo.isEncryptionAware() 2889 || ps.pkg.applicationInfo.isPartiallyEncryptionAware())) { 2890 throw new SecurityException("Package " + packageName + " is not encryption aware!"); 2891 } 2892 } 2893 } 2894 2895 @Override 2896 public boolean isPackageAvailable(String packageName, int userId) { 2897 if (!sUserManager.exists(userId)) return false; 2898 enforceCrossUserPermission(Binder.getCallingUid(), userId, 2899 false /* requireFullPermission */, false /* checkShell */, "is package available"); 2900 synchronized (mPackages) { 2901 PackageParser.Package p = mPackages.get(packageName); 2902 if (p != null) { 2903 final PackageSetting ps = (PackageSetting) p.mExtras; 2904 if (ps != null) { 2905 final PackageUserState state = ps.readUserState(userId); 2906 if (state != null) { 2907 return PackageParser.isAvailable(state); 2908 } 2909 } 2910 } 2911 } 2912 return false; 2913 } 2914 2915 @Override 2916 public PackageInfo getPackageInfo(String packageName, int flags, int userId) { 2917 if (!sUserManager.exists(userId)) return null; 2918 flags = updateFlagsForPackage(flags, userId, packageName); 2919 enforceCrossUserPermission(Binder.getCallingUid(), userId, 2920 false /* requireFullPermission */, false /* checkShell */, "get package info"); 2921 // reader 2922 synchronized (mPackages) { 2923 PackageParser.Package p = mPackages.get(packageName); 2924 if (DEBUG_PACKAGE_INFO) 2925 Log.v(TAG, "getPackageInfo " + packageName + ": " + p); 2926 if (p != null) { 2927 return generatePackageInfo(p, flags, userId); 2928 } 2929 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 2930 return generatePackageInfoFromSettingsLPw(packageName, flags, userId); 2931 } 2932 } 2933 return null; 2934 } 2935 2936 @Override 2937 public String[] currentToCanonicalPackageNames(String[] names) { 2938 String[] out = new String[names.length]; 2939 // reader 2940 synchronized (mPackages) { 2941 for (int i=names.length-1; i>=0; i--) { 2942 PackageSetting ps = mSettings.mPackages.get(names[i]); 2943 out[i] = ps != null && ps.realName != null ? ps.realName : names[i]; 2944 } 2945 } 2946 return out; 2947 } 2948 2949 @Override 2950 public String[] canonicalToCurrentPackageNames(String[] names) { 2951 String[] out = new String[names.length]; 2952 // reader 2953 synchronized (mPackages) { 2954 for (int i=names.length-1; i>=0; i--) { 2955 String cur = mSettings.mRenamedPackages.get(names[i]); 2956 out[i] = cur != null ? cur : names[i]; 2957 } 2958 } 2959 return out; 2960 } 2961 2962 @Override 2963 public int getPackageUid(String packageName, int flags, int userId) { 2964 if (!sUserManager.exists(userId)) return -1; 2965 flags = updateFlagsForPackage(flags, userId, packageName); 2966 enforceCrossUserPermission(Binder.getCallingUid(), userId, 2967 false /* requireFullPermission */, false /* checkShell */, "get package uid"); 2968 2969 // reader 2970 synchronized (mPackages) { 2971 final PackageParser.Package p = mPackages.get(packageName); 2972 if (p != null && p.isMatch(flags)) { 2973 return UserHandle.getUid(userId, p.applicationInfo.uid); 2974 } 2975 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 2976 final PackageSetting ps = mSettings.mPackages.get(packageName); 2977 if (ps != null && ps.isMatch(flags)) { 2978 return UserHandle.getUid(userId, ps.appId); 2979 } 2980 } 2981 } 2982 2983 return -1; 2984 } 2985 2986 @Override 2987 public int[] getPackageGids(String packageName, int flags, int userId) { 2988 if (!sUserManager.exists(userId)) return null; 2989 flags = updateFlagsForPackage(flags, userId, packageName); 2990 enforceCrossUserPermission(Binder.getCallingUid(), userId, 2991 false /* requireFullPermission */, false /* checkShell */, 2992 "getPackageGids"); 2993 2994 // reader 2995 synchronized (mPackages) { 2996 final PackageParser.Package p = mPackages.get(packageName); 2997 if (p != null && p.isMatch(flags)) { 2998 PackageSetting ps = (PackageSetting) p.mExtras; 2999 return ps.getPermissionsState().computeGids(userId); 3000 } 3001 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 3002 final PackageSetting ps = mSettings.mPackages.get(packageName); 3003 if (ps != null && ps.isMatch(flags)) { 3004 return ps.getPermissionsState().computeGids(userId); 3005 } 3006 } 3007 } 3008 3009 return null; 3010 } 3011 3012 static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) { 3013 if (bp.perm != null) { 3014 return PackageParser.generatePermissionInfo(bp.perm, flags); 3015 } 3016 PermissionInfo pi = new PermissionInfo(); 3017 pi.name = bp.name; 3018 pi.packageName = bp.sourcePackage; 3019 pi.nonLocalizedLabel = bp.name; 3020 pi.protectionLevel = bp.protectionLevel; 3021 return pi; 3022 } 3023 3024 @Override 3025 public PermissionInfo getPermissionInfo(String name, int flags) { 3026 // reader 3027 synchronized (mPackages) { 3028 final BasePermission p = mSettings.mPermissions.get(name); 3029 if (p != null) { 3030 return generatePermissionInfo(p, flags); 3031 } 3032 return null; 3033 } 3034 } 3035 3036 @Override 3037 public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) { 3038 // reader 3039 synchronized (mPackages) { 3040 ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10); 3041 for (BasePermission p : mSettings.mPermissions.values()) { 3042 if (group == null) { 3043 if (p.perm == null || p.perm.info.group == null) { 3044 out.add(generatePermissionInfo(p, flags)); 3045 } 3046 } else { 3047 if (p.perm != null && group.equals(p.perm.info.group)) { 3048 out.add(PackageParser.generatePermissionInfo(p.perm, flags)); 3049 } 3050 } 3051 } 3052 3053 if (out.size() > 0) { 3054 return out; 3055 } 3056 return mPermissionGroups.containsKey(group) ? out : null; 3057 } 3058 } 3059 3060 @Override 3061 public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) { 3062 // reader 3063 synchronized (mPackages) { 3064 return PackageParser.generatePermissionGroupInfo( 3065 mPermissionGroups.get(name), flags); 3066 } 3067 } 3068 3069 @Override 3070 public List<PermissionGroupInfo> getAllPermissionGroups(int flags) { 3071 // reader 3072 synchronized (mPackages) { 3073 final int N = mPermissionGroups.size(); 3074 ArrayList<PermissionGroupInfo> out 3075 = new ArrayList<PermissionGroupInfo>(N); 3076 for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) { 3077 out.add(PackageParser.generatePermissionGroupInfo(pg, flags)); 3078 } 3079 return out; 3080 } 3081 } 3082 3083 private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags, 3084 int userId) { 3085 if (!sUserManager.exists(userId)) return null; 3086 PackageSetting ps = mSettings.mPackages.get(packageName); 3087 if (ps != null) { 3088 if (ps.pkg == null) { 3089 PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName, 3090 flags, userId); 3091 if (pInfo != null) { 3092 return pInfo.applicationInfo; 3093 } 3094 return null; 3095 } 3096 return PackageParser.generateApplicationInfo(ps.pkg, flags, 3097 ps.readUserState(userId), userId); 3098 } 3099 return null; 3100 } 3101 3102 private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags, 3103 int userId) { 3104 if (!sUserManager.exists(userId)) return null; 3105 PackageSetting ps = mSettings.mPackages.get(packageName); 3106 if (ps != null) { 3107 PackageParser.Package pkg = ps.pkg; 3108 if (pkg == null) { 3109 if ((flags & MATCH_UNINSTALLED_PACKAGES) == 0) { 3110 return null; 3111 } 3112 // Only data remains, so we aren't worried about code paths 3113 pkg = new PackageParser.Package(packageName); 3114 pkg.applicationInfo.packageName = packageName; 3115 pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY; 3116 pkg.applicationInfo.privateFlags = ps.pkgPrivateFlags; 3117 pkg.applicationInfo.uid = ps.appId; 3118 pkg.applicationInfo.initForUser(userId); 3119 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString; 3120 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString; 3121 } 3122 return generatePackageInfo(pkg, flags, userId); 3123 } 3124 return null; 3125 } 3126 3127 @Override 3128 public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) { 3129 if (!sUserManager.exists(userId)) return null; 3130 flags = updateFlagsForApplication(flags, userId, packageName); 3131 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3132 false /* requireFullPermission */, false /* checkShell */, "get application info"); 3133 // writer 3134 synchronized (mPackages) { 3135 PackageParser.Package p = mPackages.get(packageName); 3136 if (DEBUG_PACKAGE_INFO) Log.v( 3137 TAG, "getApplicationInfo " + packageName 3138 + ": " + p); 3139 if (p != null) { 3140 PackageSetting ps = mSettings.mPackages.get(packageName); 3141 if (ps == null) return null; 3142 // Note: isEnabledLP() does not apply here - always return info 3143 return PackageParser.generateApplicationInfo( 3144 p, flags, ps.readUserState(userId), userId); 3145 } 3146 if ("android".equals(packageName)||"system".equals(packageName)) { 3147 return mAndroidApplication; 3148 } 3149 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 3150 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId); 3151 } 3152 } 3153 return null; 3154 } 3155 3156 @Override 3157 public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize, 3158 final IPackageDataObserver observer) { 3159 mContext.enforceCallingOrSelfPermission( 3160 android.Manifest.permission.CLEAR_APP_CACHE, null); 3161 // Queue up an async operation since clearing cache may take a little while. 3162 mHandler.post(new Runnable() { 3163 public void run() { 3164 mHandler.removeCallbacks(this); 3165 boolean success = true; 3166 synchronized (mInstallLock) { 3167 try { 3168 mInstaller.freeCache(volumeUuid, freeStorageSize); 3169 } catch (InstallerException e) { 3170 Slog.w(TAG, "Couldn't clear application caches: " + e); 3171 success = false; 3172 } 3173 } 3174 if (observer != null) { 3175 try { 3176 observer.onRemoveCompleted(null, success); 3177 } catch (RemoteException e) { 3178 Slog.w(TAG, "RemoveException when invoking call back"); 3179 } 3180 } 3181 } 3182 }); 3183 } 3184 3185 @Override 3186 public void freeStorage(final String volumeUuid, final long freeStorageSize, 3187 final IntentSender pi) { 3188 mContext.enforceCallingOrSelfPermission( 3189 android.Manifest.permission.CLEAR_APP_CACHE, null); 3190 // Queue up an async operation since clearing cache may take a little while. 3191 mHandler.post(new Runnable() { 3192 public void run() { 3193 mHandler.removeCallbacks(this); 3194 boolean success = true; 3195 synchronized (mInstallLock) { 3196 try { 3197 mInstaller.freeCache(volumeUuid, freeStorageSize); 3198 } catch (InstallerException e) { 3199 Slog.w(TAG, "Couldn't clear application caches: " + e); 3200 success = false; 3201 } 3202 } 3203 if(pi != null) { 3204 try { 3205 // Callback via pending intent 3206 int code = success ? 1 : 0; 3207 pi.sendIntent(null, code, null, 3208 null, null); 3209 } catch (SendIntentException e1) { 3210 Slog.i(TAG, "Failed to send pending intent"); 3211 } 3212 } 3213 } 3214 }); 3215 } 3216 3217 void freeStorage(String volumeUuid, long freeStorageSize) throws IOException { 3218 synchronized (mInstallLock) { 3219 try { 3220 mInstaller.freeCache(volumeUuid, freeStorageSize); 3221 } catch (InstallerException e) { 3222 throw new IOException("Failed to free enough space", e); 3223 } 3224 } 3225 } 3226 3227 /** 3228 * Return if the user key is currently unlocked. 3229 */ 3230 private boolean isUserKeyUnlocked(int userId) { 3231 if (StorageManager.isFileBasedEncryptionEnabled()) { 3232 final IMountService mount = IMountService.Stub 3233 .asInterface(ServiceManager.getService("mount")); 3234 if (mount == null) { 3235 Slog.w(TAG, "Early during boot, assuming locked"); 3236 return false; 3237 } 3238 final long token = Binder.clearCallingIdentity(); 3239 try { 3240 return mount.isUserKeyUnlocked(userId); 3241 } catch (RemoteException e) { 3242 throw e.rethrowAsRuntimeException(); 3243 } finally { 3244 Binder.restoreCallingIdentity(token); 3245 } 3246 } else { 3247 return true; 3248 } 3249 } 3250 3251 /** 3252 * Update given flags based on encryption status of current user. 3253 */ 3254 private int updateFlags(int flags, int userId) { 3255 if ((flags & (PackageManager.MATCH_ENCRYPTION_UNAWARE 3256 | PackageManager.MATCH_ENCRYPTION_AWARE)) != 0) { 3257 // Caller expressed an explicit opinion about what encryption 3258 // aware/unaware components they want to see, so fall through and 3259 // give them what they want 3260 } else { 3261 // Caller expressed no opinion, so match based on user state 3262 if (isUserKeyUnlocked(userId)) { 3263 flags |= PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE; 3264 } else { 3265 flags |= PackageManager.MATCH_ENCRYPTION_AWARE; 3266 } 3267 } 3268 return flags; 3269 } 3270 3271 /** 3272 * Update given flags when being used to request {@link PackageInfo}. 3273 */ 3274 private int updateFlagsForPackage(int flags, int userId, Object cookie) { 3275 boolean triaged = true; 3276 if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS 3277 | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) { 3278 // Caller is asking for component details, so they'd better be 3279 // asking for specific encryption matching behavior, or be triaged 3280 if ((flags & (PackageManager.MATCH_ENCRYPTION_UNAWARE 3281 | PackageManager.MATCH_ENCRYPTION_AWARE 3282 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3283 triaged = false; 3284 } 3285 } 3286 if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES 3287 | PackageManager.MATCH_SYSTEM_ONLY 3288 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3289 triaged = false; 3290 } 3291 if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) { 3292 Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie 3293 + " with flags 0x" + Integer.toHexString(flags), new Throwable()); 3294 } 3295 return updateFlags(flags, userId); 3296 } 3297 3298 /** 3299 * Update given flags when being used to request {@link ApplicationInfo}. 3300 */ 3301 private int updateFlagsForApplication(int flags, int userId, Object cookie) { 3302 return updateFlagsForPackage(flags, userId, cookie); 3303 } 3304 3305 /** 3306 * Update given flags when being used to request {@link ComponentInfo}. 3307 */ 3308 private int updateFlagsForComponent(int flags, int userId, Object cookie) { 3309 if (cookie instanceof Intent) { 3310 if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) { 3311 flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING; 3312 } 3313 } 3314 3315 boolean triaged = true; 3316 // Caller is asking for component details, so they'd better be 3317 // asking for specific encryption matching behavior, or be triaged 3318 if ((flags & (PackageManager.MATCH_ENCRYPTION_UNAWARE 3319 | PackageManager.MATCH_ENCRYPTION_AWARE 3320 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3321 triaged = false; 3322 } 3323 if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) { 3324 Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie 3325 + " with flags 0x" + Integer.toHexString(flags), new Throwable()); 3326 } 3327 3328 return updateFlags(flags, userId); 3329 } 3330 3331 /** 3332 * Update given flags when being used to request {@link ResolveInfo}. 3333 */ 3334 int updateFlagsForResolve(int flags, int userId, Object cookie) { 3335 // Safe mode means we shouldn't match any third-party components 3336 if (mSafeMode) { 3337 flags |= PackageManager.MATCH_SYSTEM_ONLY; 3338 } 3339 3340 return updateFlagsForComponent(flags, userId, cookie); 3341 } 3342 3343 @Override 3344 public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) { 3345 if (!sUserManager.exists(userId)) return null; 3346 flags = updateFlagsForComponent(flags, userId, component); 3347 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3348 false /* requireFullPermission */, false /* checkShell */, "get activity info"); 3349 synchronized (mPackages) { 3350 PackageParser.Activity a = mActivities.mActivities.get(component); 3351 3352 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a); 3353 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) { 3354 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3355 if (ps == null) return null; 3356 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 3357 userId); 3358 } 3359 if (mResolveComponentName.equals(component)) { 3360 return PackageParser.generateActivityInfo(mResolveActivity, flags, 3361 new PackageUserState(), userId); 3362 } 3363 } 3364 return null; 3365 } 3366 3367 @Override 3368 public boolean activitySupportsIntent(ComponentName component, Intent intent, 3369 String resolvedType) { 3370 synchronized (mPackages) { 3371 if (component.equals(mResolveComponentName)) { 3372 // The resolver supports EVERYTHING! 3373 return true; 3374 } 3375 PackageParser.Activity a = mActivities.mActivities.get(component); 3376 if (a == null) { 3377 return false; 3378 } 3379 for (int i=0; i<a.intents.size(); i++) { 3380 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(), 3381 intent.getData(), intent.getCategories(), TAG) >= 0) { 3382 return true; 3383 } 3384 } 3385 return false; 3386 } 3387 } 3388 3389 @Override 3390 public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) { 3391 if (!sUserManager.exists(userId)) return null; 3392 flags = updateFlagsForComponent(flags, userId, component); 3393 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3394 false /* requireFullPermission */, false /* checkShell */, "get receiver info"); 3395 synchronized (mPackages) { 3396 PackageParser.Activity a = mReceivers.mActivities.get(component); 3397 if (DEBUG_PACKAGE_INFO) Log.v( 3398 TAG, "getReceiverInfo " + component + ": " + a); 3399 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) { 3400 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3401 if (ps == null) return null; 3402 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 3403 userId); 3404 } 3405 } 3406 return null; 3407 } 3408 3409 @Override 3410 public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) { 3411 if (!sUserManager.exists(userId)) return null; 3412 flags = updateFlagsForComponent(flags, userId, component); 3413 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3414 false /* requireFullPermission */, false /* checkShell */, "get service info"); 3415 synchronized (mPackages) { 3416 PackageParser.Service s = mServices.mServices.get(component); 3417 if (DEBUG_PACKAGE_INFO) Log.v( 3418 TAG, "getServiceInfo " + component + ": " + s); 3419 if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) { 3420 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3421 if (ps == null) return null; 3422 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId), 3423 userId); 3424 } 3425 } 3426 return null; 3427 } 3428 3429 @Override 3430 public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) { 3431 if (!sUserManager.exists(userId)) return null; 3432 flags = updateFlagsForComponent(flags, userId, component); 3433 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3434 false /* requireFullPermission */, false /* checkShell */, "get provider info"); 3435 synchronized (mPackages) { 3436 PackageParser.Provider p = mProviders.mProviders.get(component); 3437 if (DEBUG_PACKAGE_INFO) Log.v( 3438 TAG, "getProviderInfo " + component + ": " + p); 3439 if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) { 3440 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3441 if (ps == null) return null; 3442 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId), 3443 userId); 3444 } 3445 } 3446 return null; 3447 } 3448 3449 @Override 3450 public String[] getSystemSharedLibraryNames() { 3451 Set<String> libSet; 3452 synchronized (mPackages) { 3453 libSet = mSharedLibraries.keySet(); 3454 int size = libSet.size(); 3455 if (size > 0) { 3456 String[] libs = new String[size]; 3457 libSet.toArray(libs); 3458 return libs; 3459 } 3460 } 3461 return null; 3462 } 3463 3464 @Override 3465 public @Nullable String getServicesSystemSharedLibraryPackageName() { 3466 synchronized (mPackages) { 3467 SharedLibraryEntry libraryEntry = mSharedLibraries.get( 3468 PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES); 3469 if (libraryEntry != null) { 3470 return libraryEntry.apk; 3471 } 3472 } 3473 return null; 3474 } 3475 3476 @Override 3477 public FeatureInfo[] getSystemAvailableFeatures() { 3478 Collection<FeatureInfo> featSet; 3479 synchronized (mPackages) { 3480 featSet = mAvailableFeatures.values(); 3481 int size = featSet.size(); 3482 if (size > 0) { 3483 FeatureInfo[] features = new FeatureInfo[size+1]; 3484 featSet.toArray(features); 3485 FeatureInfo fi = new FeatureInfo(); 3486 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version", 3487 FeatureInfo.GL_ES_VERSION_UNDEFINED); 3488 features[size] = fi; 3489 return features; 3490 } 3491 } 3492 return null; 3493 } 3494 3495 @Override 3496 public boolean hasSystemFeature(String name, int version) { 3497 synchronized (mPackages) { 3498 final FeatureInfo feat = mAvailableFeatures.get(name); 3499 if (feat == null) { 3500 return false; 3501 } else { 3502 return feat.version >= version; 3503 } 3504 } 3505 } 3506 3507 @Override 3508 public int checkPermission(String permName, String pkgName, int userId) { 3509 if (!sUserManager.exists(userId)) { 3510 return PackageManager.PERMISSION_DENIED; 3511 } 3512 3513 synchronized (mPackages) { 3514 final PackageParser.Package p = mPackages.get(pkgName); 3515 if (p != null && p.mExtras != null) { 3516 final PackageSetting ps = (PackageSetting) p.mExtras; 3517 final PermissionsState permissionsState = ps.getPermissionsState(); 3518 if (permissionsState.hasPermission(permName, userId)) { 3519 return PackageManager.PERMISSION_GRANTED; 3520 } 3521 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION 3522 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState 3523 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { 3524 return PackageManager.PERMISSION_GRANTED; 3525 } 3526 } 3527 } 3528 3529 return PackageManager.PERMISSION_DENIED; 3530 } 3531 3532 @Override 3533 public int checkUidPermission(String permName, int uid) { 3534 final int userId = UserHandle.getUserId(uid); 3535 3536 if (!sUserManager.exists(userId)) { 3537 return PackageManager.PERMISSION_DENIED; 3538 } 3539 3540 synchronized (mPackages) { 3541 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 3542 if (obj != null) { 3543 final SettingBase ps = (SettingBase) obj; 3544 final PermissionsState permissionsState = ps.getPermissionsState(); 3545 if (permissionsState.hasPermission(permName, userId)) { 3546 return PackageManager.PERMISSION_GRANTED; 3547 } 3548 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION 3549 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState 3550 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { 3551 return PackageManager.PERMISSION_GRANTED; 3552 } 3553 } else { 3554 ArraySet<String> perms = mSystemPermissions.get(uid); 3555 if (perms != null) { 3556 if (perms.contains(permName)) { 3557 return PackageManager.PERMISSION_GRANTED; 3558 } 3559 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms 3560 .contains(Manifest.permission.ACCESS_FINE_LOCATION)) { 3561 return PackageManager.PERMISSION_GRANTED; 3562 } 3563 } 3564 } 3565 } 3566 3567 return PackageManager.PERMISSION_DENIED; 3568 } 3569 3570 @Override 3571 public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) { 3572 if (UserHandle.getCallingUserId() != userId) { 3573 mContext.enforceCallingPermission( 3574 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 3575 "isPermissionRevokedByPolicy for user " + userId); 3576 } 3577 3578 if (checkPermission(permission, packageName, userId) 3579 == PackageManager.PERMISSION_GRANTED) { 3580 return false; 3581 } 3582 3583 final long identity = Binder.clearCallingIdentity(); 3584 try { 3585 final int flags = getPermissionFlags(permission, packageName, userId); 3586 return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0; 3587 } finally { 3588 Binder.restoreCallingIdentity(identity); 3589 } 3590 } 3591 3592 @Override 3593 public String getPermissionControllerPackageName() { 3594 synchronized (mPackages) { 3595 return mRequiredInstallerPackage; 3596 } 3597 } 3598 3599 /** 3600 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS 3601 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller. 3602 * @param checkShell whether to prevent shell from access if there's a debugging restriction 3603 * @param message the message to log on security exception 3604 */ 3605 void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, 3606 boolean checkShell, String message) { 3607 if (userId < 0) { 3608 throw new IllegalArgumentException("Invalid userId " + userId); 3609 } 3610 if (checkShell) { 3611 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); 3612 } 3613 if (userId == UserHandle.getUserId(callingUid)) return; 3614 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 3615 if (requireFullPermission) { 3616 mContext.enforceCallingOrSelfPermission( 3617 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 3618 } else { 3619 try { 3620 mContext.enforceCallingOrSelfPermission( 3621 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 3622 } catch (SecurityException se) { 3623 mContext.enforceCallingOrSelfPermission( 3624 android.Manifest.permission.INTERACT_ACROSS_USERS, message); 3625 } 3626 } 3627 } 3628 } 3629 3630 void enforceShellRestriction(String restriction, int callingUid, int userHandle) { 3631 if (callingUid == Process.SHELL_UID) { 3632 if (userHandle >= 0 3633 && sUserManager.hasUserRestriction(restriction, userHandle)) { 3634 throw new SecurityException("Shell does not have permission to access user " 3635 + userHandle); 3636 } else if (userHandle < 0) { 3637 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t" 3638 + Debug.getCallers(3)); 3639 } 3640 } 3641 } 3642 3643 private BasePermission findPermissionTreeLP(String permName) { 3644 for(BasePermission bp : mSettings.mPermissionTrees.values()) { 3645 if (permName.startsWith(bp.name) && 3646 permName.length() > bp.name.length() && 3647 permName.charAt(bp.name.length()) == '.') { 3648 return bp; 3649 } 3650 } 3651 return null; 3652 } 3653 3654 private BasePermission checkPermissionTreeLP(String permName) { 3655 if (permName != null) { 3656 BasePermission bp = findPermissionTreeLP(permName); 3657 if (bp != null) { 3658 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) { 3659 return bp; 3660 } 3661 throw new SecurityException("Calling uid " 3662 + Binder.getCallingUid() 3663 + " is not allowed to add to permission tree " 3664 + bp.name + " owned by uid " + bp.uid); 3665 } 3666 } 3667 throw new SecurityException("No permission tree found for " + permName); 3668 } 3669 3670 static boolean compareStrings(CharSequence s1, CharSequence s2) { 3671 if (s1 == null) { 3672 return s2 == null; 3673 } 3674 if (s2 == null) { 3675 return false; 3676 } 3677 if (s1.getClass() != s2.getClass()) { 3678 return false; 3679 } 3680 return s1.equals(s2); 3681 } 3682 3683 static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) { 3684 if (pi1.icon != pi2.icon) return false; 3685 if (pi1.logo != pi2.logo) return false; 3686 if (pi1.protectionLevel != pi2.protectionLevel) return false; 3687 if (!compareStrings(pi1.name, pi2.name)) return false; 3688 if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false; 3689 // We'll take care of setting this one. 3690 if (!compareStrings(pi1.packageName, pi2.packageName)) return false; 3691 // These are not currently stored in settings. 3692 //if (!compareStrings(pi1.group, pi2.group)) return false; 3693 //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false; 3694 //if (pi1.labelRes != pi2.labelRes) return false; 3695 //if (pi1.descriptionRes != pi2.descriptionRes) return false; 3696 return true; 3697 } 3698 3699 int permissionInfoFootprint(PermissionInfo info) { 3700 int size = info.name.length(); 3701 if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length(); 3702 if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length(); 3703 return size; 3704 } 3705 3706 int calculateCurrentPermissionFootprintLocked(BasePermission tree) { 3707 int size = 0; 3708 for (BasePermission perm : mSettings.mPermissions.values()) { 3709 if (perm.uid == tree.uid) { 3710 size += perm.name.length() + permissionInfoFootprint(perm.perm.info); 3711 } 3712 } 3713 return size; 3714 } 3715 3716 void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) { 3717 // We calculate the max size of permissions defined by this uid and throw 3718 // if that plus the size of 'info' would exceed our stated maximum. 3719 if (tree.uid != Process.SYSTEM_UID) { 3720 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree); 3721 if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) { 3722 throw new SecurityException("Permission tree size cap exceeded"); 3723 } 3724 } 3725 } 3726 3727 boolean addPermissionLocked(PermissionInfo info, boolean async) { 3728 if (info.labelRes == 0 && info.nonLocalizedLabel == null) { 3729 throw new SecurityException("Label must be specified in permission"); 3730 } 3731 BasePermission tree = checkPermissionTreeLP(info.name); 3732 BasePermission bp = mSettings.mPermissions.get(info.name); 3733 boolean added = bp == null; 3734 boolean changed = true; 3735 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel); 3736 if (added) { 3737 enforcePermissionCapLocked(info, tree); 3738 bp = new BasePermission(info.name, tree.sourcePackage, 3739 BasePermission.TYPE_DYNAMIC); 3740 } else if (bp.type != BasePermission.TYPE_DYNAMIC) { 3741 throw new SecurityException( 3742 "Not allowed to modify non-dynamic permission " 3743 + info.name); 3744 } else { 3745 if (bp.protectionLevel == fixedLevel 3746 && bp.perm.owner.equals(tree.perm.owner) 3747 && bp.uid == tree.uid 3748 && comparePermissionInfos(bp.perm.info, info)) { 3749 changed = false; 3750 } 3751 } 3752 bp.protectionLevel = fixedLevel; 3753 info = new PermissionInfo(info); 3754 info.protectionLevel = fixedLevel; 3755 bp.perm = new PackageParser.Permission(tree.perm.owner, info); 3756 bp.perm.info.packageName = tree.perm.info.packageName; 3757 bp.uid = tree.uid; 3758 if (added) { 3759 mSettings.mPermissions.put(info.name, bp); 3760 } 3761 if (changed) { 3762 if (!async) { 3763 mSettings.writeLPr(); 3764 } else { 3765 scheduleWriteSettingsLocked(); 3766 } 3767 } 3768 return added; 3769 } 3770 3771 @Override 3772 public boolean addPermission(PermissionInfo info) { 3773 synchronized (mPackages) { 3774 return addPermissionLocked(info, false); 3775 } 3776 } 3777 3778 @Override 3779 public boolean addPermissionAsync(PermissionInfo info) { 3780 synchronized (mPackages) { 3781 return addPermissionLocked(info, true); 3782 } 3783 } 3784 3785 @Override 3786 public void removePermission(String name) { 3787 synchronized (mPackages) { 3788 checkPermissionTreeLP(name); 3789 BasePermission bp = mSettings.mPermissions.get(name); 3790 if (bp != null) { 3791 if (bp.type != BasePermission.TYPE_DYNAMIC) { 3792 throw new SecurityException( 3793 "Not allowed to modify non-dynamic permission " 3794 + name); 3795 } 3796 mSettings.mPermissions.remove(name); 3797 mSettings.writeLPr(); 3798 } 3799 } 3800 } 3801 3802 private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg, 3803 BasePermission bp) { 3804 int index = pkg.requestedPermissions.indexOf(bp.name); 3805 if (index == -1) { 3806 throw new SecurityException("Package " + pkg.packageName 3807 + " has not requested permission " + bp.name); 3808 } 3809 if (!bp.isRuntime() && !bp.isDevelopment()) { 3810 throw new SecurityException("Permission " + bp.name 3811 + " is not a changeable permission type"); 3812 } 3813 } 3814 3815 @Override 3816 public void grantRuntimePermission(String packageName, String name, final int userId) { 3817 if (!sUserManager.exists(userId)) { 3818 Log.e(TAG, "No such user:" + userId); 3819 return; 3820 } 3821 3822 mContext.enforceCallingOrSelfPermission( 3823 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 3824 "grantRuntimePermission"); 3825 3826 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3827 true /* requireFullPermission */, true /* checkShell */, 3828 "grantRuntimePermission"); 3829 3830 final int uid; 3831 final SettingBase sb; 3832 3833 synchronized (mPackages) { 3834 final PackageParser.Package pkg = mPackages.get(packageName); 3835 if (pkg == null) { 3836 throw new IllegalArgumentException("Unknown package: " + packageName); 3837 } 3838 3839 final BasePermission bp = mSettings.mPermissions.get(name); 3840 if (bp == null) { 3841 throw new IllegalArgumentException("Unknown permission: " + name); 3842 } 3843 3844 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp); 3845 3846 // If a permission review is required for legacy apps we represent 3847 // their permissions as always granted runtime ones since we need 3848 // to keep the review required permission flag per user while an 3849 // install permission's state is shared across all users. 3850 if (Build.PERMISSIONS_REVIEW_REQUIRED 3851 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M 3852 && bp.isRuntime()) { 3853 return; 3854 } 3855 3856 uid = UserHandle.getUid(userId, pkg.applicationInfo.uid); 3857 sb = (SettingBase) pkg.mExtras; 3858 if (sb == null) { 3859 throw new IllegalArgumentException("Unknown package: " + packageName); 3860 } 3861 3862 final PermissionsState permissionsState = sb.getPermissionsState(); 3863 3864 final int flags = permissionsState.getPermissionFlags(name, userId); 3865 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 3866 throw new SecurityException("Cannot grant system fixed permission " 3867 + name + " for package " + packageName); 3868 } 3869 3870 if (bp.isDevelopment()) { 3871 // Development permissions must be handled specially, since they are not 3872 // normal runtime permissions. For now they apply to all users. 3873 if (permissionsState.grantInstallPermission(bp) != 3874 PermissionsState.PERMISSION_OPERATION_FAILURE) { 3875 scheduleWriteSettingsLocked(); 3876 } 3877 return; 3878 } 3879 3880 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 3881 Slog.w(TAG, "Cannot grant runtime permission to a legacy app"); 3882 return; 3883 } 3884 3885 final int result = permissionsState.grantRuntimePermission(bp, userId); 3886 switch (result) { 3887 case PermissionsState.PERMISSION_OPERATION_FAILURE: { 3888 return; 3889 } 3890 3891 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 3892 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); 3893 mHandler.post(new Runnable() { 3894 @Override 3895 public void run() { 3896 killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED); 3897 } 3898 }); 3899 } 3900 break; 3901 } 3902 3903 mOnPermissionChangeListeners.onPermissionsChanged(uid); 3904 3905 // Not critical if that is lost - app has to request again. 3906 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 3907 } 3908 3909 // Only need to do this if user is initialized. Otherwise it's a new user 3910 // and there are no processes running as the user yet and there's no need 3911 // to make an expensive call to remount processes for the changed permissions. 3912 if (READ_EXTERNAL_STORAGE.equals(name) 3913 || WRITE_EXTERNAL_STORAGE.equals(name)) { 3914 final long token = Binder.clearCallingIdentity(); 3915 try { 3916 if (sUserManager.isInitialized(userId)) { 3917 MountServiceInternal mountServiceInternal = LocalServices.getService( 3918 MountServiceInternal.class); 3919 mountServiceInternal.onExternalStoragePolicyChanged(uid, packageName); 3920 } 3921 } finally { 3922 Binder.restoreCallingIdentity(token); 3923 } 3924 } 3925 } 3926 3927 @Override 3928 public void revokeRuntimePermission(String packageName, String name, int userId) { 3929 if (!sUserManager.exists(userId)) { 3930 Log.e(TAG, "No such user:" + userId); 3931 return; 3932 } 3933 3934 mContext.enforceCallingOrSelfPermission( 3935 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 3936 "revokeRuntimePermission"); 3937 3938 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3939 true /* requireFullPermission */, true /* checkShell */, 3940 "revokeRuntimePermission"); 3941 3942 final int appId; 3943 3944 synchronized (mPackages) { 3945 final PackageParser.Package pkg = mPackages.get(packageName); 3946 if (pkg == null) { 3947 throw new IllegalArgumentException("Unknown package: " + packageName); 3948 } 3949 3950 final BasePermission bp = mSettings.mPermissions.get(name); 3951 if (bp == null) { 3952 throw new IllegalArgumentException("Unknown permission: " + name); 3953 } 3954 3955 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp); 3956 3957 // If a permission review is required for legacy apps we represent 3958 // their permissions as always granted runtime ones since we need 3959 // to keep the review required permission flag per user while an 3960 // install permission's state is shared across all users. 3961 if (Build.PERMISSIONS_REVIEW_REQUIRED 3962 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M 3963 && bp.isRuntime()) { 3964 return; 3965 } 3966 3967 SettingBase sb = (SettingBase) pkg.mExtras; 3968 if (sb == null) { 3969 throw new IllegalArgumentException("Unknown package: " + packageName); 3970 } 3971 3972 final PermissionsState permissionsState = sb.getPermissionsState(); 3973 3974 final int flags = permissionsState.getPermissionFlags(name, userId); 3975 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 3976 throw new SecurityException("Cannot revoke system fixed permission " 3977 + name + " for package " + packageName); 3978 } 3979 3980 if (bp.isDevelopment()) { 3981 // Development permissions must be handled specially, since they are not 3982 // normal runtime permissions. For now they apply to all users. 3983 if (permissionsState.revokeInstallPermission(bp) != 3984 PermissionsState.PERMISSION_OPERATION_FAILURE) { 3985 scheduleWriteSettingsLocked(); 3986 } 3987 return; 3988 } 3989 3990 if (permissionsState.revokeRuntimePermission(bp, userId) == 3991 PermissionsState.PERMISSION_OPERATION_FAILURE) { 3992 return; 3993 } 3994 3995 mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid); 3996 3997 // Critical, after this call app should never have the permission. 3998 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 3999 4000 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 4001 } 4002 4003 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED); 4004 } 4005 4006 @Override 4007 public void resetRuntimePermissions() { 4008 mContext.enforceCallingOrSelfPermission( 4009 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 4010 "revokeRuntimePermission"); 4011 4012 int callingUid = Binder.getCallingUid(); 4013 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 4014 mContext.enforceCallingOrSelfPermission( 4015 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 4016 "resetRuntimePermissions"); 4017 } 4018 4019 synchronized (mPackages) { 4020 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL); 4021 for (int userId : UserManagerService.getInstance().getUserIds()) { 4022 final int packageCount = mPackages.size(); 4023 for (int i = 0; i < packageCount; i++) { 4024 PackageParser.Package pkg = mPackages.valueAt(i); 4025 if (!(pkg.mExtras instanceof PackageSetting)) { 4026 continue; 4027 } 4028 PackageSetting ps = (PackageSetting) pkg.mExtras; 4029 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 4030 } 4031 } 4032 } 4033 } 4034 4035 @Override 4036 public int getPermissionFlags(String name, String packageName, int userId) { 4037 if (!sUserManager.exists(userId)) { 4038 return 0; 4039 } 4040 4041 enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags"); 4042 4043 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4044 true /* requireFullPermission */, false /* checkShell */, 4045 "getPermissionFlags"); 4046 4047 synchronized (mPackages) { 4048 final PackageParser.Package pkg = mPackages.get(packageName); 4049 if (pkg == null) { 4050 throw new IllegalArgumentException("Unknown package: " + packageName); 4051 } 4052 4053 final BasePermission bp = mSettings.mPermissions.get(name); 4054 if (bp == null) { 4055 throw new IllegalArgumentException("Unknown permission: " + name); 4056 } 4057 4058 SettingBase sb = (SettingBase) pkg.mExtras; 4059 if (sb == null) { 4060 throw new IllegalArgumentException("Unknown package: " + packageName); 4061 } 4062 4063 PermissionsState permissionsState = sb.getPermissionsState(); 4064 return permissionsState.getPermissionFlags(name, userId); 4065 } 4066 } 4067 4068 @Override 4069 public void updatePermissionFlags(String name, String packageName, int flagMask, 4070 int flagValues, int userId) { 4071 if (!sUserManager.exists(userId)) { 4072 return; 4073 } 4074 4075 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags"); 4076 4077 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4078 true /* requireFullPermission */, true /* checkShell */, 4079 "updatePermissionFlags"); 4080 4081 // Only the system can change these flags and nothing else. 4082 if (getCallingUid() != Process.SYSTEM_UID) { 4083 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4084 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4085 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 4086 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 4087 flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 4088 } 4089 4090 synchronized (mPackages) { 4091 final PackageParser.Package pkg = mPackages.get(packageName); 4092 if (pkg == null) { 4093 throw new IllegalArgumentException("Unknown package: " + packageName); 4094 } 4095 4096 final BasePermission bp = mSettings.mPermissions.get(name); 4097 if (bp == null) { 4098 throw new IllegalArgumentException("Unknown permission: " + name); 4099 } 4100 4101 SettingBase sb = (SettingBase) pkg.mExtras; 4102 if (sb == null) { 4103 throw new IllegalArgumentException("Unknown package: " + packageName); 4104 } 4105 4106 PermissionsState permissionsState = sb.getPermissionsState(); 4107 4108 boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null; 4109 4110 if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) { 4111 // Install and runtime permissions are stored in different places, 4112 // so figure out what permission changed and persist the change. 4113 if (permissionsState.getInstallPermissionState(name) != null) { 4114 scheduleWriteSettingsLocked(); 4115 } else if (permissionsState.getRuntimePermissionState(name, userId) != null 4116 || hadState) { 4117 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 4118 } 4119 } 4120 } 4121 } 4122 4123 /** 4124 * Update the permission flags for all packages and runtime permissions of a user in order 4125 * to allow device or profile owner to remove POLICY_FIXED. 4126 */ 4127 @Override 4128 public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) { 4129 if (!sUserManager.exists(userId)) { 4130 return; 4131 } 4132 4133 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps"); 4134 4135 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4136 true /* requireFullPermission */, true /* checkShell */, 4137 "updatePermissionFlagsForAllApps"); 4138 4139 // Only the system can change system fixed flags. 4140 if (getCallingUid() != Process.SYSTEM_UID) { 4141 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4142 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4143 } 4144 4145 synchronized (mPackages) { 4146 boolean changed = false; 4147 final int packageCount = mPackages.size(); 4148 for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) { 4149 final PackageParser.Package pkg = mPackages.valueAt(pkgIndex); 4150 SettingBase sb = (SettingBase) pkg.mExtras; 4151 if (sb == null) { 4152 continue; 4153 } 4154 PermissionsState permissionsState = sb.getPermissionsState(); 4155 changed |= permissionsState.updatePermissionFlagsForAllPermissions( 4156 userId, flagMask, flagValues); 4157 } 4158 if (changed) { 4159 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 4160 } 4161 } 4162 } 4163 4164 private void enforceGrantRevokeRuntimePermissionPermissions(String message) { 4165 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS) 4166 != PackageManager.PERMISSION_GRANTED 4167 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) 4168 != PackageManager.PERMISSION_GRANTED) { 4169 throw new SecurityException(message + " requires " 4170 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or " 4171 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS); 4172 } 4173 } 4174 4175 @Override 4176 public boolean shouldShowRequestPermissionRationale(String permissionName, 4177 String packageName, int userId) { 4178 if (UserHandle.getCallingUserId() != userId) { 4179 mContext.enforceCallingPermission( 4180 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 4181 "canShowRequestPermissionRationale for user " + userId); 4182 } 4183 4184 final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId); 4185 if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) { 4186 return false; 4187 } 4188 4189 if (checkPermission(permissionName, packageName, userId) 4190 == PackageManager.PERMISSION_GRANTED) { 4191 return false; 4192 } 4193 4194 final int flags; 4195 4196 final long identity = Binder.clearCallingIdentity(); 4197 try { 4198 flags = getPermissionFlags(permissionName, 4199 packageName, userId); 4200 } finally { 4201 Binder.restoreCallingIdentity(identity); 4202 } 4203 4204 final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 4205 | PackageManager.FLAG_PERMISSION_POLICY_FIXED 4206 | PackageManager.FLAG_PERMISSION_USER_FIXED; 4207 4208 if ((flags & fixedFlags) != 0) { 4209 return false; 4210 } 4211 4212 return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0; 4213 } 4214 4215 @Override 4216 public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 4217 mContext.enforceCallingOrSelfPermission( 4218 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS, 4219 "addOnPermissionsChangeListener"); 4220 4221 synchronized (mPackages) { 4222 mOnPermissionChangeListeners.addListenerLocked(listener); 4223 } 4224 } 4225 4226 @Override 4227 public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 4228 synchronized (mPackages) { 4229 mOnPermissionChangeListeners.removeListenerLocked(listener); 4230 } 4231 } 4232 4233 @Override 4234 public boolean isProtectedBroadcast(String actionName) { 4235 synchronized (mPackages) { 4236 if (mProtectedBroadcasts.contains(actionName)) { 4237 return true; 4238 } else if (actionName != null) { 4239 // TODO: remove these terrible hacks 4240 if (actionName.startsWith("android.net.netmon.lingerExpired") 4241 || actionName.startsWith("com.android.server.sip.SipWakeupTimer") 4242 || actionName.startsWith("com.android.internal.telephony.data-reconnect")) { 4243 return true; 4244 } 4245 } 4246 } 4247 return false; 4248 } 4249 4250 @Override 4251 public int checkSignatures(String pkg1, String pkg2) { 4252 synchronized (mPackages) { 4253 final PackageParser.Package p1 = mPackages.get(pkg1); 4254 final PackageParser.Package p2 = mPackages.get(pkg2); 4255 if (p1 == null || p1.mExtras == null 4256 || p2 == null || p2.mExtras == null) { 4257 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4258 } 4259 return compareSignatures(p1.mSignatures, p2.mSignatures); 4260 } 4261 } 4262 4263 @Override 4264 public int checkUidSignatures(int uid1, int uid2) { 4265 // Map to base uids. 4266 uid1 = UserHandle.getAppId(uid1); 4267 uid2 = UserHandle.getAppId(uid2); 4268 // reader 4269 synchronized (mPackages) { 4270 Signature[] s1; 4271 Signature[] s2; 4272 Object obj = mSettings.getUserIdLPr(uid1); 4273 if (obj != null) { 4274 if (obj instanceof SharedUserSetting) { 4275 s1 = ((SharedUserSetting)obj).signatures.mSignatures; 4276 } else if (obj instanceof PackageSetting) { 4277 s1 = ((PackageSetting)obj).signatures.mSignatures; 4278 } else { 4279 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4280 } 4281 } else { 4282 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4283 } 4284 obj = mSettings.getUserIdLPr(uid2); 4285 if (obj != null) { 4286 if (obj instanceof SharedUserSetting) { 4287 s2 = ((SharedUserSetting)obj).signatures.mSignatures; 4288 } else if (obj instanceof PackageSetting) { 4289 s2 = ((PackageSetting)obj).signatures.mSignatures; 4290 } else { 4291 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4292 } 4293 } else { 4294 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4295 } 4296 return compareSignatures(s1, s2); 4297 } 4298 } 4299 4300 private void killUid(int appId, int userId, String reason) { 4301 final long identity = Binder.clearCallingIdentity(); 4302 try { 4303 IActivityManager am = ActivityManagerNative.getDefault(); 4304 if (am != null) { 4305 try { 4306 am.killUid(appId, userId, reason); 4307 } catch (RemoteException e) { 4308 /* ignore - same process */ 4309 } 4310 } 4311 } finally { 4312 Binder.restoreCallingIdentity(identity); 4313 } 4314 } 4315 4316 /** 4317 * Compares two sets of signatures. Returns: 4318 * <br /> 4319 * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null, 4320 * <br /> 4321 * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null, 4322 * <br /> 4323 * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null, 4324 * <br /> 4325 * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical, 4326 * <br /> 4327 * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ. 4328 */ 4329 static int compareSignatures(Signature[] s1, Signature[] s2) { 4330 if (s1 == null) { 4331 return s2 == null 4332 ? PackageManager.SIGNATURE_NEITHER_SIGNED 4333 : PackageManager.SIGNATURE_FIRST_NOT_SIGNED; 4334 } 4335 4336 if (s2 == null) { 4337 return PackageManager.SIGNATURE_SECOND_NOT_SIGNED; 4338 } 4339 4340 if (s1.length != s2.length) { 4341 return PackageManager.SIGNATURE_NO_MATCH; 4342 } 4343 4344 // Since both signature sets are of size 1, we can compare without HashSets. 4345 if (s1.length == 1) { 4346 return s1[0].equals(s2[0]) ? 4347 PackageManager.SIGNATURE_MATCH : 4348 PackageManager.SIGNATURE_NO_MATCH; 4349 } 4350 4351 ArraySet<Signature> set1 = new ArraySet<Signature>(); 4352 for (Signature sig : s1) { 4353 set1.add(sig); 4354 } 4355 ArraySet<Signature> set2 = new ArraySet<Signature>(); 4356 for (Signature sig : s2) { 4357 set2.add(sig); 4358 } 4359 // Make sure s2 contains all signatures in s1. 4360 if (set1.equals(set2)) { 4361 return PackageManager.SIGNATURE_MATCH; 4362 } 4363 return PackageManager.SIGNATURE_NO_MATCH; 4364 } 4365 4366 /** 4367 * If the database version for this type of package (internal storage or 4368 * external storage) is less than the version where package signatures 4369 * were updated, return true. 4370 */ 4371 private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 4372 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); 4373 return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY; 4374 } 4375 4376 /** 4377 * Used for backward compatibility to make sure any packages with 4378 * certificate chains get upgraded to the new style. {@code existingSigs} 4379 * will be in the old format (since they were stored on disk from before the 4380 * system upgrade) and {@code scannedSigs} will be in the newer format. 4381 */ 4382 private int compareSignaturesCompat(PackageSignatures existingSigs, 4383 PackageParser.Package scannedPkg) { 4384 if (!isCompatSignatureUpdateNeeded(scannedPkg)) { 4385 return PackageManager.SIGNATURE_NO_MATCH; 4386 } 4387 4388 ArraySet<Signature> existingSet = new ArraySet<Signature>(); 4389 for (Signature sig : existingSigs.mSignatures) { 4390 existingSet.add(sig); 4391 } 4392 ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>(); 4393 for (Signature sig : scannedPkg.mSignatures) { 4394 try { 4395 Signature[] chainSignatures = sig.getChainSignatures(); 4396 for (Signature chainSig : chainSignatures) { 4397 scannedCompatSet.add(chainSig); 4398 } 4399 } catch (CertificateEncodingException e) { 4400 scannedCompatSet.add(sig); 4401 } 4402 } 4403 /* 4404 * Make sure the expanded scanned set contains all signatures in the 4405 * existing one. 4406 */ 4407 if (scannedCompatSet.equals(existingSet)) { 4408 // Migrate the old signatures to the new scheme. 4409 existingSigs.assignSignatures(scannedPkg.mSignatures); 4410 // The new KeySets will be re-added later in the scanning process. 4411 synchronized (mPackages) { 4412 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName); 4413 } 4414 return PackageManager.SIGNATURE_MATCH; 4415 } 4416 return PackageManager.SIGNATURE_NO_MATCH; 4417 } 4418 4419 private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 4420 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); 4421 return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER; 4422 } 4423 4424 private int compareSignaturesRecover(PackageSignatures existingSigs, 4425 PackageParser.Package scannedPkg) { 4426 if (!isRecoverSignatureUpdateNeeded(scannedPkg)) { 4427 return PackageManager.SIGNATURE_NO_MATCH; 4428 } 4429 4430 String msg = null; 4431 try { 4432 if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) { 4433 logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for " 4434 + scannedPkg.packageName); 4435 return PackageManager.SIGNATURE_MATCH; 4436 } 4437 } catch (CertificateException e) { 4438 msg = e.getMessage(); 4439 } 4440 4441 logCriticalInfo(Log.INFO, 4442 "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg); 4443 return PackageManager.SIGNATURE_NO_MATCH; 4444 } 4445 4446 @Override 4447 public String[] getPackagesForUid(int uid) { 4448 uid = UserHandle.getAppId(uid); 4449 // reader 4450 synchronized (mPackages) { 4451 Object obj = mSettings.getUserIdLPr(uid); 4452 if (obj instanceof SharedUserSetting) { 4453 final SharedUserSetting sus = (SharedUserSetting) obj; 4454 final int N = sus.packages.size(); 4455 final String[] res = new String[N]; 4456 final Iterator<PackageSetting> it = sus.packages.iterator(); 4457 int i = 0; 4458 while (it.hasNext()) { 4459 res[i++] = it.next().name; 4460 } 4461 return res; 4462 } else if (obj instanceof PackageSetting) { 4463 final PackageSetting ps = (PackageSetting) obj; 4464 return new String[] { ps.name }; 4465 } 4466 } 4467 return null; 4468 } 4469 4470 @Override 4471 public String getNameForUid(int uid) { 4472 // reader 4473 synchronized (mPackages) { 4474 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4475 if (obj instanceof SharedUserSetting) { 4476 final SharedUserSetting sus = (SharedUserSetting) obj; 4477 return sus.name + ":" + sus.userId; 4478 } else if (obj instanceof PackageSetting) { 4479 final PackageSetting ps = (PackageSetting) obj; 4480 return ps.name; 4481 } 4482 } 4483 return null; 4484 } 4485 4486 @Override 4487 public int getUidForSharedUser(String sharedUserName) { 4488 if(sharedUserName == null) { 4489 return -1; 4490 } 4491 // reader 4492 synchronized (mPackages) { 4493 final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false); 4494 if (suid == null) { 4495 return -1; 4496 } 4497 return suid.userId; 4498 } 4499 } 4500 4501 @Override 4502 public int getFlagsForUid(int uid) { 4503 synchronized (mPackages) { 4504 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4505 if (obj instanceof SharedUserSetting) { 4506 final SharedUserSetting sus = (SharedUserSetting) obj; 4507 return sus.pkgFlags; 4508 } else if (obj instanceof PackageSetting) { 4509 final PackageSetting ps = (PackageSetting) obj; 4510 return ps.pkgFlags; 4511 } 4512 } 4513 return 0; 4514 } 4515 4516 @Override 4517 public int getPrivateFlagsForUid(int uid) { 4518 synchronized (mPackages) { 4519 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4520 if (obj instanceof SharedUserSetting) { 4521 final SharedUserSetting sus = (SharedUserSetting) obj; 4522 return sus.pkgPrivateFlags; 4523 } else if (obj instanceof PackageSetting) { 4524 final PackageSetting ps = (PackageSetting) obj; 4525 return ps.pkgPrivateFlags; 4526 } 4527 } 4528 return 0; 4529 } 4530 4531 @Override 4532 public boolean isUidPrivileged(int uid) { 4533 uid = UserHandle.getAppId(uid); 4534 // reader 4535 synchronized (mPackages) { 4536 Object obj = mSettings.getUserIdLPr(uid); 4537 if (obj instanceof SharedUserSetting) { 4538 final SharedUserSetting sus = (SharedUserSetting) obj; 4539 final Iterator<PackageSetting> it = sus.packages.iterator(); 4540 while (it.hasNext()) { 4541 if (it.next().isPrivileged()) { 4542 return true; 4543 } 4544 } 4545 } else if (obj instanceof PackageSetting) { 4546 final PackageSetting ps = (PackageSetting) obj; 4547 return ps.isPrivileged(); 4548 } 4549 } 4550 return false; 4551 } 4552 4553 @Override 4554 public String[] getAppOpPermissionPackages(String permissionName) { 4555 synchronized (mPackages) { 4556 ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName); 4557 if (pkgs == null) { 4558 return null; 4559 } 4560 return pkgs.toArray(new String[pkgs.size()]); 4561 } 4562 } 4563 4564 @Override 4565 public ResolveInfo resolveIntent(Intent intent, String resolvedType, 4566 int flags, int userId) { 4567 if (!sUserManager.exists(userId)) return null; 4568 flags = updateFlagsForResolve(flags, userId, intent); 4569 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4570 false /* requireFullPermission */, false /* checkShell */, "resolve intent"); 4571 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 4572 final ResolveInfo bestChoice = 4573 chooseBestActivity(intent, resolvedType, flags, query, userId); 4574 4575 if (isEphemeralAllowed(intent, query, userId)) { 4576 final EphemeralResolveInfo ai = 4577 getEphemeralResolveInfo(intent, resolvedType, userId); 4578 if (ai != null) { 4579 if (DEBUG_EPHEMERAL) { 4580 Slog.v(TAG, "Returning an EphemeralResolveInfo"); 4581 } 4582 bestChoice.ephemeralInstaller = mEphemeralInstallerInfo; 4583 bestChoice.ephemeralResolveInfo = ai; 4584 } 4585 } 4586 return bestChoice; 4587 } 4588 4589 @Override 4590 public void setLastChosenActivity(Intent intent, String resolvedType, int flags, 4591 IntentFilter filter, int match, ComponentName activity) { 4592 final int userId = UserHandle.getCallingUserId(); 4593 if (DEBUG_PREFERRED) { 4594 Log.v(TAG, "setLastChosenActivity intent=" + intent 4595 + " resolvedType=" + resolvedType 4596 + " flags=" + flags 4597 + " filter=" + filter 4598 + " match=" + match 4599 + " activity=" + activity); 4600 filter.dump(new PrintStreamPrinter(System.out), " "); 4601 } 4602 intent.setComponent(null); 4603 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 4604 // Find any earlier preferred or last chosen entries and nuke them 4605 findPreferredActivity(intent, resolvedType, 4606 flags, query, 0, false, true, false, userId); 4607 // Add the new activity as the last chosen for this filter 4608 addPreferredActivityInternal(filter, match, null, activity, false, userId, 4609 "Setting last chosen"); 4610 } 4611 4612 @Override 4613 public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) { 4614 final int userId = UserHandle.getCallingUserId(); 4615 if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent); 4616 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 4617 return findPreferredActivity(intent, resolvedType, flags, query, 0, 4618 false, false, false, userId); 4619 } 4620 4621 4622 private boolean isEphemeralAllowed( 4623 Intent intent, List<ResolveInfo> resolvedActivites, int userId) { 4624 // Short circuit and return early if possible. 4625 if (DISABLE_EPHEMERAL_APPS) { 4626 return false; 4627 } 4628 final int callingUser = UserHandle.getCallingUserId(); 4629 if (callingUser != UserHandle.USER_SYSTEM) { 4630 return false; 4631 } 4632 if (mEphemeralResolverConnection == null) { 4633 return false; 4634 } 4635 if (intent.getComponent() != null) { 4636 return false; 4637 } 4638 if (intent.getPackage() != null) { 4639 return false; 4640 } 4641 final boolean isWebUri = hasWebURI(intent); 4642 if (!isWebUri) { 4643 return false; 4644 } 4645 // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution. 4646 synchronized (mPackages) { 4647 final int count = resolvedActivites.size(); 4648 for (int n = 0; n < count; n++) { 4649 ResolveInfo info = resolvedActivites.get(n); 4650 String packageName = info.activityInfo.packageName; 4651 PackageSetting ps = mSettings.mPackages.get(packageName); 4652 if (ps != null) { 4653 // Try to get the status from User settings first 4654 long packedStatus = getDomainVerificationStatusLPr(ps, userId); 4655 int status = (int) (packedStatus >> 32); 4656 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS 4657 || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) { 4658 if (DEBUG_EPHEMERAL) { 4659 Slog.v(TAG, "DENY ephemeral apps;" 4660 + " pkg: " + packageName + ", status: " + status); 4661 } 4662 return false; 4663 } 4664 } 4665 } 4666 } 4667 // We've exhausted all ways to deny ephemeral application; let the system look for them. 4668 return true; 4669 } 4670 4671 private EphemeralResolveInfo getEphemeralResolveInfo(Intent intent, String resolvedType, 4672 int userId) { 4673 MessageDigest digest = null; 4674 try { 4675 digest = MessageDigest.getInstance(EphemeralResolveInfo.SHA_ALGORITHM); 4676 } catch (NoSuchAlgorithmException e) { 4677 // If we can't create a digest, ignore ephemeral apps. 4678 return null; 4679 } 4680 4681 final byte[] hostBytes = intent.getData().getHost().getBytes(); 4682 final byte[] digestBytes = digest.digest(hostBytes); 4683 int shaPrefix = 4684 digestBytes[0] << 24 4685 | digestBytes[1] << 16 4686 | digestBytes[2] << 8 4687 | digestBytes[3] << 0; 4688 final List<EphemeralResolveInfo> ephemeralResolveInfoList = 4689 mEphemeralResolverConnection.getEphemeralResolveInfoList(shaPrefix); 4690 if (ephemeralResolveInfoList == null || ephemeralResolveInfoList.size() == 0) { 4691 // No hash prefix match; there are no ephemeral apps for this domain. 4692 return null; 4693 } 4694 for (int i = ephemeralResolveInfoList.size() - 1; i >= 0; --i) { 4695 EphemeralResolveInfo ephemeralApplication = ephemeralResolveInfoList.get(i); 4696 if (!Arrays.equals(digestBytes, ephemeralApplication.getDigestBytes())) { 4697 continue; 4698 } 4699 final List<IntentFilter> filters = ephemeralApplication.getFilters(); 4700 // No filters; this should never happen. 4701 if (filters.isEmpty()) { 4702 continue; 4703 } 4704 // We have a domain match; resolve the filters to see if anything matches. 4705 final EphemeralIntentResolver ephemeralResolver = new EphemeralIntentResolver(); 4706 for (int j = filters.size() - 1; j >= 0; --j) { 4707 final EphemeralResolveIntentInfo intentInfo = 4708 new EphemeralResolveIntentInfo(filters.get(j), ephemeralApplication); 4709 ephemeralResolver.addFilter(intentInfo); 4710 } 4711 List<EphemeralResolveInfo> matchedResolveInfoList = ephemeralResolver.queryIntent( 4712 intent, resolvedType, false /*defaultOnly*/, userId); 4713 if (!matchedResolveInfoList.isEmpty()) { 4714 return matchedResolveInfoList.get(0); 4715 } 4716 } 4717 // Hash or filter mis-match; no ephemeral apps for this domain. 4718 return null; 4719 } 4720 4721 private ResolveInfo chooseBestActivity(Intent intent, String resolvedType, 4722 int flags, List<ResolveInfo> query, int userId) { 4723 if (query != null) { 4724 final int N = query.size(); 4725 if (N == 1) { 4726 return query.get(0); 4727 } else if (N > 1) { 4728 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 4729 // If there is more than one activity with the same priority, 4730 // then let the user decide between them. 4731 ResolveInfo r0 = query.get(0); 4732 ResolveInfo r1 = query.get(1); 4733 if (DEBUG_INTENT_MATCHING || debug) { 4734 Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs " 4735 + r1.activityInfo.name + "=" + r1.priority); 4736 } 4737 // If the first activity has a higher priority, or a different 4738 // default, then it is always desirable to pick it. 4739 if (r0.priority != r1.priority 4740 || r0.preferredOrder != r1.preferredOrder 4741 || r0.isDefault != r1.isDefault) { 4742 return query.get(0); 4743 } 4744 // If we have saved a preference for a preferred activity for 4745 // this Intent, use that. 4746 ResolveInfo ri = findPreferredActivity(intent, resolvedType, 4747 flags, query, r0.priority, true, false, debug, userId); 4748 if (ri != null) { 4749 return ri; 4750 } 4751 ri = new ResolveInfo(mResolveInfo); 4752 ri.activityInfo = new ActivityInfo(ri.activityInfo); 4753 ri.activityInfo.applicationInfo = new ApplicationInfo( 4754 ri.activityInfo.applicationInfo); 4755 if (userId != 0) { 4756 ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId, 4757 UserHandle.getAppId(ri.activityInfo.applicationInfo.uid)); 4758 } 4759 // Make sure that the resolver is displayable in car mode 4760 if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle(); 4761 ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true); 4762 return ri; 4763 } 4764 } 4765 return null; 4766 } 4767 4768 private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType, 4769 int flags, List<ResolveInfo> query, boolean debug, int userId) { 4770 final int N = query.size(); 4771 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 4772 .get(userId); 4773 // Get the list of persistent preferred activities that handle the intent 4774 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities..."); 4775 List<PersistentPreferredActivity> pprefs = ppir != null 4776 ? ppir.queryIntent(intent, resolvedType, 4777 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 4778 : null; 4779 if (pprefs != null && pprefs.size() > 0) { 4780 final int M = pprefs.size(); 4781 for (int i=0; i<M; i++) { 4782 final PersistentPreferredActivity ppa = pprefs.get(i); 4783 if (DEBUG_PREFERRED || debug) { 4784 Slog.v(TAG, "Checking PersistentPreferredActivity ds=" 4785 + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>") 4786 + "\n component=" + ppa.mComponent); 4787 ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4788 } 4789 final ActivityInfo ai = getActivityInfo(ppa.mComponent, 4790 flags | MATCH_DISABLED_COMPONENTS, userId); 4791 if (DEBUG_PREFERRED || debug) { 4792 Slog.v(TAG, "Found persistent preferred activity:"); 4793 if (ai != null) { 4794 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4795 } else { 4796 Slog.v(TAG, " null"); 4797 } 4798 } 4799 if (ai == null) { 4800 // This previously registered persistent preferred activity 4801 // component is no longer known. Ignore it and do NOT remove it. 4802 continue; 4803 } 4804 for (int j=0; j<N; j++) { 4805 final ResolveInfo ri = query.get(j); 4806 if (!ri.activityInfo.applicationInfo.packageName 4807 .equals(ai.applicationInfo.packageName)) { 4808 continue; 4809 } 4810 if (!ri.activityInfo.name.equals(ai.name)) { 4811 continue; 4812 } 4813 // Found a persistent preference that can handle the intent. 4814 if (DEBUG_PREFERRED || debug) { 4815 Slog.v(TAG, "Returning persistent preferred activity: " + 4816 ri.activityInfo.packageName + "/" + ri.activityInfo.name); 4817 } 4818 return ri; 4819 } 4820 } 4821 } 4822 return null; 4823 } 4824 4825 // TODO: handle preferred activities missing while user has amnesia 4826 ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags, 4827 List<ResolveInfo> query, int priority, boolean always, 4828 boolean removeMatches, boolean debug, int userId) { 4829 if (!sUserManager.exists(userId)) return null; 4830 flags = updateFlagsForResolve(flags, userId, intent); 4831 // writer 4832 synchronized (mPackages) { 4833 if (intent.getSelector() != null) { 4834 intent = intent.getSelector(); 4835 } 4836 if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION); 4837 4838 // Try to find a matching persistent preferred activity. 4839 ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query, 4840 debug, userId); 4841 4842 // If a persistent preferred activity matched, use it. 4843 if (pri != null) { 4844 return pri; 4845 } 4846 4847 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 4848 // Get the list of preferred activities that handle the intent 4849 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities..."); 4850 List<PreferredActivity> prefs = pir != null 4851 ? pir.queryIntent(intent, resolvedType, 4852 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 4853 : null; 4854 if (prefs != null && prefs.size() > 0) { 4855 boolean changed = false; 4856 try { 4857 // First figure out how good the original match set is. 4858 // We will only allow preferred activities that came 4859 // from the same match quality. 4860 int match = 0; 4861 4862 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match..."); 4863 4864 final int N = query.size(); 4865 for (int j=0; j<N; j++) { 4866 final ResolveInfo ri = query.get(j); 4867 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo 4868 + ": 0x" + Integer.toHexString(match)); 4869 if (ri.match > match) { 4870 match = ri.match; 4871 } 4872 } 4873 4874 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x" 4875 + Integer.toHexString(match)); 4876 4877 match &= IntentFilter.MATCH_CATEGORY_MASK; 4878 final int M = prefs.size(); 4879 for (int i=0; i<M; i++) { 4880 final PreferredActivity pa = prefs.get(i); 4881 if (DEBUG_PREFERRED || debug) { 4882 Slog.v(TAG, "Checking PreferredActivity ds=" 4883 + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>") 4884 + "\n component=" + pa.mPref.mComponent); 4885 pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4886 } 4887 if (pa.mPref.mMatch != match) { 4888 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match " 4889 + Integer.toHexString(pa.mPref.mMatch)); 4890 continue; 4891 } 4892 // If it's not an "always" type preferred activity and that's what we're 4893 // looking for, skip it. 4894 if (always && !pa.mPref.mAlways) { 4895 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry"); 4896 continue; 4897 } 4898 final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent, 4899 flags | MATCH_DISABLED_COMPONENTS, userId); 4900 if (DEBUG_PREFERRED || debug) { 4901 Slog.v(TAG, "Found preferred activity:"); 4902 if (ai != null) { 4903 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4904 } else { 4905 Slog.v(TAG, " null"); 4906 } 4907 } 4908 if (ai == null) { 4909 // This previously registered preferred activity 4910 // component is no longer known. Most likely an update 4911 // to the app was installed and in the new version this 4912 // component no longer exists. Clean it up by removing 4913 // it from the preferred activities list, and skip it. 4914 Slog.w(TAG, "Removing dangling preferred activity: " 4915 + pa.mPref.mComponent); 4916 pir.removeFilter(pa); 4917 changed = true; 4918 continue; 4919 } 4920 for (int j=0; j<N; j++) { 4921 final ResolveInfo ri = query.get(j); 4922 if (!ri.activityInfo.applicationInfo.packageName 4923 .equals(ai.applicationInfo.packageName)) { 4924 continue; 4925 } 4926 if (!ri.activityInfo.name.equals(ai.name)) { 4927 continue; 4928 } 4929 4930 if (removeMatches) { 4931 pir.removeFilter(pa); 4932 changed = true; 4933 if (DEBUG_PREFERRED) { 4934 Slog.v(TAG, "Removing match " + pa.mPref.mComponent); 4935 } 4936 break; 4937 } 4938 4939 // Okay we found a previously set preferred or last chosen app. 4940 // If the result set is different from when this 4941 // was created, we need to clear it and re-ask the 4942 // user their preference, if we're looking for an "always" type entry. 4943 if (always && !pa.mPref.sameSet(query)) { 4944 Slog.i(TAG, "Result set changed, dropping preferred activity for " 4945 + intent + " type " + resolvedType); 4946 if (DEBUG_PREFERRED) { 4947 Slog.v(TAG, "Removing preferred activity since set changed " 4948 + pa.mPref.mComponent); 4949 } 4950 pir.removeFilter(pa); 4951 // Re-add the filter as a "last chosen" entry (!always) 4952 PreferredActivity lastChosen = new PreferredActivity( 4953 pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false); 4954 pir.addFilter(lastChosen); 4955 changed = true; 4956 return null; 4957 } 4958 4959 // Yay! Either the set matched or we're looking for the last chosen 4960 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: " 4961 + ri.activityInfo.packageName + "/" + ri.activityInfo.name); 4962 return ri; 4963 } 4964 } 4965 } finally { 4966 if (changed) { 4967 if (DEBUG_PREFERRED) { 4968 Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions"); 4969 } 4970 scheduleWritePackageRestrictionsLocked(userId); 4971 } 4972 } 4973 } 4974 } 4975 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return"); 4976 return null; 4977 } 4978 4979 /* 4980 * Returns if intent can be forwarded from the sourceUserId to the targetUserId 4981 */ 4982 @Override 4983 public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId, 4984 int targetUserId) { 4985 mContext.enforceCallingOrSelfPermission( 4986 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 4987 List<CrossProfileIntentFilter> matches = 4988 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId); 4989 if (matches != null) { 4990 int size = matches.size(); 4991 for (int i = 0; i < size; i++) { 4992 if (matches.get(i).getTargetUserId() == targetUserId) return true; 4993 } 4994 } 4995 if (hasWebURI(intent)) { 4996 // cross-profile app linking works only towards the parent. 4997 final UserInfo parent = getProfileParent(sourceUserId); 4998 synchronized(mPackages) { 4999 int flags = updateFlagsForResolve(0, parent.id, intent); 5000 CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr( 5001 intent, resolvedType, flags, sourceUserId, parent.id); 5002 return xpDomainInfo != null; 5003 } 5004 } 5005 return false; 5006 } 5007 5008 private UserInfo getProfileParent(int userId) { 5009 final long identity = Binder.clearCallingIdentity(); 5010 try { 5011 return sUserManager.getProfileParent(userId); 5012 } finally { 5013 Binder.restoreCallingIdentity(identity); 5014 } 5015 } 5016 5017 private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent, 5018 String resolvedType, int userId) { 5019 CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId); 5020 if (resolver != null) { 5021 return resolver.queryIntent(intent, resolvedType, false, userId); 5022 } 5023 return null; 5024 } 5025 5026 @Override 5027 public List<ResolveInfo> queryIntentActivities(Intent intent, 5028 String resolvedType, int flags, int userId) { 5029 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5030 flags = updateFlagsForResolve(flags, userId, intent); 5031 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5032 false /* requireFullPermission */, false /* checkShell */, 5033 "query intent activities"); 5034 ComponentName comp = intent.getComponent(); 5035 if (comp == null) { 5036 if (intent.getSelector() != null) { 5037 intent = intent.getSelector(); 5038 comp = intent.getComponent(); 5039 } 5040 } 5041 5042 if (comp != null) { 5043 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5044 final ActivityInfo ai = getActivityInfo(comp, flags, userId); 5045 if (ai != null) { 5046 final ResolveInfo ri = new ResolveInfo(); 5047 ri.activityInfo = ai; 5048 list.add(ri); 5049 } 5050 return list; 5051 } 5052 5053 // reader 5054 synchronized (mPackages) { 5055 final String pkgName = intent.getPackage(); 5056 if (pkgName == null) { 5057 List<CrossProfileIntentFilter> matchingFilters = 5058 getMatchingCrossProfileIntentFilters(intent, resolvedType, userId); 5059 // Check for results that need to skip the current profile. 5060 ResolveInfo xpResolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent, 5061 resolvedType, flags, userId); 5062 if (xpResolveInfo != null) { 5063 List<ResolveInfo> result = new ArrayList<ResolveInfo>(1); 5064 result.add(xpResolveInfo); 5065 return filterIfNotSystemUser(result, userId); 5066 } 5067 5068 // Check for results in the current profile. 5069 List<ResolveInfo> result = mActivities.queryIntent( 5070 intent, resolvedType, flags, userId); 5071 result = filterIfNotSystemUser(result, userId); 5072 5073 // Check for cross profile results. 5074 boolean hasNonNegativePriorityResult = hasNonNegativePriority(result); 5075 xpResolveInfo = queryCrossProfileIntents( 5076 matchingFilters, intent, resolvedType, flags, userId, 5077 hasNonNegativePriorityResult); 5078 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) { 5079 boolean isVisibleToUser = filterIfNotSystemUser( 5080 Collections.singletonList(xpResolveInfo), userId).size() > 0; 5081 if (isVisibleToUser) { 5082 result.add(xpResolveInfo); 5083 Collections.sort(result, mResolvePrioritySorter); 5084 } 5085 } 5086 if (hasWebURI(intent)) { 5087 CrossProfileDomainInfo xpDomainInfo = null; 5088 final UserInfo parent = getProfileParent(userId); 5089 if (parent != null) { 5090 xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType, 5091 flags, userId, parent.id); 5092 } 5093 if (xpDomainInfo != null) { 5094 if (xpResolveInfo != null) { 5095 // If we didn't remove it, the cross-profile ResolveInfo would be twice 5096 // in the result. 5097 result.remove(xpResolveInfo); 5098 } 5099 if (result.size() == 0) { 5100 result.add(xpDomainInfo.resolveInfo); 5101 return result; 5102 } 5103 } else if (result.size() <= 1) { 5104 return result; 5105 } 5106 result = filterCandidatesWithDomainPreferredActivitiesLPr(intent, flags, result, 5107 xpDomainInfo, userId); 5108 Collections.sort(result, mResolvePrioritySorter); 5109 } 5110 return result; 5111 } 5112 final PackageParser.Package pkg = mPackages.get(pkgName); 5113 if (pkg != null) { 5114 return filterIfNotSystemUser( 5115 mActivities.queryIntentForPackage( 5116 intent, resolvedType, flags, pkg.activities, userId), 5117 userId); 5118 } 5119 return new ArrayList<ResolveInfo>(); 5120 } 5121 } 5122 5123 private static class CrossProfileDomainInfo { 5124 /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */ 5125 ResolveInfo resolveInfo; 5126 /* Best domain verification status of the activities found in the other profile */ 5127 int bestDomainVerificationStatus; 5128 } 5129 5130 private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent, 5131 String resolvedType, int flags, int sourceUserId, int parentUserId) { 5132 if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING, 5133 sourceUserId)) { 5134 return null; 5135 } 5136 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 5137 resolvedType, flags, parentUserId); 5138 5139 if (resultTargetUser == null || resultTargetUser.isEmpty()) { 5140 return null; 5141 } 5142 CrossProfileDomainInfo result = null; 5143 int size = resultTargetUser.size(); 5144 for (int i = 0; i < size; i++) { 5145 ResolveInfo riTargetUser = resultTargetUser.get(i); 5146 // Intent filter verification is only for filters that specify a host. So don't return 5147 // those that handle all web uris. 5148 if (riTargetUser.handleAllWebDataURI) { 5149 continue; 5150 } 5151 String packageName = riTargetUser.activityInfo.packageName; 5152 PackageSetting ps = mSettings.mPackages.get(packageName); 5153 if (ps == null) { 5154 continue; 5155 } 5156 long verificationState = getDomainVerificationStatusLPr(ps, parentUserId); 5157 int status = (int)(verificationState >> 32); 5158 if (result == null) { 5159 result = new CrossProfileDomainInfo(); 5160 result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(), 5161 sourceUserId, parentUserId); 5162 result.bestDomainVerificationStatus = status; 5163 } else { 5164 result.bestDomainVerificationStatus = bestDomainVerificationStatus(status, 5165 result.bestDomainVerificationStatus); 5166 } 5167 } 5168 // Don't consider matches with status NEVER across profiles. 5169 if (result != null && result.bestDomainVerificationStatus 5170 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5171 return null; 5172 } 5173 return result; 5174 } 5175 5176 /** 5177 * Verification statuses are ordered from the worse to the best, except for 5178 * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse. 5179 */ 5180 private int bestDomainVerificationStatus(int status1, int status2) { 5181 if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5182 return status2; 5183 } 5184 if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5185 return status1; 5186 } 5187 return (int) MathUtils.max(status1, status2); 5188 } 5189 5190 private boolean isUserEnabled(int userId) { 5191 long callingId = Binder.clearCallingIdentity(); 5192 try { 5193 UserInfo userInfo = sUserManager.getUserInfo(userId); 5194 return userInfo != null && userInfo.isEnabled(); 5195 } finally { 5196 Binder.restoreCallingIdentity(callingId); 5197 } 5198 } 5199 5200 /** 5201 * Filter out activities with systemUserOnly flag set, when current user is not System. 5202 * 5203 * @return filtered list 5204 */ 5205 private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) { 5206 if (userId == UserHandle.USER_SYSTEM) { 5207 return resolveInfos; 5208 } 5209 for (int i = resolveInfos.size() - 1; i >= 0; i--) { 5210 ResolveInfo info = resolveInfos.get(i); 5211 if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) { 5212 resolveInfos.remove(i); 5213 } 5214 } 5215 return resolveInfos; 5216 } 5217 5218 /** 5219 * @param resolveInfos list of resolve infos in descending priority order 5220 * @return if the list contains a resolve info with non-negative priority 5221 */ 5222 private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) { 5223 return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0; 5224 } 5225 5226 private static boolean hasWebURI(Intent intent) { 5227 if (intent.getData() == null) { 5228 return false; 5229 } 5230 final String scheme = intent.getScheme(); 5231 if (TextUtils.isEmpty(scheme)) { 5232 return false; 5233 } 5234 return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS); 5235 } 5236 5237 private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent, 5238 int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo, 5239 int userId) { 5240 final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0; 5241 5242 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) { 5243 Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " + 5244 candidates.size()); 5245 } 5246 5247 ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>(); 5248 ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>(); 5249 ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>(); 5250 ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>(); 5251 ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>(); 5252 ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>(); 5253 5254 synchronized (mPackages) { 5255 final int count = candidates.size(); 5256 // First, try to use linked apps. Partition the candidates into four lists: 5257 // one for the final results, one for the "do not use ever", one for "undefined status" 5258 // and finally one for "browser app type". 5259 for (int n=0; n<count; n++) { 5260 ResolveInfo info = candidates.get(n); 5261 String packageName = info.activityInfo.packageName; 5262 PackageSetting ps = mSettings.mPackages.get(packageName); 5263 if (ps != null) { 5264 // Add to the special match all list (Browser use case) 5265 if (info.handleAllWebDataURI) { 5266 matchAllList.add(info); 5267 continue; 5268 } 5269 // Try to get the status from User settings first 5270 long packedStatus = getDomainVerificationStatusLPr(ps, userId); 5271 int status = (int)(packedStatus >> 32); 5272 int linkGeneration = (int)(packedStatus & 0xFFFFFFFF); 5273 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) { 5274 if (DEBUG_DOMAIN_VERIFICATION) { 5275 Slog.i(TAG, " + always: " + info.activityInfo.packageName 5276 + " : linkgen=" + linkGeneration); 5277 } 5278 // Use link-enabled generation as preferredOrder, i.e. 5279 // prefer newly-enabled over earlier-enabled. 5280 info.preferredOrder = linkGeneration; 5281 alwaysList.add(info); 5282 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5283 if (DEBUG_DOMAIN_VERIFICATION) { 5284 Slog.i(TAG, " + never: " + info.activityInfo.packageName); 5285 } 5286 neverList.add(info); 5287 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) { 5288 if (DEBUG_DOMAIN_VERIFICATION) { 5289 Slog.i(TAG, " + always-ask: " + info.activityInfo.packageName); 5290 } 5291 alwaysAskList.add(info); 5292 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED || 5293 status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) { 5294 if (DEBUG_DOMAIN_VERIFICATION) { 5295 Slog.i(TAG, " + ask: " + info.activityInfo.packageName); 5296 } 5297 undefinedList.add(info); 5298 } 5299 } 5300 } 5301 5302 // We'll want to include browser possibilities in a few cases 5303 boolean includeBrowser = false; 5304 5305 // First try to add the "always" resolution(s) for the current user, if any 5306 if (alwaysList.size() > 0) { 5307 result.addAll(alwaysList); 5308 } else { 5309 // Add all undefined apps as we want them to appear in the disambiguation dialog. 5310 result.addAll(undefinedList); 5311 // Maybe add one for the other profile. 5312 if (xpDomainInfo != null && ( 5313 xpDomainInfo.bestDomainVerificationStatus 5314 != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) { 5315 result.add(xpDomainInfo.resolveInfo); 5316 } 5317 includeBrowser = true; 5318 } 5319 5320 // The presence of any 'always ask' alternatives means we'll also offer browsers. 5321 // If there were 'always' entries their preferred order has been set, so we also 5322 // back that off to make the alternatives equivalent 5323 if (alwaysAskList.size() > 0) { 5324 for (ResolveInfo i : result) { 5325 i.preferredOrder = 0; 5326 } 5327 result.addAll(alwaysAskList); 5328 includeBrowser = true; 5329 } 5330 5331 if (includeBrowser) { 5332 // Also add browsers (all of them or only the default one) 5333 if (DEBUG_DOMAIN_VERIFICATION) { 5334 Slog.v(TAG, " ...including browsers in candidate set"); 5335 } 5336 if ((matchFlags & MATCH_ALL) != 0) { 5337 result.addAll(matchAllList); 5338 } else { 5339 // Browser/generic handling case. If there's a default browser, go straight 5340 // to that (but only if there is no other higher-priority match). 5341 final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId); 5342 int maxMatchPrio = 0; 5343 ResolveInfo defaultBrowserMatch = null; 5344 final int numCandidates = matchAllList.size(); 5345 for (int n = 0; n < numCandidates; n++) { 5346 ResolveInfo info = matchAllList.get(n); 5347 // track the highest overall match priority... 5348 if (info.priority > maxMatchPrio) { 5349 maxMatchPrio = info.priority; 5350 } 5351 // ...and the highest-priority default browser match 5352 if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) { 5353 if (defaultBrowserMatch == null 5354 || (defaultBrowserMatch.priority < info.priority)) { 5355 if (debug) { 5356 Slog.v(TAG, "Considering default browser match " + info); 5357 } 5358 defaultBrowserMatch = info; 5359 } 5360 } 5361 } 5362 if (defaultBrowserMatch != null 5363 && defaultBrowserMatch.priority >= maxMatchPrio 5364 && !TextUtils.isEmpty(defaultBrowserPackageName)) 5365 { 5366 if (debug) { 5367 Slog.v(TAG, "Default browser match " + defaultBrowserMatch); 5368 } 5369 result.add(defaultBrowserMatch); 5370 } else { 5371 result.addAll(matchAllList); 5372 } 5373 } 5374 5375 // If there is nothing selected, add all candidates and remove the ones that the user 5376 // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state 5377 if (result.size() == 0) { 5378 result.addAll(candidates); 5379 result.removeAll(neverList); 5380 } 5381 } 5382 } 5383 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) { 5384 Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " + 5385 result.size()); 5386 for (ResolveInfo info : result) { 5387 Slog.v(TAG, " + " + info.activityInfo); 5388 } 5389 } 5390 return result; 5391 } 5392 5393 // Returns a packed value as a long: 5394 // 5395 // high 'int'-sized word: link status: undefined/ask/never/always. 5396 // low 'int'-sized word: relative priority among 'always' results. 5397 private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) { 5398 long result = ps.getDomainVerificationStatusForUser(userId); 5399 // if none available, get the master status 5400 if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 5401 if (ps.getIntentFilterVerificationInfo() != null) { 5402 result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32; 5403 } 5404 } 5405 return result; 5406 } 5407 5408 private ResolveInfo querySkipCurrentProfileIntents( 5409 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 5410 int flags, int sourceUserId) { 5411 if (matchingFilters != null) { 5412 int size = matchingFilters.size(); 5413 for (int i = 0; i < size; i ++) { 5414 CrossProfileIntentFilter filter = matchingFilters.get(i); 5415 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) { 5416 // Checking if there are activities in the target user that can handle the 5417 // intent. 5418 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent, 5419 resolvedType, flags, sourceUserId); 5420 if (resolveInfo != null) { 5421 return resolveInfo; 5422 } 5423 } 5424 } 5425 } 5426 return null; 5427 } 5428 5429 // Return matching ResolveInfo in target user if any. 5430 private ResolveInfo queryCrossProfileIntents( 5431 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 5432 int flags, int sourceUserId, boolean matchInCurrentProfile) { 5433 if (matchingFilters != null) { 5434 // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and 5435 // match the same intent. For performance reasons, it is better not to 5436 // run queryIntent twice for the same userId 5437 SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray(); 5438 int size = matchingFilters.size(); 5439 for (int i = 0; i < size; i++) { 5440 CrossProfileIntentFilter filter = matchingFilters.get(i); 5441 int targetUserId = filter.getTargetUserId(); 5442 boolean skipCurrentProfile = 5443 (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0; 5444 boolean skipCurrentProfileIfNoMatchFound = 5445 (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0; 5446 if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId) 5447 && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) { 5448 // Checking if there are activities in the target user that can handle the 5449 // intent. 5450 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent, 5451 resolvedType, flags, sourceUserId); 5452 if (resolveInfo != null) return resolveInfo; 5453 alreadyTriedUserIds.put(targetUserId, true); 5454 } 5455 } 5456 } 5457 return null; 5458 } 5459 5460 /** 5461 * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that 5462 * will forward the intent to the filter's target user. 5463 * Otherwise, returns null. 5464 */ 5465 private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent, 5466 String resolvedType, int flags, int sourceUserId) { 5467 int targetUserId = filter.getTargetUserId(); 5468 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 5469 resolvedType, flags, targetUserId); 5470 if (resultTargetUser != null && isUserEnabled(targetUserId)) { 5471 // If all the matches in the target profile are suspended, return null. 5472 for (int i = resultTargetUser.size() - 1; i >= 0; i--) { 5473 if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags 5474 & ApplicationInfo.FLAG_SUSPENDED) == 0) { 5475 return createForwardingResolveInfoUnchecked(filter, sourceUserId, 5476 targetUserId); 5477 } 5478 } 5479 } 5480 return null; 5481 } 5482 5483 private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter, 5484 int sourceUserId, int targetUserId) { 5485 ResolveInfo forwardingResolveInfo = new ResolveInfo(); 5486 long ident = Binder.clearCallingIdentity(); 5487 boolean targetIsProfile; 5488 try { 5489 targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile(); 5490 } finally { 5491 Binder.restoreCallingIdentity(ident); 5492 } 5493 String className; 5494 if (targetIsProfile) { 5495 className = FORWARD_INTENT_TO_MANAGED_PROFILE; 5496 } else { 5497 className = FORWARD_INTENT_TO_PARENT; 5498 } 5499 ComponentName forwardingActivityComponentName = new ComponentName( 5500 mAndroidApplication.packageName, className); 5501 ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0, 5502 sourceUserId); 5503 if (!targetIsProfile) { 5504 forwardingActivityInfo.showUserIcon = targetUserId; 5505 forwardingResolveInfo.noResourceId = true; 5506 } 5507 forwardingResolveInfo.activityInfo = forwardingActivityInfo; 5508 forwardingResolveInfo.priority = 0; 5509 forwardingResolveInfo.preferredOrder = 0; 5510 forwardingResolveInfo.match = 0; 5511 forwardingResolveInfo.isDefault = true; 5512 forwardingResolveInfo.filter = filter; 5513 forwardingResolveInfo.targetUserId = targetUserId; 5514 return forwardingResolveInfo; 5515 } 5516 5517 @Override 5518 public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller, 5519 Intent[] specifics, String[] specificTypes, Intent intent, 5520 String resolvedType, int flags, int userId) { 5521 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5522 flags = updateFlagsForResolve(flags, userId, intent); 5523 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5524 false /* requireFullPermission */, false /* checkShell */, 5525 "query intent activity options"); 5526 final String resultsAction = intent.getAction(); 5527 5528 List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags 5529 | PackageManager.GET_RESOLVED_FILTER, userId); 5530 5531 if (DEBUG_INTENT_MATCHING) { 5532 Log.v(TAG, "Query " + intent + ": " + results); 5533 } 5534 5535 int specificsPos = 0; 5536 int N; 5537 5538 // todo: note that the algorithm used here is O(N^2). This 5539 // isn't a problem in our current environment, but if we start running 5540 // into situations where we have more than 5 or 10 matches then this 5541 // should probably be changed to something smarter... 5542 5543 // First we go through and resolve each of the specific items 5544 // that were supplied, taking care of removing any corresponding 5545 // duplicate items in the generic resolve list. 5546 if (specifics != null) { 5547 for (int i=0; i<specifics.length; i++) { 5548 final Intent sintent = specifics[i]; 5549 if (sintent == null) { 5550 continue; 5551 } 5552 5553 if (DEBUG_INTENT_MATCHING) { 5554 Log.v(TAG, "Specific #" + i + ": " + sintent); 5555 } 5556 5557 String action = sintent.getAction(); 5558 if (resultsAction != null && resultsAction.equals(action)) { 5559 // If this action was explicitly requested, then don't 5560 // remove things that have it. 5561 action = null; 5562 } 5563 5564 ResolveInfo ri = null; 5565 ActivityInfo ai = null; 5566 5567 ComponentName comp = sintent.getComponent(); 5568 if (comp == null) { 5569 ri = resolveIntent( 5570 sintent, 5571 specificTypes != null ? specificTypes[i] : null, 5572 flags, userId); 5573 if (ri == null) { 5574 continue; 5575 } 5576 if (ri == mResolveInfo) { 5577 // ACK! Must do something better with this. 5578 } 5579 ai = ri.activityInfo; 5580 comp = new ComponentName(ai.applicationInfo.packageName, 5581 ai.name); 5582 } else { 5583 ai = getActivityInfo(comp, flags, userId); 5584 if (ai == null) { 5585 continue; 5586 } 5587 } 5588 5589 // Look for any generic query activities that are duplicates 5590 // of this specific one, and remove them from the results. 5591 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai); 5592 N = results.size(); 5593 int j; 5594 for (j=specificsPos; j<N; j++) { 5595 ResolveInfo sri = results.get(j); 5596 if ((sri.activityInfo.name.equals(comp.getClassName()) 5597 && sri.activityInfo.applicationInfo.packageName.equals( 5598 comp.getPackageName())) 5599 || (action != null && sri.filter.matchAction(action))) { 5600 results.remove(j); 5601 if (DEBUG_INTENT_MATCHING) Log.v( 5602 TAG, "Removing duplicate item from " + j 5603 + " due to specific " + specificsPos); 5604 if (ri == null) { 5605 ri = sri; 5606 } 5607 j--; 5608 N--; 5609 } 5610 } 5611 5612 // Add this specific item to its proper place. 5613 if (ri == null) { 5614 ri = new ResolveInfo(); 5615 ri.activityInfo = ai; 5616 } 5617 results.add(specificsPos, ri); 5618 ri.specificIndex = i; 5619 specificsPos++; 5620 } 5621 } 5622 5623 // Now we go through the remaining generic results and remove any 5624 // duplicate actions that are found here. 5625 N = results.size(); 5626 for (int i=specificsPos; i<N-1; i++) { 5627 final ResolveInfo rii = results.get(i); 5628 if (rii.filter == null) { 5629 continue; 5630 } 5631 5632 // Iterate over all of the actions of this result's intent 5633 // filter... typically this should be just one. 5634 final Iterator<String> it = rii.filter.actionsIterator(); 5635 if (it == null) { 5636 continue; 5637 } 5638 while (it.hasNext()) { 5639 final String action = it.next(); 5640 if (resultsAction != null && resultsAction.equals(action)) { 5641 // If this action was explicitly requested, then don't 5642 // remove things that have it. 5643 continue; 5644 } 5645 for (int j=i+1; j<N; j++) { 5646 final ResolveInfo rij = results.get(j); 5647 if (rij.filter != null && rij.filter.hasAction(action)) { 5648 results.remove(j); 5649 if (DEBUG_INTENT_MATCHING) Log.v( 5650 TAG, "Removing duplicate item from " + j 5651 + " due to action " + action + " at " + i); 5652 j--; 5653 N--; 5654 } 5655 } 5656 } 5657 5658 // If the caller didn't request filter information, drop it now 5659 // so we don't have to marshall/unmarshall it. 5660 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 5661 rii.filter = null; 5662 } 5663 } 5664 5665 // Filter out the caller activity if so requested. 5666 if (caller != null) { 5667 N = results.size(); 5668 for (int i=0; i<N; i++) { 5669 ActivityInfo ainfo = results.get(i).activityInfo; 5670 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName) 5671 && caller.getClassName().equals(ainfo.name)) { 5672 results.remove(i); 5673 break; 5674 } 5675 } 5676 } 5677 5678 // If the caller didn't request filter information, 5679 // drop them now so we don't have to 5680 // marshall/unmarshall it. 5681 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 5682 N = results.size(); 5683 for (int i=0; i<N; i++) { 5684 results.get(i).filter = null; 5685 } 5686 } 5687 5688 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results); 5689 return results; 5690 } 5691 5692 @Override 5693 public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags, 5694 int userId) { 5695 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5696 flags = updateFlagsForResolve(flags, userId, intent); 5697 ComponentName comp = intent.getComponent(); 5698 if (comp == null) { 5699 if (intent.getSelector() != null) { 5700 intent = intent.getSelector(); 5701 comp = intent.getComponent(); 5702 } 5703 } 5704 if (comp != null) { 5705 List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5706 ActivityInfo ai = getReceiverInfo(comp, flags, userId); 5707 if (ai != null) { 5708 ResolveInfo ri = new ResolveInfo(); 5709 ri.activityInfo = ai; 5710 list.add(ri); 5711 } 5712 return list; 5713 } 5714 5715 // reader 5716 synchronized (mPackages) { 5717 String pkgName = intent.getPackage(); 5718 if (pkgName == null) { 5719 return mReceivers.queryIntent(intent, resolvedType, flags, userId); 5720 } 5721 final PackageParser.Package pkg = mPackages.get(pkgName); 5722 if (pkg != null) { 5723 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers, 5724 userId); 5725 } 5726 return null; 5727 } 5728 } 5729 5730 @Override 5731 public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) { 5732 if (!sUserManager.exists(userId)) return null; 5733 flags = updateFlagsForResolve(flags, userId, intent); 5734 List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId); 5735 if (query != null) { 5736 if (query.size() >= 1) { 5737 // If there is more than one service with the same priority, 5738 // just arbitrarily pick the first one. 5739 return query.get(0); 5740 } 5741 } 5742 return null; 5743 } 5744 5745 @Override 5746 public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags, 5747 int userId) { 5748 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5749 flags = updateFlagsForResolve(flags, userId, intent); 5750 ComponentName comp = intent.getComponent(); 5751 if (comp == null) { 5752 if (intent.getSelector() != null) { 5753 intent = intent.getSelector(); 5754 comp = intent.getComponent(); 5755 } 5756 } 5757 if (comp != null) { 5758 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5759 final ServiceInfo si = getServiceInfo(comp, flags, userId); 5760 if (si != null) { 5761 final ResolveInfo ri = new ResolveInfo(); 5762 ri.serviceInfo = si; 5763 list.add(ri); 5764 } 5765 return list; 5766 } 5767 5768 // reader 5769 synchronized (mPackages) { 5770 String pkgName = intent.getPackage(); 5771 if (pkgName == null) { 5772 return mServices.queryIntent(intent, resolvedType, flags, userId); 5773 } 5774 final PackageParser.Package pkg = mPackages.get(pkgName); 5775 if (pkg != null) { 5776 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services, 5777 userId); 5778 } 5779 return null; 5780 } 5781 } 5782 5783 @Override 5784 public List<ResolveInfo> queryIntentContentProviders( 5785 Intent intent, String resolvedType, int flags, int userId) { 5786 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5787 flags = updateFlagsForResolve(flags, userId, intent); 5788 ComponentName comp = intent.getComponent(); 5789 if (comp == null) { 5790 if (intent.getSelector() != null) { 5791 intent = intent.getSelector(); 5792 comp = intent.getComponent(); 5793 } 5794 } 5795 if (comp != null) { 5796 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5797 final ProviderInfo pi = getProviderInfo(comp, flags, userId); 5798 if (pi != null) { 5799 final ResolveInfo ri = new ResolveInfo(); 5800 ri.providerInfo = pi; 5801 list.add(ri); 5802 } 5803 return list; 5804 } 5805 5806 // reader 5807 synchronized (mPackages) { 5808 String pkgName = intent.getPackage(); 5809 if (pkgName == null) { 5810 return mProviders.queryIntent(intent, resolvedType, flags, userId); 5811 } 5812 final PackageParser.Package pkg = mPackages.get(pkgName); 5813 if (pkg != null) { 5814 return mProviders.queryIntentForPackage( 5815 intent, resolvedType, flags, pkg.providers, userId); 5816 } 5817 return null; 5818 } 5819 } 5820 5821 @Override 5822 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) { 5823 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 5824 flags = updateFlagsForPackage(flags, userId, null); 5825 final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0; 5826 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5827 true /* requireFullPermission */, false /* checkShell */, 5828 "get installed packages"); 5829 5830 // writer 5831 synchronized (mPackages) { 5832 ArrayList<PackageInfo> list; 5833 if (listUninstalled) { 5834 list = new ArrayList<PackageInfo>(mSettings.mPackages.size()); 5835 for (PackageSetting ps : mSettings.mPackages.values()) { 5836 PackageInfo pi; 5837 if (ps.pkg != null) { 5838 pi = generatePackageInfo(ps.pkg, flags, userId); 5839 } else { 5840 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId); 5841 } 5842 if (pi != null) { 5843 list.add(pi); 5844 } 5845 } 5846 } else { 5847 list = new ArrayList<PackageInfo>(mPackages.size()); 5848 for (PackageParser.Package p : mPackages.values()) { 5849 PackageInfo pi = generatePackageInfo(p, flags, userId); 5850 if (pi != null) { 5851 list.add(pi); 5852 } 5853 } 5854 } 5855 5856 return new ParceledListSlice<PackageInfo>(list); 5857 } 5858 } 5859 5860 private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps, 5861 String[] permissions, boolean[] tmp, int flags, int userId) { 5862 int numMatch = 0; 5863 final PermissionsState permissionsState = ps.getPermissionsState(); 5864 for (int i=0; i<permissions.length; i++) { 5865 final String permission = permissions[i]; 5866 if (permissionsState.hasPermission(permission, userId)) { 5867 tmp[i] = true; 5868 numMatch++; 5869 } else { 5870 tmp[i] = false; 5871 } 5872 } 5873 if (numMatch == 0) { 5874 return; 5875 } 5876 PackageInfo pi; 5877 if (ps.pkg != null) { 5878 pi = generatePackageInfo(ps.pkg, flags, userId); 5879 } else { 5880 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId); 5881 } 5882 // The above might return null in cases of uninstalled apps or install-state 5883 // skew across users/profiles. 5884 if (pi != null) { 5885 if ((flags&PackageManager.GET_PERMISSIONS) == 0) { 5886 if (numMatch == permissions.length) { 5887 pi.requestedPermissions = permissions; 5888 } else { 5889 pi.requestedPermissions = new String[numMatch]; 5890 numMatch = 0; 5891 for (int i=0; i<permissions.length; i++) { 5892 if (tmp[i]) { 5893 pi.requestedPermissions[numMatch] = permissions[i]; 5894 numMatch++; 5895 } 5896 } 5897 } 5898 } 5899 list.add(pi); 5900 } 5901 } 5902 5903 @Override 5904 public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions( 5905 String[] permissions, int flags, int userId) { 5906 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 5907 flags = updateFlagsForPackage(flags, userId, permissions); 5908 final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0; 5909 5910 // writer 5911 synchronized (mPackages) { 5912 ArrayList<PackageInfo> list = new ArrayList<PackageInfo>(); 5913 boolean[] tmpBools = new boolean[permissions.length]; 5914 if (listUninstalled) { 5915 for (PackageSetting ps : mSettings.mPackages.values()) { 5916 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId); 5917 } 5918 } else { 5919 for (PackageParser.Package pkg : mPackages.values()) { 5920 PackageSetting ps = (PackageSetting)pkg.mExtras; 5921 if (ps != null) { 5922 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, 5923 userId); 5924 } 5925 } 5926 } 5927 5928 return new ParceledListSlice<PackageInfo>(list); 5929 } 5930 } 5931 5932 @Override 5933 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) { 5934 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 5935 flags = updateFlagsForApplication(flags, userId, null); 5936 final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0; 5937 5938 // writer 5939 synchronized (mPackages) { 5940 ArrayList<ApplicationInfo> list; 5941 if (listUninstalled) { 5942 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size()); 5943 for (PackageSetting ps : mSettings.mPackages.values()) { 5944 ApplicationInfo ai; 5945 if (ps.pkg != null) { 5946 ai = PackageParser.generateApplicationInfo(ps.pkg, flags, 5947 ps.readUserState(userId), userId); 5948 } else { 5949 ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId); 5950 } 5951 if (ai != null) { 5952 list.add(ai); 5953 } 5954 } 5955 } else { 5956 list = new ArrayList<ApplicationInfo>(mPackages.size()); 5957 for (PackageParser.Package p : mPackages.values()) { 5958 if (p.mExtras != null) { 5959 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 5960 ((PackageSetting)p.mExtras).readUserState(userId), userId); 5961 if (ai != null) { 5962 list.add(ai); 5963 } 5964 } 5965 } 5966 } 5967 5968 return new ParceledListSlice<ApplicationInfo>(list); 5969 } 5970 } 5971 5972 @Override 5973 public ParceledListSlice<EphemeralApplicationInfo> getEphemeralApplications(int userId) { 5974 if (DISABLE_EPHEMERAL_APPS) { 5975 return null; 5976 } 5977 5978 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS, 5979 "getEphemeralApplications"); 5980 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5981 true /* requireFullPermission */, false /* checkShell */, 5982 "getEphemeralApplications"); 5983 synchronized (mPackages) { 5984 List<EphemeralApplicationInfo> ephemeralApps = mEphemeralApplicationRegistry 5985 .getEphemeralApplicationsLPw(userId); 5986 if (ephemeralApps != null) { 5987 return new ParceledListSlice<>(ephemeralApps); 5988 } 5989 } 5990 return null; 5991 } 5992 5993 @Override 5994 public boolean isEphemeralApplication(String packageName, int userId) { 5995 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5996 true /* requireFullPermission */, false /* checkShell */, 5997 "isEphemeral"); 5998 if (DISABLE_EPHEMERAL_APPS) { 5999 return false; 6000 } 6001 6002 if (!isCallerSameApp(packageName)) { 6003 return false; 6004 } 6005 synchronized (mPackages) { 6006 PackageParser.Package pkg = mPackages.get(packageName); 6007 if (pkg != null) { 6008 return pkg.applicationInfo.isEphemeralApp(); 6009 } 6010 } 6011 return false; 6012 } 6013 6014 @Override 6015 public byte[] getEphemeralApplicationCookie(String packageName, int userId) { 6016 if (DISABLE_EPHEMERAL_APPS) { 6017 return null; 6018 } 6019 6020 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6021 true /* requireFullPermission */, false /* checkShell */, 6022 "getCookie"); 6023 if (!isCallerSameApp(packageName)) { 6024 return null; 6025 } 6026 synchronized (mPackages) { 6027 return mEphemeralApplicationRegistry.getEphemeralApplicationCookieLPw( 6028 packageName, userId); 6029 } 6030 } 6031 6032 @Override 6033 public boolean setEphemeralApplicationCookie(String packageName, byte[] cookie, int userId) { 6034 if (DISABLE_EPHEMERAL_APPS) { 6035 return true; 6036 } 6037 6038 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6039 true /* requireFullPermission */, true /* checkShell */, 6040 "setCookie"); 6041 if (!isCallerSameApp(packageName)) { 6042 return false; 6043 } 6044 synchronized (mPackages) { 6045 return mEphemeralApplicationRegistry.setEphemeralApplicationCookieLPw( 6046 packageName, cookie, userId); 6047 } 6048 } 6049 6050 @Override 6051 public Bitmap getEphemeralApplicationIcon(String packageName, int userId) { 6052 if (DISABLE_EPHEMERAL_APPS) { 6053 return null; 6054 } 6055 6056 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS, 6057 "getEphemeralApplicationIcon"); 6058 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6059 true /* requireFullPermission */, false /* checkShell */, 6060 "getEphemeralApplicationIcon"); 6061 synchronized (mPackages) { 6062 return mEphemeralApplicationRegistry.getEphemeralApplicationIconLPw( 6063 packageName, userId); 6064 } 6065 } 6066 6067 private boolean isCallerSameApp(String packageName) { 6068 PackageParser.Package pkg = mPackages.get(packageName); 6069 return pkg != null 6070 && UserHandle.getAppId(Binder.getCallingUid()) == pkg.applicationInfo.uid; 6071 } 6072 6073 public List<ApplicationInfo> getPersistentApplications(int flags) { 6074 final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>(); 6075 6076 // reader 6077 synchronized (mPackages) { 6078 final Iterator<PackageParser.Package> i = mPackages.values().iterator(); 6079 final int userId = UserHandle.getCallingUserId(); 6080 while (i.hasNext()) { 6081 final PackageParser.Package p = i.next(); 6082 if (p.applicationInfo != null 6083 && (p.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) != 0 6084 && (!mSafeMode || isSystemApp(p))) { 6085 PackageSetting ps = mSettings.mPackages.get(p.packageName); 6086 if (ps != null) { 6087 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 6088 ps.readUserState(userId), userId); 6089 if (ai != null) { 6090 finalList.add(ai); 6091 } 6092 } 6093 } 6094 } 6095 } 6096 6097 return finalList; 6098 } 6099 6100 @Override 6101 public ProviderInfo resolveContentProvider(String name, int flags, int userId) { 6102 if (!sUserManager.exists(userId)) return null; 6103 flags = updateFlagsForComponent(flags, userId, name); 6104 // reader 6105 synchronized (mPackages) { 6106 final PackageParser.Provider provider = mProvidersByAuthority.get(name); 6107 PackageSetting ps = provider != null 6108 ? mSettings.mPackages.get(provider.owner.packageName) 6109 : null; 6110 return ps != null 6111 && mSettings.isEnabledAndMatchLPr(provider.info, flags, userId) 6112 ? PackageParser.generateProviderInfo(provider, flags, 6113 ps.readUserState(userId), userId) 6114 : null; 6115 } 6116 } 6117 6118 /** 6119 * @deprecated 6120 */ 6121 @Deprecated 6122 public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) { 6123 // reader 6124 synchronized (mPackages) { 6125 final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority 6126 .entrySet().iterator(); 6127 final int userId = UserHandle.getCallingUserId(); 6128 while (i.hasNext()) { 6129 Map.Entry<String, PackageParser.Provider> entry = i.next(); 6130 PackageParser.Provider p = entry.getValue(); 6131 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 6132 6133 if (ps != null && p.syncable 6134 && (!mSafeMode || (p.info.applicationInfo.flags 6135 &ApplicationInfo.FLAG_SYSTEM) != 0)) { 6136 ProviderInfo info = PackageParser.generateProviderInfo(p, 0, 6137 ps.readUserState(userId), userId); 6138 if (info != null) { 6139 outNames.add(entry.getKey()); 6140 outInfo.add(info); 6141 } 6142 } 6143 } 6144 } 6145 } 6146 6147 @Override 6148 public ParceledListSlice<ProviderInfo> queryContentProviders(String processName, 6149 int uid, int flags) { 6150 final int userId = processName != null ? UserHandle.getUserId(uid) 6151 : UserHandle.getCallingUserId(); 6152 if (!sUserManager.exists(userId)) return null; 6153 flags = updateFlagsForComponent(flags, userId, processName); 6154 6155 ArrayList<ProviderInfo> finalList = null; 6156 // reader 6157 synchronized (mPackages) { 6158 final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator(); 6159 while (i.hasNext()) { 6160 final PackageParser.Provider p = i.next(); 6161 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 6162 if (ps != null && p.info.authority != null 6163 && (processName == null 6164 || (p.info.processName.equals(processName) 6165 && UserHandle.isSameApp(p.info.applicationInfo.uid, uid))) 6166 && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) { 6167 if (finalList == null) { 6168 finalList = new ArrayList<ProviderInfo>(3); 6169 } 6170 ProviderInfo info = PackageParser.generateProviderInfo(p, flags, 6171 ps.readUserState(userId), userId); 6172 if (info != null) { 6173 finalList.add(info); 6174 } 6175 } 6176 } 6177 } 6178 6179 if (finalList != null) { 6180 Collections.sort(finalList, mProviderInitOrderSorter); 6181 return new ParceledListSlice<ProviderInfo>(finalList); 6182 } 6183 6184 return null; 6185 } 6186 6187 @Override 6188 public InstrumentationInfo getInstrumentationInfo(ComponentName name, int flags) { 6189 // reader 6190 synchronized (mPackages) { 6191 final PackageParser.Instrumentation i = mInstrumentation.get(name); 6192 return PackageParser.generateInstrumentationInfo(i, flags); 6193 } 6194 } 6195 6196 @Override 6197 public List<InstrumentationInfo> queryInstrumentation(String targetPackage, 6198 int flags) { 6199 ArrayList<InstrumentationInfo> finalList = 6200 new ArrayList<InstrumentationInfo>(); 6201 6202 // reader 6203 synchronized (mPackages) { 6204 final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator(); 6205 while (i.hasNext()) { 6206 final PackageParser.Instrumentation p = i.next(); 6207 if (targetPackage == null 6208 || targetPackage.equals(p.info.targetPackage)) { 6209 InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p, 6210 flags); 6211 if (ii != null) { 6212 finalList.add(ii); 6213 } 6214 } 6215 } 6216 } 6217 6218 return finalList; 6219 } 6220 6221 private void createIdmapsForPackageLI(PackageParser.Package pkg) { 6222 ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName); 6223 if (overlays == null) { 6224 Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages"); 6225 return; 6226 } 6227 for (PackageParser.Package opkg : overlays.values()) { 6228 // Not much to do if idmap fails: we already logged the error 6229 // and we certainly don't want to abort installation of pkg simply 6230 // because an overlay didn't fit properly. For these reasons, 6231 // ignore the return value of createIdmapForPackagePairLI. 6232 createIdmapForPackagePairLI(pkg, opkg); 6233 } 6234 } 6235 6236 private boolean createIdmapForPackagePairLI(PackageParser.Package pkg, 6237 PackageParser.Package opkg) { 6238 if (!opkg.mTrustedOverlay) { 6239 Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " + 6240 opkg.baseCodePath + ": overlay not trusted"); 6241 return false; 6242 } 6243 ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName); 6244 if (overlaySet == null) { 6245 Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " + 6246 opkg.baseCodePath + " but target package has no known overlays"); 6247 return false; 6248 } 6249 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 6250 // TODO: generate idmap for split APKs 6251 try { 6252 mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid); 6253 } catch (InstallerException e) { 6254 Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and " 6255 + opkg.baseCodePath); 6256 return false; 6257 } 6258 PackageParser.Package[] overlayArray = 6259 overlaySet.values().toArray(new PackageParser.Package[0]); 6260 Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() { 6261 public int compare(PackageParser.Package p1, PackageParser.Package p2) { 6262 return p1.mOverlayPriority - p2.mOverlayPriority; 6263 } 6264 }; 6265 Arrays.sort(overlayArray, cmp); 6266 6267 pkg.applicationInfo.resourceDirs = new String[overlayArray.length]; 6268 int i = 0; 6269 for (PackageParser.Package p : overlayArray) { 6270 pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath; 6271 } 6272 return true; 6273 } 6274 6275 private void scanDirTracedLI(File dir, int parseFlags, int scanFlags, long currentTime) { 6276 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir"); 6277 try { 6278 scanDirLI(dir, parseFlags, scanFlags, currentTime); 6279 } finally { 6280 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6281 } 6282 } 6283 6284 private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) { 6285 final File[] files = dir.listFiles(); 6286 if (ArrayUtils.isEmpty(files)) { 6287 Log.d(TAG, "No files in app dir " + dir); 6288 return; 6289 } 6290 6291 if (DEBUG_PACKAGE_SCANNING) { 6292 Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags 6293 + " flags=0x" + Integer.toHexString(parseFlags)); 6294 } 6295 6296 for (File file : files) { 6297 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 6298 && !PackageInstallerService.isStageName(file.getName()); 6299 if (!isPackage) { 6300 // Ignore entries which are not packages 6301 continue; 6302 } 6303 try { 6304 scanPackageTracedLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK, 6305 scanFlags, currentTime, null); 6306 } catch (PackageManagerException e) { 6307 Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage()); 6308 6309 // Delete invalid userdata apps 6310 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 && 6311 e.error == PackageManager.INSTALL_FAILED_INVALID_APK) { 6312 logCriticalInfo(Log.WARN, "Deleting invalid package at " + file); 6313 removeCodePathLI(file); 6314 } 6315 } 6316 } 6317 } 6318 6319 private static File getSettingsProblemFile() { 6320 File dataDir = Environment.getDataDirectory(); 6321 File systemDir = new File(dataDir, "system"); 6322 File fname = new File(systemDir, "uiderrors.txt"); 6323 return fname; 6324 } 6325 6326 static void reportSettingsProblem(int priority, String msg) { 6327 logCriticalInfo(priority, msg); 6328 } 6329 6330 static void logCriticalInfo(int priority, String msg) { 6331 Slog.println(priority, TAG, msg); 6332 EventLogTags.writePmCriticalInfo(msg); 6333 try { 6334 File fname = getSettingsProblemFile(); 6335 FileOutputStream out = new FileOutputStream(fname, true); 6336 PrintWriter pw = new FastPrintWriter(out); 6337 SimpleDateFormat formatter = new SimpleDateFormat(); 6338 String dateString = formatter.format(new Date(System.currentTimeMillis())); 6339 pw.println(dateString + ": " + msg); 6340 pw.close(); 6341 FileUtils.setPermissions( 6342 fname.toString(), 6343 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH, 6344 -1, -1); 6345 } catch (java.io.IOException e) { 6346 } 6347 } 6348 6349 private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile, 6350 int parseFlags) throws PackageManagerException { 6351 if (ps != null 6352 && ps.codePath.equals(srcFile) 6353 && ps.timeStamp == srcFile.lastModified() 6354 && !isCompatSignatureUpdateNeeded(pkg) 6355 && !isRecoverSignatureUpdateNeeded(pkg)) { 6356 long mSigningKeySetId = ps.keySetData.getProperSigningKeySet(); 6357 KeySetManagerService ksms = mSettings.mKeySetManagerService; 6358 ArraySet<PublicKey> signingKs; 6359 synchronized (mPackages) { 6360 signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId); 6361 } 6362 if (ps.signatures.mSignatures != null 6363 && ps.signatures.mSignatures.length != 0 6364 && signingKs != null) { 6365 // Optimization: reuse the existing cached certificates 6366 // if the package appears to be unchanged. 6367 pkg.mSignatures = ps.signatures.mSignatures; 6368 pkg.mSigningKeys = signingKs; 6369 return; 6370 } 6371 6372 Slog.w(TAG, "PackageSetting for " + ps.name 6373 + " is missing signatures. Collecting certs again to recover them."); 6374 } else { 6375 Log.i(TAG, srcFile.toString() + " changed; collecting certs"); 6376 } 6377 6378 try { 6379 PackageParser.collectCertificates(pkg, parseFlags); 6380 } catch (PackageParserException e) { 6381 throw PackageManagerException.from(e); 6382 } 6383 } 6384 6385 /** 6386 * Traces a package scan. 6387 * @see #scanPackageLI(File, int, int, long, UserHandle) 6388 */ 6389 private PackageParser.Package scanPackageTracedLI(File scanFile, int parseFlags, int scanFlags, 6390 long currentTime, UserHandle user) throws PackageManagerException { 6391 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage"); 6392 try { 6393 return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user); 6394 } finally { 6395 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6396 } 6397 } 6398 6399 /** 6400 * Scans a package and returns the newly parsed package. 6401 * Returns {@code null} in case of errors and the error code is stored in mLastScanError 6402 */ 6403 private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags, 6404 long currentTime, UserHandle user) throws PackageManagerException { 6405 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile); 6406 parseFlags |= mDefParseFlags; 6407 PackageParser pp = new PackageParser(); 6408 pp.setSeparateProcesses(mSeparateProcesses); 6409 pp.setOnlyCoreApps(mOnlyCore); 6410 pp.setDisplayMetrics(mMetrics); 6411 6412 if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) { 6413 parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY; 6414 } 6415 6416 final PackageParser.Package pkg; 6417 try { 6418 pkg = pp.parsePackage(scanFile, parseFlags); 6419 } catch (PackageParserException e) { 6420 throw PackageManagerException.from(e); 6421 } 6422 6423 return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user); 6424 } 6425 6426 /** 6427 * Scans a package and returns the newly parsed package. 6428 * @throws PackageManagerException on a parse error. 6429 */ 6430 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile, 6431 int parseFlags, int scanFlags, long currentTime, UserHandle user) 6432 throws PackageManagerException { 6433 // If the package has children and this is the first dive in the function 6434 // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all 6435 // packages (parent and children) would be successfully scanned before the 6436 // actual scan since scanning mutates internal state and we want to atomically 6437 // install the package and its children. 6438 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 6439 if (pkg.childPackages != null && pkg.childPackages.size() > 0) { 6440 scanFlags |= SCAN_CHECK_ONLY; 6441 } 6442 } else { 6443 scanFlags &= ~SCAN_CHECK_ONLY; 6444 } 6445 6446 // Scan the parent 6447 PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, parseFlags, 6448 scanFlags, currentTime, user); 6449 6450 // Scan the children 6451 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 6452 for (int i = 0; i < childCount; i++) { 6453 PackageParser.Package childPackage = pkg.childPackages.get(i); 6454 scanPackageInternalLI(childPackage, scanFile, parseFlags, scanFlags, 6455 currentTime, user); 6456 } 6457 6458 6459 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 6460 return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user); 6461 } 6462 6463 return scannedPkg; 6464 } 6465 6466 /** 6467 * Scans a package and returns the newly parsed package. 6468 * @throws PackageManagerException on a parse error. 6469 */ 6470 private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile, 6471 int parseFlags, int scanFlags, long currentTime, UserHandle user) 6472 throws PackageManagerException { 6473 PackageSetting ps = null; 6474 PackageSetting updatedPkg; 6475 // reader 6476 synchronized (mPackages) { 6477 // Look to see if we already know about this package. 6478 String oldName = mSettings.mRenamedPackages.get(pkg.packageName); 6479 if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) { 6480 // This package has been renamed to its original name. Let's 6481 // use that. 6482 ps = mSettings.peekPackageLPr(oldName); 6483 } 6484 // If there was no original package, see one for the real package name. 6485 if (ps == null) { 6486 ps = mSettings.peekPackageLPr(pkg.packageName); 6487 } 6488 // Check to see if this package could be hiding/updating a system 6489 // package. Must look for it either under the original or real 6490 // package name depending on our state. 6491 updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName); 6492 if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg); 6493 6494 // If this is a package we don't know about on the system partition, we 6495 // may need to remove disabled child packages on the system partition 6496 // or may need to not add child packages if the parent apk is updated 6497 // on the data partition and no longer defines this child package. 6498 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) != 0) { 6499 // If this is a parent package for an updated system app and this system 6500 // app got an OTA update which no longer defines some of the child packages 6501 // we have to prune them from the disabled system packages. 6502 PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName); 6503 if (disabledPs != null) { 6504 final int scannedChildCount = (pkg.childPackages != null) 6505 ? pkg.childPackages.size() : 0; 6506 final int disabledChildCount = disabledPs.childPackageNames != null 6507 ? disabledPs.childPackageNames.size() : 0; 6508 for (int i = 0; i < disabledChildCount; i++) { 6509 String disabledChildPackageName = disabledPs.childPackageNames.get(i); 6510 boolean disabledPackageAvailable = false; 6511 for (int j = 0; j < scannedChildCount; j++) { 6512 PackageParser.Package childPkg = pkg.childPackages.get(j); 6513 if (childPkg.packageName.equals(disabledChildPackageName)) { 6514 disabledPackageAvailable = true; 6515 break; 6516 } 6517 } 6518 if (!disabledPackageAvailable) { 6519 mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName); 6520 } 6521 } 6522 } 6523 } 6524 } 6525 6526 boolean updatedPkgBetter = false; 6527 // First check if this is a system package that may involve an update 6528 if (updatedPkg != null && (parseFlags & PackageParser.PARSE_IS_SYSTEM) != 0) { 6529 // If new package is not located in "/system/priv-app" (e.g. due to an OTA), 6530 // it needs to drop FLAG_PRIVILEGED. 6531 if (locationIsPrivileged(scanFile)) { 6532 updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 6533 } else { 6534 updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 6535 } 6536 6537 if (ps != null && !ps.codePath.equals(scanFile)) { 6538 // The path has changed from what was last scanned... check the 6539 // version of the new path against what we have stored to determine 6540 // what to do. 6541 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath); 6542 if (pkg.mVersionCode <= ps.versionCode) { 6543 // The system package has been updated and the code path does not match 6544 // Ignore entry. Skip it. 6545 if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile 6546 + " ignored: updated version " + ps.versionCode 6547 + " better than this " + pkg.mVersionCode); 6548 if (!updatedPkg.codePath.equals(scanFile)) { 6549 Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg " 6550 + ps.name + " changing from " + updatedPkg.codePathString 6551 + " to " + scanFile); 6552 updatedPkg.codePath = scanFile; 6553 updatedPkg.codePathString = scanFile.toString(); 6554 updatedPkg.resourcePath = scanFile; 6555 updatedPkg.resourcePathString = scanFile.toString(); 6556 } 6557 updatedPkg.pkg = pkg; 6558 updatedPkg.versionCode = pkg.mVersionCode; 6559 6560 // Update the disabled system child packages to point to the package too. 6561 final int childCount = updatedPkg.childPackageNames != null 6562 ? updatedPkg.childPackageNames.size() : 0; 6563 for (int i = 0; i < childCount; i++) { 6564 String childPackageName = updatedPkg.childPackageNames.get(i); 6565 PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr( 6566 childPackageName); 6567 if (updatedChildPkg != null) { 6568 updatedChildPkg.pkg = pkg; 6569 updatedChildPkg.versionCode = pkg.mVersionCode; 6570 } 6571 } 6572 6573 throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at " 6574 + scanFile + " ignored: updated version " + ps.versionCode 6575 + " better than this " + pkg.mVersionCode); 6576 } else { 6577 // The current app on the system partition is better than 6578 // what we have updated to on the data partition; switch 6579 // back to the system partition version. 6580 // At this point, its safely assumed that package installation for 6581 // apps in system partition will go through. If not there won't be a working 6582 // version of the app 6583 // writer 6584 synchronized (mPackages) { 6585 // Just remove the loaded entries from package lists. 6586 mPackages.remove(ps.name); 6587 } 6588 6589 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 6590 + " reverting from " + ps.codePathString 6591 + ": new version " + pkg.mVersionCode 6592 + " better than installed " + ps.versionCode); 6593 6594 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 6595 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 6596 synchronized (mInstallLock) { 6597 args.cleanUpResourcesLI(); 6598 } 6599 synchronized (mPackages) { 6600 mSettings.enableSystemPackageLPw(ps.name); 6601 } 6602 updatedPkgBetter = true; 6603 } 6604 } 6605 } 6606 6607 if (updatedPkg != null) { 6608 // An updated system app will not have the PARSE_IS_SYSTEM flag set 6609 // initially 6610 parseFlags |= PackageParser.PARSE_IS_SYSTEM; 6611 6612 // An updated privileged app will not have the PARSE_IS_PRIVILEGED 6613 // flag set initially 6614 if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) { 6615 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 6616 } 6617 } 6618 6619 // Verify certificates against what was last scanned 6620 collectCertificatesLI(ps, pkg, scanFile, parseFlags); 6621 6622 /* 6623 * A new system app appeared, but we already had a non-system one of the 6624 * same name installed earlier. 6625 */ 6626 boolean shouldHideSystemApp = false; 6627 if (updatedPkg == null && ps != null 6628 && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) { 6629 /* 6630 * Check to make sure the signatures match first. If they don't, 6631 * wipe the installed application and its data. 6632 */ 6633 if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures) 6634 != PackageManager.SIGNATURE_MATCH) { 6635 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but" 6636 + " signatures don't match existing userdata copy; removing"); 6637 deletePackageLI(pkg.packageName, null, true, null, 0, null, false, null); 6638 ps = null; 6639 } else { 6640 /* 6641 * If the newly-added system app is an older version than the 6642 * already installed version, hide it. It will be scanned later 6643 * and re-added like an update. 6644 */ 6645 if (pkg.mVersionCode <= ps.versionCode) { 6646 shouldHideSystemApp = true; 6647 logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile 6648 + " but new version " + pkg.mVersionCode + " better than installed " 6649 + ps.versionCode + "; hiding system"); 6650 } else { 6651 /* 6652 * The newly found system app is a newer version that the 6653 * one previously installed. Simply remove the 6654 * already-installed application and replace it with our own 6655 * while keeping the application data. 6656 */ 6657 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 6658 + " reverting from " + ps.codePathString + ": new version " 6659 + pkg.mVersionCode + " better than installed " + ps.versionCode); 6660 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 6661 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 6662 synchronized (mInstallLock) { 6663 args.cleanUpResourcesLI(); 6664 } 6665 } 6666 } 6667 } 6668 6669 // The apk is forward locked (not public) if its code and resources 6670 // are kept in different files. (except for app in either system or 6671 // vendor path). 6672 // TODO grab this value from PackageSettings 6673 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 6674 if (ps != null && !ps.codePath.equals(ps.resourcePath)) { 6675 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 6676 } 6677 } 6678 6679 // TODO: extend to support forward-locked splits 6680 String resourcePath = null; 6681 String baseResourcePath = null; 6682 if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) { 6683 if (ps != null && ps.resourcePathString != null) { 6684 resourcePath = ps.resourcePathString; 6685 baseResourcePath = ps.resourcePathString; 6686 } else { 6687 // Should not happen at all. Just log an error. 6688 Slog.e(TAG, "Resource path not set for package " + pkg.packageName); 6689 } 6690 } else { 6691 resourcePath = pkg.codePath; 6692 baseResourcePath = pkg.baseCodePath; 6693 } 6694 6695 // Set application objects path explicitly. 6696 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 6697 pkg.setApplicationInfoCodePath(pkg.codePath); 6698 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 6699 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 6700 pkg.setApplicationInfoResourcePath(resourcePath); 6701 pkg.setApplicationInfoBaseResourcePath(baseResourcePath); 6702 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 6703 6704 // Note that we invoke the following method only if we are about to unpack an application 6705 PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags 6706 | SCAN_UPDATE_SIGNATURE, currentTime, user); 6707 6708 /* 6709 * If the system app should be overridden by a previously installed 6710 * data, hide the system app now and let the /data/app scan pick it up 6711 * again. 6712 */ 6713 if (shouldHideSystemApp) { 6714 synchronized (mPackages) { 6715 mSettings.disableSystemPackageLPw(pkg.packageName, true); 6716 } 6717 } 6718 6719 return scannedPkg; 6720 } 6721 6722 private static String fixProcessName(String defProcessName, 6723 String processName, int uid) { 6724 if (processName == null) { 6725 return defProcessName; 6726 } 6727 return processName; 6728 } 6729 6730 private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg) 6731 throws PackageManagerException { 6732 if (pkgSetting.signatures.mSignatures != null) { 6733 // Already existing package. Make sure signatures match 6734 boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures) 6735 == PackageManager.SIGNATURE_MATCH; 6736 if (!match) { 6737 match = compareSignaturesCompat(pkgSetting.signatures, pkg) 6738 == PackageManager.SIGNATURE_MATCH; 6739 } 6740 if (!match) { 6741 match = compareSignaturesRecover(pkgSetting.signatures, pkg) 6742 == PackageManager.SIGNATURE_MATCH; 6743 } 6744 if (!match) { 6745 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 6746 + pkg.packageName + " signatures do not match the " 6747 + "previously installed version; ignoring!"); 6748 } 6749 } 6750 6751 // Check for shared user signatures 6752 if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) { 6753 // Already existing package. Make sure signatures match 6754 boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 6755 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 6756 if (!match) { 6757 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg) 6758 == PackageManager.SIGNATURE_MATCH; 6759 } 6760 if (!match) { 6761 match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg) 6762 == PackageManager.SIGNATURE_MATCH; 6763 } 6764 if (!match) { 6765 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 6766 "Package " + pkg.packageName 6767 + " has no signatures that match those in shared user " 6768 + pkgSetting.sharedUser.name + "; ignoring!"); 6769 } 6770 } 6771 } 6772 6773 /** 6774 * Enforces that only the system UID or root's UID can call a method exposed 6775 * via Binder. 6776 * 6777 * @param message used as message if SecurityException is thrown 6778 * @throws SecurityException if the caller is not system or root 6779 */ 6780 private static final void enforceSystemOrRoot(String message) { 6781 final int uid = Binder.getCallingUid(); 6782 if (uid != Process.SYSTEM_UID && uid != 0) { 6783 throw new SecurityException(message); 6784 } 6785 } 6786 6787 @Override 6788 public void performFstrimIfNeeded() { 6789 enforceSystemOrRoot("Only the system can request fstrim"); 6790 6791 // Before everything else, see whether we need to fstrim. 6792 try { 6793 IMountService ms = PackageHelper.getMountService(); 6794 if (ms != null) { 6795 final boolean isUpgrade = isUpgrade(); 6796 boolean doTrim = isUpgrade; 6797 if (doTrim) { 6798 Slog.w(TAG, "Running disk maintenance immediately due to system update"); 6799 } else { 6800 final long interval = android.provider.Settings.Global.getLong( 6801 mContext.getContentResolver(), 6802 android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL, 6803 DEFAULT_MANDATORY_FSTRIM_INTERVAL); 6804 if (interval > 0) { 6805 final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance(); 6806 if (timeSinceLast > interval) { 6807 doTrim = true; 6808 Slog.w(TAG, "No disk maintenance in " + timeSinceLast 6809 + "; running immediately"); 6810 } 6811 } 6812 } 6813 if (doTrim) { 6814 if (!isFirstBoot()) { 6815 try { 6816 ActivityManagerNative.getDefault().showBootMessage( 6817 mContext.getResources().getString( 6818 R.string.android_upgrading_fstrim), true); 6819 } catch (RemoteException e) { 6820 } 6821 } 6822 ms.runMaintenance(); 6823 } 6824 } else { 6825 Slog.e(TAG, "Mount service unavailable!"); 6826 } 6827 } catch (RemoteException e) { 6828 // Can't happen; MountService is local 6829 } 6830 } 6831 6832 @Override 6833 public void extractPackagesIfNeeded() { 6834 enforceSystemOrRoot("Only the system can request package extraction"); 6835 6836 // Extract pacakges only if profile-guided compilation is enabled because 6837 // otherwise BackgroundDexOptService will not dexopt them later. 6838 if (!mUseJitProfiles || !isUpgrade()) { 6839 return; 6840 } 6841 6842 List<PackageParser.Package> pkgs; 6843 synchronized (mPackages) { 6844 pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this); 6845 } 6846 6847 int curr = 0; 6848 int total = pkgs.size(); 6849 for (PackageParser.Package pkg : pkgs) { 6850 curr++; 6851 6852 if (DEBUG_DEXOPT) { 6853 Log.i(TAG, "Extracting app " + curr + " of " + total + ": " + pkg.packageName); 6854 } 6855 6856 if (!isFirstBoot()) { 6857 try { 6858 ActivityManagerNative.getDefault().showBootMessage( 6859 mContext.getResources().getString(R.string.android_upgrading_apk, 6860 curr, total), true); 6861 } catch (RemoteException e) { 6862 } 6863 } 6864 6865 if (PackageDexOptimizer.canOptimizePackage(pkg)) { 6866 performDexOpt(pkg.packageName, null /* instructionSet */, 6867 false /* useProfiles */, true /* extractOnly */, false /* force */); 6868 } 6869 } 6870 } 6871 6872 @Override 6873 public void notifyPackageUse(String packageName) { 6874 synchronized (mPackages) { 6875 PackageParser.Package p = mPackages.get(packageName); 6876 if (p == null) { 6877 return; 6878 } 6879 p.mLastPackageUsageTimeInMills = System.currentTimeMillis(); 6880 } 6881 } 6882 6883 // TODO: this is not used nor needed. Delete it. 6884 @Override 6885 public boolean performDexOptIfNeeded(String packageName, String instructionSet) { 6886 return performDexOptTraced(packageName, instructionSet, false /* useProfiles */, 6887 false /* extractOnly */, false /* force */); 6888 } 6889 6890 @Override 6891 public boolean performDexOpt(String packageName, String instructionSet, boolean useProfiles, 6892 boolean extractOnly, boolean force) { 6893 return performDexOptTraced(packageName, instructionSet, useProfiles, extractOnly, force); 6894 } 6895 6896 private boolean performDexOptTraced(String packageName, String instructionSet, 6897 boolean useProfiles, boolean extractOnly, boolean force) { 6898 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 6899 try { 6900 return performDexOptInternal(packageName, instructionSet, useProfiles, extractOnly, 6901 force); 6902 } finally { 6903 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6904 } 6905 } 6906 6907 private boolean performDexOptInternal(String packageName, String instructionSet, 6908 boolean useProfiles, boolean extractOnly, boolean force) { 6909 PackageParser.Package p; 6910 final String targetInstructionSet; 6911 synchronized (mPackages) { 6912 p = mPackages.get(packageName); 6913 if (p == null) { 6914 return false; 6915 } 6916 mPackageUsage.write(false); 6917 6918 targetInstructionSet = instructionSet != null ? instructionSet : 6919 getPrimaryInstructionSet(p.applicationInfo); 6920 if (!force && !useProfiles && p.mDexOptPerformed.contains(targetInstructionSet)) { 6921 // Skip only if we do not use profiles since they might trigger a recompilation. 6922 return false; 6923 } 6924 } 6925 long callingId = Binder.clearCallingIdentity(); 6926 try { 6927 synchronized (mInstallLock) { 6928 final String[] instructionSets = new String[] { targetInstructionSet }; 6929 int result = performDexOptInternalWithDependenciesLI(p, instructionSets, 6930 useProfiles, extractOnly, force); 6931 return result == PackageDexOptimizer.DEX_OPT_PERFORMED; 6932 } 6933 } finally { 6934 Binder.restoreCallingIdentity(callingId); 6935 } 6936 } 6937 6938 public ArraySet<String> getOptimizablePackages() { 6939 ArraySet<String> pkgs = new ArraySet<String>(); 6940 synchronized (mPackages) { 6941 for (PackageParser.Package p : mPackages.values()) { 6942 if (PackageDexOptimizer.canOptimizePackage(p)) { 6943 pkgs.add(p.packageName); 6944 } 6945 } 6946 } 6947 return pkgs; 6948 } 6949 6950 private int performDexOptInternalWithDependenciesLI(PackageParser.Package p, 6951 String instructionSets[], boolean useProfiles, boolean extractOnly, boolean force) { 6952 // Select the dex optimizer based on the force parameter. 6953 // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to 6954 // allocate an object here. 6955 PackageDexOptimizer pdo = force 6956 ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer) 6957 : mPackageDexOptimizer; 6958 6959 // Optimize all dependencies first. Note: we ignore the return value and march on 6960 // on errors. 6961 Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p); 6962 if (!deps.isEmpty()) { 6963 for (PackageParser.Package depPackage : deps) { 6964 // TODO: Analyze and investigate if we (should) profile libraries. 6965 // Currently this will do a full compilation of the library. 6966 pdo.performDexOpt(depPackage, instructionSets, false /* useProfiles */, 6967 false /* extractOnly */); 6968 } 6969 } 6970 6971 return pdo.performDexOpt(p, instructionSets, useProfiles, extractOnly); 6972 } 6973 6974 Collection<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) { 6975 if (p.usesLibraries != null || p.usesOptionalLibraries != null) { 6976 ArrayList<PackageParser.Package> retValue = new ArrayList<>(); 6977 Set<String> collectedNames = new HashSet<>(); 6978 findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames); 6979 6980 retValue.remove(p); 6981 6982 return retValue; 6983 } else { 6984 return Collections.emptyList(); 6985 } 6986 } 6987 6988 private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p, 6989 Collection<PackageParser.Package> collected, Set<String> collectedNames) { 6990 if (!collectedNames.contains(p.packageName)) { 6991 collectedNames.add(p.packageName); 6992 collected.add(p); 6993 6994 if (p.usesLibraries != null) { 6995 findSharedNonSystemLibrariesRecursive(p.usesLibraries, collected, collectedNames); 6996 } 6997 if (p.usesOptionalLibraries != null) { 6998 findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries, collected, 6999 collectedNames); 7000 } 7001 } 7002 } 7003 7004 private void findSharedNonSystemLibrariesRecursive(Collection<String> libs, 7005 Collection<PackageParser.Package> collected, Set<String> collectedNames) { 7006 for (String libName : libs) { 7007 PackageParser.Package libPkg = findSharedNonSystemLibrary(libName); 7008 if (libPkg != null) { 7009 findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames); 7010 } 7011 } 7012 } 7013 7014 private PackageParser.Package findSharedNonSystemLibrary(String libName) { 7015 synchronized (mPackages) { 7016 PackageManagerService.SharedLibraryEntry lib = mSharedLibraries.get(libName); 7017 if (lib != null && lib.apk != null) { 7018 return mPackages.get(lib.apk); 7019 } 7020 } 7021 return null; 7022 } 7023 7024 public void shutdown() { 7025 mPackageUsage.write(true); 7026 } 7027 7028 @Override 7029 public void forceDexOpt(String packageName) { 7030 enforceSystemOrRoot("forceDexOpt"); 7031 7032 PackageParser.Package pkg; 7033 synchronized (mPackages) { 7034 pkg = mPackages.get(packageName); 7035 if (pkg == null) { 7036 throw new IllegalArgumentException("Unknown package: " + packageName); 7037 } 7038 } 7039 7040 synchronized (mInstallLock) { 7041 final String[] instructionSets = new String[] { 7042 getPrimaryInstructionSet(pkg.applicationInfo) }; 7043 7044 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 7045 7046 // Whoever is calling forceDexOpt wants a fully compiled package. 7047 // Don't use profiles since that may cause compilation to be skipped. 7048 final int res = performDexOptInternalWithDependenciesLI(pkg, instructionSets, 7049 false /* useProfiles */, false /* extractOnly */, true /* force */); 7050 7051 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7052 if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) { 7053 throw new IllegalStateException("Failed to dexopt: " + res); 7054 } 7055 } 7056 } 7057 7058 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) { 7059 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) { 7060 Slog.w(TAG, "Unable to update from " + oldPkg.name 7061 + " to " + newPkg.packageName 7062 + ": old package not in system partition"); 7063 return false; 7064 } else if (mPackages.get(oldPkg.name) != null) { 7065 Slog.w(TAG, "Unable to update from " + oldPkg.name 7066 + " to " + newPkg.packageName 7067 + ": old package still exists"); 7068 return false; 7069 } 7070 return true; 7071 } 7072 7073 private boolean removeDataDirsLI(String volumeUuid, String packageName) { 7074 // TODO: triage flags as part of 26466827 7075 final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE; 7076 7077 boolean res = true; 7078 final int[] users = sUserManager.getUserIds(); 7079 for (int user : users) { 7080 try { 7081 mInstaller.destroyAppData(volumeUuid, packageName, user, flags); 7082 } catch (InstallerException e) { 7083 Slog.w(TAG, "Failed to delete data directory", e); 7084 res = false; 7085 } 7086 } 7087 return res; 7088 } 7089 7090 void removeCodePathLI(File codePath) { 7091 if (codePath.isDirectory()) { 7092 try { 7093 mInstaller.rmPackageDir(codePath.getAbsolutePath()); 7094 } catch (InstallerException e) { 7095 Slog.w(TAG, "Failed to remove code path", e); 7096 } 7097 } else { 7098 codePath.delete(); 7099 } 7100 } 7101 7102 void destroyAppDataLI(String volumeUuid, String packageName, int userId, int flags) { 7103 try { 7104 mInstaller.destroyAppData(volumeUuid, packageName, userId, flags); 7105 } catch (InstallerException e) { 7106 Slog.w(TAG, "Failed to destroy app data", e); 7107 } 7108 } 7109 7110 void restoreconAppDataLI(String volumeUuid, String packageName, int userId, int flags, 7111 int appId, String seinfo) { 7112 try { 7113 mInstaller.restoreconAppData(volumeUuid, packageName, userId, flags, appId, seinfo); 7114 } catch (InstallerException e) { 7115 Slog.e(TAG, "Failed to restorecon for " + packageName + ": " + e); 7116 } 7117 } 7118 7119 private void deleteCodeCacheDirsLI(String volumeUuid, String packageName) { 7120 final PackageParser.Package pkg; 7121 synchronized (mPackages) { 7122 pkg = mPackages.get(packageName); 7123 } 7124 if (pkg == null) { 7125 Slog.w(TAG, "Failed to delete code cache directory. No package: " + packageName); 7126 return; 7127 } 7128 deleteCodeCacheDirsLI(pkg); 7129 } 7130 7131 private void deleteCodeCacheDirsLI(PackageParser.Package pkg) { 7132 // TODO: triage flags as part of 26466827 7133 final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE; 7134 7135 int[] users = sUserManager.getUserIds(); 7136 int res = 0; 7137 for (int user : users) { 7138 // Remove the parent code cache 7139 try { 7140 mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, user, 7141 flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 7142 } catch (InstallerException e) { 7143 Slog.w(TAG, "Failed to delete code cache directory", e); 7144 } 7145 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7146 for (int i = 0; i < childCount; i++) { 7147 PackageParser.Package childPkg = pkg.childPackages.get(i); 7148 // Remove the child code cache 7149 try { 7150 mInstaller.clearAppData(childPkg.volumeUuid, childPkg.packageName, 7151 user, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 7152 } catch (InstallerException e) { 7153 Slog.w(TAG, "Failed to delete code cache directory", e); 7154 } 7155 } 7156 } 7157 } 7158 7159 private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime, 7160 long lastUpdateTime) { 7161 // Set parent install/update time 7162 PackageSetting ps = (PackageSetting) pkg.mExtras; 7163 if (ps != null) { 7164 ps.firstInstallTime = firstInstallTime; 7165 ps.lastUpdateTime = lastUpdateTime; 7166 } 7167 // Set children install/update time 7168 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7169 for (int i = 0; i < childCount; i++) { 7170 PackageParser.Package childPkg = pkg.childPackages.get(i); 7171 ps = (PackageSetting) childPkg.mExtras; 7172 if (ps != null) { 7173 ps.firstInstallTime = firstInstallTime; 7174 ps.lastUpdateTime = lastUpdateTime; 7175 } 7176 } 7177 } 7178 7179 private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file, 7180 PackageParser.Package changingLib) { 7181 if (file.path != null) { 7182 usesLibraryFiles.add(file.path); 7183 return; 7184 } 7185 PackageParser.Package p = mPackages.get(file.apk); 7186 if (changingLib != null && changingLib.packageName.equals(file.apk)) { 7187 // If we are doing this while in the middle of updating a library apk, 7188 // then we need to make sure to use that new apk for determining the 7189 // dependencies here. (We haven't yet finished committing the new apk 7190 // to the package manager state.) 7191 if (p == null || p.packageName.equals(changingLib.packageName)) { 7192 p = changingLib; 7193 } 7194 } 7195 if (p != null) { 7196 usesLibraryFiles.addAll(p.getAllCodePaths()); 7197 } 7198 } 7199 7200 private void updateSharedLibrariesLPw(PackageParser.Package pkg, 7201 PackageParser.Package changingLib) throws PackageManagerException { 7202 if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) { 7203 final ArraySet<String> usesLibraryFiles = new ArraySet<>(); 7204 int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0; 7205 for (int i=0; i<N; i++) { 7206 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i)); 7207 if (file == null) { 7208 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, 7209 "Package " + pkg.packageName + " requires unavailable shared library " 7210 + pkg.usesLibraries.get(i) + "; failing!"); 7211 } 7212 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 7213 } 7214 N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0; 7215 for (int i=0; i<N; i++) { 7216 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i)); 7217 if (file == null) { 7218 Slog.w(TAG, "Package " + pkg.packageName 7219 + " desires unavailable shared library " 7220 + pkg.usesOptionalLibraries.get(i) + "; ignoring!"); 7221 } else { 7222 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 7223 } 7224 } 7225 N = usesLibraryFiles.size(); 7226 if (N > 0) { 7227 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]); 7228 } else { 7229 pkg.usesLibraryFiles = null; 7230 } 7231 } 7232 } 7233 7234 private static boolean hasString(List<String> list, List<String> which) { 7235 if (list == null) { 7236 return false; 7237 } 7238 for (int i=list.size()-1; i>=0; i--) { 7239 for (int j=which.size()-1; j>=0; j--) { 7240 if (which.get(j).equals(list.get(i))) { 7241 return true; 7242 } 7243 } 7244 } 7245 return false; 7246 } 7247 7248 private void updateAllSharedLibrariesLPw() { 7249 for (PackageParser.Package pkg : mPackages.values()) { 7250 try { 7251 updateSharedLibrariesLPw(pkg, null); 7252 } catch (PackageManagerException e) { 7253 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 7254 } 7255 } 7256 } 7257 7258 private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw( 7259 PackageParser.Package changingPkg) { 7260 ArrayList<PackageParser.Package> res = null; 7261 for (PackageParser.Package pkg : mPackages.values()) { 7262 if (hasString(pkg.usesLibraries, changingPkg.libraryNames) 7263 || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) { 7264 if (res == null) { 7265 res = new ArrayList<PackageParser.Package>(); 7266 } 7267 res.add(pkg); 7268 try { 7269 updateSharedLibrariesLPw(pkg, changingPkg); 7270 } catch (PackageManagerException e) { 7271 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 7272 } 7273 } 7274 } 7275 return res; 7276 } 7277 7278 /** 7279 * Derive the value of the {@code cpuAbiOverride} based on the provided 7280 * value and an optional stored value from the package settings. 7281 */ 7282 private static String deriveAbiOverride(String abiOverride, PackageSetting settings) { 7283 String cpuAbiOverride = null; 7284 7285 if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) { 7286 cpuAbiOverride = null; 7287 } else if (abiOverride != null) { 7288 cpuAbiOverride = abiOverride; 7289 } else if (settings != null) { 7290 cpuAbiOverride = settings.cpuAbiOverrideString; 7291 } 7292 7293 return cpuAbiOverride; 7294 } 7295 7296 private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg, int parseFlags, 7297 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 7298 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage"); 7299 // If the package has children and this is the first dive in the function 7300 // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see 7301 // whether all packages (parent and children) would be successfully scanned 7302 // before the actual scan since scanning mutates internal state and we want 7303 // to atomically install the package and its children. 7304 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 7305 if (pkg.childPackages != null && pkg.childPackages.size() > 0) { 7306 scanFlags |= SCAN_CHECK_ONLY; 7307 } 7308 } else { 7309 scanFlags &= ~SCAN_CHECK_ONLY; 7310 } 7311 7312 final PackageParser.Package scannedPkg; 7313 try { 7314 // Scan the parent 7315 scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags, currentTime, user); 7316 // Scan the children 7317 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7318 for (int i = 0; i < childCount; i++) { 7319 PackageParser.Package childPkg = pkg.childPackages.get(i); 7320 scanPackageLI(childPkg, parseFlags, 7321 scanFlags, currentTime, user); 7322 } 7323 } finally { 7324 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7325 } 7326 7327 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 7328 return scanPackageTracedLI(pkg, parseFlags, scanFlags, currentTime, user); 7329 } 7330 7331 return scannedPkg; 7332 } 7333 7334 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags, 7335 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 7336 boolean success = false; 7337 try { 7338 final PackageParser.Package res = scanPackageDirtyLI(pkg, parseFlags, scanFlags, 7339 currentTime, user); 7340 success = true; 7341 return res; 7342 } finally { 7343 if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) { 7344 removeDataDirsLI(pkg.volumeUuid, pkg.packageName); 7345 } 7346 } 7347 } 7348 7349 private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags, 7350 int scanFlags, long currentTime, UserHandle user) 7351 throws PackageManagerException { 7352 final File scanFile = new File(pkg.codePath); 7353 if (pkg.applicationInfo.getCodePath() == null || 7354 pkg.applicationInfo.getResourcePath() == null) { 7355 // Bail out. The resource and code paths haven't been set. 7356 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 7357 "Code and resource paths haven't been set correctly"); 7358 } 7359 7360 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 7361 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; 7362 } else { 7363 // Only allow system apps to be flagged as core apps. 7364 pkg.coreApp = false; 7365 } 7366 7367 if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) { 7368 pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 7369 } 7370 7371 if (mCustomResolverComponentName != null && 7372 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) { 7373 setUpCustomResolverActivity(pkg); 7374 } 7375 7376 if (pkg.packageName.equals("android")) { 7377 synchronized (mPackages) { 7378 if (mAndroidApplication != null) { 7379 Slog.w(TAG, "*************************************************"); 7380 Slog.w(TAG, "Core android package being redefined. Skipping."); 7381 Slog.w(TAG, " file=" + scanFile); 7382 Slog.w(TAG, "*************************************************"); 7383 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 7384 "Core android package being redefined. Skipping."); 7385 } 7386 7387 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 7388 // Set up information for our fall-back user intent resolution activity. 7389 mPlatformPackage = pkg; 7390 pkg.mVersionCode = mSdkVersion; 7391 mAndroidApplication = pkg.applicationInfo; 7392 7393 if (!mResolverReplaced) { 7394 mResolveActivity.applicationInfo = mAndroidApplication; 7395 mResolveActivity.name = ResolverActivity.class.getName(); 7396 mResolveActivity.packageName = mAndroidApplication.packageName; 7397 mResolveActivity.processName = "system:ui"; 7398 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 7399 mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER; 7400 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS; 7401 mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert; 7402 mResolveActivity.exported = true; 7403 mResolveActivity.enabled = true; 7404 mResolveInfo.activityInfo = mResolveActivity; 7405 mResolveInfo.priority = 0; 7406 mResolveInfo.preferredOrder = 0; 7407 mResolveInfo.match = 0; 7408 mResolveComponentName = new ComponentName( 7409 mAndroidApplication.packageName, mResolveActivity.name); 7410 } 7411 } 7412 } 7413 } 7414 7415 if (DEBUG_PACKAGE_SCANNING) { 7416 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 7417 Log.d(TAG, "Scanning package " + pkg.packageName); 7418 } 7419 7420 synchronized (mPackages) { 7421 if (mPackages.containsKey(pkg.packageName) 7422 || mSharedLibraries.containsKey(pkg.packageName)) { 7423 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 7424 "Application package " + pkg.packageName 7425 + " already installed. Skipping duplicate."); 7426 } 7427 7428 // If we're only installing presumed-existing packages, require that the 7429 // scanned APK is both already known and at the path previously established 7430 // for it. Previously unknown packages we pick up normally, but if we have an 7431 // a priori expectation about this package's install presence, enforce it. 7432 // With a singular exception for new system packages. When an OTA contains 7433 // a new system package, we allow the codepath to change from a system location 7434 // to the user-installed location. If we don't allow this change, any newer, 7435 // user-installed version of the application will be ignored. 7436 if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) { 7437 if (mExpectingBetter.containsKey(pkg.packageName)) { 7438 logCriticalInfo(Log.WARN, 7439 "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName); 7440 } else { 7441 PackageSetting known = mSettings.peekPackageLPr(pkg.packageName); 7442 if (known != null) { 7443 if (DEBUG_PACKAGE_SCANNING) { 7444 Log.d(TAG, "Examining " + pkg.codePath 7445 + " and requiring known paths " + known.codePathString 7446 + " & " + known.resourcePathString); 7447 } 7448 if (!pkg.applicationInfo.getCodePath().equals(known.codePathString) 7449 || !pkg.applicationInfo.getResourcePath().equals( 7450 known.resourcePathString)) { 7451 throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED, 7452 "Application package " + pkg.packageName 7453 + " found at " + pkg.applicationInfo.getCodePath() 7454 + " but expected at " + known.codePathString 7455 + "; ignoring."); 7456 } 7457 } 7458 } 7459 } 7460 } 7461 7462 // Initialize package source and resource directories 7463 File destCodeFile = new File(pkg.applicationInfo.getCodePath()); 7464 File destResourceFile = new File(pkg.applicationInfo.getResourcePath()); 7465 7466 SharedUserSetting suid = null; 7467 PackageSetting pkgSetting = null; 7468 7469 if (!isSystemApp(pkg)) { 7470 // Only system apps can use these features. 7471 pkg.mOriginalPackages = null; 7472 pkg.mRealPackage = null; 7473 pkg.mAdoptPermissions = null; 7474 } 7475 7476 // Getting the package setting may have a side-effect, so if we 7477 // are only checking if scan would succeed, stash a copy of the 7478 // old setting to restore at the end. 7479 PackageSetting nonMutatedPs = null; 7480 7481 // writer 7482 synchronized (mPackages) { 7483 if (pkg.mSharedUserId != null) { 7484 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, true); 7485 if (suid == null) { 7486 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 7487 "Creating application package " + pkg.packageName 7488 + " for shared user failed"); 7489 } 7490 if (DEBUG_PACKAGE_SCANNING) { 7491 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 7492 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId 7493 + "): packages=" + suid.packages); 7494 } 7495 } 7496 7497 // Check if we are renaming from an original package name. 7498 PackageSetting origPackage = null; 7499 String realName = null; 7500 if (pkg.mOriginalPackages != null) { 7501 // This package may need to be renamed to a previously 7502 // installed name. Let's check on that... 7503 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage); 7504 if (pkg.mOriginalPackages.contains(renamed)) { 7505 // This package had originally been installed as the 7506 // original name, and we have already taken care of 7507 // transitioning to the new one. Just update the new 7508 // one to continue using the old name. 7509 realName = pkg.mRealPackage; 7510 if (!pkg.packageName.equals(renamed)) { 7511 // Callers into this function may have already taken 7512 // care of renaming the package; only do it here if 7513 // it is not already done. 7514 pkg.setPackageName(renamed); 7515 } 7516 7517 } else { 7518 for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) { 7519 if ((origPackage = mSettings.peekPackageLPr( 7520 pkg.mOriginalPackages.get(i))) != null) { 7521 // We do have the package already installed under its 7522 // original name... should we use it? 7523 if (!verifyPackageUpdateLPr(origPackage, pkg)) { 7524 // New package is not compatible with original. 7525 origPackage = null; 7526 continue; 7527 } else if (origPackage.sharedUser != null) { 7528 // Make sure uid is compatible between packages. 7529 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) { 7530 Slog.w(TAG, "Unable to migrate data from " + origPackage.name 7531 + " to " + pkg.packageName + ": old uid " 7532 + origPackage.sharedUser.name 7533 + " differs from " + pkg.mSharedUserId); 7534 origPackage = null; 7535 continue; 7536 } 7537 } else { 7538 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package " 7539 + pkg.packageName + " to old name " + origPackage.name); 7540 } 7541 break; 7542 } 7543 } 7544 } 7545 } 7546 7547 if (mTransferedPackages.contains(pkg.packageName)) { 7548 Slog.w(TAG, "Package " + pkg.packageName 7549 + " was transferred to another, but its .apk remains"); 7550 } 7551 7552 // See comments in nonMutatedPs declaration 7553 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 7554 PackageSetting foundPs = mSettings.peekPackageLPr(pkg.packageName); 7555 if (foundPs != null) { 7556 nonMutatedPs = new PackageSetting(foundPs); 7557 } 7558 } 7559 7560 // Just create the setting, don't add it yet. For already existing packages 7561 // the PkgSetting exists already and doesn't have to be created. 7562 pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile, 7563 destResourceFile, pkg.applicationInfo.nativeLibraryRootDir, 7564 pkg.applicationInfo.primaryCpuAbi, 7565 pkg.applicationInfo.secondaryCpuAbi, 7566 pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, 7567 user, false); 7568 if (pkgSetting == null) { 7569 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 7570 "Creating application package " + pkg.packageName + " failed"); 7571 } 7572 7573 if (pkgSetting.origPackage != null) { 7574 // If we are first transitioning from an original package, 7575 // fix up the new package's name now. We need to do this after 7576 // looking up the package under its new name, so getPackageLP 7577 // can take care of fiddling things correctly. 7578 pkg.setPackageName(origPackage.name); 7579 7580 // File a report about this. 7581 String msg = "New package " + pkgSetting.realName 7582 + " renamed to replace old package " + pkgSetting.name; 7583 reportSettingsProblem(Log.WARN, msg); 7584 7585 // Make a note of it. 7586 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 7587 mTransferedPackages.add(origPackage.name); 7588 } 7589 7590 // No longer need to retain this. 7591 pkgSetting.origPackage = null; 7592 } 7593 7594 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) { 7595 // Make a note of it. 7596 mTransferedPackages.add(pkg.packageName); 7597 } 7598 7599 if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) { 7600 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 7601 } 7602 7603 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 7604 // Check all shared libraries and map to their actual file path. 7605 // We only do this here for apps not on a system dir, because those 7606 // are the only ones that can fail an install due to this. We 7607 // will take care of the system apps by updating all of their 7608 // library paths after the scan is done. 7609 updateSharedLibrariesLPw(pkg, null); 7610 } 7611 7612 if (mFoundPolicyFile) { 7613 SELinuxMMAC.assignSeinfoValue(pkg); 7614 } 7615 7616 pkg.applicationInfo.uid = pkgSetting.appId; 7617 pkg.mExtras = pkgSetting; 7618 if (shouldCheckUpgradeKeySetLP(pkgSetting, scanFlags)) { 7619 if (checkUpgradeKeySetLP(pkgSetting, pkg)) { 7620 // We just determined the app is signed correctly, so bring 7621 // over the latest parsed certs. 7622 pkgSetting.signatures.mSignatures = pkg.mSignatures; 7623 } else { 7624 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 7625 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 7626 "Package " + pkg.packageName + " upgrade keys do not match the " 7627 + "previously installed version"); 7628 } else { 7629 pkgSetting.signatures.mSignatures = pkg.mSignatures; 7630 String msg = "System package " + pkg.packageName 7631 + " signature changed; retaining data."; 7632 reportSettingsProblem(Log.WARN, msg); 7633 } 7634 } 7635 } else { 7636 try { 7637 verifySignaturesLP(pkgSetting, pkg); 7638 // We just determined the app is signed correctly, so bring 7639 // over the latest parsed certs. 7640 pkgSetting.signatures.mSignatures = pkg.mSignatures; 7641 } catch (PackageManagerException e) { 7642 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 7643 throw e; 7644 } 7645 // The signature has changed, but this package is in the system 7646 // image... let's recover! 7647 pkgSetting.signatures.mSignatures = pkg.mSignatures; 7648 // However... if this package is part of a shared user, but it 7649 // doesn't match the signature of the shared user, let's fail. 7650 // What this means is that you can't change the signatures 7651 // associated with an overall shared user, which doesn't seem all 7652 // that unreasonable. 7653 if (pkgSetting.sharedUser != null) { 7654 if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 7655 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { 7656 throw new PackageManagerException( 7657 INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES, 7658 "Signature mismatch for shared user: " 7659 + pkgSetting.sharedUser); 7660 } 7661 } 7662 // File a report about this. 7663 String msg = "System package " + pkg.packageName 7664 + " signature changed; retaining data."; 7665 reportSettingsProblem(Log.WARN, msg); 7666 } 7667 } 7668 // Verify that this new package doesn't have any content providers 7669 // that conflict with existing packages. Only do this if the 7670 // package isn't already installed, since we don't want to break 7671 // things that are installed. 7672 if ((scanFlags & SCAN_NEW_INSTALL) != 0) { 7673 final int N = pkg.providers.size(); 7674 int i; 7675 for (i=0; i<N; i++) { 7676 PackageParser.Provider p = pkg.providers.get(i); 7677 if (p.info.authority != null) { 7678 String names[] = p.info.authority.split(";"); 7679 for (int j = 0; j < names.length; j++) { 7680 if (mProvidersByAuthority.containsKey(names[j])) { 7681 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 7682 final String otherPackageName = 7683 ((other != null && other.getComponentName() != null) ? 7684 other.getComponentName().getPackageName() : "?"); 7685 throw new PackageManagerException( 7686 INSTALL_FAILED_CONFLICTING_PROVIDER, 7687 "Can't install because provider name " + names[j] 7688 + " (in package " + pkg.applicationInfo.packageName 7689 + ") is already used by " + otherPackageName); 7690 } 7691 } 7692 } 7693 } 7694 } 7695 7696 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) { 7697 // This package wants to adopt ownership of permissions from 7698 // another package. 7699 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) { 7700 final String origName = pkg.mAdoptPermissions.get(i); 7701 final PackageSetting orig = mSettings.peekPackageLPr(origName); 7702 if (orig != null) { 7703 if (verifyPackageUpdateLPr(orig, pkg)) { 7704 Slog.i(TAG, "Adopting permissions from " + origName + " to " 7705 + pkg.packageName); 7706 mSettings.transferPermissionsLPw(origName, pkg.packageName); 7707 } 7708 } 7709 } 7710 } 7711 } 7712 7713 final String pkgName = pkg.packageName; 7714 7715 final long scanFileTime = scanFile.lastModified(); 7716 final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0; 7717 pkg.applicationInfo.processName = fixProcessName( 7718 pkg.applicationInfo.packageName, 7719 pkg.applicationInfo.processName, 7720 pkg.applicationInfo.uid); 7721 7722 if (pkg != mPlatformPackage) { 7723 // Get all of our default paths setup 7724 pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM); 7725 } 7726 7727 final String path = scanFile.getPath(); 7728 final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting); 7729 7730 if ((scanFlags & SCAN_NEW_INSTALL) == 0) { 7731 derivePackageAbi(pkg, scanFile, cpuAbiOverride, true /* extract libs */); 7732 7733 // Some system apps still use directory structure for native libraries 7734 // in which case we might end up not detecting abi solely based on apk 7735 // structure. Try to detect abi based on directory structure. 7736 if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() && 7737 pkg.applicationInfo.primaryCpuAbi == null) { 7738 setBundledAppAbisAndRoots(pkg, pkgSetting); 7739 setNativeLibraryPaths(pkg); 7740 } 7741 7742 } else { 7743 if ((scanFlags & SCAN_MOVE) != 0) { 7744 // We haven't run dex-opt for this move (since we've moved the compiled output too) 7745 // but we already have this packages package info in the PackageSetting. We just 7746 // use that and derive the native library path based on the new codepath. 7747 pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString; 7748 pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString; 7749 } 7750 7751 // Set native library paths again. For moves, the path will be updated based on the 7752 // ABIs we've determined above. For non-moves, the path will be updated based on the 7753 // ABIs we determined during compilation, but the path will depend on the final 7754 // package path (after the rename away from the stage path). 7755 setNativeLibraryPaths(pkg); 7756 } 7757 7758 // This is a special case for the "system" package, where the ABI is 7759 // dictated by the zygote configuration (and init.rc). We should keep track 7760 // of this ABI so that we can deal with "normal" applications that run under 7761 // the same UID correctly. 7762 if (mPlatformPackage == pkg) { 7763 pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ? 7764 Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]; 7765 } 7766 7767 // If there's a mismatch between the abi-override in the package setting 7768 // and the abiOverride specified for the install. Warn about this because we 7769 // would've already compiled the app without taking the package setting into 7770 // account. 7771 if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) { 7772 if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) { 7773 Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride + 7774 " for package " + pkg.packageName); 7775 } 7776 } 7777 7778 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 7779 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 7780 pkgSetting.cpuAbiOverrideString = cpuAbiOverride; 7781 7782 // Copy the derived override back to the parsed package, so that we can 7783 // update the package settings accordingly. 7784 pkg.cpuAbiOverride = cpuAbiOverride; 7785 7786 if (DEBUG_ABI_SELECTION) { 7787 Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName 7788 + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa=" 7789 + pkg.applicationInfo.nativeLibraryRootRequiresIsa); 7790 } 7791 7792 // Push the derived path down into PackageSettings so we know what to 7793 // clean up at uninstall time. 7794 pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir; 7795 7796 if (DEBUG_ABI_SELECTION) { 7797 Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" + 7798 " primary=" + pkg.applicationInfo.primaryCpuAbi + 7799 " secondary=" + pkg.applicationInfo.secondaryCpuAbi); 7800 } 7801 7802 if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) { 7803 // We don't do this here during boot because we can do it all 7804 // at once after scanning all existing packages. 7805 // 7806 // We also do this *before* we perform dexopt on this package, so that 7807 // we can avoid redundant dexopts, and also to make sure we've got the 7808 // code and package path correct. 7809 adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, 7810 pkg, true /* boot complete */); 7811 } 7812 7813 if (mFactoryTest && pkg.requestedPermissions.contains( 7814 android.Manifest.permission.FACTORY_TEST)) { 7815 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST; 7816 } 7817 7818 ArrayList<PackageParser.Package> clientLibPkgs = null; 7819 7820 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 7821 if (nonMutatedPs != null) { 7822 synchronized (mPackages) { 7823 mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs); 7824 } 7825 } 7826 return pkg; 7827 } 7828 7829 // Only privileged apps and updated privileged apps can add child packages. 7830 if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) { 7831 if ((parseFlags & PARSE_IS_PRIVILEGED) == 0) { 7832 throw new PackageManagerException("Only privileged apps and updated " 7833 + "privileged apps can add child packages. Ignoring package " 7834 + pkg.packageName); 7835 } 7836 final int childCount = pkg.childPackages.size(); 7837 for (int i = 0; i < childCount; i++) { 7838 PackageParser.Package childPkg = pkg.childPackages.get(i); 7839 if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName, 7840 childPkg.packageName)) { 7841 throw new PackageManagerException("Cannot override a child package of " 7842 + "another disabled system app. Ignoring package " + pkg.packageName); 7843 } 7844 } 7845 } 7846 7847 // writer 7848 synchronized (mPackages) { 7849 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7850 // Only system apps can add new shared libraries. 7851 if (pkg.libraryNames != null) { 7852 for (int i=0; i<pkg.libraryNames.size(); i++) { 7853 String name = pkg.libraryNames.get(i); 7854 boolean allowed = false; 7855 if (pkg.isUpdatedSystemApp()) { 7856 // New library entries can only be added through the 7857 // system image. This is important to get rid of a lot 7858 // of nasty edge cases: for example if we allowed a non- 7859 // system update of the app to add a library, then uninstalling 7860 // the update would make the library go away, and assumptions 7861 // we made such as through app install filtering would now 7862 // have allowed apps on the device which aren't compatible 7863 // with it. Better to just have the restriction here, be 7864 // conservative, and create many fewer cases that can negatively 7865 // impact the user experience. 7866 final PackageSetting sysPs = mSettings 7867 .getDisabledSystemPkgLPr(pkg.packageName); 7868 if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) { 7869 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) { 7870 if (name.equals(sysPs.pkg.libraryNames.get(j))) { 7871 allowed = true; 7872 break; 7873 } 7874 } 7875 } 7876 } else { 7877 allowed = true; 7878 } 7879 if (allowed) { 7880 if (!mSharedLibraries.containsKey(name)) { 7881 mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName)); 7882 } else if (!name.equals(pkg.packageName)) { 7883 Slog.w(TAG, "Package " + pkg.packageName + " library " 7884 + name + " already exists; skipping"); 7885 } 7886 } else { 7887 Slog.w(TAG, "Package " + pkg.packageName + " declares lib " 7888 + name + " that is not declared on system image; skipping"); 7889 } 7890 } 7891 if ((scanFlags & SCAN_BOOTING) == 0) { 7892 // If we are not booting, we need to update any applications 7893 // that are clients of our shared library. If we are booting, 7894 // this will all be done once the scan is complete. 7895 clientLibPkgs = updateAllSharedLibrariesLPw(pkg); 7896 } 7897 } 7898 } 7899 } 7900 7901 // Request the ActivityManager to kill the process(only for existing packages) 7902 // so that we do not end up in a confused state while the user is still using the older 7903 // version of the application while the new one gets installed. 7904 final boolean isReplacing = (scanFlags & SCAN_REPLACING) != 0; 7905 final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0; 7906 if (killApp) { 7907 if (isReplacing) { 7908 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "killApplication"); 7909 7910 killApplication(pkg.applicationInfo.packageName, 7911 pkg.applicationInfo.uid, "replace pkg"); 7912 7913 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7914 } 7915 } 7916 7917 // Also need to kill any apps that are dependent on the library. 7918 if (clientLibPkgs != null) { 7919 for (int i=0; i<clientLibPkgs.size(); i++) { 7920 PackageParser.Package clientPkg = clientLibPkgs.get(i); 7921 killApplication(clientPkg.applicationInfo.packageName, 7922 clientPkg.applicationInfo.uid, "update lib"); 7923 } 7924 } 7925 7926 // Make sure we're not adding any bogus keyset info 7927 KeySetManagerService ksms = mSettings.mKeySetManagerService; 7928 ksms.assertScannedPackageValid(pkg); 7929 7930 // writer 7931 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 7932 7933 boolean createIdmapFailed = false; 7934 synchronized (mPackages) { 7935 // We don't expect installation to fail beyond this point 7936 7937 // Add the new setting to mSettings 7938 mSettings.insertPackageSettingLPw(pkgSetting, pkg); 7939 // Add the new setting to mPackages 7940 mPackages.put(pkg.applicationInfo.packageName, pkg); 7941 // Make sure we don't accidentally delete its data. 7942 final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator(); 7943 while (iter.hasNext()) { 7944 PackageCleanItem item = iter.next(); 7945 if (pkgName.equals(item.packageName)) { 7946 iter.remove(); 7947 } 7948 } 7949 7950 // Take care of first install / last update times. 7951 if (currentTime != 0) { 7952 if (pkgSetting.firstInstallTime == 0) { 7953 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime; 7954 } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) { 7955 pkgSetting.lastUpdateTime = currentTime; 7956 } 7957 } else if (pkgSetting.firstInstallTime == 0) { 7958 // We need *something*. Take time time stamp of the file. 7959 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime; 7960 } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) { 7961 if (scanFileTime != pkgSetting.timeStamp) { 7962 // A package on the system image has changed; consider this 7963 // to be an update. 7964 pkgSetting.lastUpdateTime = scanFileTime; 7965 } 7966 } 7967 7968 // Add the package's KeySets to the global KeySetManagerService 7969 ksms.addScannedPackageLPw(pkg); 7970 7971 int N = pkg.providers.size(); 7972 StringBuilder r = null; 7973 int i; 7974 for (i=0; i<N; i++) { 7975 PackageParser.Provider p = pkg.providers.get(i); 7976 p.info.processName = fixProcessName(pkg.applicationInfo.processName, 7977 p.info.processName, pkg.applicationInfo.uid); 7978 mProviders.addProvider(p); 7979 p.syncable = p.info.isSyncable; 7980 if (p.info.authority != null) { 7981 String names[] = p.info.authority.split(";"); 7982 p.info.authority = null; 7983 for (int j = 0; j < names.length; j++) { 7984 if (j == 1 && p.syncable) { 7985 // We only want the first authority for a provider to possibly be 7986 // syncable, so if we already added this provider using a different 7987 // authority clear the syncable flag. We copy the provider before 7988 // changing it because the mProviders object contains a reference 7989 // to a provider that we don't want to change. 7990 // Only do this for the second authority since the resulting provider 7991 // object can be the same for all future authorities for this provider. 7992 p = new PackageParser.Provider(p); 7993 p.syncable = false; 7994 } 7995 if (!mProvidersByAuthority.containsKey(names[j])) { 7996 mProvidersByAuthority.put(names[j], p); 7997 if (p.info.authority == null) { 7998 p.info.authority = names[j]; 7999 } else { 8000 p.info.authority = p.info.authority + ";" + names[j]; 8001 } 8002 if (DEBUG_PACKAGE_SCANNING) { 8003 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 8004 Log.d(TAG, "Registered content provider: " + names[j] 8005 + ", className = " + p.info.name + ", isSyncable = " 8006 + p.info.isSyncable); 8007 } 8008 } else { 8009 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 8010 Slog.w(TAG, "Skipping provider name " + names[j] + 8011 " (in package " + pkg.applicationInfo.packageName + 8012 "): name already used by " 8013 + ((other != null && other.getComponentName() != null) 8014 ? other.getComponentName().getPackageName() : "?")); 8015 } 8016 } 8017 } 8018 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8019 if (r == null) { 8020 r = new StringBuilder(256); 8021 } else { 8022 r.append(' '); 8023 } 8024 r.append(p.info.name); 8025 } 8026 } 8027 if (r != null) { 8028 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r); 8029 } 8030 8031 N = pkg.services.size(); 8032 r = null; 8033 for (i=0; i<N; i++) { 8034 PackageParser.Service s = pkg.services.get(i); 8035 s.info.processName = fixProcessName(pkg.applicationInfo.processName, 8036 s.info.processName, pkg.applicationInfo.uid); 8037 mServices.addService(s); 8038 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8039 if (r == null) { 8040 r = new StringBuilder(256); 8041 } else { 8042 r.append(' '); 8043 } 8044 r.append(s.info.name); 8045 } 8046 } 8047 if (r != null) { 8048 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r); 8049 } 8050 8051 N = pkg.receivers.size(); 8052 r = null; 8053 for (i=0; i<N; i++) { 8054 PackageParser.Activity a = pkg.receivers.get(i); 8055 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 8056 a.info.processName, pkg.applicationInfo.uid); 8057 mReceivers.addActivity(a, "receiver"); 8058 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8059 if (r == null) { 8060 r = new StringBuilder(256); 8061 } else { 8062 r.append(' '); 8063 } 8064 r.append(a.info.name); 8065 } 8066 } 8067 if (r != null) { 8068 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r); 8069 } 8070 8071 N = pkg.activities.size(); 8072 r = null; 8073 for (i=0; i<N; i++) { 8074 PackageParser.Activity a = pkg.activities.get(i); 8075 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 8076 a.info.processName, pkg.applicationInfo.uid); 8077 mActivities.addActivity(a, "activity"); 8078 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8079 if (r == null) { 8080 r = new StringBuilder(256); 8081 } else { 8082 r.append(' '); 8083 } 8084 r.append(a.info.name); 8085 } 8086 } 8087 if (r != null) { 8088 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r); 8089 } 8090 8091 N = pkg.permissionGroups.size(); 8092 r = null; 8093 for (i=0; i<N; i++) { 8094 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i); 8095 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name); 8096 if (cur == null) { 8097 mPermissionGroups.put(pg.info.name, pg); 8098 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8099 if (r == null) { 8100 r = new StringBuilder(256); 8101 } else { 8102 r.append(' '); 8103 } 8104 r.append(pg.info.name); 8105 } 8106 } else { 8107 Slog.w(TAG, "Permission group " + pg.info.name + " from package " 8108 + pg.info.packageName + " ignored: original from " 8109 + cur.info.packageName); 8110 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8111 if (r == null) { 8112 r = new StringBuilder(256); 8113 } else { 8114 r.append(' '); 8115 } 8116 r.append("DUP:"); 8117 r.append(pg.info.name); 8118 } 8119 } 8120 } 8121 if (r != null) { 8122 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permission Groups: " + r); 8123 } 8124 8125 N = pkg.permissions.size(); 8126 r = null; 8127 for (i=0; i<N; i++) { 8128 PackageParser.Permission p = pkg.permissions.get(i); 8129 8130 // Assume by default that we did not install this permission into the system. 8131 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED; 8132 8133 // Now that permission groups have a special meaning, we ignore permission 8134 // groups for legacy apps to prevent unexpected behavior. In particular, 8135 // permissions for one app being granted to someone just becase they happen 8136 // to be in a group defined by another app (before this had no implications). 8137 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) { 8138 p.group = mPermissionGroups.get(p.info.group); 8139 // Warn for a permission in an unknown group. 8140 if (p.info.group != null && p.group == null) { 8141 Slog.w(TAG, "Permission " + p.info.name + " from package " 8142 + p.info.packageName + " in an unknown group " + p.info.group); 8143 } 8144 } 8145 8146 ArrayMap<String, BasePermission> permissionMap = 8147 p.tree ? mSettings.mPermissionTrees 8148 : mSettings.mPermissions; 8149 BasePermission bp = permissionMap.get(p.info.name); 8150 8151 // Allow system apps to redefine non-system permissions 8152 if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) { 8153 final boolean currentOwnerIsSystem = (bp.perm != null 8154 && isSystemApp(bp.perm.owner)); 8155 if (isSystemApp(p.owner)) { 8156 if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) { 8157 // It's a built-in permission and no owner, take ownership now 8158 bp.packageSetting = pkgSetting; 8159 bp.perm = p; 8160 bp.uid = pkg.applicationInfo.uid; 8161 bp.sourcePackage = p.info.packageName; 8162 p.info.flags |= PermissionInfo.FLAG_INSTALLED; 8163 } else if (!currentOwnerIsSystem) { 8164 String msg = "New decl " + p.owner + " of permission " 8165 + p.info.name + " is system; overriding " + bp.sourcePackage; 8166 reportSettingsProblem(Log.WARN, msg); 8167 bp = null; 8168 } 8169 } 8170 } 8171 8172 if (bp == null) { 8173 bp = new BasePermission(p.info.name, p.info.packageName, 8174 BasePermission.TYPE_NORMAL); 8175 permissionMap.put(p.info.name, bp); 8176 } 8177 8178 if (bp.perm == null) { 8179 if (bp.sourcePackage == null 8180 || bp.sourcePackage.equals(p.info.packageName)) { 8181 BasePermission tree = findPermissionTreeLP(p.info.name); 8182 if (tree == null 8183 || tree.sourcePackage.equals(p.info.packageName)) { 8184 bp.packageSetting = pkgSetting; 8185 bp.perm = p; 8186 bp.uid = pkg.applicationInfo.uid; 8187 bp.sourcePackage = p.info.packageName; 8188 p.info.flags |= PermissionInfo.FLAG_INSTALLED; 8189 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8190 if (r == null) { 8191 r = new StringBuilder(256); 8192 } else { 8193 r.append(' '); 8194 } 8195 r.append(p.info.name); 8196 } 8197 } else { 8198 Slog.w(TAG, "Permission " + p.info.name + " from package " 8199 + p.info.packageName + " ignored: base tree " 8200 + tree.name + " is from package " 8201 + tree.sourcePackage); 8202 } 8203 } else { 8204 Slog.w(TAG, "Permission " + p.info.name + " from package " 8205 + p.info.packageName + " ignored: original from " 8206 + bp.sourcePackage); 8207 } 8208 } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8209 if (r == null) { 8210 r = new StringBuilder(256); 8211 } else { 8212 r.append(' '); 8213 } 8214 r.append("DUP:"); 8215 r.append(p.info.name); 8216 } 8217 if (bp.perm == p) { 8218 bp.protectionLevel = p.info.protectionLevel; 8219 } 8220 } 8221 8222 if (r != null) { 8223 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permissions: " + r); 8224 } 8225 8226 N = pkg.instrumentation.size(); 8227 r = null; 8228 for (i=0; i<N; i++) { 8229 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 8230 a.info.packageName = pkg.applicationInfo.packageName; 8231 a.info.sourceDir = pkg.applicationInfo.sourceDir; 8232 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir; 8233 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs; 8234 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs; 8235 a.info.dataDir = pkg.applicationInfo.dataDir; 8236 a.info.deviceEncryptedDataDir = pkg.applicationInfo.deviceEncryptedDataDir; 8237 a.info.credentialEncryptedDataDir = pkg.applicationInfo.credentialEncryptedDataDir; 8238 8239 // TODO: Update instrumentation.nativeLibraryDir as well ? Does it 8240 // need other information about the application, like the ABI and what not ? 8241 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir; 8242 mInstrumentation.put(a.getComponentName(), a); 8243 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8244 if (r == null) { 8245 r = new StringBuilder(256); 8246 } else { 8247 r.append(' '); 8248 } 8249 r.append(a.info.name); 8250 } 8251 } 8252 if (r != null) { 8253 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r); 8254 } 8255 8256 if (pkg.protectedBroadcasts != null) { 8257 N = pkg.protectedBroadcasts.size(); 8258 for (i=0; i<N; i++) { 8259 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i)); 8260 } 8261 } 8262 8263 pkgSetting.setTimeStamp(scanFileTime); 8264 8265 // Create idmap files for pairs of (packages, overlay packages). 8266 // Note: "android", ie framework-res.apk, is handled by native layers. 8267 if (pkg.mOverlayTarget != null) { 8268 // This is an overlay package. 8269 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) { 8270 if (!mOverlays.containsKey(pkg.mOverlayTarget)) { 8271 mOverlays.put(pkg.mOverlayTarget, 8272 new ArrayMap<String, PackageParser.Package>()); 8273 } 8274 ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget); 8275 map.put(pkg.packageName, pkg); 8276 PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget); 8277 if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) { 8278 createIdmapFailed = true; 8279 } 8280 } 8281 } else if (mOverlays.containsKey(pkg.packageName) && 8282 !pkg.packageName.equals("android")) { 8283 // This is a regular package, with one or more known overlay packages. 8284 createIdmapsForPackageLI(pkg); 8285 } 8286 } 8287 8288 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 8289 8290 if (createIdmapFailed) { 8291 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 8292 "scanPackageLI failed to createIdmap"); 8293 } 8294 return pkg; 8295 } 8296 8297 /** 8298 * Derive the ABI of a non-system package located at {@code scanFile}. This information 8299 * is derived purely on the basis of the contents of {@code scanFile} and 8300 * {@code cpuAbiOverride}. 8301 * 8302 * If {@code extractLibs} is true, native libraries are extracted from the app if required. 8303 */ 8304 private void derivePackageAbi(PackageParser.Package pkg, File scanFile, 8305 String cpuAbiOverride, boolean extractLibs) 8306 throws PackageManagerException { 8307 // TODO: We can probably be smarter about this stuff. For installed apps, 8308 // we can calculate this information at install time once and for all. For 8309 // system apps, we can probably assume that this information doesn't change 8310 // after the first boot scan. As things stand, we do lots of unnecessary work. 8311 8312 // Give ourselves some initial paths; we'll come back for another 8313 // pass once we've determined ABI below. 8314 setNativeLibraryPaths(pkg); 8315 8316 // We would never need to extract libs for forward-locked and external packages, 8317 // since the container service will do it for us. We shouldn't attempt to 8318 // extract libs from system app when it was not updated. 8319 if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() || 8320 (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) { 8321 extractLibs = false; 8322 } 8323 8324 final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir; 8325 final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa; 8326 8327 NativeLibraryHelper.Handle handle = null; 8328 try { 8329 handle = NativeLibraryHelper.Handle.create(pkg); 8330 // TODO(multiArch): This can be null for apps that didn't go through the 8331 // usual installation process. We can calculate it again, like we 8332 // do during install time. 8333 // 8334 // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally 8335 // unnecessary. 8336 final File nativeLibraryRoot = new File(nativeLibraryRootStr); 8337 8338 // Null out the abis so that they can be recalculated. 8339 pkg.applicationInfo.primaryCpuAbi = null; 8340 pkg.applicationInfo.secondaryCpuAbi = null; 8341 if (isMultiArch(pkg.applicationInfo)) { 8342 // Warn if we've set an abiOverride for multi-lib packages.. 8343 // By definition, we need to copy both 32 and 64 bit libraries for 8344 // such packages. 8345 if (pkg.cpuAbiOverride != null 8346 && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) { 8347 Slog.w(TAG, "Ignoring abiOverride for multi arch application."); 8348 } 8349 8350 int abi32 = PackageManager.NO_NATIVE_LIBRARIES; 8351 int abi64 = PackageManager.NO_NATIVE_LIBRARIES; 8352 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) { 8353 if (extractLibs) { 8354 abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 8355 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS, 8356 useIsaSpecificSubdirs); 8357 } else { 8358 abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS); 8359 } 8360 } 8361 8362 maybeThrowExceptionForMultiArchCopy( 8363 "Error unpackaging 32 bit native libs for multiarch app.", abi32); 8364 8365 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) { 8366 if (extractLibs) { 8367 abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 8368 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS, 8369 useIsaSpecificSubdirs); 8370 } else { 8371 abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS); 8372 } 8373 } 8374 8375 maybeThrowExceptionForMultiArchCopy( 8376 "Error unpackaging 64 bit native libs for multiarch app.", abi64); 8377 8378 if (abi64 >= 0) { 8379 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64]; 8380 } 8381 8382 if (abi32 >= 0) { 8383 final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32]; 8384 if (abi64 >= 0) { 8385 if (cpuAbiOverride == null && pkg.use32bitAbi) { 8386 pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi; 8387 pkg.applicationInfo.primaryCpuAbi = abi; 8388 } else { 8389 pkg.applicationInfo.secondaryCpuAbi = abi; 8390 } 8391 } else { 8392 pkg.applicationInfo.primaryCpuAbi = abi; 8393 } 8394 } 8395 8396 } else { 8397 String[] abiList = (cpuAbiOverride != null) ? 8398 new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS; 8399 8400 // Enable gross and lame hacks for apps that are built with old 8401 // SDK tools. We must scan their APKs for renderscript bitcode and 8402 // not launch them if it's present. Don't bother checking on devices 8403 // that don't have 64 bit support. 8404 boolean needsRenderScriptOverride = false; 8405 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null && 8406 NativeLibraryHelper.hasRenderscriptBitcode(handle)) { 8407 abiList = Build.SUPPORTED_32_BIT_ABIS; 8408 needsRenderScriptOverride = true; 8409 } 8410 8411 final int copyRet; 8412 if (extractLibs) { 8413 copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 8414 nativeLibraryRoot, abiList, useIsaSpecificSubdirs); 8415 } else { 8416 copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList); 8417 } 8418 8419 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { 8420 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, 8421 "Error unpackaging native libs for app, errorCode=" + copyRet); 8422 } 8423 8424 if (copyRet >= 0) { 8425 pkg.applicationInfo.primaryCpuAbi = abiList[copyRet]; 8426 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) { 8427 pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride; 8428 } else if (needsRenderScriptOverride) { 8429 pkg.applicationInfo.primaryCpuAbi = abiList[0]; 8430 } 8431 } 8432 } catch (IOException ioe) { 8433 Slog.e(TAG, "Unable to get canonical file " + ioe.toString()); 8434 } finally { 8435 IoUtils.closeQuietly(handle); 8436 } 8437 8438 // Now that we've calculated the ABIs and determined if it's an internal app, 8439 // we will go ahead and populate the nativeLibraryPath. 8440 setNativeLibraryPaths(pkg); 8441 } 8442 8443 /** 8444 * Adjusts ABIs for a set of packages belonging to a shared user so that they all match. 8445 * i.e, so that all packages can be run inside a single process if required. 8446 * 8447 * Optionally, callers can pass in a parsed package via {@code newPackage} in which case 8448 * this function will either try and make the ABI for all packages in {@code packagesForUser} 8449 * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match 8450 * the ABI selected for {@code packagesForUser}. This variant is used when installing or 8451 * updating a package that belongs to a shared user. 8452 * 8453 * NOTE: We currently only match for the primary CPU abi string. Matching the secondary 8454 * adds unnecessary complexity. 8455 */ 8456 private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser, 8457 PackageParser.Package scannedPackage, boolean bootComplete) { 8458 String requiredInstructionSet = null; 8459 if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) { 8460 requiredInstructionSet = VMRuntime.getInstructionSet( 8461 scannedPackage.applicationInfo.primaryCpuAbi); 8462 } 8463 8464 PackageSetting requirer = null; 8465 for (PackageSetting ps : packagesForUser) { 8466 // If packagesForUser contains scannedPackage, we skip it. This will happen 8467 // when scannedPackage is an update of an existing package. Without this check, 8468 // we will never be able to change the ABI of any package belonging to a shared 8469 // user, even if it's compatible with other packages. 8470 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 8471 if (ps.primaryCpuAbiString == null) { 8472 continue; 8473 } 8474 8475 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString); 8476 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) { 8477 // We have a mismatch between instruction sets (say arm vs arm64) warn about 8478 // this but there's not much we can do. 8479 String errorMessage = "Instruction set mismatch, " 8480 + ((requirer == null) ? "[caller]" : requirer) 8481 + " requires " + requiredInstructionSet + " whereas " + ps 8482 + " requires " + instructionSet; 8483 Slog.w(TAG, errorMessage); 8484 } 8485 8486 if (requiredInstructionSet == null) { 8487 requiredInstructionSet = instructionSet; 8488 requirer = ps; 8489 } 8490 } 8491 } 8492 8493 if (requiredInstructionSet != null) { 8494 String adjustedAbi; 8495 if (requirer != null) { 8496 // requirer != null implies that either scannedPackage was null or that scannedPackage 8497 // did not require an ABI, in which case we have to adjust scannedPackage to match 8498 // the ABI of the set (which is the same as requirer's ABI) 8499 adjustedAbi = requirer.primaryCpuAbiString; 8500 if (scannedPackage != null) { 8501 scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi; 8502 } 8503 } else { 8504 // requirer == null implies that we're updating all ABIs in the set to 8505 // match scannedPackage. 8506 adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi; 8507 } 8508 8509 for (PackageSetting ps : packagesForUser) { 8510 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 8511 if (ps.primaryCpuAbiString != null) { 8512 continue; 8513 } 8514 8515 ps.primaryCpuAbiString = adjustedAbi; 8516 if (ps.pkg != null && ps.pkg.applicationInfo != null && 8517 !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) { 8518 ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi; 8519 Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi 8520 + " (requirer=" 8521 + (requirer == null ? "null" : requirer.pkg.packageName) 8522 + ", scannedPackage=" 8523 + (scannedPackage != null ? scannedPackage.packageName : "null") 8524 + ")"); 8525 try { 8526 mInstaller.rmdex(ps.codePathString, 8527 getDexCodeInstructionSet(getPreferredInstructionSet())); 8528 } catch (InstallerException ignored) { 8529 } 8530 } 8531 } 8532 } 8533 } 8534 } 8535 8536 private void setUpCustomResolverActivity(PackageParser.Package pkg) { 8537 synchronized (mPackages) { 8538 mResolverReplaced = true; 8539 // Set up information for custom user intent resolution activity. 8540 mResolveActivity.applicationInfo = pkg.applicationInfo; 8541 mResolveActivity.name = mCustomResolverComponentName.getClassName(); 8542 mResolveActivity.packageName = pkg.applicationInfo.packageName; 8543 mResolveActivity.processName = pkg.applicationInfo.packageName; 8544 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 8545 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS | 8546 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 8547 mResolveActivity.theme = 0; 8548 mResolveActivity.exported = true; 8549 mResolveActivity.enabled = true; 8550 mResolveInfo.activityInfo = mResolveActivity; 8551 mResolveInfo.priority = 0; 8552 mResolveInfo.preferredOrder = 0; 8553 mResolveInfo.match = 0; 8554 mResolveComponentName = mCustomResolverComponentName; 8555 Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " + 8556 mResolveComponentName); 8557 } 8558 } 8559 8560 private void setUpEphemeralInstallerActivityLP(ComponentName installerComponent) { 8561 final PackageParser.Package pkg = mPackages.get(installerComponent.getPackageName()); 8562 8563 // Set up information for ephemeral installer activity 8564 mEphemeralInstallerActivity.applicationInfo = pkg.applicationInfo; 8565 mEphemeralInstallerActivity.name = mEphemeralInstallerComponent.getClassName(); 8566 mEphemeralInstallerActivity.packageName = pkg.applicationInfo.packageName; 8567 mEphemeralInstallerActivity.processName = pkg.applicationInfo.packageName; 8568 mEphemeralInstallerActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 8569 mEphemeralInstallerActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS | 8570 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 8571 mEphemeralInstallerActivity.theme = 0; 8572 mEphemeralInstallerActivity.exported = true; 8573 mEphemeralInstallerActivity.enabled = true; 8574 mEphemeralInstallerInfo.activityInfo = mEphemeralInstallerActivity; 8575 mEphemeralInstallerInfo.priority = 0; 8576 mEphemeralInstallerInfo.preferredOrder = 0; 8577 mEphemeralInstallerInfo.match = 0; 8578 8579 if (DEBUG_EPHEMERAL) { 8580 Slog.d(TAG, "Set ephemeral installer activity: " + mEphemeralInstallerComponent); 8581 } 8582 } 8583 8584 private static String calculateBundledApkRoot(final String codePathString) { 8585 final File codePath = new File(codePathString); 8586 final File codeRoot; 8587 if (FileUtils.contains(Environment.getRootDirectory(), codePath)) { 8588 codeRoot = Environment.getRootDirectory(); 8589 } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) { 8590 codeRoot = Environment.getOemDirectory(); 8591 } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) { 8592 codeRoot = Environment.getVendorDirectory(); 8593 } else { 8594 // Unrecognized code path; take its top real segment as the apk root: 8595 // e.g. /something/app/blah.apk => /something 8596 try { 8597 File f = codePath.getCanonicalFile(); 8598 File parent = f.getParentFile(); // non-null because codePath is a file 8599 File tmp; 8600 while ((tmp = parent.getParentFile()) != null) { 8601 f = parent; 8602 parent = tmp; 8603 } 8604 codeRoot = f; 8605 Slog.w(TAG, "Unrecognized code path " 8606 + codePath + " - using " + codeRoot); 8607 } catch (IOException e) { 8608 // Can't canonicalize the code path -- shenanigans? 8609 Slog.w(TAG, "Can't canonicalize code path " + codePath); 8610 return Environment.getRootDirectory().getPath(); 8611 } 8612 } 8613 return codeRoot.getPath(); 8614 } 8615 8616 /** 8617 * Derive and set the location of native libraries for the given package, 8618 * which varies depending on where and how the package was installed. 8619 */ 8620 private void setNativeLibraryPaths(PackageParser.Package pkg) { 8621 final ApplicationInfo info = pkg.applicationInfo; 8622 final String codePath = pkg.codePath; 8623 final File codeFile = new File(codePath); 8624 final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp(); 8625 final boolean asecApp = info.isForwardLocked() || info.isExternalAsec(); 8626 8627 info.nativeLibraryRootDir = null; 8628 info.nativeLibraryRootRequiresIsa = false; 8629 info.nativeLibraryDir = null; 8630 info.secondaryNativeLibraryDir = null; 8631 8632 if (isApkFile(codeFile)) { 8633 // Monolithic install 8634 if (bundledApp) { 8635 // If "/system/lib64/apkname" exists, assume that is the per-package 8636 // native library directory to use; otherwise use "/system/lib/apkname". 8637 final String apkRoot = calculateBundledApkRoot(info.sourceDir); 8638 final boolean is64Bit = VMRuntime.is64BitInstructionSet( 8639 getPrimaryInstructionSet(info)); 8640 8641 // This is a bundled system app so choose the path based on the ABI. 8642 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this 8643 // is just the default path. 8644 final String apkName = deriveCodePathName(codePath); 8645 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME; 8646 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir, 8647 apkName).getAbsolutePath(); 8648 8649 if (info.secondaryCpuAbi != null) { 8650 final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME; 8651 info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot), 8652 secondaryLibDir, apkName).getAbsolutePath(); 8653 } 8654 } else if (asecApp) { 8655 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME) 8656 .getAbsolutePath(); 8657 } else { 8658 final String apkName = deriveCodePathName(codePath); 8659 info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName) 8660 .getAbsolutePath(); 8661 } 8662 8663 info.nativeLibraryRootRequiresIsa = false; 8664 info.nativeLibraryDir = info.nativeLibraryRootDir; 8665 } else { 8666 // Cluster install 8667 info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath(); 8668 info.nativeLibraryRootRequiresIsa = true; 8669 8670 info.nativeLibraryDir = new File(info.nativeLibraryRootDir, 8671 getPrimaryInstructionSet(info)).getAbsolutePath(); 8672 8673 if (info.secondaryCpuAbi != null) { 8674 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir, 8675 VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath(); 8676 } 8677 } 8678 } 8679 8680 /** 8681 * Calculate the abis and roots for a bundled app. These can uniquely 8682 * be determined from the contents of the system partition, i.e whether 8683 * it contains 64 or 32 bit shared libraries etc. We do not validate any 8684 * of this information, and instead assume that the system was built 8685 * sensibly. 8686 */ 8687 private void setBundledAppAbisAndRoots(PackageParser.Package pkg, 8688 PackageSetting pkgSetting) { 8689 final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath()); 8690 8691 // If "/system/lib64/apkname" exists, assume that is the per-package 8692 // native library directory to use; otherwise use "/system/lib/apkname". 8693 final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir); 8694 setBundledAppAbi(pkg, apkRoot, apkName); 8695 // pkgSetting might be null during rescan following uninstall of updates 8696 // to a bundled app, so accommodate that possibility. The settings in 8697 // that case will be established later from the parsed package. 8698 // 8699 // If the settings aren't null, sync them up with what we've just derived. 8700 // note that apkRoot isn't stored in the package settings. 8701 if (pkgSetting != null) { 8702 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 8703 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 8704 } 8705 } 8706 8707 /** 8708 * Deduces the ABI of a bundled app and sets the relevant fields on the 8709 * parsed pkg object. 8710 * 8711 * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem} 8712 * under which system libraries are installed. 8713 * @param apkName the name of the installed package. 8714 */ 8715 private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) { 8716 final File codeFile = new File(pkg.codePath); 8717 8718 final boolean has64BitLibs; 8719 final boolean has32BitLibs; 8720 if (isApkFile(codeFile)) { 8721 // Monolithic install 8722 has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists(); 8723 has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists(); 8724 } else { 8725 // Cluster install 8726 final File rootDir = new File(codeFile, LIB_DIR_NAME); 8727 if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS) 8728 && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) { 8729 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]); 8730 has64BitLibs = (new File(rootDir, isa)).exists(); 8731 } else { 8732 has64BitLibs = false; 8733 } 8734 if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS) 8735 && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) { 8736 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]); 8737 has32BitLibs = (new File(rootDir, isa)).exists(); 8738 } else { 8739 has32BitLibs = false; 8740 } 8741 } 8742 8743 if (has64BitLibs && !has32BitLibs) { 8744 // The package has 64 bit libs, but not 32 bit libs. Its primary 8745 // ABI should be 64 bit. We can safely assume here that the bundled 8746 // native libraries correspond to the most preferred ABI in the list. 8747 8748 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 8749 pkg.applicationInfo.secondaryCpuAbi = null; 8750 } else if (has32BitLibs && !has64BitLibs) { 8751 // The package has 32 bit libs but not 64 bit libs. Its primary 8752 // ABI should be 32 bit. 8753 8754 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 8755 pkg.applicationInfo.secondaryCpuAbi = null; 8756 } else if (has32BitLibs && has64BitLibs) { 8757 // The application has both 64 and 32 bit bundled libraries. We check 8758 // here that the app declares multiArch support, and warn if it doesn't. 8759 // 8760 // We will be lenient here and record both ABIs. The primary will be the 8761 // ABI that's higher on the list, i.e, a device that's configured to prefer 8762 // 64 bit apps will see a 64 bit primary ABI, 8763 8764 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) { 8765 Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch."); 8766 } 8767 8768 if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) { 8769 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 8770 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 8771 } else { 8772 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 8773 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 8774 } 8775 } else { 8776 pkg.applicationInfo.primaryCpuAbi = null; 8777 pkg.applicationInfo.secondaryCpuAbi = null; 8778 } 8779 } 8780 8781 private void killPackage(PackageParser.Package pkg, String reason) { 8782 // Kill the parent package 8783 killApplication(pkg.packageName, pkg.applicationInfo.uid, reason); 8784 // Kill the child packages 8785 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8786 for (int i = 0; i < childCount; i++) { 8787 PackageParser.Package childPkg = pkg.childPackages.get(i); 8788 killApplication(childPkg.packageName, childPkg.applicationInfo.uid, reason); 8789 } 8790 } 8791 8792 private void killApplication(String pkgName, int appId, String reason) { 8793 // Request the ActivityManager to kill the process(only for existing packages) 8794 // so that we do not end up in a confused state while the user is still using the older 8795 // version of the application while the new one gets installed. 8796 IActivityManager am = ActivityManagerNative.getDefault(); 8797 if (am != null) { 8798 try { 8799 am.killApplicationWithAppId(pkgName, appId, reason); 8800 } catch (RemoteException e) { 8801 } 8802 } 8803 } 8804 8805 private void removePackageLI(PackageParser.Package pkg, boolean chatty) { 8806 // Remove the parent package setting 8807 PackageSetting ps = (PackageSetting) pkg.mExtras; 8808 if (ps != null) { 8809 removePackageLI(ps, chatty); 8810 } 8811 // Remove the child package setting 8812 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8813 for (int i = 0; i < childCount; i++) { 8814 PackageParser.Package childPkg = pkg.childPackages.get(i); 8815 ps = (PackageSetting) childPkg.mExtras; 8816 if (ps != null) { 8817 removePackageLI(ps, chatty); 8818 } 8819 } 8820 } 8821 8822 void removePackageLI(PackageSetting ps, boolean chatty) { 8823 if (DEBUG_INSTALL) { 8824 if (chatty) 8825 Log.d(TAG, "Removing package " + ps.name); 8826 } 8827 8828 // writer 8829 synchronized (mPackages) { 8830 mPackages.remove(ps.name); 8831 final PackageParser.Package pkg = ps.pkg; 8832 if (pkg != null) { 8833 cleanPackageDataStructuresLILPw(pkg, chatty); 8834 } 8835 } 8836 } 8837 8838 void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) { 8839 if (DEBUG_INSTALL) { 8840 if (chatty) 8841 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName); 8842 } 8843 8844 // writer 8845 synchronized (mPackages) { 8846 // Remove the parent package 8847 mPackages.remove(pkg.applicationInfo.packageName); 8848 cleanPackageDataStructuresLILPw(pkg, chatty); 8849 8850 // Remove the child packages 8851 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8852 for (int i = 0; i < childCount; i++) { 8853 PackageParser.Package childPkg = pkg.childPackages.get(i); 8854 mPackages.remove(childPkg.applicationInfo.packageName); 8855 cleanPackageDataStructuresLILPw(childPkg, chatty); 8856 } 8857 } 8858 } 8859 8860 void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) { 8861 int N = pkg.providers.size(); 8862 StringBuilder r = null; 8863 int i; 8864 for (i=0; i<N; i++) { 8865 PackageParser.Provider p = pkg.providers.get(i); 8866 mProviders.removeProvider(p); 8867 if (p.info.authority == null) { 8868 8869 /* There was another ContentProvider with this authority when 8870 * this app was installed so this authority is null, 8871 * Ignore it as we don't have to unregister the provider. 8872 */ 8873 continue; 8874 } 8875 String names[] = p.info.authority.split(";"); 8876 for (int j = 0; j < names.length; j++) { 8877 if (mProvidersByAuthority.get(names[j]) == p) { 8878 mProvidersByAuthority.remove(names[j]); 8879 if (DEBUG_REMOVE) { 8880 if (chatty) 8881 Log.d(TAG, "Unregistered content provider: " + names[j] 8882 + ", className = " + p.info.name + ", isSyncable = " 8883 + p.info.isSyncable); 8884 } 8885 } 8886 } 8887 if (DEBUG_REMOVE && chatty) { 8888 if (r == null) { 8889 r = new StringBuilder(256); 8890 } else { 8891 r.append(' '); 8892 } 8893 r.append(p.info.name); 8894 } 8895 } 8896 if (r != null) { 8897 if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r); 8898 } 8899 8900 N = pkg.services.size(); 8901 r = null; 8902 for (i=0; i<N; i++) { 8903 PackageParser.Service s = pkg.services.get(i); 8904 mServices.removeService(s); 8905 if (chatty) { 8906 if (r == null) { 8907 r = new StringBuilder(256); 8908 } else { 8909 r.append(' '); 8910 } 8911 r.append(s.info.name); 8912 } 8913 } 8914 if (r != null) { 8915 if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r); 8916 } 8917 8918 N = pkg.receivers.size(); 8919 r = null; 8920 for (i=0; i<N; i++) { 8921 PackageParser.Activity a = pkg.receivers.get(i); 8922 mReceivers.removeActivity(a, "receiver"); 8923 if (DEBUG_REMOVE && chatty) { 8924 if (r == null) { 8925 r = new StringBuilder(256); 8926 } else { 8927 r.append(' '); 8928 } 8929 r.append(a.info.name); 8930 } 8931 } 8932 if (r != null) { 8933 if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r); 8934 } 8935 8936 N = pkg.activities.size(); 8937 r = null; 8938 for (i=0; i<N; i++) { 8939 PackageParser.Activity a = pkg.activities.get(i); 8940 mActivities.removeActivity(a, "activity"); 8941 if (DEBUG_REMOVE && chatty) { 8942 if (r == null) { 8943 r = new StringBuilder(256); 8944 } else { 8945 r.append(' '); 8946 } 8947 r.append(a.info.name); 8948 } 8949 } 8950 if (r != null) { 8951 if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r); 8952 } 8953 8954 N = pkg.permissions.size(); 8955 r = null; 8956 for (i=0; i<N; i++) { 8957 PackageParser.Permission p = pkg.permissions.get(i); 8958 BasePermission bp = mSettings.mPermissions.get(p.info.name); 8959 if (bp == null) { 8960 bp = mSettings.mPermissionTrees.get(p.info.name); 8961 } 8962 if (bp != null && bp.perm == p) { 8963 bp.perm = null; 8964 if (DEBUG_REMOVE && chatty) { 8965 if (r == null) { 8966 r = new StringBuilder(256); 8967 } else { 8968 r.append(' '); 8969 } 8970 r.append(p.info.name); 8971 } 8972 } 8973 if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 8974 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name); 8975 if (appOpPkgs != null) { 8976 appOpPkgs.remove(pkg.packageName); 8977 } 8978 } 8979 } 8980 if (r != null) { 8981 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 8982 } 8983 8984 N = pkg.requestedPermissions.size(); 8985 r = null; 8986 for (i=0; i<N; i++) { 8987 String perm = pkg.requestedPermissions.get(i); 8988 BasePermission bp = mSettings.mPermissions.get(perm); 8989 if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 8990 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm); 8991 if (appOpPkgs != null) { 8992 appOpPkgs.remove(pkg.packageName); 8993 if (appOpPkgs.isEmpty()) { 8994 mAppOpPermissionPackages.remove(perm); 8995 } 8996 } 8997 } 8998 } 8999 if (r != null) { 9000 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 9001 } 9002 9003 N = pkg.instrumentation.size(); 9004 r = null; 9005 for (i=0; i<N; i++) { 9006 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 9007 mInstrumentation.remove(a.getComponentName()); 9008 if (DEBUG_REMOVE && chatty) { 9009 if (r == null) { 9010 r = new StringBuilder(256); 9011 } else { 9012 r.append(' '); 9013 } 9014 r.append(a.info.name); 9015 } 9016 } 9017 if (r != null) { 9018 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r); 9019 } 9020 9021 r = null; 9022 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9023 // Only system apps can hold shared libraries. 9024 if (pkg.libraryNames != null) { 9025 for (i=0; i<pkg.libraryNames.size(); i++) { 9026 String name = pkg.libraryNames.get(i); 9027 SharedLibraryEntry cur = mSharedLibraries.get(name); 9028 if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) { 9029 mSharedLibraries.remove(name); 9030 if (DEBUG_REMOVE && chatty) { 9031 if (r == null) { 9032 r = new StringBuilder(256); 9033 } else { 9034 r.append(' '); 9035 } 9036 r.append(name); 9037 } 9038 } 9039 } 9040 } 9041 } 9042 if (r != null) { 9043 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r); 9044 } 9045 } 9046 9047 private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) { 9048 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) { 9049 if (pkgInfo.permissions.get(i).info.name.equals(perm)) { 9050 return true; 9051 } 9052 } 9053 return false; 9054 } 9055 9056 static final int UPDATE_PERMISSIONS_ALL = 1<<0; 9057 static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1; 9058 static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2; 9059 9060 private void updatePermissionsLPw(PackageParser.Package pkg, int flags) { 9061 // Update the parent permissions 9062 updatePermissionsLPw(pkg.packageName, pkg, flags); 9063 // Update the child permissions 9064 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 9065 for (int i = 0; i < childCount; i++) { 9066 PackageParser.Package childPkg = pkg.childPackages.get(i); 9067 updatePermissionsLPw(childPkg.packageName, childPkg, flags); 9068 } 9069 } 9070 9071 private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo, 9072 int flags) { 9073 final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null; 9074 updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags); 9075 } 9076 9077 private void updatePermissionsLPw(String changingPkg, 9078 PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) { 9079 // Make sure there are no dangling permission trees. 9080 Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator(); 9081 while (it.hasNext()) { 9082 final BasePermission bp = it.next(); 9083 if (bp.packageSetting == null) { 9084 // We may not yet have parsed the package, so just see if 9085 // we still know about its settings. 9086 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 9087 } 9088 if (bp.packageSetting == null) { 9089 Slog.w(TAG, "Removing dangling permission tree: " + bp.name 9090 + " from package " + bp.sourcePackage); 9091 it.remove(); 9092 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 9093 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 9094 Slog.i(TAG, "Removing old permission tree: " + bp.name 9095 + " from package " + bp.sourcePackage); 9096 flags |= UPDATE_PERMISSIONS_ALL; 9097 it.remove(); 9098 } 9099 } 9100 } 9101 9102 // Make sure all dynamic permissions have been assigned to a package, 9103 // and make sure there are no dangling permissions. 9104 it = mSettings.mPermissions.values().iterator(); 9105 while (it.hasNext()) { 9106 final BasePermission bp = it.next(); 9107 if (bp.type == BasePermission.TYPE_DYNAMIC) { 9108 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name=" 9109 + bp.name + " pkg=" + bp.sourcePackage 9110 + " info=" + bp.pendingInfo); 9111 if (bp.packageSetting == null && bp.pendingInfo != null) { 9112 final BasePermission tree = findPermissionTreeLP(bp.name); 9113 if (tree != null && tree.perm != null) { 9114 bp.packageSetting = tree.packageSetting; 9115 bp.perm = new PackageParser.Permission(tree.perm.owner, 9116 new PermissionInfo(bp.pendingInfo)); 9117 bp.perm.info.packageName = tree.perm.info.packageName; 9118 bp.perm.info.name = bp.name; 9119 bp.uid = tree.uid; 9120 } 9121 } 9122 } 9123 if (bp.packageSetting == null) { 9124 // We may not yet have parsed the package, so just see if 9125 // we still know about its settings. 9126 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 9127 } 9128 if (bp.packageSetting == null) { 9129 Slog.w(TAG, "Removing dangling permission: " + bp.name 9130 + " from package " + bp.sourcePackage); 9131 it.remove(); 9132 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 9133 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 9134 Slog.i(TAG, "Removing old permission: " + bp.name 9135 + " from package " + bp.sourcePackage); 9136 flags |= UPDATE_PERMISSIONS_ALL; 9137 it.remove(); 9138 } 9139 } 9140 } 9141 9142 // Now update the permissions for all packages, in particular 9143 // replace the granted permissions of the system packages. 9144 if ((flags&UPDATE_PERMISSIONS_ALL) != 0) { 9145 for (PackageParser.Package pkg : mPackages.values()) { 9146 if (pkg != pkgInfo) { 9147 // Only replace for packages on requested volume 9148 final String volumeUuid = getVolumeUuidForPackage(pkg); 9149 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0) 9150 && Objects.equals(replaceVolumeUuid, volumeUuid); 9151 grantPermissionsLPw(pkg, replace, changingPkg); 9152 } 9153 } 9154 } 9155 9156 if (pkgInfo != null) { 9157 // Only replace for packages on requested volume 9158 final String volumeUuid = getVolumeUuidForPackage(pkgInfo); 9159 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0) 9160 && Objects.equals(replaceVolumeUuid, volumeUuid); 9161 grantPermissionsLPw(pkgInfo, replace, changingPkg); 9162 } 9163 } 9164 9165 private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace, 9166 String packageOfInterest) { 9167 // IMPORTANT: There are two types of permissions: install and runtime. 9168 // Install time permissions are granted when the app is installed to 9169 // all device users and users added in the future. Runtime permissions 9170 // are granted at runtime explicitly to specific users. Normal and signature 9171 // protected permissions are install time permissions. Dangerous permissions 9172 // are install permissions if the app's target SDK is Lollipop MR1 or older, 9173 // otherwise they are runtime permissions. This function does not manage 9174 // runtime permissions except for the case an app targeting Lollipop MR1 9175 // being upgraded to target a newer SDK, in which case dangerous permissions 9176 // are transformed from install time to runtime ones. 9177 9178 final PackageSetting ps = (PackageSetting) pkg.mExtras; 9179 if (ps == null) { 9180 return; 9181 } 9182 9183 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions"); 9184 9185 PermissionsState permissionsState = ps.getPermissionsState(); 9186 PermissionsState origPermissions = permissionsState; 9187 9188 final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); 9189 9190 boolean runtimePermissionsRevoked = false; 9191 int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY; 9192 9193 boolean changedInstallPermission = false; 9194 9195 if (replace) { 9196 ps.installPermissionsFixed = false; 9197 if (!ps.isSharedUser()) { 9198 origPermissions = new PermissionsState(permissionsState); 9199 permissionsState.reset(); 9200 } else { 9201 // We need to know only about runtime permission changes since the 9202 // calling code always writes the install permissions state but 9203 // the runtime ones are written only if changed. The only cases of 9204 // changed runtime permissions here are promotion of an install to 9205 // runtime and revocation of a runtime from a shared user. 9206 changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw( 9207 ps.sharedUser, UserManagerService.getInstance().getUserIds()); 9208 if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) { 9209 runtimePermissionsRevoked = true; 9210 } 9211 } 9212 } 9213 9214 permissionsState.setGlobalGids(mGlobalGids); 9215 9216 final int N = pkg.requestedPermissions.size(); 9217 for (int i=0; i<N; i++) { 9218 final String name = pkg.requestedPermissions.get(i); 9219 final BasePermission bp = mSettings.mPermissions.get(name); 9220 9221 if (DEBUG_INSTALL) { 9222 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp); 9223 } 9224 9225 if (bp == null || bp.packageSetting == null) { 9226 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 9227 Slog.w(TAG, "Unknown permission " + name 9228 + " in package " + pkg.packageName); 9229 } 9230 continue; 9231 } 9232 9233 final String perm = bp.name; 9234 boolean allowedSig = false; 9235 int grant = GRANT_DENIED; 9236 9237 // Keep track of app op permissions. 9238 if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 9239 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name); 9240 if (pkgs == null) { 9241 pkgs = new ArraySet<>(); 9242 mAppOpPermissionPackages.put(bp.name, pkgs); 9243 } 9244 pkgs.add(pkg.packageName); 9245 } 9246 9247 final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; 9248 final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion 9249 >= Build.VERSION_CODES.M; 9250 switch (level) { 9251 case PermissionInfo.PROTECTION_NORMAL: { 9252 // For all apps normal permissions are install time ones. 9253 grant = GRANT_INSTALL; 9254 } break; 9255 9256 case PermissionInfo.PROTECTION_DANGEROUS: { 9257 // If a permission review is required for legacy apps we represent 9258 // their permissions as always granted runtime ones since we need 9259 // to keep the review required permission flag per user while an 9260 // install permission's state is shared across all users. 9261 if (!appSupportsRuntimePermissions && !Build.PERMISSIONS_REVIEW_REQUIRED) { 9262 // For legacy apps dangerous permissions are install time ones. 9263 grant = GRANT_INSTALL; 9264 } else if (origPermissions.hasInstallPermission(bp.name)) { 9265 // For legacy apps that became modern, install becomes runtime. 9266 grant = GRANT_UPGRADE; 9267 } else if (mPromoteSystemApps 9268 && isSystemApp(ps) 9269 && mExistingSystemPackages.contains(ps.name)) { 9270 // For legacy system apps, install becomes runtime. 9271 // We cannot check hasInstallPermission() for system apps since those 9272 // permissions were granted implicitly and not persisted pre-M. 9273 grant = GRANT_UPGRADE; 9274 } else { 9275 // For modern apps keep runtime permissions unchanged. 9276 grant = GRANT_RUNTIME; 9277 } 9278 } break; 9279 9280 case PermissionInfo.PROTECTION_SIGNATURE: { 9281 // For all apps signature permissions are install time ones. 9282 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions); 9283 if (allowedSig) { 9284 grant = GRANT_INSTALL; 9285 } 9286 } break; 9287 } 9288 9289 if (DEBUG_INSTALL) { 9290 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm); 9291 } 9292 9293 if (grant != GRANT_DENIED) { 9294 if (!isSystemApp(ps) && ps.installPermissionsFixed) { 9295 // If this is an existing, non-system package, then 9296 // we can't add any new permissions to it. 9297 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) { 9298 // Except... if this is a permission that was added 9299 // to the platform (note: need to only do this when 9300 // updating the platform). 9301 if (!isNewPlatformPermissionForPackage(perm, pkg)) { 9302 grant = GRANT_DENIED; 9303 } 9304 } 9305 } 9306 9307 switch (grant) { 9308 case GRANT_INSTALL: { 9309 // Revoke this as runtime permission to handle the case of 9310 // a runtime permission being downgraded to an install one. Also in permission review mode we keep dangerous permissions for legacy apps 9311 for (int userId : UserManagerService.getInstance().getUserIds()) { 9312 if (origPermissions.getRuntimePermissionState( 9313 bp.name, userId) != null) { 9314 // Revoke the runtime permission and clear the flags. 9315 origPermissions.revokeRuntimePermission(bp, userId); 9316 origPermissions.updatePermissionFlags(bp, userId, 9317 PackageManager.MASK_PERMISSION_FLAGS, 0); 9318 // If we revoked a permission permission, we have to write. 9319 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 9320 changedRuntimePermissionUserIds, userId); 9321 } 9322 } 9323 // Grant an install permission. 9324 if (permissionsState.grantInstallPermission(bp) != 9325 PermissionsState.PERMISSION_OPERATION_FAILURE) { 9326 changedInstallPermission = true; 9327 } 9328 } break; 9329 9330 case GRANT_RUNTIME: { 9331 // Grant previously granted runtime permissions. 9332 for (int userId : UserManagerService.getInstance().getUserIds()) { 9333 PermissionState permissionState = origPermissions 9334 .getRuntimePermissionState(bp.name, userId); 9335 int flags = permissionState != null 9336 ? permissionState.getFlags() : 0; 9337 if (origPermissions.hasRuntimePermission(bp.name, userId)) { 9338 if (permissionsState.grantRuntimePermission(bp, userId) == 9339 PermissionsState.PERMISSION_OPERATION_FAILURE) { 9340 // If we cannot put the permission as it was, we have to write. 9341 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 9342 changedRuntimePermissionUserIds, userId); 9343 } 9344 // If the app supports runtime permissions no need for a review. 9345 if (Build.PERMISSIONS_REVIEW_REQUIRED 9346 && appSupportsRuntimePermissions 9347 && (flags & PackageManager 9348 .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) { 9349 flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 9350 // Since we changed the flags, we have to write. 9351 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 9352 changedRuntimePermissionUserIds, userId); 9353 } 9354 } else if (Build.PERMISSIONS_REVIEW_REQUIRED 9355 && !appSupportsRuntimePermissions) { 9356 // For legacy apps that need a permission review, every new 9357 // runtime permission is granted but it is pending a review. 9358 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) { 9359 permissionsState.grantRuntimePermission(bp, userId); 9360 flags |= FLAG_PERMISSION_REVIEW_REQUIRED; 9361 // We changed the permission and flags, hence have to write. 9362 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 9363 changedRuntimePermissionUserIds, userId); 9364 } 9365 } 9366 // Propagate the permission flags. 9367 permissionsState.updatePermissionFlags(bp, userId, flags, flags); 9368 } 9369 } break; 9370 9371 case GRANT_UPGRADE: { 9372 // Grant runtime permissions for a previously held install permission. 9373 PermissionState permissionState = origPermissions 9374 .getInstallPermissionState(bp.name); 9375 final int flags = permissionState != null ? permissionState.getFlags() : 0; 9376 9377 if (origPermissions.revokeInstallPermission(bp) 9378 != PermissionsState.PERMISSION_OPERATION_FAILURE) { 9379 // We will be transferring the permission flags, so clear them. 9380 origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL, 9381 PackageManager.MASK_PERMISSION_FLAGS, 0); 9382 changedInstallPermission = true; 9383 } 9384 9385 // If the permission is not to be promoted to runtime we ignore it and 9386 // also its other flags as they are not applicable to install permissions. 9387 if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) { 9388 for (int userId : currentUserIds) { 9389 if (permissionsState.grantRuntimePermission(bp, userId) != 9390 PermissionsState.PERMISSION_OPERATION_FAILURE) { 9391 // Transfer the permission flags. 9392 permissionsState.updatePermissionFlags(bp, userId, 9393 flags, flags); 9394 // If we granted the permission, we have to write. 9395 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 9396 changedRuntimePermissionUserIds, userId); 9397 } 9398 } 9399 } 9400 } break; 9401 9402 default: { 9403 if (packageOfInterest == null 9404 || packageOfInterest.equals(pkg.packageName)) { 9405 Slog.w(TAG, "Not granting permission " + perm 9406 + " to package " + pkg.packageName 9407 + " because it was previously installed without"); 9408 } 9409 } break; 9410 } 9411 } else { 9412 if (permissionsState.revokeInstallPermission(bp) != 9413 PermissionsState.PERMISSION_OPERATION_FAILURE) { 9414 // Also drop the permission flags. 9415 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 9416 PackageManager.MASK_PERMISSION_FLAGS, 0); 9417 changedInstallPermission = true; 9418 Slog.i(TAG, "Un-granting permission " + perm 9419 + " from package " + pkg.packageName 9420 + " (protectionLevel=" + bp.protectionLevel 9421 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 9422 + ")"); 9423 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) { 9424 // Don't print warning for app op permissions, since it is fine for them 9425 // not to be granted, there is a UI for the user to decide. 9426 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 9427 Slog.w(TAG, "Not granting permission " + perm 9428 + " to package " + pkg.packageName 9429 + " (protectionLevel=" + bp.protectionLevel 9430 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 9431 + ")"); 9432 } 9433 } 9434 } 9435 } 9436 9437 if ((changedInstallPermission || replace) && !ps.installPermissionsFixed && 9438 !isSystemApp(ps) || isUpdatedSystemApp(ps)){ 9439 // This is the first that we have heard about this package, so the 9440 // permissions we have now selected are fixed until explicitly 9441 // changed. 9442 ps.installPermissionsFixed = true; 9443 } 9444 9445 // Persist the runtime permissions state for users with changes. If permissions 9446 // were revoked because no app in the shared user declares them we have to 9447 // write synchronously to avoid losing runtime permissions state. 9448 for (int userId : changedRuntimePermissionUserIds) { 9449 mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked); 9450 } 9451 9452 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 9453 } 9454 9455 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) { 9456 boolean allowed = false; 9457 final int NP = PackageParser.NEW_PERMISSIONS.length; 9458 for (int ip=0; ip<NP; ip++) { 9459 final PackageParser.NewPermissionInfo npi 9460 = PackageParser.NEW_PERMISSIONS[ip]; 9461 if (npi.name.equals(perm) 9462 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) { 9463 allowed = true; 9464 Log.i(TAG, "Auto-granting " + perm + " to old pkg " 9465 + pkg.packageName); 9466 break; 9467 } 9468 } 9469 return allowed; 9470 } 9471 9472 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg, 9473 BasePermission bp, PermissionsState origPermissions) { 9474 boolean allowed; 9475 allowed = (compareSignatures( 9476 bp.packageSetting.signatures.mSignatures, pkg.mSignatures) 9477 == PackageManager.SIGNATURE_MATCH) 9478 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures) 9479 == PackageManager.SIGNATURE_MATCH); 9480 if (!allowed && (bp.protectionLevel 9481 & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) { 9482 if (isSystemApp(pkg)) { 9483 // For updated system applications, a system permission 9484 // is granted only if it had been defined by the original application. 9485 if (pkg.isUpdatedSystemApp()) { 9486 final PackageSetting sysPs = mSettings 9487 .getDisabledSystemPkgLPr(pkg.packageName); 9488 if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) { 9489 // If the original was granted this permission, we take 9490 // that grant decision as read and propagate it to the 9491 // update. 9492 if (sysPs.isPrivileged()) { 9493 allowed = true; 9494 } 9495 } else { 9496 // The system apk may have been updated with an older 9497 // version of the one on the data partition, but which 9498 // granted a new system permission that it didn't have 9499 // before. In this case we do want to allow the app to 9500 // now get the new permission if the ancestral apk is 9501 // privileged to get it. 9502 if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) { 9503 for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) { 9504 if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) { 9505 allowed = true; 9506 break; 9507 } 9508 } 9509 } 9510 // Also if a privileged parent package on the system image or any of 9511 // its children requested a privileged permission, the updated child 9512 // packages can also get the permission. 9513 if (pkg.parentPackage != null) { 9514 final PackageSetting disabledSysParentPs = mSettings 9515 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName); 9516 if (disabledSysParentPs != null && disabledSysParentPs.pkg != null 9517 && disabledSysParentPs.isPrivileged()) { 9518 if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) { 9519 allowed = true; 9520 } else if (disabledSysParentPs.pkg.childPackages != null) { 9521 final int count = disabledSysParentPs.pkg.childPackages.size(); 9522 for (int i = 0; i < count; i++) { 9523 PackageParser.Package disabledSysChildPkg = 9524 disabledSysParentPs.pkg.childPackages.get(i); 9525 if (isPackageRequestingPermission(disabledSysChildPkg, 9526 perm)) { 9527 allowed = true; 9528 break; 9529 } 9530 } 9531 } 9532 } 9533 } 9534 } 9535 } else { 9536 allowed = isPrivilegedApp(pkg); 9537 } 9538 } 9539 } 9540 if (!allowed) { 9541 if (!allowed && (bp.protectionLevel 9542 & PermissionInfo.PROTECTION_FLAG_PRE23) != 0 9543 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 9544 // If this was a previously normal/dangerous permission that got moved 9545 // to a system permission as part of the runtime permission redesign, then 9546 // we still want to blindly grant it to old apps. 9547 allowed = true; 9548 } 9549 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0 9550 && pkg.packageName.equals(mRequiredInstallerPackage)) { 9551 // If this permission is to be granted to the system installer and 9552 // this app is an installer, then it gets the permission. 9553 allowed = true; 9554 } 9555 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0 9556 && pkg.packageName.equals(mRequiredVerifierPackage)) { 9557 // If this permission is to be granted to the system verifier and 9558 // this app is a verifier, then it gets the permission. 9559 allowed = true; 9560 } 9561 if (!allowed && (bp.protectionLevel 9562 & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0 9563 && isSystemApp(pkg)) { 9564 // Any pre-installed system app is allowed to get this permission. 9565 allowed = true; 9566 } 9567 if (!allowed && (bp.protectionLevel 9568 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) { 9569 // For development permissions, a development permission 9570 // is granted only if it was already granted. 9571 allowed = origPermissions.hasInstallPermission(perm); 9572 } 9573 } 9574 return allowed; 9575 } 9576 9577 private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) { 9578 final int permCount = pkg.requestedPermissions.size(); 9579 for (int j = 0; j < permCount; j++) { 9580 String requestedPermission = pkg.requestedPermissions.get(j); 9581 if (permission.equals(requestedPermission)) { 9582 return true; 9583 } 9584 } 9585 return false; 9586 } 9587 9588 final class ActivityIntentResolver 9589 extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> { 9590 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 9591 boolean defaultOnly, int userId) { 9592 if (!sUserManager.exists(userId)) return null; 9593 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 9594 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 9595 } 9596 9597 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 9598 int userId) { 9599 if (!sUserManager.exists(userId)) return null; 9600 mFlags = flags; 9601 return super.queryIntent(intent, resolvedType, 9602 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 9603 } 9604 9605 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 9606 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) { 9607 if (!sUserManager.exists(userId)) return null; 9608 if (packageActivities == null) { 9609 return null; 9610 } 9611 mFlags = flags; 9612 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 9613 final int N = packageActivities.size(); 9614 ArrayList<PackageParser.ActivityIntentInfo[]> listCut = 9615 new ArrayList<PackageParser.ActivityIntentInfo[]>(N); 9616 9617 ArrayList<PackageParser.ActivityIntentInfo> intentFilters; 9618 for (int i = 0; i < N; ++i) { 9619 intentFilters = packageActivities.get(i).intents; 9620 if (intentFilters != null && intentFilters.size() > 0) { 9621 PackageParser.ActivityIntentInfo[] array = 9622 new PackageParser.ActivityIntentInfo[intentFilters.size()]; 9623 intentFilters.toArray(array); 9624 listCut.add(array); 9625 } 9626 } 9627 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 9628 } 9629 9630 public final void addActivity(PackageParser.Activity a, String type) { 9631 final boolean systemApp = a.info.applicationInfo.isSystemApp(); 9632 mActivities.put(a.getComponentName(), a); 9633 if (DEBUG_SHOW_INFO) 9634 Log.v( 9635 TAG, " " + type + " " + 9636 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":"); 9637 if (DEBUG_SHOW_INFO) 9638 Log.v(TAG, " Class=" + a.info.name); 9639 final int NI = a.intents.size(); 9640 for (int j=0; j<NI; j++) { 9641 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 9642 if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) { 9643 intent.setPriority(0); 9644 Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity " 9645 + a.className + " with priority > 0, forcing to 0"); 9646 } 9647 if (DEBUG_SHOW_INFO) { 9648 Log.v(TAG, " IntentFilter:"); 9649 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 9650 } 9651 if (!intent.debugCheck()) { 9652 Log.w(TAG, "==> For Activity " + a.info.name); 9653 } 9654 addFilter(intent); 9655 } 9656 } 9657 9658 public final void removeActivity(PackageParser.Activity a, String type) { 9659 mActivities.remove(a.getComponentName()); 9660 if (DEBUG_SHOW_INFO) { 9661 Log.v(TAG, " " + type + " " 9662 + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel 9663 : a.info.name) + ":"); 9664 Log.v(TAG, " Class=" + a.info.name); 9665 } 9666 final int NI = a.intents.size(); 9667 for (int j=0; j<NI; j++) { 9668 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 9669 if (DEBUG_SHOW_INFO) { 9670 Log.v(TAG, " IntentFilter:"); 9671 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 9672 } 9673 removeFilter(intent); 9674 } 9675 } 9676 9677 @Override 9678 protected boolean allowFilterResult( 9679 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) { 9680 ActivityInfo filterAi = filter.activity.info; 9681 for (int i=dest.size()-1; i>=0; i--) { 9682 ActivityInfo destAi = dest.get(i).activityInfo; 9683 if (destAi.name == filterAi.name 9684 && destAi.packageName == filterAi.packageName) { 9685 return false; 9686 } 9687 } 9688 return true; 9689 } 9690 9691 @Override 9692 protected ActivityIntentInfo[] newArray(int size) { 9693 return new ActivityIntentInfo[size]; 9694 } 9695 9696 @Override 9697 protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) { 9698 if (!sUserManager.exists(userId)) return true; 9699 PackageParser.Package p = filter.activity.owner; 9700 if (p != null) { 9701 PackageSetting ps = (PackageSetting)p.mExtras; 9702 if (ps != null) { 9703 // System apps are never considered stopped for purposes of 9704 // filtering, because there may be no way for the user to 9705 // actually re-launch them. 9706 return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0 9707 && ps.getStopped(userId); 9708 } 9709 } 9710 return false; 9711 } 9712 9713 @Override 9714 protected boolean isPackageForFilter(String packageName, 9715 PackageParser.ActivityIntentInfo info) { 9716 return packageName.equals(info.activity.owner.packageName); 9717 } 9718 9719 @Override 9720 protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info, 9721 int match, int userId) { 9722 if (!sUserManager.exists(userId)) return null; 9723 if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) { 9724 return null; 9725 } 9726 final PackageParser.Activity activity = info.activity; 9727 PackageSetting ps = (PackageSetting) activity.owner.mExtras; 9728 if (ps == null) { 9729 return null; 9730 } 9731 ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags, 9732 ps.readUserState(userId), userId); 9733 if (ai == null) { 9734 return null; 9735 } 9736 final ResolveInfo res = new ResolveInfo(); 9737 res.activityInfo = ai; 9738 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 9739 res.filter = info; 9740 } 9741 if (info != null) { 9742 res.handleAllWebDataURI = info.handleAllWebDataURI(); 9743 } 9744 res.priority = info.getPriority(); 9745 res.preferredOrder = activity.owner.mPreferredOrder; 9746 //System.out.println("Result: " + res.activityInfo.className + 9747 // " = " + res.priority); 9748 res.match = match; 9749 res.isDefault = info.hasDefault; 9750 res.labelRes = info.labelRes; 9751 res.nonLocalizedLabel = info.nonLocalizedLabel; 9752 if (userNeedsBadging(userId)) { 9753 res.noResourceId = true; 9754 } else { 9755 res.icon = info.icon; 9756 } 9757 res.iconResourceId = info.icon; 9758 res.system = res.activityInfo.applicationInfo.isSystemApp(); 9759 return res; 9760 } 9761 9762 @Override 9763 protected void sortResults(List<ResolveInfo> results) { 9764 Collections.sort(results, mResolvePrioritySorter); 9765 } 9766 9767 @Override 9768 protected void dumpFilter(PrintWriter out, String prefix, 9769 PackageParser.ActivityIntentInfo filter) { 9770 out.print(prefix); out.print( 9771 Integer.toHexString(System.identityHashCode(filter.activity))); 9772 out.print(' '); 9773 filter.activity.printComponentShortName(out); 9774 out.print(" filter "); 9775 out.println(Integer.toHexString(System.identityHashCode(filter))); 9776 } 9777 9778 @Override 9779 protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) { 9780 return filter.activity; 9781 } 9782 9783 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 9784 PackageParser.Activity activity = (PackageParser.Activity)label; 9785 out.print(prefix); out.print( 9786 Integer.toHexString(System.identityHashCode(activity))); 9787 out.print(' '); 9788 activity.printComponentShortName(out); 9789 if (count > 1) { 9790 out.print(" ("); out.print(count); out.print(" filters)"); 9791 } 9792 out.println(); 9793 } 9794 9795// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 9796// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 9797// final List<ResolveInfo> retList = Lists.newArrayList(); 9798// while (i.hasNext()) { 9799// final ResolveInfo resolveInfo = i.next(); 9800// if (isEnabledLP(resolveInfo.activityInfo)) { 9801// retList.add(resolveInfo); 9802// } 9803// } 9804// return retList; 9805// } 9806 9807 // Keys are String (activity class name), values are Activity. 9808 private final ArrayMap<ComponentName, PackageParser.Activity> mActivities 9809 = new ArrayMap<ComponentName, PackageParser.Activity>(); 9810 private int mFlags; 9811 } 9812 9813 private final class ServiceIntentResolver 9814 extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> { 9815 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 9816 boolean defaultOnly, int userId) { 9817 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 9818 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 9819 } 9820 9821 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 9822 int userId) { 9823 if (!sUserManager.exists(userId)) return null; 9824 mFlags = flags; 9825 return super.queryIntent(intent, resolvedType, 9826 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 9827 } 9828 9829 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 9830 int flags, ArrayList<PackageParser.Service> packageServices, int userId) { 9831 if (!sUserManager.exists(userId)) return null; 9832 if (packageServices == null) { 9833 return null; 9834 } 9835 mFlags = flags; 9836 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 9837 final int N = packageServices.size(); 9838 ArrayList<PackageParser.ServiceIntentInfo[]> listCut = 9839 new ArrayList<PackageParser.ServiceIntentInfo[]>(N); 9840 9841 ArrayList<PackageParser.ServiceIntentInfo> intentFilters; 9842 for (int i = 0; i < N; ++i) { 9843 intentFilters = packageServices.get(i).intents; 9844 if (intentFilters != null && intentFilters.size() > 0) { 9845 PackageParser.ServiceIntentInfo[] array = 9846 new PackageParser.ServiceIntentInfo[intentFilters.size()]; 9847 intentFilters.toArray(array); 9848 listCut.add(array); 9849 } 9850 } 9851 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 9852 } 9853 9854 public final void addService(PackageParser.Service s) { 9855 mServices.put(s.getComponentName(), s); 9856 if (DEBUG_SHOW_INFO) { 9857 Log.v(TAG, " " 9858 + (s.info.nonLocalizedLabel != null 9859 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 9860 Log.v(TAG, " Class=" + s.info.name); 9861 } 9862 final int NI = s.intents.size(); 9863 int j; 9864 for (j=0; j<NI; j++) { 9865 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 9866 if (DEBUG_SHOW_INFO) { 9867 Log.v(TAG, " IntentFilter:"); 9868 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 9869 } 9870 if (!intent.debugCheck()) { 9871 Log.w(TAG, "==> For Service " + s.info.name); 9872 } 9873 addFilter(intent); 9874 } 9875 } 9876 9877 public final void removeService(PackageParser.Service s) { 9878 mServices.remove(s.getComponentName()); 9879 if (DEBUG_SHOW_INFO) { 9880 Log.v(TAG, " " + (s.info.nonLocalizedLabel != null 9881 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 9882 Log.v(TAG, " Class=" + s.info.name); 9883 } 9884 final int NI = s.intents.size(); 9885 int j; 9886 for (j=0; j<NI; j++) { 9887 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 9888 if (DEBUG_SHOW_INFO) { 9889 Log.v(TAG, " IntentFilter:"); 9890 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 9891 } 9892 removeFilter(intent); 9893 } 9894 } 9895 9896 @Override 9897 protected boolean allowFilterResult( 9898 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) { 9899 ServiceInfo filterSi = filter.service.info; 9900 for (int i=dest.size()-1; i>=0; i--) { 9901 ServiceInfo destAi = dest.get(i).serviceInfo; 9902 if (destAi.name == filterSi.name 9903 && destAi.packageName == filterSi.packageName) { 9904 return false; 9905 } 9906 } 9907 return true; 9908 } 9909 9910 @Override 9911 protected PackageParser.ServiceIntentInfo[] newArray(int size) { 9912 return new PackageParser.ServiceIntentInfo[size]; 9913 } 9914 9915 @Override 9916 protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) { 9917 if (!sUserManager.exists(userId)) return true; 9918 PackageParser.Package p = filter.service.owner; 9919 if (p != null) { 9920 PackageSetting ps = (PackageSetting)p.mExtras; 9921 if (ps != null) { 9922 // System apps are never considered stopped for purposes of 9923 // filtering, because there may be no way for the user to 9924 // actually re-launch them. 9925 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 9926 && ps.getStopped(userId); 9927 } 9928 } 9929 return false; 9930 } 9931 9932 @Override 9933 protected boolean isPackageForFilter(String packageName, 9934 PackageParser.ServiceIntentInfo info) { 9935 return packageName.equals(info.service.owner.packageName); 9936 } 9937 9938 @Override 9939 protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter, 9940 int match, int userId) { 9941 if (!sUserManager.exists(userId)) return null; 9942 final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter; 9943 if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) { 9944 return null; 9945 } 9946 final PackageParser.Service service = info.service; 9947 PackageSetting ps = (PackageSetting) service.owner.mExtras; 9948 if (ps == null) { 9949 return null; 9950 } 9951 ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags, 9952 ps.readUserState(userId), userId); 9953 if (si == null) { 9954 return null; 9955 } 9956 final ResolveInfo res = new ResolveInfo(); 9957 res.serviceInfo = si; 9958 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 9959 res.filter = filter; 9960 } 9961 res.priority = info.getPriority(); 9962 res.preferredOrder = service.owner.mPreferredOrder; 9963 res.match = match; 9964 res.isDefault = info.hasDefault; 9965 res.labelRes = info.labelRes; 9966 res.nonLocalizedLabel = info.nonLocalizedLabel; 9967 res.icon = info.icon; 9968 res.system = res.serviceInfo.applicationInfo.isSystemApp(); 9969 return res; 9970 } 9971 9972 @Override 9973 protected void sortResults(List<ResolveInfo> results) { 9974 Collections.sort(results, mResolvePrioritySorter); 9975 } 9976 9977 @Override 9978 protected void dumpFilter(PrintWriter out, String prefix, 9979 PackageParser.ServiceIntentInfo filter) { 9980 out.print(prefix); out.print( 9981 Integer.toHexString(System.identityHashCode(filter.service))); 9982 out.print(' '); 9983 filter.service.printComponentShortName(out); 9984 out.print(" filter "); 9985 out.println(Integer.toHexString(System.identityHashCode(filter))); 9986 } 9987 9988 @Override 9989 protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) { 9990 return filter.service; 9991 } 9992 9993 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 9994 PackageParser.Service service = (PackageParser.Service)label; 9995 out.print(prefix); out.print( 9996 Integer.toHexString(System.identityHashCode(service))); 9997 out.print(' '); 9998 service.printComponentShortName(out); 9999 if (count > 1) { 10000 out.print(" ("); out.print(count); out.print(" filters)"); 10001 } 10002 out.println(); 10003 } 10004 10005// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 10006// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 10007// final List<ResolveInfo> retList = Lists.newArrayList(); 10008// while (i.hasNext()) { 10009// final ResolveInfo resolveInfo = (ResolveInfo) i; 10010// if (isEnabledLP(resolveInfo.serviceInfo)) { 10011// retList.add(resolveInfo); 10012// } 10013// } 10014// return retList; 10015// } 10016 10017 // Keys are String (activity class name), values are Activity. 10018 private final ArrayMap<ComponentName, PackageParser.Service> mServices 10019 = new ArrayMap<ComponentName, PackageParser.Service>(); 10020 private int mFlags; 10021 }; 10022 10023 private final class ProviderIntentResolver 10024 extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> { 10025 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 10026 boolean defaultOnly, int userId) { 10027 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 10028 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 10029 } 10030 10031 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 10032 int userId) { 10033 if (!sUserManager.exists(userId)) 10034 return null; 10035 mFlags = flags; 10036 return super.queryIntent(intent, resolvedType, 10037 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 10038 } 10039 10040 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 10041 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) { 10042 if (!sUserManager.exists(userId)) 10043 return null; 10044 if (packageProviders == null) { 10045 return null; 10046 } 10047 mFlags = flags; 10048 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; 10049 final int N = packageProviders.size(); 10050 ArrayList<PackageParser.ProviderIntentInfo[]> listCut = 10051 new ArrayList<PackageParser.ProviderIntentInfo[]>(N); 10052 10053 ArrayList<PackageParser.ProviderIntentInfo> intentFilters; 10054 for (int i = 0; i < N; ++i) { 10055 intentFilters = packageProviders.get(i).intents; 10056 if (intentFilters != null && intentFilters.size() > 0) { 10057 PackageParser.ProviderIntentInfo[] array = 10058 new PackageParser.ProviderIntentInfo[intentFilters.size()]; 10059 intentFilters.toArray(array); 10060 listCut.add(array); 10061 } 10062 } 10063 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 10064 } 10065 10066 public final void addProvider(PackageParser.Provider p) { 10067 if (mProviders.containsKey(p.getComponentName())) { 10068 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring"); 10069 return; 10070 } 10071 10072 mProviders.put(p.getComponentName(), p); 10073 if (DEBUG_SHOW_INFO) { 10074 Log.v(TAG, " " 10075 + (p.info.nonLocalizedLabel != null 10076 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 10077 Log.v(TAG, " Class=" + p.info.name); 10078 } 10079 final int NI = p.intents.size(); 10080 int j; 10081 for (j = 0; j < NI; j++) { 10082 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 10083 if (DEBUG_SHOW_INFO) { 10084 Log.v(TAG, " IntentFilter:"); 10085 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10086 } 10087 if (!intent.debugCheck()) { 10088 Log.w(TAG, "==> For Provider " + p.info.name); 10089 } 10090 addFilter(intent); 10091 } 10092 } 10093 10094 public final void removeProvider(PackageParser.Provider p) { 10095 mProviders.remove(p.getComponentName()); 10096 if (DEBUG_SHOW_INFO) { 10097 Log.v(TAG, " " + (p.info.nonLocalizedLabel != null 10098 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 10099 Log.v(TAG, " Class=" + p.info.name); 10100 } 10101 final int NI = p.intents.size(); 10102 int j; 10103 for (j = 0; j < NI; j++) { 10104 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 10105 if (DEBUG_SHOW_INFO) { 10106 Log.v(TAG, " IntentFilter:"); 10107 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10108 } 10109 removeFilter(intent); 10110 } 10111 } 10112 10113 @Override 10114 protected boolean allowFilterResult( 10115 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) { 10116 ProviderInfo filterPi = filter.provider.info; 10117 for (int i = dest.size() - 1; i >= 0; i--) { 10118 ProviderInfo destPi = dest.get(i).providerInfo; 10119 if (destPi.name == filterPi.name 10120 && destPi.packageName == filterPi.packageName) { 10121 return false; 10122 } 10123 } 10124 return true; 10125 } 10126 10127 @Override 10128 protected PackageParser.ProviderIntentInfo[] newArray(int size) { 10129 return new PackageParser.ProviderIntentInfo[size]; 10130 } 10131 10132 @Override 10133 protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) { 10134 if (!sUserManager.exists(userId)) 10135 return true; 10136 PackageParser.Package p = filter.provider.owner; 10137 if (p != null) { 10138 PackageSetting ps = (PackageSetting) p.mExtras; 10139 if (ps != null) { 10140 // System apps are never considered stopped for purposes of 10141 // filtering, because there may be no way for the user to 10142 // actually re-launch them. 10143 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 10144 && ps.getStopped(userId); 10145 } 10146 } 10147 return false; 10148 } 10149 10150 @Override 10151 protected boolean isPackageForFilter(String packageName, 10152 PackageParser.ProviderIntentInfo info) { 10153 return packageName.equals(info.provider.owner.packageName); 10154 } 10155 10156 @Override 10157 protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter, 10158 int match, int userId) { 10159 if (!sUserManager.exists(userId)) 10160 return null; 10161 final PackageParser.ProviderIntentInfo info = filter; 10162 if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) { 10163 return null; 10164 } 10165 final PackageParser.Provider provider = info.provider; 10166 PackageSetting ps = (PackageSetting) provider.owner.mExtras; 10167 if (ps == null) { 10168 return null; 10169 } 10170 ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags, 10171 ps.readUserState(userId), userId); 10172 if (pi == null) { 10173 return null; 10174 } 10175 final ResolveInfo res = new ResolveInfo(); 10176 res.providerInfo = pi; 10177 if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) { 10178 res.filter = filter; 10179 } 10180 res.priority = info.getPriority(); 10181 res.preferredOrder = provider.owner.mPreferredOrder; 10182 res.match = match; 10183 res.isDefault = info.hasDefault; 10184 res.labelRes = info.labelRes; 10185 res.nonLocalizedLabel = info.nonLocalizedLabel; 10186 res.icon = info.icon; 10187 res.system = res.providerInfo.applicationInfo.isSystemApp(); 10188 return res; 10189 } 10190 10191 @Override 10192 protected void sortResults(List<ResolveInfo> results) { 10193 Collections.sort(results, mResolvePrioritySorter); 10194 } 10195 10196 @Override 10197 protected void dumpFilter(PrintWriter out, String prefix, 10198 PackageParser.ProviderIntentInfo filter) { 10199 out.print(prefix); 10200 out.print( 10201 Integer.toHexString(System.identityHashCode(filter.provider))); 10202 out.print(' '); 10203 filter.provider.printComponentShortName(out); 10204 out.print(" filter "); 10205 out.println(Integer.toHexString(System.identityHashCode(filter))); 10206 } 10207 10208 @Override 10209 protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) { 10210 return filter.provider; 10211 } 10212 10213 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 10214 PackageParser.Provider provider = (PackageParser.Provider)label; 10215 out.print(prefix); out.print( 10216 Integer.toHexString(System.identityHashCode(provider))); 10217 out.print(' '); 10218 provider.printComponentShortName(out); 10219 if (count > 1) { 10220 out.print(" ("); out.print(count); out.print(" filters)"); 10221 } 10222 out.println(); 10223 } 10224 10225 private final ArrayMap<ComponentName, PackageParser.Provider> mProviders 10226 = new ArrayMap<ComponentName, PackageParser.Provider>(); 10227 private int mFlags; 10228 } 10229 10230 private static final class EphemeralIntentResolver 10231 extends IntentResolver<EphemeralResolveIntentInfo, EphemeralResolveInfo> { 10232 @Override 10233 protected EphemeralResolveIntentInfo[] newArray(int size) { 10234 return new EphemeralResolveIntentInfo[size]; 10235 } 10236 10237 @Override 10238 protected boolean isPackageForFilter(String packageName, EphemeralResolveIntentInfo info) { 10239 return true; 10240 } 10241 10242 @Override 10243 protected EphemeralResolveInfo newResult(EphemeralResolveIntentInfo info, int match, 10244 int userId) { 10245 if (!sUserManager.exists(userId)) { 10246 return null; 10247 } 10248 return info.getEphemeralResolveInfo(); 10249 } 10250 } 10251 10252 private static final Comparator<ResolveInfo> mResolvePrioritySorter = 10253 new Comparator<ResolveInfo>() { 10254 public int compare(ResolveInfo r1, ResolveInfo r2) { 10255 int v1 = r1.priority; 10256 int v2 = r2.priority; 10257 //System.out.println("Comparing: q1=" + q1 + " q2=" + q2); 10258 if (v1 != v2) { 10259 return (v1 > v2) ? -1 : 1; 10260 } 10261 v1 = r1.preferredOrder; 10262 v2 = r2.preferredOrder; 10263 if (v1 != v2) { 10264 return (v1 > v2) ? -1 : 1; 10265 } 10266 if (r1.isDefault != r2.isDefault) { 10267 return r1.isDefault ? -1 : 1; 10268 } 10269 v1 = r1.match; 10270 v2 = r2.match; 10271 //System.out.println("Comparing: m1=" + m1 + " m2=" + m2); 10272 if (v1 != v2) { 10273 return (v1 > v2) ? -1 : 1; 10274 } 10275 if (r1.system != r2.system) { 10276 return r1.system ? -1 : 1; 10277 } 10278 if (r1.activityInfo != null) { 10279 return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName); 10280 } 10281 if (r1.serviceInfo != null) { 10282 return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName); 10283 } 10284 if (r1.providerInfo != null) { 10285 return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName); 10286 } 10287 return 0; 10288 } 10289 }; 10290 10291 private static final Comparator<ProviderInfo> mProviderInitOrderSorter = 10292 new Comparator<ProviderInfo>() { 10293 public int compare(ProviderInfo p1, ProviderInfo p2) { 10294 final int v1 = p1.initOrder; 10295 final int v2 = p2.initOrder; 10296 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0); 10297 } 10298 }; 10299 10300 final void sendPackageBroadcast(final String action, final String pkg, final Bundle extras, 10301 final int flags, final String targetPkg, final IIntentReceiver finishedReceiver, 10302 final int[] userIds) { 10303 mHandler.post(new Runnable() { 10304 @Override 10305 public void run() { 10306 try { 10307 final IActivityManager am = ActivityManagerNative.getDefault(); 10308 if (am == null) return; 10309 final int[] resolvedUserIds; 10310 if (userIds == null) { 10311 resolvedUserIds = am.getRunningUserIds(); 10312 } else { 10313 resolvedUserIds = userIds; 10314 } 10315 for (int id : resolvedUserIds) { 10316 final Intent intent = new Intent(action, 10317 pkg != null ? Uri.fromParts("package", pkg, null) : null); 10318 if (extras != null) { 10319 intent.putExtras(extras); 10320 } 10321 if (targetPkg != null) { 10322 intent.setPackage(targetPkg); 10323 } 10324 // Modify the UID when posting to other users 10325 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); 10326 if (uid > 0 && UserHandle.getUserId(uid) != id) { 10327 uid = UserHandle.getUid(id, UserHandle.getAppId(uid)); 10328 intent.putExtra(Intent.EXTRA_UID, uid); 10329 } 10330 intent.putExtra(Intent.EXTRA_USER_HANDLE, id); 10331 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags); 10332 if (DEBUG_BROADCASTS) { 10333 RuntimeException here = new RuntimeException("here"); 10334 here.fillInStackTrace(); 10335 Slog.d(TAG, "Sending to user " + id + ": " 10336 + intent.toShortString(false, true, false, false) 10337 + " " + intent.getExtras(), here); 10338 } 10339 am.broadcastIntent(null, intent, null, finishedReceiver, 10340 0, null, null, null, android.app.AppOpsManager.OP_NONE, 10341 null, finishedReceiver != null, false, id); 10342 } 10343 } catch (RemoteException ex) { 10344 } 10345 } 10346 }); 10347 } 10348 10349 /** 10350 * Check if the external storage media is available. This is true if there 10351 * is a mounted external storage medium or if the external storage is 10352 * emulated. 10353 */ 10354 private boolean isExternalMediaAvailable() { 10355 return mMediaMounted || Environment.isExternalStorageEmulated(); 10356 } 10357 10358 @Override 10359 public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) { 10360 // writer 10361 synchronized (mPackages) { 10362 if (!isExternalMediaAvailable()) { 10363 // If the external storage is no longer mounted at this point, 10364 // the caller may not have been able to delete all of this 10365 // packages files and can not delete any more. Bail. 10366 return null; 10367 } 10368 final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned; 10369 if (lastPackage != null) { 10370 pkgs.remove(lastPackage); 10371 } 10372 if (pkgs.size() > 0) { 10373 return pkgs.get(0); 10374 } 10375 } 10376 return null; 10377 } 10378 10379 void schedulePackageCleaning(String packageName, int userId, boolean andCode) { 10380 final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE, 10381 userId, andCode ? 1 : 0, packageName); 10382 if (mSystemReady) { 10383 msg.sendToTarget(); 10384 } else { 10385 if (mPostSystemReadyMessages == null) { 10386 mPostSystemReadyMessages = new ArrayList<>(); 10387 } 10388 mPostSystemReadyMessages.add(msg); 10389 } 10390 } 10391 10392 void startCleaningPackages() { 10393 // reader 10394 synchronized (mPackages) { 10395 if (!isExternalMediaAvailable()) { 10396 return; 10397 } 10398 if (mSettings.mPackagesToBeCleaned.isEmpty()) { 10399 return; 10400 } 10401 } 10402 Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE); 10403 intent.setComponent(DEFAULT_CONTAINER_COMPONENT); 10404 IActivityManager am = ActivityManagerNative.getDefault(); 10405 if (am != null) { 10406 try { 10407 am.startService(null, intent, null, mContext.getOpPackageName(), 10408 UserHandle.USER_SYSTEM); 10409 } catch (RemoteException e) { 10410 } 10411 } 10412 } 10413 10414 @Override 10415 public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer, 10416 int installFlags, String installerPackageName, int userId) { 10417 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null); 10418 10419 final int callingUid = Binder.getCallingUid(); 10420 enforceCrossUserPermission(callingUid, userId, 10421 true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser"); 10422 10423 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 10424 try { 10425 if (observer != null) { 10426 observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null); 10427 } 10428 } catch (RemoteException re) { 10429 } 10430 return; 10431 } 10432 10433 if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) { 10434 installFlags |= PackageManager.INSTALL_FROM_ADB; 10435 10436 } else { 10437 // Caller holds INSTALL_PACKAGES permission, so we're less strict 10438 // about installerPackageName. 10439 10440 installFlags &= ~PackageManager.INSTALL_FROM_ADB; 10441 installFlags &= ~PackageManager.INSTALL_ALL_USERS; 10442 } 10443 10444 UserHandle user; 10445 if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) { 10446 user = UserHandle.ALL; 10447 } else { 10448 user = new UserHandle(userId); 10449 } 10450 10451 // Only system components can circumvent runtime permissions when installing. 10452 if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0 10453 && mContext.checkCallingOrSelfPermission(Manifest.permission 10454 .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) { 10455 throw new SecurityException("You need the " 10456 + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission " 10457 + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag"); 10458 } 10459 10460 final File originFile = new File(originPath); 10461 final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile); 10462 10463 final Message msg = mHandler.obtainMessage(INIT_COPY); 10464 final VerificationInfo verificationInfo = new VerificationInfo( 10465 null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid); 10466 final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer, 10467 installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user, 10468 null /*packageAbiOverride*/, null /*grantedPermissions*/); 10469 params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params)); 10470 msg.obj = params; 10471 10472 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser", 10473 System.identityHashCode(msg.obj)); 10474 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 10475 System.identityHashCode(msg.obj)); 10476 10477 mHandler.sendMessage(msg); 10478 } 10479 10480 void installStage(String packageName, File stagedDir, String stagedCid, 10481 IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams, 10482 String installerPackageName, int installerUid, UserHandle user) { 10483 if (DEBUG_EPHEMERAL) { 10484 if ((sessionParams.installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) { 10485 Slog.d(TAG, "Ephemeral install of " + packageName); 10486 } 10487 } 10488 final VerificationInfo verificationInfo = new VerificationInfo( 10489 sessionParams.originatingUri, sessionParams.referrerUri, 10490 sessionParams.originatingUid, installerUid); 10491 10492 final OriginInfo origin; 10493 if (stagedDir != null) { 10494 origin = OriginInfo.fromStagedFile(stagedDir); 10495 } else { 10496 origin = OriginInfo.fromStagedContainer(stagedCid); 10497 } 10498 10499 final Message msg = mHandler.obtainMessage(INIT_COPY); 10500 final InstallParams params = new InstallParams(origin, null, observer, 10501 sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid, 10502 verificationInfo, user, sessionParams.abiOverride, 10503 sessionParams.grantedRuntimePermissions); 10504 params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params)); 10505 msg.obj = params; 10506 10507 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage", 10508 System.identityHashCode(msg.obj)); 10509 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 10510 System.identityHashCode(msg.obj)); 10511 10512 mHandler.sendMessage(msg); 10513 } 10514 10515 private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, 10516 int userId) { 10517 final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting); 10518 sendPackageAddedForUser(packageName, isSystem, pkgSetting.appId, userId); 10519 } 10520 10521 private void sendPackageAddedForUser(String packageName, boolean isSystem, 10522 int appId, int userId) { 10523 Bundle extras = new Bundle(1); 10524 extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, appId)); 10525 10526 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 10527 packageName, extras, 0, null, null, new int[] {userId}); 10528 try { 10529 IActivityManager am = ActivityManagerNative.getDefault(); 10530 if (isSystem && am.isUserRunning(userId, 0)) { 10531 // The just-installed/enabled app is bundled on the system, so presumed 10532 // to be able to run automatically without needing an explicit launch. 10533 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one. 10534 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED) 10535 .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES) 10536 .setPackage(packageName); 10537 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null, 10538 android.app.AppOpsManager.OP_NONE, null, false, false, userId); 10539 } 10540 } catch (RemoteException e) { 10541 // shouldn't happen 10542 Slog.w(TAG, "Unable to bootstrap installed package", e); 10543 } 10544 } 10545 10546 @Override 10547 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, 10548 int userId) { 10549 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 10550 PackageSetting pkgSetting; 10551 final int uid = Binder.getCallingUid(); 10552 enforceCrossUserPermission(uid, userId, 10553 true /* requireFullPermission */, true /* checkShell */, 10554 "setApplicationHiddenSetting for user " + userId); 10555 10556 if (hidden && isPackageDeviceAdmin(packageName, userId)) { 10557 Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin"); 10558 return false; 10559 } 10560 10561 long callingId = Binder.clearCallingIdentity(); 10562 try { 10563 boolean sendAdded = false; 10564 boolean sendRemoved = false; 10565 // writer 10566 synchronized (mPackages) { 10567 pkgSetting = mSettings.mPackages.get(packageName); 10568 if (pkgSetting == null) { 10569 return false; 10570 } 10571 if (pkgSetting.getHidden(userId) != hidden) { 10572 pkgSetting.setHidden(hidden, userId); 10573 mSettings.writePackageRestrictionsLPr(userId); 10574 if (hidden) { 10575 sendRemoved = true; 10576 } else { 10577 sendAdded = true; 10578 } 10579 } 10580 } 10581 if (sendAdded) { 10582 sendPackageAddedForUser(packageName, pkgSetting, userId); 10583 return true; 10584 } 10585 if (sendRemoved) { 10586 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId), 10587 "hiding pkg"); 10588 sendApplicationHiddenForUser(packageName, pkgSetting, userId); 10589 return true; 10590 } 10591 } finally { 10592 Binder.restoreCallingIdentity(callingId); 10593 } 10594 return false; 10595 } 10596 10597 private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting, 10598 int userId) { 10599 final PackageRemovedInfo info = new PackageRemovedInfo(); 10600 info.removedPackage = packageName; 10601 info.removedUsers = new int[] {userId}; 10602 info.uid = UserHandle.getUid(userId, pkgSetting.appId); 10603 info.sendPackageRemovedBroadcasts(true /*killApp*/); 10604 } 10605 10606 private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) { 10607 if (pkgList.length > 0) { 10608 Bundle extras = new Bundle(1); 10609 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 10610 10611 sendPackageBroadcast( 10612 suspended ? Intent.ACTION_PACKAGES_SUSPENDED 10613 : Intent.ACTION_PACKAGES_UNSUSPENDED, 10614 null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null, 10615 new int[] {userId}); 10616 } 10617 } 10618 10619 /** 10620 * Returns true if application is not found or there was an error. Otherwise it returns 10621 * the hidden state of the package for the given user. 10622 */ 10623 @Override 10624 public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) { 10625 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 10626 enforceCrossUserPermission(Binder.getCallingUid(), userId, 10627 true /* requireFullPermission */, false /* checkShell */, 10628 "getApplicationHidden for user " + userId); 10629 PackageSetting pkgSetting; 10630 long callingId = Binder.clearCallingIdentity(); 10631 try { 10632 // writer 10633 synchronized (mPackages) { 10634 pkgSetting = mSettings.mPackages.get(packageName); 10635 if (pkgSetting == null) { 10636 return true; 10637 } 10638 return pkgSetting.getHidden(userId); 10639 } 10640 } finally { 10641 Binder.restoreCallingIdentity(callingId); 10642 } 10643 } 10644 10645 /** 10646 * @hide 10647 */ 10648 @Override 10649 public int installExistingPackageAsUser(String packageName, int userId) { 10650 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, 10651 null); 10652 PackageSetting pkgSetting; 10653 final int uid = Binder.getCallingUid(); 10654 enforceCrossUserPermission(uid, userId, 10655 true /* requireFullPermission */, true /* checkShell */, 10656 "installExistingPackage for user " + userId); 10657 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 10658 return PackageManager.INSTALL_FAILED_USER_RESTRICTED; 10659 } 10660 10661 long callingId = Binder.clearCallingIdentity(); 10662 try { 10663 boolean installed = false; 10664 10665 // writer 10666 synchronized (mPackages) { 10667 pkgSetting = mSettings.mPackages.get(packageName); 10668 if (pkgSetting == null) { 10669 return PackageManager.INSTALL_FAILED_INVALID_URI; 10670 } 10671 if (!pkgSetting.getInstalled(userId)) { 10672 pkgSetting.setInstalled(true, userId); 10673 pkgSetting.setHidden(false, userId); 10674 mSettings.writePackageRestrictionsLPr(userId); 10675 installed = true; 10676 } 10677 } 10678 10679 if (installed) { 10680 if (pkgSetting.pkg != null) { 10681 prepareAppDataAfterInstall(pkgSetting.pkg); 10682 } 10683 sendPackageAddedForUser(packageName, pkgSetting, userId); 10684 } 10685 } finally { 10686 Binder.restoreCallingIdentity(callingId); 10687 } 10688 10689 return PackageManager.INSTALL_SUCCEEDED; 10690 } 10691 10692 boolean isUserRestricted(int userId, String restrictionKey) { 10693 Bundle restrictions = sUserManager.getUserRestrictions(userId); 10694 if (restrictions.getBoolean(restrictionKey, false)) { 10695 Log.w(TAG, "User is restricted: " + restrictionKey); 10696 return true; 10697 } 10698 return false; 10699 } 10700 10701 @Override 10702 public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended, 10703 int userId) { 10704 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 10705 enforceCrossUserPermission(Binder.getCallingUid(), userId, 10706 true /* requireFullPermission */, true /* checkShell */, 10707 "setPackagesSuspended for user " + userId); 10708 10709 if (ArrayUtils.isEmpty(packageNames)) { 10710 return packageNames; 10711 } 10712 10713 // List of package names for whom the suspended state has changed. 10714 List<String> changedPackages = new ArrayList<>(packageNames.length); 10715 // List of package names for whom the suspended state is not set as requested in this 10716 // method. 10717 List<String> unactionedPackages = new ArrayList<>(packageNames.length); 10718 for (int i = 0; i < packageNames.length; i++) { 10719 String packageName = packageNames[i]; 10720 long callingId = Binder.clearCallingIdentity(); 10721 try { 10722 boolean changed = false; 10723 final int appId; 10724 synchronized (mPackages) { 10725 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName); 10726 if (pkgSetting == null) { 10727 Slog.w(TAG, "Could not find package setting for package \"" + packageName 10728 + "\". Skipping suspending/un-suspending."); 10729 unactionedPackages.add(packageName); 10730 continue; 10731 } 10732 appId = pkgSetting.appId; 10733 if (pkgSetting.getSuspended(userId) != suspended) { 10734 if (!canSuspendPackageForUserLocked(packageName, userId)) { 10735 unactionedPackages.add(packageName); 10736 continue; 10737 } 10738 pkgSetting.setSuspended(suspended, userId); 10739 mSettings.writePackageRestrictionsLPr(userId); 10740 changed = true; 10741 changedPackages.add(packageName); 10742 } 10743 } 10744 10745 if (changed && suspended) { 10746 killApplication(packageName, UserHandle.getUid(userId, appId), 10747 "suspending package"); 10748 } 10749 } finally { 10750 Binder.restoreCallingIdentity(callingId); 10751 } 10752 } 10753 10754 if (!changedPackages.isEmpty()) { 10755 sendPackagesSuspendedForUser(changedPackages.toArray( 10756 new String[changedPackages.size()]), userId, suspended); 10757 } 10758 10759 return unactionedPackages.toArray(new String[unactionedPackages.size()]); 10760 } 10761 10762 @Override 10763 public boolean isPackageSuspendedForUser(String packageName, int userId) { 10764 enforceCrossUserPermission(Binder.getCallingUid(), userId, 10765 true /* requireFullPermission */, false /* checkShell */, 10766 "isPackageSuspendedForUser for user " + userId); 10767 synchronized (mPackages) { 10768 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName); 10769 return pkgSetting != null && pkgSetting.getSuspended(userId); 10770 } 10771 } 10772 10773 // TODO: investigate and add more restrictions for suspending crucial packages. 10774 private boolean canSuspendPackageForUserLocked(String packageName, int userId) { 10775 if (isPackageDeviceAdmin(packageName, userId)) { 10776 Slog.w(TAG, "Not suspending/un-suspending package \"" + packageName 10777 + "\": has active device admin"); 10778 return false; 10779 } 10780 10781 String activeLauncherPackageName = getActiveLauncherPackageName(userId); 10782 if (packageName.equals(activeLauncherPackageName)) { 10783 Slog.w(TAG, "Not suspending/un-suspending package \"" + packageName 10784 + "\" because it is set as the active launcher"); 10785 return false; 10786 } 10787 10788 final PackageParser.Package pkg = mPackages.get(packageName); 10789 if (pkg != null && isPrivilegedApp(pkg)) { 10790 Slog.w(TAG, "Not suspending/un-suspending package \"" + packageName 10791 + "\" because it is a privileged app"); 10792 return false; 10793 } 10794 10795 return true; 10796 } 10797 10798 private String getActiveLauncherPackageName(int userId) { 10799 Intent intent = new Intent(Intent.ACTION_MAIN); 10800 intent.addCategory(Intent.CATEGORY_HOME); 10801 ResolveInfo resolveInfo = resolveIntent( 10802 intent, 10803 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 10804 PackageManager.MATCH_DEFAULT_ONLY, 10805 userId); 10806 10807 return resolveInfo == null ? null : resolveInfo.activityInfo.packageName; 10808 } 10809 10810 @Override 10811 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException { 10812 mContext.enforceCallingOrSelfPermission( 10813 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 10814 "Only package verification agents can verify applications"); 10815 10816 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 10817 final PackageVerificationResponse response = new PackageVerificationResponse( 10818 verificationCode, Binder.getCallingUid()); 10819 msg.arg1 = id; 10820 msg.obj = response; 10821 mHandler.sendMessage(msg); 10822 } 10823 10824 @Override 10825 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, 10826 long millisecondsToDelay) { 10827 mContext.enforceCallingOrSelfPermission( 10828 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 10829 "Only package verification agents can extend verification timeouts"); 10830 10831 final PackageVerificationState state = mPendingVerification.get(id); 10832 final PackageVerificationResponse response = new PackageVerificationResponse( 10833 verificationCodeAtTimeout, Binder.getCallingUid()); 10834 10835 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) { 10836 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT; 10837 } 10838 if (millisecondsToDelay < 0) { 10839 millisecondsToDelay = 0; 10840 } 10841 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW) 10842 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) { 10843 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT; 10844 } 10845 10846 if ((state != null) && !state.timeoutExtended()) { 10847 state.extendTimeout(); 10848 10849 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 10850 msg.arg1 = id; 10851 msg.obj = response; 10852 mHandler.sendMessageDelayed(msg, millisecondsToDelay); 10853 } 10854 } 10855 10856 private void broadcastPackageVerified(int verificationId, Uri packageUri, 10857 int verificationCode, UserHandle user) { 10858 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED); 10859 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE); 10860 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 10861 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 10862 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode); 10863 10864 mContext.sendBroadcastAsUser(intent, user, 10865 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT); 10866 } 10867 10868 private ComponentName matchComponentForVerifier(String packageName, 10869 List<ResolveInfo> receivers) { 10870 ActivityInfo targetReceiver = null; 10871 10872 final int NR = receivers.size(); 10873 for (int i = 0; i < NR; i++) { 10874 final ResolveInfo info = receivers.get(i); 10875 if (info.activityInfo == null) { 10876 continue; 10877 } 10878 10879 if (packageName.equals(info.activityInfo.packageName)) { 10880 targetReceiver = info.activityInfo; 10881 break; 10882 } 10883 } 10884 10885 if (targetReceiver == null) { 10886 return null; 10887 } 10888 10889 return new ComponentName(targetReceiver.packageName, targetReceiver.name); 10890 } 10891 10892 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo, 10893 List<ResolveInfo> receivers, final PackageVerificationState verificationState) { 10894 if (pkgInfo.verifiers.length == 0) { 10895 return null; 10896 } 10897 10898 final int N = pkgInfo.verifiers.length; 10899 final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1); 10900 for (int i = 0; i < N; i++) { 10901 final VerifierInfo verifierInfo = pkgInfo.verifiers[i]; 10902 10903 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName, 10904 receivers); 10905 if (comp == null) { 10906 continue; 10907 } 10908 10909 final int verifierUid = getUidForVerifier(verifierInfo); 10910 if (verifierUid == -1) { 10911 continue; 10912 } 10913 10914 if (DEBUG_VERIFY) { 10915 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName 10916 + " with the correct signature"); 10917 } 10918 sufficientVerifiers.add(comp); 10919 verificationState.addSufficientVerifier(verifierUid); 10920 } 10921 10922 return sufficientVerifiers; 10923 } 10924 10925 private int getUidForVerifier(VerifierInfo verifierInfo) { 10926 synchronized (mPackages) { 10927 final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName); 10928 if (pkg == null) { 10929 return -1; 10930 } else if (pkg.mSignatures.length != 1) { 10931 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 10932 + " has more than one signature; ignoring"); 10933 return -1; 10934 } 10935 10936 /* 10937 * If the public key of the package's signature does not match 10938 * our expected public key, then this is a different package and 10939 * we should skip. 10940 */ 10941 10942 final byte[] expectedPublicKey; 10943 try { 10944 final Signature verifierSig = pkg.mSignatures[0]; 10945 final PublicKey publicKey = verifierSig.getPublicKey(); 10946 expectedPublicKey = publicKey.getEncoded(); 10947 } catch (CertificateException e) { 10948 return -1; 10949 } 10950 10951 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded(); 10952 10953 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) { 10954 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 10955 + " does not have the expected public key; ignoring"); 10956 return -1; 10957 } 10958 10959 return pkg.applicationInfo.uid; 10960 } 10961 } 10962 10963 @Override 10964 public void finishPackageInstall(int token) { 10965 enforceSystemOrRoot("Only the system is allowed to finish installs"); 10966 10967 if (DEBUG_INSTALL) { 10968 Slog.v(TAG, "BM finishing package install for " + token); 10969 } 10970 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token); 10971 10972 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 10973 mHandler.sendMessage(msg); 10974 } 10975 10976 /** 10977 * Get the verification agent timeout. 10978 * 10979 * @return verification timeout in milliseconds 10980 */ 10981 private long getVerificationTimeout() { 10982 return android.provider.Settings.Global.getLong(mContext.getContentResolver(), 10983 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT, 10984 DEFAULT_VERIFICATION_TIMEOUT); 10985 } 10986 10987 /** 10988 * Get the default verification agent response code. 10989 * 10990 * @return default verification response code 10991 */ 10992 private int getDefaultVerificationResponse() { 10993 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 10994 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE, 10995 DEFAULT_VERIFICATION_RESPONSE); 10996 } 10997 10998 /** 10999 * Check whether or not package verification has been enabled. 11000 * 11001 * @return true if verification should be performed 11002 */ 11003 private boolean isVerificationEnabled(int userId, int installFlags) { 11004 if (!DEFAULT_VERIFY_ENABLE) { 11005 return false; 11006 } 11007 // Ephemeral apps don't get the full verification treatment 11008 if ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) { 11009 if (DEBUG_EPHEMERAL) { 11010 Slog.d(TAG, "INSTALL_EPHEMERAL so skipping verification"); 11011 } 11012 return false; 11013 } 11014 11015 boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS); 11016 11017 // Check if installing from ADB 11018 if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) { 11019 // Do not run verification in a test harness environment 11020 if (ActivityManager.isRunningInTestHarness()) { 11021 return false; 11022 } 11023 if (ensureVerifyAppsEnabled) { 11024 return true; 11025 } 11026 // Check if the developer does not want package verification for ADB installs 11027 if (android.provider.Settings.Global.getInt(mContext.getContentResolver(), 11028 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) { 11029 return false; 11030 } 11031 } 11032 11033 if (ensureVerifyAppsEnabled) { 11034 return true; 11035 } 11036 11037 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 11038 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1; 11039 } 11040 11041 @Override 11042 public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains) 11043 throws RemoteException { 11044 mContext.enforceCallingOrSelfPermission( 11045 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 11046 "Only intentfilter verification agents can verify applications"); 11047 11048 final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED); 11049 final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse( 11050 Binder.getCallingUid(), verificationCode, failedDomains); 11051 msg.arg1 = id; 11052 msg.obj = response; 11053 mHandler.sendMessage(msg); 11054 } 11055 11056 @Override 11057 public int getIntentVerificationStatus(String packageName, int userId) { 11058 synchronized (mPackages) { 11059 return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 11060 } 11061 } 11062 11063 @Override 11064 public boolean updateIntentVerificationStatus(String packageName, int status, int userId) { 11065 mContext.enforceCallingOrSelfPermission( 11066 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 11067 11068 boolean result = false; 11069 synchronized (mPackages) { 11070 result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId); 11071 } 11072 if (result) { 11073 scheduleWritePackageRestrictionsLocked(userId); 11074 } 11075 return result; 11076 } 11077 11078 @Override 11079 public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) { 11080 synchronized (mPackages) { 11081 return mSettings.getIntentFilterVerificationsLPr(packageName); 11082 } 11083 } 11084 11085 @Override 11086 public List<IntentFilter> getAllIntentFilters(String packageName) { 11087 if (TextUtils.isEmpty(packageName)) { 11088 return Collections.<IntentFilter>emptyList(); 11089 } 11090 synchronized (mPackages) { 11091 PackageParser.Package pkg = mPackages.get(packageName); 11092 if (pkg == null || pkg.activities == null) { 11093 return Collections.<IntentFilter>emptyList(); 11094 } 11095 final int count = pkg.activities.size(); 11096 ArrayList<IntentFilter> result = new ArrayList<>(); 11097 for (int n=0; n<count; n++) { 11098 PackageParser.Activity activity = pkg.activities.get(n); 11099 if (activity.intents != null && activity.intents.size() > 0) { 11100 result.addAll(activity.intents); 11101 } 11102 } 11103 return result; 11104 } 11105 } 11106 11107 @Override 11108 public boolean setDefaultBrowserPackageName(String packageName, int userId) { 11109 mContext.enforceCallingOrSelfPermission( 11110 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 11111 11112 synchronized (mPackages) { 11113 boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId); 11114 if (packageName != null) { 11115 result |= updateIntentVerificationStatus(packageName, 11116 PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, 11117 userId); 11118 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr( 11119 packageName, userId); 11120 } 11121 return result; 11122 } 11123 } 11124 11125 @Override 11126 public String getDefaultBrowserPackageName(int userId) { 11127 synchronized (mPackages) { 11128 return mSettings.getDefaultBrowserPackageNameLPw(userId); 11129 } 11130 } 11131 11132 /** 11133 * Get the "allow unknown sources" setting. 11134 * 11135 * @return the current "allow unknown sources" setting 11136 */ 11137 private int getUnknownSourcesSettings() { 11138 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 11139 android.provider.Settings.Global.INSTALL_NON_MARKET_APPS, 11140 -1); 11141 } 11142 11143 @Override 11144 public void setInstallerPackageName(String targetPackage, String installerPackageName) { 11145 final int uid = Binder.getCallingUid(); 11146 // writer 11147 synchronized (mPackages) { 11148 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage); 11149 if (targetPackageSetting == null) { 11150 throw new IllegalArgumentException("Unknown target package: " + targetPackage); 11151 } 11152 11153 PackageSetting installerPackageSetting; 11154 if (installerPackageName != null) { 11155 installerPackageSetting = mSettings.mPackages.get(installerPackageName); 11156 if (installerPackageSetting == null) { 11157 throw new IllegalArgumentException("Unknown installer package: " 11158 + installerPackageName); 11159 } 11160 } else { 11161 installerPackageSetting = null; 11162 } 11163 11164 Signature[] callerSignature; 11165 Object obj = mSettings.getUserIdLPr(uid); 11166 if (obj != null) { 11167 if (obj instanceof SharedUserSetting) { 11168 callerSignature = ((SharedUserSetting)obj).signatures.mSignatures; 11169 } else if (obj instanceof PackageSetting) { 11170 callerSignature = ((PackageSetting)obj).signatures.mSignatures; 11171 } else { 11172 throw new SecurityException("Bad object " + obj + " for uid " + uid); 11173 } 11174 } else { 11175 throw new SecurityException("Unknown calling UID: " + uid); 11176 } 11177 11178 // Verify: can't set installerPackageName to a package that is 11179 // not signed with the same cert as the caller. 11180 if (installerPackageSetting != null) { 11181 if (compareSignatures(callerSignature, 11182 installerPackageSetting.signatures.mSignatures) 11183 != PackageManager.SIGNATURE_MATCH) { 11184 throw new SecurityException( 11185 "Caller does not have same cert as new installer package " 11186 + installerPackageName); 11187 } 11188 } 11189 11190 // Verify: if target already has an installer package, it must 11191 // be signed with the same cert as the caller. 11192 if (targetPackageSetting.installerPackageName != null) { 11193 PackageSetting setting = mSettings.mPackages.get( 11194 targetPackageSetting.installerPackageName); 11195 // If the currently set package isn't valid, then it's always 11196 // okay to change it. 11197 if (setting != null) { 11198 if (compareSignatures(callerSignature, 11199 setting.signatures.mSignatures) 11200 != PackageManager.SIGNATURE_MATCH) { 11201 throw new SecurityException( 11202 "Caller does not have same cert as old installer package " 11203 + targetPackageSetting.installerPackageName); 11204 } 11205 } 11206 } 11207 11208 // Okay! 11209 targetPackageSetting.installerPackageName = installerPackageName; 11210 scheduleWriteSettingsLocked(); 11211 } 11212 } 11213 11214 private void processPendingInstall(final InstallArgs args, final int currentStatus) { 11215 // Queue up an async operation since the package installation may take a little while. 11216 mHandler.post(new Runnable() { 11217 public void run() { 11218 mHandler.removeCallbacks(this); 11219 // Result object to be returned 11220 PackageInstalledInfo res = new PackageInstalledInfo(); 11221 res.setReturnCode(currentStatus); 11222 res.uid = -1; 11223 res.pkg = null; 11224 res.removedInfo = null; 11225 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 11226 args.doPreInstall(res.returnCode); 11227 synchronized (mInstallLock) { 11228 installPackageTracedLI(args, res); 11229 } 11230 args.doPostInstall(res.returnCode, res.uid); 11231 } 11232 11233 // A restore should be performed at this point if (a) the install 11234 // succeeded, (b) the operation is not an update, and (c) the new 11235 // package has not opted out of backup participation. 11236 final boolean update = res.removedInfo != null 11237 && res.removedInfo.removedPackage != null; 11238 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags; 11239 boolean doRestore = !update 11240 && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0); 11241 11242 // Set up the post-install work request bookkeeping. This will be used 11243 // and cleaned up by the post-install event handling regardless of whether 11244 // there's a restore pass performed. Token values are >= 1. 11245 int token; 11246 if (mNextInstallToken < 0) mNextInstallToken = 1; 11247 token = mNextInstallToken++; 11248 11249 PostInstallData data = new PostInstallData(args, res); 11250 mRunningInstalls.put(token, data); 11251 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token); 11252 11253 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) { 11254 // Pass responsibility to the Backup Manager. It will perform a 11255 // restore if appropriate, then pass responsibility back to the 11256 // Package Manager to run the post-install observer callbacks 11257 // and broadcasts. 11258 IBackupManager bm = IBackupManager.Stub.asInterface( 11259 ServiceManager.getService(Context.BACKUP_SERVICE)); 11260 if (bm != null) { 11261 if (DEBUG_INSTALL) Log.v(TAG, "token " + token 11262 + " to BM for possible restore"); 11263 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token); 11264 try { 11265 // TODO: http://b/22388012 11266 if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) { 11267 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token); 11268 } else { 11269 doRestore = false; 11270 } 11271 } catch (RemoteException e) { 11272 // can't happen; the backup manager is local 11273 } catch (Exception e) { 11274 Slog.e(TAG, "Exception trying to enqueue restore", e); 11275 doRestore = false; 11276 } 11277 } else { 11278 Slog.e(TAG, "Backup Manager not found!"); 11279 doRestore = false; 11280 } 11281 } 11282 11283 if (!doRestore) { 11284 // No restore possible, or the Backup Manager was mysteriously not 11285 // available -- just fire the post-install work request directly. 11286 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token); 11287 11288 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token); 11289 11290 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 11291 mHandler.sendMessage(msg); 11292 } 11293 } 11294 }); 11295 } 11296 11297 private abstract class HandlerParams { 11298 private static final int MAX_RETRIES = 4; 11299 11300 /** 11301 * Number of times startCopy() has been attempted and had a non-fatal 11302 * error. 11303 */ 11304 private int mRetries = 0; 11305 11306 /** User handle for the user requesting the information or installation. */ 11307 private final UserHandle mUser; 11308 String traceMethod; 11309 int traceCookie; 11310 11311 HandlerParams(UserHandle user) { 11312 mUser = user; 11313 } 11314 11315 UserHandle getUser() { 11316 return mUser; 11317 } 11318 11319 HandlerParams setTraceMethod(String traceMethod) { 11320 this.traceMethod = traceMethod; 11321 return this; 11322 } 11323 11324 HandlerParams setTraceCookie(int traceCookie) { 11325 this.traceCookie = traceCookie; 11326 return this; 11327 } 11328 11329 final boolean startCopy() { 11330 boolean res; 11331 try { 11332 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this); 11333 11334 if (++mRetries > MAX_RETRIES) { 11335 Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up"); 11336 mHandler.sendEmptyMessage(MCS_GIVE_UP); 11337 handleServiceError(); 11338 return false; 11339 } else { 11340 handleStartCopy(); 11341 res = true; 11342 } 11343 } catch (RemoteException e) { 11344 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT"); 11345 mHandler.sendEmptyMessage(MCS_RECONNECT); 11346 res = false; 11347 } 11348 handleReturnCode(); 11349 return res; 11350 } 11351 11352 final void serviceError() { 11353 if (DEBUG_INSTALL) Slog.i(TAG, "serviceError"); 11354 handleServiceError(); 11355 handleReturnCode(); 11356 } 11357 11358 abstract void handleStartCopy() throws RemoteException; 11359 abstract void handleServiceError(); 11360 abstract void handleReturnCode(); 11361 } 11362 11363 class MeasureParams extends HandlerParams { 11364 private final PackageStats mStats; 11365 private boolean mSuccess; 11366 11367 private final IPackageStatsObserver mObserver; 11368 11369 public MeasureParams(PackageStats stats, IPackageStatsObserver observer) { 11370 super(new UserHandle(stats.userHandle)); 11371 mObserver = observer; 11372 mStats = stats; 11373 } 11374 11375 @Override 11376 public String toString() { 11377 return "MeasureParams{" 11378 + Integer.toHexString(System.identityHashCode(this)) 11379 + " " + mStats.packageName + "}"; 11380 } 11381 11382 @Override 11383 void handleStartCopy() throws RemoteException { 11384 synchronized (mInstallLock) { 11385 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats); 11386 } 11387 11388 if (mSuccess) { 11389 final boolean mounted; 11390 if (Environment.isExternalStorageEmulated()) { 11391 mounted = true; 11392 } else { 11393 final String status = Environment.getExternalStorageState(); 11394 mounted = (Environment.MEDIA_MOUNTED.equals(status) 11395 || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status)); 11396 } 11397 11398 if (mounted) { 11399 final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle); 11400 11401 mStats.externalCacheSize = calculateDirectorySize(mContainerService, 11402 userEnv.buildExternalStorageAppCacheDirs(mStats.packageName)); 11403 11404 mStats.externalDataSize = calculateDirectorySize(mContainerService, 11405 userEnv.buildExternalStorageAppDataDirs(mStats.packageName)); 11406 11407 // Always subtract cache size, since it's a subdirectory 11408 mStats.externalDataSize -= mStats.externalCacheSize; 11409 11410 mStats.externalMediaSize = calculateDirectorySize(mContainerService, 11411 userEnv.buildExternalStorageAppMediaDirs(mStats.packageName)); 11412 11413 mStats.externalObbSize = calculateDirectorySize(mContainerService, 11414 userEnv.buildExternalStorageAppObbDirs(mStats.packageName)); 11415 } 11416 } 11417 } 11418 11419 @Override 11420 void handleReturnCode() { 11421 if (mObserver != null) { 11422 try { 11423 mObserver.onGetStatsCompleted(mStats, mSuccess); 11424 } catch (RemoteException e) { 11425 Slog.i(TAG, "Observer no longer exists."); 11426 } 11427 } 11428 } 11429 11430 @Override 11431 void handleServiceError() { 11432 Slog.e(TAG, "Could not measure application " + mStats.packageName 11433 + " external storage"); 11434 } 11435 } 11436 11437 private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths) 11438 throws RemoteException { 11439 long result = 0; 11440 for (File path : paths) { 11441 result += mcs.calculateDirectorySize(path.getAbsolutePath()); 11442 } 11443 return result; 11444 } 11445 11446 private static void clearDirectory(IMediaContainerService mcs, File[] paths) { 11447 for (File path : paths) { 11448 try { 11449 mcs.clearDirectory(path.getAbsolutePath()); 11450 } catch (RemoteException e) { 11451 } 11452 } 11453 } 11454 11455 static class OriginInfo { 11456 /** 11457 * Location where install is coming from, before it has been 11458 * copied/renamed into place. This could be a single monolithic APK 11459 * file, or a cluster directory. This location may be untrusted. 11460 */ 11461 final File file; 11462 final String cid; 11463 11464 /** 11465 * Flag indicating that {@link #file} or {@link #cid} has already been 11466 * staged, meaning downstream users don't need to defensively copy the 11467 * contents. 11468 */ 11469 final boolean staged; 11470 11471 /** 11472 * Flag indicating that {@link #file} or {@link #cid} is an already 11473 * installed app that is being moved. 11474 */ 11475 final boolean existing; 11476 11477 final String resolvedPath; 11478 final File resolvedFile; 11479 11480 static OriginInfo fromNothing() { 11481 return new OriginInfo(null, null, false, false); 11482 } 11483 11484 static OriginInfo fromUntrustedFile(File file) { 11485 return new OriginInfo(file, null, false, false); 11486 } 11487 11488 static OriginInfo fromExistingFile(File file) { 11489 return new OriginInfo(file, null, false, true); 11490 } 11491 11492 static OriginInfo fromStagedFile(File file) { 11493 return new OriginInfo(file, null, true, false); 11494 } 11495 11496 static OriginInfo fromStagedContainer(String cid) { 11497 return new OriginInfo(null, cid, true, false); 11498 } 11499 11500 private OriginInfo(File file, String cid, boolean staged, boolean existing) { 11501 this.file = file; 11502 this.cid = cid; 11503 this.staged = staged; 11504 this.existing = existing; 11505 11506 if (cid != null) { 11507 resolvedPath = PackageHelper.getSdDir(cid); 11508 resolvedFile = new File(resolvedPath); 11509 } else if (file != null) { 11510 resolvedPath = file.getAbsolutePath(); 11511 resolvedFile = file; 11512 } else { 11513 resolvedPath = null; 11514 resolvedFile = null; 11515 } 11516 } 11517 } 11518 11519 static class MoveInfo { 11520 final int moveId; 11521 final String fromUuid; 11522 final String toUuid; 11523 final String packageName; 11524 final String dataAppName; 11525 final int appId; 11526 final String seinfo; 11527 final int targetSdkVersion; 11528 11529 public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName, 11530 String dataAppName, int appId, String seinfo, int targetSdkVersion) { 11531 this.moveId = moveId; 11532 this.fromUuid = fromUuid; 11533 this.toUuid = toUuid; 11534 this.packageName = packageName; 11535 this.dataAppName = dataAppName; 11536 this.appId = appId; 11537 this.seinfo = seinfo; 11538 this.targetSdkVersion = targetSdkVersion; 11539 } 11540 } 11541 11542 static class VerificationInfo { 11543 /** A constant used to indicate that a uid value is not present. */ 11544 public static final int NO_UID = -1; 11545 11546 /** URI referencing where the package was downloaded from. */ 11547 final Uri originatingUri; 11548 11549 /** HTTP referrer URI associated with the originatingURI. */ 11550 final Uri referrer; 11551 11552 /** UID of the application that the install request originated from. */ 11553 final int originatingUid; 11554 11555 /** UID of application requesting the install */ 11556 final int installerUid; 11557 11558 VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) { 11559 this.originatingUri = originatingUri; 11560 this.referrer = referrer; 11561 this.originatingUid = originatingUid; 11562 this.installerUid = installerUid; 11563 } 11564 } 11565 11566 class InstallParams extends HandlerParams { 11567 final OriginInfo origin; 11568 final MoveInfo move; 11569 final IPackageInstallObserver2 observer; 11570 int installFlags; 11571 final String installerPackageName; 11572 final String volumeUuid; 11573 private InstallArgs mArgs; 11574 private int mRet; 11575 final String packageAbiOverride; 11576 final String[] grantedRuntimePermissions; 11577 final VerificationInfo verificationInfo; 11578 11579 InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 11580 int installFlags, String installerPackageName, String volumeUuid, 11581 VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride, 11582 String[] grantedPermissions) { 11583 super(user); 11584 this.origin = origin; 11585 this.move = move; 11586 this.observer = observer; 11587 this.installFlags = installFlags; 11588 this.installerPackageName = installerPackageName; 11589 this.volumeUuid = volumeUuid; 11590 this.verificationInfo = verificationInfo; 11591 this.packageAbiOverride = packageAbiOverride; 11592 this.grantedRuntimePermissions = grantedPermissions; 11593 } 11594 11595 @Override 11596 public String toString() { 11597 return "InstallParams{" + Integer.toHexString(System.identityHashCode(this)) 11598 + " file=" + origin.file + " cid=" + origin.cid + "}"; 11599 } 11600 11601 private int installLocationPolicy(PackageInfoLite pkgLite) { 11602 String packageName = pkgLite.packageName; 11603 int installLocation = pkgLite.installLocation; 11604 boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 11605 // reader 11606 synchronized (mPackages) { 11607 // Currently installed package which the new package is attempting to replace or 11608 // null if no such package is installed. 11609 PackageParser.Package installedPkg = mPackages.get(packageName); 11610 // Package which currently owns the data which the new package will own if installed. 11611 // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg 11612 // will be null whereas dataOwnerPkg will contain information about the package 11613 // which was uninstalled while keeping its data. 11614 PackageParser.Package dataOwnerPkg = installedPkg; 11615 if (dataOwnerPkg == null) { 11616 PackageSetting ps = mSettings.mPackages.get(packageName); 11617 if (ps != null) { 11618 dataOwnerPkg = ps.pkg; 11619 } 11620 } 11621 11622 if (dataOwnerPkg != null) { 11623 // If installed, the package will get access to data left on the device by its 11624 // predecessor. As a security measure, this is permited only if this is not a 11625 // version downgrade or if the predecessor package is marked as debuggable and 11626 // a downgrade is explicitly requested. 11627 if (((dataOwnerPkg.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) 11628 || ((installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) == 0)) { 11629 try { 11630 checkDowngrade(dataOwnerPkg, pkgLite); 11631 } catch (PackageManagerException e) { 11632 Slog.w(TAG, "Downgrade detected: " + e.getMessage()); 11633 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE; 11634 } 11635 } 11636 } 11637 11638 if (installedPkg != null) { 11639 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 11640 // Check for updated system application. 11641 if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11642 if (onSd) { 11643 Slog.w(TAG, "Cannot install update to system app on sdcard"); 11644 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION; 11645 } 11646 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 11647 } else { 11648 if (onSd) { 11649 // Install flag overrides everything. 11650 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 11651 } 11652 // If current upgrade specifies particular preference 11653 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) { 11654 // Application explicitly specified internal. 11655 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 11656 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) { 11657 // App explictly prefers external. Let policy decide 11658 } else { 11659 // Prefer previous location 11660 if (isExternal(installedPkg)) { 11661 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 11662 } 11663 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 11664 } 11665 } 11666 } else { 11667 // Invalid install. Return error code 11668 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS; 11669 } 11670 } 11671 } 11672 // All the special cases have been taken care of. 11673 // Return result based on recommended install location. 11674 if (onSd) { 11675 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 11676 } 11677 return pkgLite.recommendedInstallLocation; 11678 } 11679 11680 /* 11681 * Invoke remote method to get package information and install 11682 * location values. Override install location based on default 11683 * policy if needed and then create install arguments based 11684 * on the install location. 11685 */ 11686 public void handleStartCopy() throws RemoteException { 11687 int ret = PackageManager.INSTALL_SUCCEEDED; 11688 11689 // If we're already staged, we've firmly committed to an install location 11690 if (origin.staged) { 11691 if (origin.file != null) { 11692 installFlags |= PackageManager.INSTALL_INTERNAL; 11693 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 11694 } else if (origin.cid != null) { 11695 installFlags |= PackageManager.INSTALL_EXTERNAL; 11696 installFlags &= ~PackageManager.INSTALL_INTERNAL; 11697 } else { 11698 throw new IllegalStateException("Invalid stage location"); 11699 } 11700 } 11701 11702 final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 11703 final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0; 11704 final boolean ephemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; 11705 PackageInfoLite pkgLite = null; 11706 11707 if (onInt && onSd) { 11708 // Check if both bits are set. 11709 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external"); 11710 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 11711 } else if (onSd && ephemeral) { 11712 Slog.w(TAG, "Conflicting flags specified for installing ephemeral on external"); 11713 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 11714 } else { 11715 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags, 11716 packageAbiOverride); 11717 11718 if (DEBUG_EPHEMERAL && ephemeral) { 11719 Slog.v(TAG, "pkgLite for install: " + pkgLite); 11720 } 11721 11722 /* 11723 * If we have too little free space, try to free cache 11724 * before giving up. 11725 */ 11726 if (!origin.staged && pkgLite.recommendedInstallLocation 11727 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 11728 // TODO: focus freeing disk space on the target device 11729 final StorageManager storage = StorageManager.from(mContext); 11730 final long lowThreshold = storage.getStorageLowBytes( 11731 Environment.getDataDirectory()); 11732 11733 final long sizeBytes = mContainerService.calculateInstalledSize( 11734 origin.resolvedPath, isForwardLocked(), packageAbiOverride); 11735 11736 try { 11737 mInstaller.freeCache(null, sizeBytes + lowThreshold); 11738 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, 11739 installFlags, packageAbiOverride); 11740 } catch (InstallerException e) { 11741 Slog.w(TAG, "Failed to free cache", e); 11742 } 11743 11744 /* 11745 * The cache free must have deleted the file we 11746 * downloaded to install. 11747 * 11748 * TODO: fix the "freeCache" call to not delete 11749 * the file we care about. 11750 */ 11751 if (pkgLite.recommendedInstallLocation 11752 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 11753 pkgLite.recommendedInstallLocation 11754 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE; 11755 } 11756 } 11757 } 11758 11759 if (ret == PackageManager.INSTALL_SUCCEEDED) { 11760 int loc = pkgLite.recommendedInstallLocation; 11761 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) { 11762 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 11763 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) { 11764 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 11765 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 11766 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 11767 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) { 11768 ret = PackageManager.INSTALL_FAILED_INVALID_APK; 11769 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 11770 ret = PackageManager.INSTALL_FAILED_INVALID_URI; 11771 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) { 11772 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE; 11773 } else { 11774 // Override with defaults if needed. 11775 loc = installLocationPolicy(pkgLite); 11776 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) { 11777 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 11778 } else if (!onSd && !onInt) { 11779 // Override install location with flags 11780 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) { 11781 // Set the flag to install on external media. 11782 installFlags |= PackageManager.INSTALL_EXTERNAL; 11783 installFlags &= ~PackageManager.INSTALL_INTERNAL; 11784 } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) { 11785 if (DEBUG_EPHEMERAL) { 11786 Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag"); 11787 } 11788 installFlags |= PackageManager.INSTALL_EPHEMERAL; 11789 installFlags &= ~(PackageManager.INSTALL_EXTERNAL 11790 |PackageManager.INSTALL_INTERNAL); 11791 } else { 11792 // Make sure the flag for installing on external 11793 // media is unset 11794 installFlags |= PackageManager.INSTALL_INTERNAL; 11795 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 11796 } 11797 } 11798 } 11799 } 11800 11801 final InstallArgs args = createInstallArgs(this); 11802 mArgs = args; 11803 11804 if (ret == PackageManager.INSTALL_SUCCEEDED) { 11805 // TODO: http://b/22976637 11806 // Apps installed for "all" users use the device owner to verify the app 11807 UserHandle verifierUser = getUser(); 11808 if (verifierUser == UserHandle.ALL) { 11809 verifierUser = UserHandle.SYSTEM; 11810 } 11811 11812 /* 11813 * Determine if we have any installed package verifiers. If we 11814 * do, then we'll defer to them to verify the packages. 11815 */ 11816 final int requiredUid = mRequiredVerifierPackage == null ? -1 11817 : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 11818 verifierUser.getIdentifier()); 11819 if (!origin.existing && requiredUid != -1 11820 && isVerificationEnabled(verifierUser.getIdentifier(), installFlags)) { 11821 final Intent verification = new Intent( 11822 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 11823 verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 11824 verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)), 11825 PACKAGE_MIME_TYPE); 11826 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 11827 11828 // Query all live verifiers based on current user state 11829 final List<ResolveInfo> receivers = queryIntentReceivers(verification, 11830 PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier()); 11831 11832 if (DEBUG_VERIFY) { 11833 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent " 11834 + verification.toString() + " with " + pkgLite.verifiers.length 11835 + " optional verifiers"); 11836 } 11837 11838 final int verificationId = mPendingVerificationToken++; 11839 11840 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 11841 11842 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE, 11843 installerPackageName); 11844 11845 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, 11846 installFlags); 11847 11848 verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME, 11849 pkgLite.packageName); 11850 11851 verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE, 11852 pkgLite.versionCode); 11853 11854 if (verificationInfo != null) { 11855 if (verificationInfo.originatingUri != null) { 11856 verification.putExtra(Intent.EXTRA_ORIGINATING_URI, 11857 verificationInfo.originatingUri); 11858 } 11859 if (verificationInfo.referrer != null) { 11860 verification.putExtra(Intent.EXTRA_REFERRER, 11861 verificationInfo.referrer); 11862 } 11863 if (verificationInfo.originatingUid >= 0) { 11864 verification.putExtra(Intent.EXTRA_ORIGINATING_UID, 11865 verificationInfo.originatingUid); 11866 } 11867 if (verificationInfo.installerUid >= 0) { 11868 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID, 11869 verificationInfo.installerUid); 11870 } 11871 } 11872 11873 final PackageVerificationState verificationState = new PackageVerificationState( 11874 requiredUid, args); 11875 11876 mPendingVerification.append(verificationId, verificationState); 11877 11878 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite, 11879 receivers, verificationState); 11880 11881 /* 11882 * If any sufficient verifiers were listed in the package 11883 * manifest, attempt to ask them. 11884 */ 11885 if (sufficientVerifiers != null) { 11886 final int N = sufficientVerifiers.size(); 11887 if (N == 0) { 11888 Slog.i(TAG, "Additional verifiers required, but none installed."); 11889 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 11890 } else { 11891 for (int i = 0; i < N; i++) { 11892 final ComponentName verifierComponent = sufficientVerifiers.get(i); 11893 11894 final Intent sufficientIntent = new Intent(verification); 11895 sufficientIntent.setComponent(verifierComponent); 11896 mContext.sendBroadcastAsUser(sufficientIntent, verifierUser); 11897 } 11898 } 11899 } 11900 11901 final ComponentName requiredVerifierComponent = matchComponentForVerifier( 11902 mRequiredVerifierPackage, receivers); 11903 if (ret == PackageManager.INSTALL_SUCCEEDED 11904 && mRequiredVerifierPackage != null) { 11905 Trace.asyncTraceBegin( 11906 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 11907 /* 11908 * Send the intent to the required verification agent, 11909 * but only start the verification timeout after the 11910 * target BroadcastReceivers have run. 11911 */ 11912 verification.setComponent(requiredVerifierComponent); 11913 mContext.sendOrderedBroadcastAsUser(verification, verifierUser, 11914 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 11915 new BroadcastReceiver() { 11916 @Override 11917 public void onReceive(Context context, Intent intent) { 11918 final Message msg = mHandler 11919 .obtainMessage(CHECK_PENDING_VERIFICATION); 11920 msg.arg1 = verificationId; 11921 mHandler.sendMessageDelayed(msg, getVerificationTimeout()); 11922 } 11923 }, null, 0, null, null); 11924 11925 /* 11926 * We don't want the copy to proceed until verification 11927 * succeeds, so null out this field. 11928 */ 11929 mArgs = null; 11930 } 11931 } else { 11932 /* 11933 * No package verification is enabled, so immediately start 11934 * the remote call to initiate copy using temporary file. 11935 */ 11936 ret = args.copyApk(mContainerService, true); 11937 } 11938 } 11939 11940 mRet = ret; 11941 } 11942 11943 @Override 11944 void handleReturnCode() { 11945 // If mArgs is null, then MCS couldn't be reached. When it 11946 // reconnects, it will try again to install. At that point, this 11947 // will succeed. 11948 if (mArgs != null) { 11949 processPendingInstall(mArgs, mRet); 11950 } 11951 } 11952 11953 @Override 11954 void handleServiceError() { 11955 mArgs = createInstallArgs(this); 11956 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 11957 } 11958 11959 public boolean isForwardLocked() { 11960 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 11961 } 11962 } 11963 11964 /** 11965 * Used during creation of InstallArgs 11966 * 11967 * @param installFlags package installation flags 11968 * @return true if should be installed on external storage 11969 */ 11970 private static boolean installOnExternalAsec(int installFlags) { 11971 if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) { 11972 return false; 11973 } 11974 if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) { 11975 return true; 11976 } 11977 return false; 11978 } 11979 11980 /** 11981 * Used during creation of InstallArgs 11982 * 11983 * @param installFlags package installation flags 11984 * @return true if should be installed as forward locked 11985 */ 11986 private static boolean installForwardLocked(int installFlags) { 11987 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 11988 } 11989 11990 private InstallArgs createInstallArgs(InstallParams params) { 11991 if (params.move != null) { 11992 return new MoveInstallArgs(params); 11993 } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) { 11994 return new AsecInstallArgs(params); 11995 } else { 11996 return new FileInstallArgs(params); 11997 } 11998 } 11999 12000 /** 12001 * Create args that describe an existing installed package. Typically used 12002 * when cleaning up old installs, or used as a move source. 12003 */ 12004 private InstallArgs createInstallArgsForExisting(int installFlags, String codePath, 12005 String resourcePath, String[] instructionSets) { 12006 final boolean isInAsec; 12007 if (installOnExternalAsec(installFlags)) { 12008 /* Apps on SD card are always in ASEC containers. */ 12009 isInAsec = true; 12010 } else if (installForwardLocked(installFlags) 12011 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) { 12012 /* 12013 * Forward-locked apps are only in ASEC containers if they're the 12014 * new style 12015 */ 12016 isInAsec = true; 12017 } else { 12018 isInAsec = false; 12019 } 12020 12021 if (isInAsec) { 12022 return new AsecInstallArgs(codePath, instructionSets, 12023 installOnExternalAsec(installFlags), installForwardLocked(installFlags)); 12024 } else { 12025 return new FileInstallArgs(codePath, resourcePath, instructionSets); 12026 } 12027 } 12028 12029 static abstract class InstallArgs { 12030 /** @see InstallParams#origin */ 12031 final OriginInfo origin; 12032 /** @see InstallParams#move */ 12033 final MoveInfo move; 12034 12035 final IPackageInstallObserver2 observer; 12036 // Always refers to PackageManager flags only 12037 final int installFlags; 12038 final String installerPackageName; 12039 final String volumeUuid; 12040 final UserHandle user; 12041 final String abiOverride; 12042 final String[] installGrantPermissions; 12043 /** If non-null, drop an async trace when the install completes */ 12044 final String traceMethod; 12045 final int traceCookie; 12046 12047 // The list of instruction sets supported by this app. This is currently 12048 // only used during the rmdex() phase to clean up resources. We can get rid of this 12049 // if we move dex files under the common app path. 12050 /* nullable */ String[] instructionSets; 12051 12052 InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 12053 int installFlags, String installerPackageName, String volumeUuid, 12054 UserHandle user, String[] instructionSets, 12055 String abiOverride, String[] installGrantPermissions, 12056 String traceMethod, int traceCookie) { 12057 this.origin = origin; 12058 this.move = move; 12059 this.installFlags = installFlags; 12060 this.observer = observer; 12061 this.installerPackageName = installerPackageName; 12062 this.volumeUuid = volumeUuid; 12063 this.user = user; 12064 this.instructionSets = instructionSets; 12065 this.abiOverride = abiOverride; 12066 this.installGrantPermissions = installGrantPermissions; 12067 this.traceMethod = traceMethod; 12068 this.traceCookie = traceCookie; 12069 } 12070 12071 abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException; 12072 abstract int doPreInstall(int status); 12073 12074 /** 12075 * Rename package into final resting place. All paths on the given 12076 * scanned package should be updated to reflect the rename. 12077 */ 12078 abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath); 12079 abstract int doPostInstall(int status, int uid); 12080 12081 /** @see PackageSettingBase#codePathString */ 12082 abstract String getCodePath(); 12083 /** @see PackageSettingBase#resourcePathString */ 12084 abstract String getResourcePath(); 12085 12086 // Need installer lock especially for dex file removal. 12087 abstract void cleanUpResourcesLI(); 12088 abstract boolean doPostDeleteLI(boolean delete); 12089 12090 /** 12091 * Called before the source arguments are copied. This is used mostly 12092 * for MoveParams when it needs to read the source file to put it in the 12093 * destination. 12094 */ 12095 int doPreCopy() { 12096 return PackageManager.INSTALL_SUCCEEDED; 12097 } 12098 12099 /** 12100 * Called after the source arguments are copied. This is used mostly for 12101 * MoveParams when it needs to read the source file to put it in the 12102 * destination. 12103 * 12104 * @return 12105 */ 12106 int doPostCopy(int uid) { 12107 return PackageManager.INSTALL_SUCCEEDED; 12108 } 12109 12110 protected boolean isFwdLocked() { 12111 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 12112 } 12113 12114 protected boolean isExternalAsec() { 12115 return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 12116 } 12117 12118 protected boolean isEphemeral() { 12119 return (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; 12120 } 12121 12122 UserHandle getUser() { 12123 return user; 12124 } 12125 } 12126 12127 private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) { 12128 if (!allCodePaths.isEmpty()) { 12129 if (instructionSets == null) { 12130 throw new IllegalStateException("instructionSet == null"); 12131 } 12132 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); 12133 for (String codePath : allCodePaths) { 12134 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 12135 try { 12136 mInstaller.rmdex(codePath, dexCodeInstructionSet); 12137 } catch (InstallerException ignored) { 12138 } 12139 } 12140 } 12141 } 12142 } 12143 12144 /** 12145 * Logic to handle installation of non-ASEC applications, including copying 12146 * and renaming logic. 12147 */ 12148 class FileInstallArgs extends InstallArgs { 12149 private File codeFile; 12150 private File resourceFile; 12151 12152 // Example topology: 12153 // /data/app/com.example/base.apk 12154 // /data/app/com.example/split_foo.apk 12155 // /data/app/com.example/lib/arm/libfoo.so 12156 // /data/app/com.example/lib/arm64/libfoo.so 12157 // /data/app/com.example/dalvik/arm/base.apk@classes.dex 12158 12159 /** New install */ 12160 FileInstallArgs(InstallParams params) { 12161 super(params.origin, params.move, params.observer, params.installFlags, 12162 params.installerPackageName, params.volumeUuid, 12163 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 12164 params.grantedRuntimePermissions, 12165 params.traceMethod, params.traceCookie); 12166 if (isFwdLocked()) { 12167 throw new IllegalArgumentException("Forward locking only supported in ASEC"); 12168 } 12169 } 12170 12171 /** Existing install */ 12172 FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) { 12173 super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets, 12174 null, null, null, 0); 12175 this.codeFile = (codePath != null) ? new File(codePath) : null; 12176 this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null; 12177 } 12178 12179 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 12180 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk"); 12181 try { 12182 return doCopyApk(imcs, temp); 12183 } finally { 12184 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 12185 } 12186 } 12187 12188 private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 12189 if (origin.staged) { 12190 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy"); 12191 codeFile = origin.file; 12192 resourceFile = origin.file; 12193 return PackageManager.INSTALL_SUCCEEDED; 12194 } 12195 12196 try { 12197 final boolean isEphemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; 12198 final File tempDir = 12199 mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral); 12200 codeFile = tempDir; 12201 resourceFile = tempDir; 12202 } catch (IOException e) { 12203 Slog.w(TAG, "Failed to create copy file: " + e); 12204 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 12205 } 12206 12207 final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() { 12208 @Override 12209 public ParcelFileDescriptor open(String name, int mode) throws RemoteException { 12210 if (!FileUtils.isValidExtFilename(name)) { 12211 throw new IllegalArgumentException("Invalid filename: " + name); 12212 } 12213 try { 12214 final File file = new File(codeFile, name); 12215 final FileDescriptor fd = Os.open(file.getAbsolutePath(), 12216 O_RDWR | O_CREAT, 0644); 12217 Os.chmod(file.getAbsolutePath(), 0644); 12218 return new ParcelFileDescriptor(fd); 12219 } catch (ErrnoException e) { 12220 throw new RemoteException("Failed to open: " + e.getMessage()); 12221 } 12222 } 12223 }; 12224 12225 int ret = PackageManager.INSTALL_SUCCEEDED; 12226 ret = imcs.copyPackage(origin.file.getAbsolutePath(), target); 12227 if (ret != PackageManager.INSTALL_SUCCEEDED) { 12228 Slog.e(TAG, "Failed to copy package"); 12229 return ret; 12230 } 12231 12232 final File libraryRoot = new File(codeFile, LIB_DIR_NAME); 12233 NativeLibraryHelper.Handle handle = null; 12234 try { 12235 handle = NativeLibraryHelper.Handle.create(codeFile); 12236 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot, 12237 abiOverride); 12238 } catch (IOException e) { 12239 Slog.e(TAG, "Copying native libraries failed", e); 12240 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 12241 } finally { 12242 IoUtils.closeQuietly(handle); 12243 } 12244 12245 return ret; 12246 } 12247 12248 int doPreInstall(int status) { 12249 if (status != PackageManager.INSTALL_SUCCEEDED) { 12250 cleanUp(); 12251 } 12252 return status; 12253 } 12254 12255 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 12256 if (status != PackageManager.INSTALL_SUCCEEDED) { 12257 cleanUp(); 12258 return false; 12259 } 12260 12261 final File targetDir = codeFile.getParentFile(); 12262 final File beforeCodeFile = codeFile; 12263 final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName); 12264 12265 if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile); 12266 try { 12267 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath()); 12268 } catch (ErrnoException e) { 12269 Slog.w(TAG, "Failed to rename", e); 12270 return false; 12271 } 12272 12273 if (!SELinux.restoreconRecursive(afterCodeFile)) { 12274 Slog.w(TAG, "Failed to restorecon"); 12275 return false; 12276 } 12277 12278 // Reflect the rename internally 12279 codeFile = afterCodeFile; 12280 resourceFile = afterCodeFile; 12281 12282 // Reflect the rename in scanned details 12283 pkg.setCodePath(afterCodeFile.getAbsolutePath()); 12284 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile, 12285 afterCodeFile, pkg.baseCodePath)); 12286 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile, 12287 afterCodeFile, pkg.splitCodePaths)); 12288 12289 // Reflect the rename in app info 12290 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 12291 pkg.setApplicationInfoCodePath(pkg.codePath); 12292 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 12293 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 12294 pkg.setApplicationInfoResourcePath(pkg.codePath); 12295 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 12296 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 12297 12298 return true; 12299 } 12300 12301 int doPostInstall(int status, int uid) { 12302 if (status != PackageManager.INSTALL_SUCCEEDED) { 12303 cleanUp(); 12304 } 12305 return status; 12306 } 12307 12308 @Override 12309 String getCodePath() { 12310 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 12311 } 12312 12313 @Override 12314 String getResourcePath() { 12315 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 12316 } 12317 12318 private boolean cleanUp() { 12319 if (codeFile == null || !codeFile.exists()) { 12320 return false; 12321 } 12322 12323 removeCodePathLI(codeFile); 12324 12325 if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) { 12326 resourceFile.delete(); 12327 } 12328 12329 return true; 12330 } 12331 12332 void cleanUpResourcesLI() { 12333 // Try enumerating all code paths before deleting 12334 List<String> allCodePaths = Collections.EMPTY_LIST; 12335 if (codeFile != null && codeFile.exists()) { 12336 try { 12337 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 12338 allCodePaths = pkg.getAllCodePaths(); 12339 } catch (PackageParserException e) { 12340 // Ignored; we tried our best 12341 } 12342 } 12343 12344 cleanUp(); 12345 removeDexFiles(allCodePaths, instructionSets); 12346 } 12347 12348 boolean doPostDeleteLI(boolean delete) { 12349 // XXX err, shouldn't we respect the delete flag? 12350 cleanUpResourcesLI(); 12351 return true; 12352 } 12353 } 12354 12355 private boolean isAsecExternal(String cid) { 12356 final String asecPath = PackageHelper.getSdFilesystem(cid); 12357 return !asecPath.startsWith(mAsecInternalPath); 12358 } 12359 12360 private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws 12361 PackageManagerException { 12362 if (copyRet < 0) { 12363 if (copyRet != PackageManager.NO_NATIVE_LIBRARIES && 12364 copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) { 12365 throw new PackageManagerException(copyRet, message); 12366 } 12367 } 12368 } 12369 12370 /** 12371 * Extract the MountService "container ID" from the full code path of an 12372 * .apk. 12373 */ 12374 static String cidFromCodePath(String fullCodePath) { 12375 int eidx = fullCodePath.lastIndexOf("/"); 12376 String subStr1 = fullCodePath.substring(0, eidx); 12377 int sidx = subStr1.lastIndexOf("/"); 12378 return subStr1.substring(sidx+1, eidx); 12379 } 12380 12381 /** 12382 * Logic to handle installation of ASEC applications, including copying and 12383 * renaming logic. 12384 */ 12385 class AsecInstallArgs extends InstallArgs { 12386 static final String RES_FILE_NAME = "pkg.apk"; 12387 static final String PUBLIC_RES_FILE_NAME = "res.zip"; 12388 12389 String cid; 12390 String packagePath; 12391 String resourcePath; 12392 12393 /** New install */ 12394 AsecInstallArgs(InstallParams params) { 12395 super(params.origin, params.move, params.observer, params.installFlags, 12396 params.installerPackageName, params.volumeUuid, 12397 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 12398 params.grantedRuntimePermissions, 12399 params.traceMethod, params.traceCookie); 12400 } 12401 12402 /** Existing install */ 12403 AsecInstallArgs(String fullCodePath, String[] instructionSets, 12404 boolean isExternal, boolean isForwardLocked) { 12405 super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0) 12406 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, 12407 instructionSets, null, null, null, 0); 12408 // Hackily pretend we're still looking at a full code path 12409 if (!fullCodePath.endsWith(RES_FILE_NAME)) { 12410 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath(); 12411 } 12412 12413 // Extract cid from fullCodePath 12414 int eidx = fullCodePath.lastIndexOf("/"); 12415 String subStr1 = fullCodePath.substring(0, eidx); 12416 int sidx = subStr1.lastIndexOf("/"); 12417 cid = subStr1.substring(sidx+1, eidx); 12418 setMountPath(subStr1); 12419 } 12420 12421 AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) { 12422 super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0) 12423 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, 12424 instructionSets, null, null, null, 0); 12425 this.cid = cid; 12426 setMountPath(PackageHelper.getSdDir(cid)); 12427 } 12428 12429 void createCopyFile() { 12430 cid = mInstallerService.allocateExternalStageCidLegacy(); 12431 } 12432 12433 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 12434 if (origin.staged && origin.cid != null) { 12435 if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy"); 12436 cid = origin.cid; 12437 setMountPath(PackageHelper.getSdDir(cid)); 12438 return PackageManager.INSTALL_SUCCEEDED; 12439 } 12440 12441 if (temp) { 12442 createCopyFile(); 12443 } else { 12444 /* 12445 * Pre-emptively destroy the container since it's destroyed if 12446 * copying fails due to it existing anyway. 12447 */ 12448 PackageHelper.destroySdDir(cid); 12449 } 12450 12451 final String newMountPath = imcs.copyPackageToContainer( 12452 origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(), 12453 isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */)); 12454 12455 if (newMountPath != null) { 12456 setMountPath(newMountPath); 12457 return PackageManager.INSTALL_SUCCEEDED; 12458 } else { 12459 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 12460 } 12461 } 12462 12463 @Override 12464 String getCodePath() { 12465 return packagePath; 12466 } 12467 12468 @Override 12469 String getResourcePath() { 12470 return resourcePath; 12471 } 12472 12473 int doPreInstall(int status) { 12474 if (status != PackageManager.INSTALL_SUCCEEDED) { 12475 // Destroy container 12476 PackageHelper.destroySdDir(cid); 12477 } else { 12478 boolean mounted = PackageHelper.isContainerMounted(cid); 12479 if (!mounted) { 12480 String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(), 12481 Process.SYSTEM_UID); 12482 if (newMountPath != null) { 12483 setMountPath(newMountPath); 12484 } else { 12485 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 12486 } 12487 } 12488 } 12489 return status; 12490 } 12491 12492 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 12493 String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME); 12494 String newMountPath = null; 12495 if (PackageHelper.isContainerMounted(cid)) { 12496 // Unmount the container 12497 if (!PackageHelper.unMountSdDir(cid)) { 12498 Slog.i(TAG, "Failed to unmount " + cid + " before renaming"); 12499 return false; 12500 } 12501 } 12502 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 12503 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId + 12504 " which might be stale. Will try to clean up."); 12505 // Clean up the stale container and proceed to recreate. 12506 if (!PackageHelper.destroySdDir(newCacheId)) { 12507 Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId); 12508 return false; 12509 } 12510 // Successfully cleaned up stale container. Try to rename again. 12511 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 12512 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId 12513 + " inspite of cleaning it up."); 12514 return false; 12515 } 12516 } 12517 if (!PackageHelper.isContainerMounted(newCacheId)) { 12518 Slog.w(TAG, "Mounting container " + newCacheId); 12519 newMountPath = PackageHelper.mountSdDir(newCacheId, 12520 getEncryptKey(), Process.SYSTEM_UID); 12521 } else { 12522 newMountPath = PackageHelper.getSdDir(newCacheId); 12523 } 12524 if (newMountPath == null) { 12525 Slog.w(TAG, "Failed to get cache path for " + newCacheId); 12526 return false; 12527 } 12528 Log.i(TAG, "Succesfully renamed " + cid + 12529 " to " + newCacheId + 12530 " at new path: " + newMountPath); 12531 cid = newCacheId; 12532 12533 final File beforeCodeFile = new File(packagePath); 12534 setMountPath(newMountPath); 12535 final File afterCodeFile = new File(packagePath); 12536 12537 // Reflect the rename in scanned details 12538 pkg.setCodePath(afterCodeFile.getAbsolutePath()); 12539 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile, 12540 afterCodeFile, pkg.baseCodePath)); 12541 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile, 12542 afterCodeFile, pkg.splitCodePaths)); 12543 12544 // Reflect the rename in app info 12545 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 12546 pkg.setApplicationInfoCodePath(pkg.codePath); 12547 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 12548 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 12549 pkg.setApplicationInfoResourcePath(pkg.codePath); 12550 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 12551 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 12552 12553 return true; 12554 } 12555 12556 private void setMountPath(String mountPath) { 12557 final File mountFile = new File(mountPath); 12558 12559 final File monolithicFile = new File(mountFile, RES_FILE_NAME); 12560 if (monolithicFile.exists()) { 12561 packagePath = monolithicFile.getAbsolutePath(); 12562 if (isFwdLocked()) { 12563 resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath(); 12564 } else { 12565 resourcePath = packagePath; 12566 } 12567 } else { 12568 packagePath = mountFile.getAbsolutePath(); 12569 resourcePath = packagePath; 12570 } 12571 } 12572 12573 int doPostInstall(int status, int uid) { 12574 if (status != PackageManager.INSTALL_SUCCEEDED) { 12575 cleanUp(); 12576 } else { 12577 final int groupOwner; 12578 final String protectedFile; 12579 if (isFwdLocked()) { 12580 groupOwner = UserHandle.getSharedAppGid(uid); 12581 protectedFile = RES_FILE_NAME; 12582 } else { 12583 groupOwner = -1; 12584 protectedFile = null; 12585 } 12586 12587 if (uid < Process.FIRST_APPLICATION_UID 12588 || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) { 12589 Slog.e(TAG, "Failed to finalize " + cid); 12590 PackageHelper.destroySdDir(cid); 12591 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 12592 } 12593 12594 boolean mounted = PackageHelper.isContainerMounted(cid); 12595 if (!mounted) { 12596 PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid()); 12597 } 12598 } 12599 return status; 12600 } 12601 12602 private void cleanUp() { 12603 if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp"); 12604 12605 // Destroy secure container 12606 PackageHelper.destroySdDir(cid); 12607 } 12608 12609 private List<String> getAllCodePaths() { 12610 final File codeFile = new File(getCodePath()); 12611 if (codeFile != null && codeFile.exists()) { 12612 try { 12613 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 12614 return pkg.getAllCodePaths(); 12615 } catch (PackageParserException e) { 12616 // Ignored; we tried our best 12617 } 12618 } 12619 return Collections.EMPTY_LIST; 12620 } 12621 12622 void cleanUpResourcesLI() { 12623 // Enumerate all code paths before deleting 12624 cleanUpResourcesLI(getAllCodePaths()); 12625 } 12626 12627 private void cleanUpResourcesLI(List<String> allCodePaths) { 12628 cleanUp(); 12629 removeDexFiles(allCodePaths, instructionSets); 12630 } 12631 12632 String getPackageName() { 12633 return getAsecPackageName(cid); 12634 } 12635 12636 boolean doPostDeleteLI(boolean delete) { 12637 if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete); 12638 final List<String> allCodePaths = getAllCodePaths(); 12639 boolean mounted = PackageHelper.isContainerMounted(cid); 12640 if (mounted) { 12641 // Unmount first 12642 if (PackageHelper.unMountSdDir(cid)) { 12643 mounted = false; 12644 } 12645 } 12646 if (!mounted && delete) { 12647 cleanUpResourcesLI(allCodePaths); 12648 } 12649 return !mounted; 12650 } 12651 12652 @Override 12653 int doPreCopy() { 12654 if (isFwdLocked()) { 12655 if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE, 12656 MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) { 12657 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 12658 } 12659 } 12660 12661 return PackageManager.INSTALL_SUCCEEDED; 12662 } 12663 12664 @Override 12665 int doPostCopy(int uid) { 12666 if (isFwdLocked()) { 12667 if (uid < Process.FIRST_APPLICATION_UID 12668 || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid), 12669 RES_FILE_NAME)) { 12670 Slog.e(TAG, "Failed to finalize " + cid); 12671 PackageHelper.destroySdDir(cid); 12672 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 12673 } 12674 } 12675 12676 return PackageManager.INSTALL_SUCCEEDED; 12677 } 12678 } 12679 12680 /** 12681 * Logic to handle movement of existing installed applications. 12682 */ 12683 class MoveInstallArgs extends InstallArgs { 12684 private File codeFile; 12685 private File resourceFile; 12686 12687 /** New install */ 12688 MoveInstallArgs(InstallParams params) { 12689 super(params.origin, params.move, params.observer, params.installFlags, 12690 params.installerPackageName, params.volumeUuid, 12691 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 12692 params.grantedRuntimePermissions, 12693 params.traceMethod, params.traceCookie); 12694 } 12695 12696 int copyApk(IMediaContainerService imcs, boolean temp) { 12697 if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from " 12698 + move.fromUuid + " to " + move.toUuid); 12699 synchronized (mInstaller) { 12700 try { 12701 mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName, 12702 move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion); 12703 } catch (InstallerException e) { 12704 Slog.w(TAG, "Failed to move app", e); 12705 return PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 12706 } 12707 } 12708 12709 codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName); 12710 resourceFile = codeFile; 12711 if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile); 12712 12713 return PackageManager.INSTALL_SUCCEEDED; 12714 } 12715 12716 int doPreInstall(int status) { 12717 if (status != PackageManager.INSTALL_SUCCEEDED) { 12718 cleanUp(move.toUuid); 12719 } 12720 return status; 12721 } 12722 12723 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 12724 if (status != PackageManager.INSTALL_SUCCEEDED) { 12725 cleanUp(move.toUuid); 12726 return false; 12727 } 12728 12729 // Reflect the move in app info 12730 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 12731 pkg.setApplicationInfoCodePath(pkg.codePath); 12732 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 12733 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 12734 pkg.setApplicationInfoResourcePath(pkg.codePath); 12735 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 12736 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 12737 12738 return true; 12739 } 12740 12741 int doPostInstall(int status, int uid) { 12742 if (status == PackageManager.INSTALL_SUCCEEDED) { 12743 cleanUp(move.fromUuid); 12744 } else { 12745 cleanUp(move.toUuid); 12746 } 12747 return status; 12748 } 12749 12750 @Override 12751 String getCodePath() { 12752 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 12753 } 12754 12755 @Override 12756 String getResourcePath() { 12757 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 12758 } 12759 12760 private boolean cleanUp(String volumeUuid) { 12761 final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid), 12762 move.dataAppName); 12763 Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid); 12764 synchronized (mInstallLock) { 12765 // Clean up both app data and code 12766 removeDataDirsLI(volumeUuid, move.packageName); 12767 removeCodePathLI(codeFile); 12768 } 12769 return true; 12770 } 12771 12772 void cleanUpResourcesLI() { 12773 throw new UnsupportedOperationException(); 12774 } 12775 12776 boolean doPostDeleteLI(boolean delete) { 12777 throw new UnsupportedOperationException(); 12778 } 12779 } 12780 12781 static String getAsecPackageName(String packageCid) { 12782 int idx = packageCid.lastIndexOf("-"); 12783 if (idx == -1) { 12784 return packageCid; 12785 } 12786 return packageCid.substring(0, idx); 12787 } 12788 12789 // Utility method used to create code paths based on package name and available index. 12790 private static String getNextCodePath(String oldCodePath, String prefix, String suffix) { 12791 String idxStr = ""; 12792 int idx = 1; 12793 // Fall back to default value of idx=1 if prefix is not 12794 // part of oldCodePath 12795 if (oldCodePath != null) { 12796 String subStr = oldCodePath; 12797 // Drop the suffix right away 12798 if (suffix != null && subStr.endsWith(suffix)) { 12799 subStr = subStr.substring(0, subStr.length() - suffix.length()); 12800 } 12801 // If oldCodePath already contains prefix find out the 12802 // ending index to either increment or decrement. 12803 int sidx = subStr.lastIndexOf(prefix); 12804 if (sidx != -1) { 12805 subStr = subStr.substring(sidx + prefix.length()); 12806 if (subStr != null) { 12807 if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) { 12808 subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length()); 12809 } 12810 try { 12811 idx = Integer.parseInt(subStr); 12812 if (idx <= 1) { 12813 idx++; 12814 } else { 12815 idx--; 12816 } 12817 } catch(NumberFormatException e) { 12818 } 12819 } 12820 } 12821 } 12822 idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx); 12823 return prefix + idxStr; 12824 } 12825 12826 private File getNextCodePath(File targetDir, String packageName) { 12827 int suffix = 1; 12828 File result; 12829 do { 12830 result = new File(targetDir, packageName + "-" + suffix); 12831 suffix++; 12832 } while (result.exists()); 12833 return result; 12834 } 12835 12836 // Utility method that returns the relative package path with respect 12837 // to the installation directory. Like say for /data/data/com.test-1.apk 12838 // string com.test-1 is returned. 12839 static String deriveCodePathName(String codePath) { 12840 if (codePath == null) { 12841 return null; 12842 } 12843 final File codeFile = new File(codePath); 12844 final String name = codeFile.getName(); 12845 if (codeFile.isDirectory()) { 12846 return name; 12847 } else if (name.endsWith(".apk") || name.endsWith(".tmp")) { 12848 final int lastDot = name.lastIndexOf('.'); 12849 return name.substring(0, lastDot); 12850 } else { 12851 Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK"); 12852 return null; 12853 } 12854 } 12855 12856 static class PackageInstalledInfo { 12857 String name; 12858 int uid; 12859 // The set of users that originally had this package installed. 12860 int[] origUsers; 12861 // The set of users that now have this package installed. 12862 int[] newUsers; 12863 PackageParser.Package pkg; 12864 int returnCode; 12865 String returnMsg; 12866 PackageRemovedInfo removedInfo; 12867 ArrayMap<String, PackageInstalledInfo> addedChildPackages; 12868 12869 public void setError(int code, String msg) { 12870 setReturnCode(code); 12871 setReturnMessage(msg); 12872 Slog.w(TAG, msg); 12873 } 12874 12875 public void setError(String msg, PackageParserException e) { 12876 setReturnCode(e.error); 12877 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e)); 12878 Slog.w(TAG, msg, e); 12879 } 12880 12881 public void setError(String msg, PackageManagerException e) { 12882 returnCode = e.error; 12883 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e)); 12884 Slog.w(TAG, msg, e); 12885 } 12886 12887 public void setReturnCode(int returnCode) { 12888 this.returnCode = returnCode; 12889 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0; 12890 for (int i = 0; i < childCount; i++) { 12891 addedChildPackages.valueAt(i).returnCode = returnCode; 12892 } 12893 } 12894 12895 private void setReturnMessage(String returnMsg) { 12896 this.returnMsg = returnMsg; 12897 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0; 12898 for (int i = 0; i < childCount; i++) { 12899 addedChildPackages.valueAt(i).returnMsg = returnMsg; 12900 } 12901 } 12902 12903 // In some error cases we want to convey more info back to the observer 12904 String origPackage; 12905 String origPermission; 12906 } 12907 12908 /* 12909 * Install a non-existing package. 12910 */ 12911 private void installNewPackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, 12912 UserHandle user, String installerPackageName, String volumeUuid, 12913 PackageInstalledInfo res) { 12914 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage"); 12915 12916 // Remember this for later, in case we need to rollback this install 12917 String pkgName = pkg.packageName; 12918 12919 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg); 12920 12921 synchronized(mPackages) { 12922 if (mSettings.mRenamedPackages.containsKey(pkgName)) { 12923 // A package with the same name is already installed, though 12924 // it has been renamed to an older name. The package we 12925 // are trying to install should be installed as an update to 12926 // the existing one, but that has not been requested, so bail. 12927 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 12928 + " without first uninstalling package running as " 12929 + mSettings.mRenamedPackages.get(pkgName)); 12930 return; 12931 } 12932 if (mPackages.containsKey(pkgName)) { 12933 // Don't allow installation over an existing package with the same name. 12934 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 12935 + " without first uninstalling."); 12936 return; 12937 } 12938 } 12939 12940 try { 12941 PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags, 12942 System.currentTimeMillis(), user); 12943 12944 updateSettingsLI(newPackage, installerPackageName, null, res, user); 12945 12946 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 12947 prepareAppDataAfterInstall(newPackage); 12948 12949 } else { 12950 // Remove package from internal structures, but keep around any 12951 // data that might have already existed 12952 deletePackageLI(pkgName, UserHandle.ALL, false, null, 12953 PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null); 12954 } 12955 } catch (PackageManagerException e) { 12956 res.setError("Package couldn't be installed in " + pkg.codePath, e); 12957 } 12958 12959 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 12960 } 12961 12962 private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) { 12963 // Can't rotate keys during boot or if sharedUser. 12964 if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null 12965 || !oldPs.keySetData.isUsingUpgradeKeySets()) { 12966 return false; 12967 } 12968 // app is using upgradeKeySets; make sure all are valid 12969 KeySetManagerService ksms = mSettings.mKeySetManagerService; 12970 long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets(); 12971 for (int i = 0; i < upgradeKeySets.length; i++) { 12972 if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) { 12973 Slog.wtf(TAG, "Package " 12974 + (oldPs.name != null ? oldPs.name : "<null>") 12975 + " contains upgrade-key-set reference to unknown key-set: " 12976 + upgradeKeySets[i] 12977 + " reverting to signatures check."); 12978 return false; 12979 } 12980 } 12981 return true; 12982 } 12983 12984 private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) { 12985 // Upgrade keysets are being used. Determine if new package has a superset of the 12986 // required keys. 12987 long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets(); 12988 KeySetManagerService ksms = mSettings.mKeySetManagerService; 12989 for (int i = 0; i < upgradeKeySets.length; i++) { 12990 Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]); 12991 if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) { 12992 return true; 12993 } 12994 } 12995 return false; 12996 } 12997 12998 private void replacePackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, 12999 UserHandle user, String installerPackageName, PackageInstalledInfo res) { 13000 final boolean isEphemeral = (parseFlags & PackageParser.PARSE_IS_EPHEMERAL) != 0; 13001 13002 final PackageParser.Package oldPackage; 13003 final String pkgName = pkg.packageName; 13004 final int[] allUsers; 13005 13006 // First find the old package info and check signatures 13007 synchronized(mPackages) { 13008 oldPackage = mPackages.get(pkgName); 13009 final boolean oldIsEphemeral = oldPackage.applicationInfo.isEphemeralApp(); 13010 if (isEphemeral && !oldIsEphemeral) { 13011 // can't downgrade from full to ephemeral 13012 Slog.w(TAG, "Can't replace app with ephemeral: " + pkgName); 13013 res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID); 13014 return; 13015 } 13016 if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage); 13017 final PackageSetting ps = mSettings.mPackages.get(pkgName); 13018 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { 13019 if (!checkUpgradeKeySetLP(ps, pkg)) { 13020 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 13021 "New package not signed by keys specified by upgrade-keysets: " 13022 + pkgName); 13023 return; 13024 } 13025 } else { 13026 // default to original signature matching 13027 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures) 13028 != PackageManager.SIGNATURE_MATCH) { 13029 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 13030 "New package has a different signature: " + pkgName); 13031 return; 13032 } 13033 } 13034 13035 // In case of rollback, remember per-user/profile install state 13036 allUsers = sUserManager.getUserIds(); 13037 } 13038 13039 // Update what is removed 13040 res.removedInfo = new PackageRemovedInfo(); 13041 res.removedInfo.uid = oldPackage.applicationInfo.uid; 13042 res.removedInfo.removedPackage = oldPackage.packageName; 13043 res.removedInfo.isUpdate = true; 13044 final int childCount = (oldPackage.childPackages != null) 13045 ? oldPackage.childPackages.size() : 0; 13046 for (int i = 0; i < childCount; i++) { 13047 boolean childPackageUpdated = false; 13048 PackageParser.Package childPkg = oldPackage.childPackages.get(i); 13049 if (res.addedChildPackages != null) { 13050 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName); 13051 if (childRes != null) { 13052 childRes.removedInfo.uid = childPkg.applicationInfo.uid; 13053 childRes.removedInfo.removedPackage = childPkg.packageName; 13054 childRes.removedInfo.isUpdate = true; 13055 childPackageUpdated = true; 13056 } 13057 } 13058 if (!childPackageUpdated) { 13059 PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(); 13060 childRemovedRes.removedPackage = childPkg.packageName; 13061 childRemovedRes.isUpdate = false; 13062 childRemovedRes.dataRemoved = true; 13063 synchronized (mPackages) { 13064 PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName); 13065 if (childPs != null) { 13066 childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true); 13067 } 13068 } 13069 if (res.removedInfo.removedChildPackages == null) { 13070 res.removedInfo.removedChildPackages = new ArrayMap<>(); 13071 } 13072 res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes); 13073 } 13074 } 13075 13076 boolean sysPkg = (isSystemApp(oldPackage)); 13077 if (sysPkg) { 13078 replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags, 13079 user, allUsers, installerPackageName, res); 13080 } else { 13081 replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags, 13082 user, allUsers, installerPackageName, res); 13083 } 13084 } 13085 13086 public List<String> getPreviousCodePaths(String packageName) { 13087 final PackageSetting ps = mSettings.mPackages.get(packageName); 13088 final List<String> result = new ArrayList<String>(); 13089 if (ps != null && ps.oldCodePaths != null) { 13090 result.addAll(ps.oldCodePaths); 13091 } 13092 return result; 13093 } 13094 13095 private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage, 13096 PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, 13097 int[] allUsers, String installerPackageName, PackageInstalledInfo res) { 13098 if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old=" 13099 + deletedPackage); 13100 13101 String pkgName = deletedPackage.packageName; 13102 boolean deletedPkg = true; 13103 boolean addedPkg = false; 13104 boolean updatedSettings = false; 13105 final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0; 13106 final int deleteFlags = PackageManager.DELETE_KEEP_DATA 13107 | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP); 13108 13109 final long origUpdateTime = (pkg.mExtras != null) 13110 ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0; 13111 13112 // First delete the existing package while retaining the data directory 13113 if (!deletePackageLI(pkgName, null, true, allUsers, deleteFlags, 13114 res.removedInfo, true, pkg)) { 13115 // If the existing package wasn't successfully deleted 13116 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI"); 13117 deletedPkg = false; 13118 } else { 13119 // Successfully deleted the old package; proceed with replace. 13120 13121 // If deleted package lived in a container, give users a chance to 13122 // relinquish resources before killing. 13123 if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) { 13124 if (DEBUG_INSTALL) { 13125 Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE"); 13126 } 13127 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid }; 13128 final ArrayList<String> pkgList = new ArrayList<String>(1); 13129 pkgList.add(deletedPackage.applicationInfo.packageName); 13130 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null); 13131 } 13132 13133 deleteCodeCacheDirsLI(pkg); 13134 13135 try { 13136 final PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags, 13137 scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user); 13138 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user); 13139 13140 // Update the in-memory copy of the previous code paths. 13141 PackageSetting ps = mSettings.mPackages.get(pkgName); 13142 if (!killApp) { 13143 if (ps.oldCodePaths == null) { 13144 ps.oldCodePaths = new ArraySet<>(); 13145 } 13146 Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath); 13147 if (deletedPackage.splitCodePaths != null) { 13148 Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths); 13149 } 13150 } else { 13151 ps.oldCodePaths = null; 13152 } 13153 if (ps.childPackageNames != null) { 13154 for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) { 13155 final String childPkgName = ps.childPackageNames.get(i); 13156 final PackageSetting childPs = mSettings.mPackages.get(childPkgName); 13157 childPs.oldCodePaths = ps.oldCodePaths; 13158 } 13159 } 13160 prepareAppDataAfterInstall(newPackage); 13161 addedPkg = true; 13162 } catch (PackageManagerException e) { 13163 res.setError("Package couldn't be installed in " + pkg.codePath, e); 13164 } 13165 } 13166 13167 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 13168 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName); 13169 13170 // Revert all internal state mutations and added folders for the failed install 13171 if (addedPkg) { 13172 deletePackageLI(pkgName, null, true, allUsers, deleteFlags, 13173 res.removedInfo, true, null); 13174 } 13175 13176 // Restore the old package 13177 if (deletedPkg) { 13178 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage); 13179 File restoreFile = new File(deletedPackage.codePath); 13180 // Parse old package 13181 boolean oldExternal = isExternal(deletedPackage); 13182 int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY | 13183 (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) | 13184 (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0); 13185 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME; 13186 try { 13187 scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, 13188 null); 13189 } catch (PackageManagerException e) { 13190 Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: " 13191 + e.getMessage()); 13192 return; 13193 } 13194 13195 synchronized (mPackages) { 13196 // Ensure the installer package name up to date 13197 setInstallerPackageNameLPw(deletedPackage, installerPackageName); 13198 13199 // Update permissions for restored package 13200 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL); 13201 13202 mSettings.writeLPr(); 13203 } 13204 13205 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade"); 13206 } 13207 } else { 13208 synchronized (mPackages) { 13209 PackageSetting ps = mSettings.peekPackageLPr(pkg.packageName); 13210 if (ps != null) { 13211 res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null; 13212 if (res.removedInfo.removedChildPackages != null) { 13213 final int childCount = res.removedInfo.removedChildPackages.size(); 13214 // Iterate in reverse as we may modify the collection 13215 for (int i = childCount - 1; i >= 0; i--) { 13216 String childPackageName = res.removedInfo.removedChildPackages.keyAt(i); 13217 if (res.addedChildPackages.containsKey(childPackageName)) { 13218 res.removedInfo.removedChildPackages.removeAt(i); 13219 } else { 13220 PackageRemovedInfo childInfo = res.removedInfo 13221 .removedChildPackages.valueAt(i); 13222 childInfo.removedForAllUsers = mPackages.get( 13223 childInfo.removedPackage) == null; 13224 } 13225 } 13226 } 13227 } 13228 } 13229 } 13230 } 13231 13232 private void replaceSystemPackageLI(PackageParser.Package deletedPackage, 13233 PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, 13234 int[] allUsers, String installerPackageName, PackageInstalledInfo res) { 13235 if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg 13236 + ", old=" + deletedPackage); 13237 13238 final boolean disabledSystem; 13239 13240 // Set the system/privileged flags as needed 13241 parseFlags |= PackageParser.PARSE_IS_SYSTEM; 13242 if ((deletedPackage.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) 13243 != 0) { 13244 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 13245 } 13246 13247 // Kill package processes including services, providers, etc. 13248 killPackage(deletedPackage, "replace sys pkg"); 13249 13250 // Remove existing system package 13251 removePackageLI(deletedPackage, true); 13252 13253 disabledSystem = disableSystemPackageLPw(deletedPackage, pkg); 13254 if (!disabledSystem) { 13255 // We didn't need to disable the .apk as a current system package, 13256 // which means we are replacing another update that is already 13257 // installed. We need to make sure to delete the older one's .apk. 13258 res.removedInfo.args = createInstallArgsForExisting(0, 13259 deletedPackage.applicationInfo.getCodePath(), 13260 deletedPackage.applicationInfo.getResourcePath(), 13261 getAppDexInstructionSets(deletedPackage.applicationInfo)); 13262 } else { 13263 res.removedInfo.args = null; 13264 } 13265 13266 // Successfully disabled the old package. Now proceed with re-installation 13267 deleteCodeCacheDirsLI(pkg); 13268 13269 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 13270 pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP, 13271 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP); 13272 13273 PackageParser.Package newPackage = null; 13274 try { 13275 // Add the package to the internal data structures 13276 newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags, 0, user); 13277 13278 // Set the update and install times 13279 PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras; 13280 setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime, 13281 System.currentTimeMillis()); 13282 13283 // Check for shared user id changes 13284 String invalidPackageName = getParentOrChildPackageChangedSharedUser( 13285 deletedPackage, newPackage); 13286 if (invalidPackageName != null) { 13287 res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 13288 "Forbidding shared user change from " + deletedPkgSetting.sharedUser 13289 + " to " + invalidPackageName); 13290 } 13291 13292 // Update the package dynamic state if succeeded 13293 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 13294 // Now that the install succeeded make sure we remove data 13295 // directories for any child package the update removed. 13296 final int deletedChildCount = (deletedPackage.childPackages != null) 13297 ? deletedPackage.childPackages.size() : 0; 13298 final int newChildCount = (newPackage.childPackages != null) 13299 ? newPackage.childPackages.size() : 0; 13300 for (int i = 0; i < deletedChildCount; i++) { 13301 PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i); 13302 boolean childPackageDeleted = true; 13303 for (int j = 0; j < newChildCount; j++) { 13304 PackageParser.Package newChildPkg = newPackage.childPackages.get(j); 13305 if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) { 13306 childPackageDeleted = false; 13307 break; 13308 } 13309 } 13310 if (childPackageDeleted) { 13311 PackageSetting ps = mSettings.getDisabledSystemPkgLPr( 13312 deletedChildPkg.packageName); 13313 if (ps != null && res.removedInfo.removedChildPackages != null) { 13314 PackageRemovedInfo removedChildRes = res.removedInfo 13315 .removedChildPackages.get(deletedChildPkg.packageName); 13316 removePackageDataLI(ps, allUsers, removedChildRes, 0, false); 13317 removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null; 13318 } 13319 } 13320 } 13321 13322 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user); 13323 prepareAppDataAfterInstall(newPackage); 13324 } 13325 } catch (PackageManagerException e) { 13326 res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR); 13327 res.setError("Package couldn't be installed in " + pkg.codePath, e); 13328 } 13329 13330 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 13331 // Re installation failed. Restore old information 13332 // Remove new pkg information 13333 if (newPackage != null) { 13334 removeInstalledPackageLI(newPackage, true); 13335 } 13336 // Add back the old system package 13337 try { 13338 scanPackageTracedLI(deletedPackage, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user); 13339 } catch (PackageManagerException e) { 13340 Slog.e(TAG, "Failed to restore original package: " + e.getMessage()); 13341 } 13342 13343 synchronized (mPackages) { 13344 if (disabledSystem) { 13345 enableSystemPackageLPw(deletedPackage); 13346 } 13347 13348 // Ensure the installer package name up to date 13349 setInstallerPackageNameLPw(deletedPackage, installerPackageName); 13350 13351 // Update permissions for restored package 13352 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL); 13353 13354 mSettings.writeLPr(); 13355 } 13356 13357 Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName 13358 + " after failed upgrade"); 13359 } 13360 } 13361 13362 /** 13363 * Checks whether the parent or any of the child packages have a change shared 13364 * user. For a package to be a valid update the shred users of the parent and 13365 * the children should match. We may later support changing child shared users. 13366 * @param oldPkg The updated package. 13367 * @param newPkg The update package. 13368 * @return The shared user that change between the versions. 13369 */ 13370 private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg, 13371 PackageParser.Package newPkg) { 13372 // Check parent shared user 13373 if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) { 13374 return newPkg.packageName; 13375 } 13376 // Check child shared users 13377 final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0; 13378 final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0; 13379 for (int i = 0; i < newChildCount; i++) { 13380 PackageParser.Package newChildPkg = newPkg.childPackages.get(i); 13381 // If this child was present, did it have the same shared user? 13382 for (int j = 0; j < oldChildCount; j++) { 13383 PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j); 13384 if (newChildPkg.packageName.equals(oldChildPkg.packageName) 13385 && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) { 13386 return newChildPkg.packageName; 13387 } 13388 } 13389 } 13390 return null; 13391 } 13392 13393 private void removeNativeBinariesLI(PackageSetting ps) { 13394 // Remove the lib path for the parent package 13395 if (ps != null) { 13396 NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString); 13397 // Remove the lib path for the child packages 13398 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0; 13399 for (int i = 0; i < childCount; i++) { 13400 PackageSetting childPs = null; 13401 synchronized (mPackages) { 13402 childPs = mSettings.peekPackageLPr(ps.childPackageNames.get(i)); 13403 } 13404 if (childPs != null) { 13405 NativeLibraryHelper.removeNativeBinariesLI(childPs 13406 .legacyNativeLibraryPathString); 13407 } 13408 } 13409 } 13410 } 13411 13412 private void enableSystemPackageLPw(PackageParser.Package pkg) { 13413 // Enable the parent package 13414 mSettings.enableSystemPackageLPw(pkg.packageName); 13415 // Enable the child packages 13416 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 13417 for (int i = 0; i < childCount; i++) { 13418 PackageParser.Package childPkg = pkg.childPackages.get(i); 13419 mSettings.enableSystemPackageLPw(childPkg.packageName); 13420 } 13421 } 13422 13423 private boolean disableSystemPackageLPw(PackageParser.Package oldPkg, 13424 PackageParser.Package newPkg) { 13425 // Disable the parent package (parent always replaced) 13426 boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true); 13427 // Disable the child packages 13428 final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0; 13429 for (int i = 0; i < childCount; i++) { 13430 PackageParser.Package childPkg = oldPkg.childPackages.get(i); 13431 final boolean replace = newPkg.hasChildPackage(childPkg.packageName); 13432 disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace); 13433 } 13434 return disabled; 13435 } 13436 13437 private void setInstallerPackageNameLPw(PackageParser.Package pkg, 13438 String installerPackageName) { 13439 // Enable the parent package 13440 mSettings.setInstallerPackageName(pkg.packageName, installerPackageName); 13441 // Enable the child packages 13442 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 13443 for (int i = 0; i < childCount; i++) { 13444 PackageParser.Package childPkg = pkg.childPackages.get(i); 13445 mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName); 13446 } 13447 } 13448 13449 private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) { 13450 // Collect all used permissions in the UID 13451 ArraySet<String> usedPermissions = new ArraySet<>(); 13452 final int packageCount = su.packages.size(); 13453 for (int i = 0; i < packageCount; i++) { 13454 PackageSetting ps = su.packages.valueAt(i); 13455 if (ps.pkg == null) { 13456 continue; 13457 } 13458 final int requestedPermCount = ps.pkg.requestedPermissions.size(); 13459 for (int j = 0; j < requestedPermCount; j++) { 13460 String permission = ps.pkg.requestedPermissions.get(j); 13461 BasePermission bp = mSettings.mPermissions.get(permission); 13462 if (bp != null) { 13463 usedPermissions.add(permission); 13464 } 13465 } 13466 } 13467 13468 PermissionsState permissionsState = su.getPermissionsState(); 13469 // Prune install permissions 13470 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates(); 13471 final int installPermCount = installPermStates.size(); 13472 for (int i = installPermCount - 1; i >= 0; i--) { 13473 PermissionState permissionState = installPermStates.get(i); 13474 if (!usedPermissions.contains(permissionState.getName())) { 13475 BasePermission bp = mSettings.mPermissions.get(permissionState.getName()); 13476 if (bp != null) { 13477 permissionsState.revokeInstallPermission(bp); 13478 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 13479 PackageManager.MASK_PERMISSION_FLAGS, 0); 13480 } 13481 } 13482 } 13483 13484 int[] runtimePermissionChangedUserIds = EmptyArray.INT; 13485 13486 // Prune runtime permissions 13487 for (int userId : allUserIds) { 13488 List<PermissionState> runtimePermStates = permissionsState 13489 .getRuntimePermissionStates(userId); 13490 final int runtimePermCount = runtimePermStates.size(); 13491 for (int i = runtimePermCount - 1; i >= 0; i--) { 13492 PermissionState permissionState = runtimePermStates.get(i); 13493 if (!usedPermissions.contains(permissionState.getName())) { 13494 BasePermission bp = mSettings.mPermissions.get(permissionState.getName()); 13495 if (bp != null) { 13496 permissionsState.revokeRuntimePermission(bp, userId); 13497 permissionsState.updatePermissionFlags(bp, userId, 13498 PackageManager.MASK_PERMISSION_FLAGS, 0); 13499 runtimePermissionChangedUserIds = ArrayUtils.appendInt( 13500 runtimePermissionChangedUserIds, userId); 13501 } 13502 } 13503 } 13504 } 13505 13506 return runtimePermissionChangedUserIds; 13507 } 13508 13509 private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, 13510 int[] allUsers, PackageInstalledInfo res, UserHandle user) { 13511 // Update the parent package setting 13512 updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers, 13513 res, user); 13514 // Update the child packages setting 13515 final int childCount = (newPackage.childPackages != null) 13516 ? newPackage.childPackages.size() : 0; 13517 for (int i = 0; i < childCount; i++) { 13518 PackageParser.Package childPackage = newPackage.childPackages.get(i); 13519 PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName); 13520 updateSettingsInternalLI(childPackage, installerPackageName, allUsers, 13521 childRes.origUsers, childRes, user); 13522 } 13523 } 13524 13525 private void updateSettingsInternalLI(PackageParser.Package newPackage, 13526 String installerPackageName, int[] allUsers, int[] installedForUsers, 13527 PackageInstalledInfo res, UserHandle user) { 13528 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 13529 13530 String pkgName = newPackage.packageName; 13531 synchronized (mPackages) { 13532 //write settings. the installStatus will be incomplete at this stage. 13533 //note that the new package setting would have already been 13534 //added to mPackages. It hasn't been persisted yet. 13535 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE); 13536 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings"); 13537 mSettings.writeLPr(); 13538 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13539 } 13540 13541 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath); 13542 synchronized (mPackages) { 13543 updatePermissionsLPw(newPackage.packageName, newPackage, 13544 UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0 13545 ? UPDATE_PERMISSIONS_ALL : 0)); 13546 // For system-bundled packages, we assume that installing an upgraded version 13547 // of the package implies that the user actually wants to run that new code, 13548 // so we enable the package. 13549 PackageSetting ps = mSettings.mPackages.get(pkgName); 13550 final int userId = user.getIdentifier(); 13551 if (ps != null) { 13552 if (isSystemApp(newPackage)) { 13553 if (DEBUG_INSTALL) { 13554 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName); 13555 } 13556 // Enable system package for requested users 13557 if (res.origUsers != null) { 13558 for (int origUserId : res.origUsers) { 13559 if (userId == UserHandle.USER_ALL || userId == origUserId) { 13560 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 13561 origUserId, installerPackageName); 13562 } 13563 } 13564 } 13565 // Also convey the prior install/uninstall state 13566 if (allUsers != null && installedForUsers != null) { 13567 for (int currentUserId : allUsers) { 13568 final boolean installed = ArrayUtils.contains( 13569 installedForUsers, currentUserId); 13570 if (DEBUG_INSTALL) { 13571 Slog.d(TAG, " user " + currentUserId + " => " + installed); 13572 } 13573 ps.setInstalled(installed, currentUserId); 13574 } 13575 // these install state changes will be persisted in the 13576 // upcoming call to mSettings.writeLPr(). 13577 } 13578 } 13579 // It's implied that when a user requests installation, they want the app to be 13580 // installed and enabled. 13581 if (userId != UserHandle.USER_ALL) { 13582 ps.setInstalled(true, userId); 13583 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName); 13584 } 13585 } 13586 res.name = pkgName; 13587 res.uid = newPackage.applicationInfo.uid; 13588 res.pkg = newPackage; 13589 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE); 13590 mSettings.setInstallerPackageName(pkgName, installerPackageName); 13591 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 13592 //to update install status 13593 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings"); 13594 mSettings.writeLPr(); 13595 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13596 } 13597 13598 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13599 } 13600 13601 private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) { 13602 try { 13603 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage"); 13604 installPackageLI(args, res); 13605 } finally { 13606 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13607 } 13608 } 13609 13610 private void installPackageLI(InstallArgs args, PackageInstalledInfo res) { 13611 final int installFlags = args.installFlags; 13612 final String installerPackageName = args.installerPackageName; 13613 final String volumeUuid = args.volumeUuid; 13614 final File tmpPackageFile = new File(args.getCodePath()); 13615 final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0); 13616 final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) 13617 || (args.volumeUuid != null)); 13618 final boolean ephemeral = ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0); 13619 boolean replace = false; 13620 int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE; 13621 if (args.move != null) { 13622 // moving a complete application; perform an initial scan on the new install location 13623 scanFlags |= SCAN_INITIAL; 13624 } 13625 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) { 13626 scanFlags |= SCAN_DONT_KILL_APP; 13627 } 13628 13629 // Result object to be returned 13630 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 13631 13632 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile); 13633 13634 // Sanity check 13635 if (ephemeral && (forwardLocked || onExternal)) { 13636 Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked 13637 + " external=" + onExternal); 13638 res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID); 13639 return; 13640 } 13641 13642 // Retrieve PackageSettings and parse package 13643 final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY 13644 | PackageParser.PARSE_ENFORCE_CODE 13645 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) 13646 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0) 13647 | (ephemeral ? PackageParser.PARSE_IS_EPHEMERAL : 0); 13648 PackageParser pp = new PackageParser(); 13649 pp.setSeparateProcesses(mSeparateProcesses); 13650 pp.setDisplayMetrics(mMetrics); 13651 13652 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage"); 13653 final PackageParser.Package pkg; 13654 try { 13655 pkg = pp.parsePackage(tmpPackageFile, parseFlags); 13656 } catch (PackageParserException e) { 13657 res.setError("Failed parse during installPackageLI", e); 13658 return; 13659 } finally { 13660 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13661 } 13662 13663 // If we are installing a clustered package add results for the children 13664 if (pkg.childPackages != null) { 13665 synchronized (mPackages) { 13666 final int childCount = pkg.childPackages.size(); 13667 for (int i = 0; i < childCount; i++) { 13668 PackageParser.Package childPkg = pkg.childPackages.get(i); 13669 PackageInstalledInfo childRes = new PackageInstalledInfo(); 13670 childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 13671 childRes.pkg = childPkg; 13672 childRes.name = childPkg.packageName; 13673 PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName); 13674 if (childPs != null) { 13675 childRes.origUsers = childPs.queryInstalledUsers( 13676 sUserManager.getUserIds(), true); 13677 } 13678 if ((mPackages.containsKey(childPkg.packageName))) { 13679 childRes.removedInfo = new PackageRemovedInfo(); 13680 childRes.removedInfo.removedPackage = childPkg.packageName; 13681 } 13682 if (res.addedChildPackages == null) { 13683 res.addedChildPackages = new ArrayMap<>(); 13684 } 13685 res.addedChildPackages.put(childPkg.packageName, childRes); 13686 } 13687 } 13688 } 13689 13690 // If package doesn't declare API override, mark that we have an install 13691 // time CPU ABI override. 13692 if (TextUtils.isEmpty(pkg.cpuAbiOverride)) { 13693 pkg.cpuAbiOverride = args.abiOverride; 13694 } 13695 13696 String pkgName = res.name = pkg.packageName; 13697 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) { 13698 if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) { 13699 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI"); 13700 return; 13701 } 13702 } 13703 13704 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates"); 13705 try { 13706 PackageParser.collectCertificates(pkg, parseFlags); 13707 } catch (PackageParserException e) { 13708 res.setError("Failed collect during installPackageLI", e); 13709 return; 13710 } finally { 13711 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13712 } 13713 13714 // Get rid of all references to package scan path via parser. 13715 pp = null; 13716 String oldCodePath = null; 13717 boolean systemApp = false; 13718 synchronized (mPackages) { 13719 // Check if installing already existing package 13720 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 13721 String oldName = mSettings.mRenamedPackages.get(pkgName); 13722 if (pkg.mOriginalPackages != null 13723 && pkg.mOriginalPackages.contains(oldName) 13724 && mPackages.containsKey(oldName)) { 13725 // This package is derived from an original package, 13726 // and this device has been updating from that original 13727 // name. We must continue using the original name, so 13728 // rename the new package here. 13729 pkg.setPackageName(oldName); 13730 pkgName = pkg.packageName; 13731 replace = true; 13732 if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName=" 13733 + oldName + " pkgName=" + pkgName); 13734 } else if (mPackages.containsKey(pkgName)) { 13735 // This package, under its official name, already exists 13736 // on the device; we should replace it. 13737 replace = true; 13738 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName); 13739 } 13740 13741 // Child packages are installed through the parent package 13742 if (pkg.parentPackage != null) { 13743 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME, 13744 "Package " + pkg.packageName + " is child of package " 13745 + pkg.parentPackage.parentPackage + ". Child packages " 13746 + "can be updated only through the parent package."); 13747 return; 13748 } 13749 13750 if (replace) { 13751 // Prevent apps opting out from runtime permissions 13752 PackageParser.Package oldPackage = mPackages.get(pkgName); 13753 final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion; 13754 final int newTargetSdk = pkg.applicationInfo.targetSdkVersion; 13755 if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1 13756 && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) { 13757 res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE, 13758 "Package " + pkg.packageName + " new target SDK " + newTargetSdk 13759 + " doesn't support runtime permissions but the old" 13760 + " target SDK " + oldTargetSdk + " does."); 13761 return; 13762 } 13763 13764 // Prevent installing of child packages 13765 if (oldPackage.parentPackage != null) { 13766 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME, 13767 "Package " + pkg.packageName + " is child of package " 13768 + oldPackage.parentPackage + ". Child packages " 13769 + "can be updated only through the parent package."); 13770 return; 13771 } 13772 } 13773 } 13774 13775 PackageSetting ps = mSettings.mPackages.get(pkgName); 13776 if (ps != null) { 13777 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps); 13778 13779 // Quick sanity check that we're signed correctly if updating; 13780 // we'll check this again later when scanning, but we want to 13781 // bail early here before tripping over redefined permissions. 13782 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { 13783 if (!checkUpgradeKeySetLP(ps, pkg)) { 13784 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 13785 + pkg.packageName + " upgrade keys do not match the " 13786 + "previously installed version"); 13787 return; 13788 } 13789 } else { 13790 try { 13791 verifySignaturesLP(ps, pkg); 13792 } catch (PackageManagerException e) { 13793 res.setError(e.error, e.getMessage()); 13794 return; 13795 } 13796 } 13797 13798 oldCodePath = mSettings.mPackages.get(pkgName).codePathString; 13799 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 13800 systemApp = (ps.pkg.applicationInfo.flags & 13801 ApplicationInfo.FLAG_SYSTEM) != 0; 13802 } 13803 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 13804 } 13805 13806 // Check whether the newly-scanned package wants to define an already-defined perm 13807 int N = pkg.permissions.size(); 13808 for (int i = N-1; i >= 0; i--) { 13809 PackageParser.Permission perm = pkg.permissions.get(i); 13810 BasePermission bp = mSettings.mPermissions.get(perm.info.name); 13811 if (bp != null) { 13812 // If the defining package is signed with our cert, it's okay. This 13813 // also includes the "updating the same package" case, of course. 13814 // "updating same package" could also involve key-rotation. 13815 final boolean sigsOk; 13816 if (bp.sourcePackage.equals(pkg.packageName) 13817 && (bp.packageSetting instanceof PackageSetting) 13818 && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting, 13819 scanFlags))) { 13820 sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg); 13821 } else { 13822 sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures, 13823 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 13824 } 13825 if (!sigsOk) { 13826 // If the owning package is the system itself, we log but allow 13827 // install to proceed; we fail the install on all other permission 13828 // redefinitions. 13829 if (!bp.sourcePackage.equals("android")) { 13830 res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package " 13831 + pkg.packageName + " attempting to redeclare permission " 13832 + perm.info.name + " already owned by " + bp.sourcePackage); 13833 res.origPermission = perm.info.name; 13834 res.origPackage = bp.sourcePackage; 13835 return; 13836 } else { 13837 Slog.w(TAG, "Package " + pkg.packageName 13838 + " attempting to redeclare system permission " 13839 + perm.info.name + "; ignoring new declaration"); 13840 pkg.permissions.remove(i); 13841 } 13842 } 13843 } 13844 } 13845 } 13846 13847 if (systemApp) { 13848 if (onExternal) { 13849 // Abort update; system app can't be replaced with app on sdcard 13850 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION, 13851 "Cannot install updates to system apps on sdcard"); 13852 return; 13853 } else if (ephemeral) { 13854 // Abort update; system app can't be replaced with an ephemeral app 13855 res.setError(INSTALL_FAILED_EPHEMERAL_INVALID, 13856 "Cannot update a system app with an ephemeral app"); 13857 return; 13858 } 13859 } 13860 13861 if (args.move != null) { 13862 // We did an in-place move, so dex is ready to roll 13863 scanFlags |= SCAN_NO_DEX; 13864 scanFlags |= SCAN_MOVE; 13865 13866 synchronized (mPackages) { 13867 final PackageSetting ps = mSettings.mPackages.get(pkgName); 13868 if (ps == null) { 13869 res.setError(INSTALL_FAILED_INTERNAL_ERROR, 13870 "Missing settings for moved package " + pkgName); 13871 } 13872 13873 // We moved the entire application as-is, so bring over the 13874 // previously derived ABI information. 13875 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString; 13876 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString; 13877 } 13878 13879 } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) { 13880 // Enable SCAN_NO_DEX flag to skip dexopt at a later stage 13881 scanFlags |= SCAN_NO_DEX; 13882 13883 try { 13884 String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ? 13885 args.abiOverride : pkg.cpuAbiOverride); 13886 derivePackageAbi(pkg, new File(pkg.codePath), abiOverride, 13887 true /* extract libs */); 13888 } catch (PackageManagerException pme) { 13889 Slog.e(TAG, "Error deriving application ABI", pme); 13890 res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI"); 13891 return; 13892 } 13893 13894 // Extract package to save the VM unzipping the APK in memory during 13895 // launch. Only do this if profile-guided compilation is enabled because 13896 // otherwise BackgroundDexOptService will not dexopt the package later. 13897 if (mUseJitProfiles) { 13898 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 13899 // Do not run PackageDexOptimizer through the local performDexOpt 13900 // method because `pkg` is not in `mPackages` yet. 13901 int result = mPackageDexOptimizer.performDexOpt(pkg, null /* instructionSets */, 13902 false /* useProfiles */, true /* extractOnly */); 13903 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13904 if (result == PackageDexOptimizer.DEX_OPT_FAILED) { 13905 String msg = "Extracking package failed for " + pkgName; 13906 res.setError(INSTALL_FAILED_DEXOPT, msg); 13907 return; 13908 } 13909 } 13910 } 13911 13912 if (!args.doRename(res.returnCode, pkg, oldCodePath)) { 13913 res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename"); 13914 return; 13915 } 13916 13917 startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg); 13918 13919 if (replace) { 13920 replacePackageLI(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user, 13921 installerPackageName, res); 13922 } else { 13923 installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES, 13924 args.user, installerPackageName, volumeUuid, res); 13925 } 13926 synchronized (mPackages) { 13927 final PackageSetting ps = mSettings.mPackages.get(pkgName); 13928 if (ps != null) { 13929 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 13930 } 13931 13932 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 13933 for (int i = 0; i < childCount; i++) { 13934 PackageParser.Package childPkg = pkg.childPackages.get(i); 13935 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName); 13936 PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName); 13937 if (childPs != null) { 13938 childRes.newUsers = childPs.queryInstalledUsers( 13939 sUserManager.getUserIds(), true); 13940 } 13941 } 13942 } 13943 } 13944 13945 private void startIntentFilterVerifications(int userId, boolean replacing, 13946 PackageParser.Package pkg) { 13947 if (mIntentFilterVerifierComponent == null) { 13948 Slog.w(TAG, "No IntentFilter verification will not be done as " 13949 + "there is no IntentFilterVerifier available!"); 13950 return; 13951 } 13952 13953 final int verifierUid = getPackageUid( 13954 mIntentFilterVerifierComponent.getPackageName(), 13955 MATCH_DEBUG_TRIAGED_MISSING, 13956 (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId); 13957 13958 Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 13959 msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid); 13960 mHandler.sendMessage(msg); 13961 13962 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 13963 for (int i = 0; i < childCount; i++) { 13964 PackageParser.Package childPkg = pkg.childPackages.get(i); 13965 msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 13966 msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid); 13967 mHandler.sendMessage(msg); 13968 } 13969 } 13970 13971 private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing, 13972 PackageParser.Package pkg) { 13973 int size = pkg.activities.size(); 13974 if (size == 0) { 13975 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 13976 "No activity, so no need to verify any IntentFilter!"); 13977 return; 13978 } 13979 13980 final boolean hasDomainURLs = hasDomainURLs(pkg); 13981 if (!hasDomainURLs) { 13982 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 13983 "No domain URLs, so no need to verify any IntentFilter!"); 13984 return; 13985 } 13986 13987 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId 13988 + " if any IntentFilter from the " + size 13989 + " Activities needs verification ..."); 13990 13991 int count = 0; 13992 final String packageName = pkg.packageName; 13993 13994 synchronized (mPackages) { 13995 // If this is a new install and we see that we've already run verification for this 13996 // package, we have nothing to do: it means the state was restored from backup. 13997 if (!replacing) { 13998 IntentFilterVerificationInfo ivi = 13999 mSettings.getIntentFilterVerificationLPr(packageName); 14000 if (ivi != null) { 14001 if (DEBUG_DOMAIN_VERIFICATION) { 14002 Slog.i(TAG, "Package " + packageName+ " already verified: status=" 14003 + ivi.getStatusString()); 14004 } 14005 return; 14006 } 14007 } 14008 14009 // If any filters need to be verified, then all need to be. 14010 boolean needToVerify = false; 14011 for (PackageParser.Activity a : pkg.activities) { 14012 for (ActivityIntentInfo filter : a.intents) { 14013 if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) { 14014 if (DEBUG_DOMAIN_VERIFICATION) { 14015 Slog.d(TAG, "Intent filter needs verification, so processing all filters"); 14016 } 14017 needToVerify = true; 14018 break; 14019 } 14020 } 14021 } 14022 14023 if (needToVerify) { 14024 final int verificationId = mIntentFilterVerificationToken++; 14025 for (PackageParser.Activity a : pkg.activities) { 14026 for (ActivityIntentInfo filter : a.intents) { 14027 if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) { 14028 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 14029 "Verification needed for IntentFilter:" + filter.toString()); 14030 mIntentFilterVerifier.addOneIntentFilterVerification( 14031 verifierUid, userId, verificationId, filter, packageName); 14032 count++; 14033 } 14034 } 14035 } 14036 } 14037 } 14038 14039 if (count > 0) { 14040 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count 14041 + " IntentFilter verification" + (count > 1 ? "s" : "") 14042 + " for userId:" + userId); 14043 mIntentFilterVerifier.startVerifications(userId); 14044 } else { 14045 if (DEBUG_DOMAIN_VERIFICATION) { 14046 Slog.d(TAG, "No filters or not all autoVerify for " + packageName); 14047 } 14048 } 14049 } 14050 14051 private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) { 14052 final ComponentName cn = filter.activity.getComponentName(); 14053 final String packageName = cn.getPackageName(); 14054 14055 IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr( 14056 packageName); 14057 if (ivi == null) { 14058 return true; 14059 } 14060 int status = ivi.getStatus(); 14061 switch (status) { 14062 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 14063 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 14064 return true; 14065 14066 default: 14067 // Nothing to do 14068 return false; 14069 } 14070 } 14071 14072 private static boolean isMultiArch(ApplicationInfo info) { 14073 return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0; 14074 } 14075 14076 private static boolean isExternal(PackageParser.Package pkg) { 14077 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 14078 } 14079 14080 private static boolean isExternal(PackageSetting ps) { 14081 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 14082 } 14083 14084 private static boolean isEphemeral(PackageParser.Package pkg) { 14085 return pkg.applicationInfo.isEphemeralApp(); 14086 } 14087 14088 private static boolean isEphemeral(PackageSetting ps) { 14089 return ps.pkg != null && isEphemeral(ps.pkg); 14090 } 14091 14092 private static boolean isSystemApp(PackageParser.Package pkg) { 14093 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 14094 } 14095 14096 private static boolean isPrivilegedApp(PackageParser.Package pkg) { 14097 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; 14098 } 14099 14100 private static boolean hasDomainURLs(PackageParser.Package pkg) { 14101 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0; 14102 } 14103 14104 private static boolean isSystemApp(PackageSetting ps) { 14105 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0; 14106 } 14107 14108 private static boolean isUpdatedSystemApp(PackageSetting ps) { 14109 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; 14110 } 14111 14112 private int packageFlagsToInstallFlags(PackageSetting ps) { 14113 int installFlags = 0; 14114 if (isEphemeral(ps)) { 14115 installFlags |= PackageManager.INSTALL_EPHEMERAL; 14116 } 14117 if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) { 14118 // This existing package was an external ASEC install when we have 14119 // the external flag without a UUID 14120 installFlags |= PackageManager.INSTALL_EXTERNAL; 14121 } 14122 if (ps.isForwardLocked()) { 14123 installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 14124 } 14125 return installFlags; 14126 } 14127 14128 private String getVolumeUuidForPackage(PackageParser.Package pkg) { 14129 if (isExternal(pkg)) { 14130 if (TextUtils.isEmpty(pkg.volumeUuid)) { 14131 return StorageManager.UUID_PRIMARY_PHYSICAL; 14132 } else { 14133 return pkg.volumeUuid; 14134 } 14135 } else { 14136 return StorageManager.UUID_PRIVATE_INTERNAL; 14137 } 14138 } 14139 14140 private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) { 14141 if (isExternal(pkg)) { 14142 if (TextUtils.isEmpty(pkg.volumeUuid)) { 14143 return mSettings.getExternalVersion(); 14144 } else { 14145 return mSettings.findOrCreateVersion(pkg.volumeUuid); 14146 } 14147 } else { 14148 return mSettings.getInternalVersion(); 14149 } 14150 } 14151 14152 private void deleteTempPackageFiles() { 14153 final FilenameFilter filter = new FilenameFilter() { 14154 public boolean accept(File dir, String name) { 14155 return name.startsWith("vmdl") && name.endsWith(".tmp"); 14156 } 14157 }; 14158 for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) { 14159 file.delete(); 14160 } 14161 } 14162 14163 @Override 14164 public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId, 14165 int flags) { 14166 deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId, 14167 flags); 14168 } 14169 14170 @Override 14171 public void deletePackage(final String packageName, 14172 final IPackageDeleteObserver2 observer, final int userId, final int flags) { 14173 mContext.enforceCallingOrSelfPermission( 14174 android.Manifest.permission.DELETE_PACKAGES, null); 14175 Preconditions.checkNotNull(packageName); 14176 Preconditions.checkNotNull(observer); 14177 final int uid = Binder.getCallingUid(); 14178 final boolean deleteAllUsers = (flags & PackageManager.DELETE_ALL_USERS) != 0; 14179 final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId }; 14180 if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) { 14181 mContext.enforceCallingOrSelfPermission( 14182 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 14183 "deletePackage for user " + userId); 14184 } 14185 14186 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) { 14187 try { 14188 observer.onPackageDeleted(packageName, 14189 PackageManager.DELETE_FAILED_USER_RESTRICTED, null); 14190 } catch (RemoteException re) { 14191 } 14192 return; 14193 } 14194 14195 if (!deleteAllUsers && getBlockUninstallForUser(packageName, userId)) { 14196 try { 14197 observer.onPackageDeleted(packageName, 14198 PackageManager.DELETE_FAILED_OWNER_BLOCKED, null); 14199 } catch (RemoteException re) { 14200 } 14201 return; 14202 } 14203 14204 if (DEBUG_REMOVE) { 14205 Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId 14206 + " deleteAllUsers: " + deleteAllUsers ); 14207 } 14208 // Queue up an async operation since the package deletion may take a little while. 14209 mHandler.post(new Runnable() { 14210 public void run() { 14211 mHandler.removeCallbacks(this); 14212 int returnCode; 14213 if (!deleteAllUsers) { 14214 returnCode = deletePackageX(packageName, userId, flags); 14215 } else { 14216 int[] blockUninstallUserIds = getBlockUninstallForUsers(packageName, users); 14217 // If nobody is blocking uninstall, proceed with delete for all users 14218 if (ArrayUtils.isEmpty(blockUninstallUserIds)) { 14219 returnCode = deletePackageX(packageName, userId, flags); 14220 } else { 14221 // Otherwise uninstall individually for users with blockUninstalls=false 14222 final int userFlags = flags & ~PackageManager.DELETE_ALL_USERS; 14223 for (int userId : users) { 14224 if (!ArrayUtils.contains(blockUninstallUserIds, userId)) { 14225 returnCode = deletePackageX(packageName, userId, userFlags); 14226 if (returnCode != PackageManager.DELETE_SUCCEEDED) { 14227 Slog.w(TAG, "Package delete failed for user " + userId 14228 + ", returnCode " + returnCode); 14229 } 14230 } 14231 } 14232 // The app has only been marked uninstalled for certain users. 14233 // We still need to report that delete was blocked 14234 returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED; 14235 } 14236 } 14237 try { 14238 observer.onPackageDeleted(packageName, returnCode, null); 14239 } catch (RemoteException e) { 14240 Log.i(TAG, "Observer no longer exists."); 14241 } //end catch 14242 } //end run 14243 }); 14244 } 14245 14246 private int[] getBlockUninstallForUsers(String packageName, int[] userIds) { 14247 int[] result = EMPTY_INT_ARRAY; 14248 for (int userId : userIds) { 14249 if (getBlockUninstallForUser(packageName, userId)) { 14250 result = ArrayUtils.appendInt(result, userId); 14251 } 14252 } 14253 return result; 14254 } 14255 14256 @Override 14257 public boolean isPackageDeviceAdminOnAnyUser(String packageName) { 14258 return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL); 14259 } 14260 14261 private boolean isPackageDeviceAdmin(String packageName, int userId) { 14262 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface( 14263 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); 14264 try { 14265 if (dpm != null) { 14266 final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent( 14267 /* callingUserOnly =*/ false); 14268 final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null 14269 : deviceOwnerComponentName.getPackageName(); 14270 // Does the package contains the device owner? 14271 // TODO Do we have to do it even if userId != UserHandle.USER_ALL? Otherwise, 14272 // this check is probably not needed, since DO should be registered as a device 14273 // admin on some user too. (Original bug for this: b/17657954) 14274 if (packageName.equals(deviceOwnerPackageName)) { 14275 return true; 14276 } 14277 // Does it contain a device admin for any user? 14278 int[] users; 14279 if (userId == UserHandle.USER_ALL) { 14280 users = sUserManager.getUserIds(); 14281 } else { 14282 users = new int[]{userId}; 14283 } 14284 for (int i = 0; i < users.length; ++i) { 14285 if (dpm.packageHasActiveAdmins(packageName, users[i])) { 14286 return true; 14287 } 14288 } 14289 } 14290 } catch (RemoteException e) { 14291 } 14292 return false; 14293 } 14294 14295 private boolean shouldKeepUninstalledPackageLPr(String packageName) { 14296 return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName); 14297 } 14298 14299 /** 14300 * This method is an internal method that could be get invoked either 14301 * to delete an installed package or to clean up a failed installation. 14302 * After deleting an installed package, a broadcast is sent to notify any 14303 * listeners that the package has been installed. For cleaning up a failed 14304 * installation, the broadcast is not necessary since the package's 14305 * installation wouldn't have sent the initial broadcast either 14306 * The key steps in deleting a package are 14307 * deleting the package information in internal structures like mPackages, 14308 * deleting the packages base directories through installd 14309 * updating mSettings to reflect current status 14310 * persisting settings for later use 14311 * sending a broadcast if necessary 14312 */ 14313 private int deletePackageX(String packageName, int userId, int flags) { 14314 final PackageRemovedInfo info = new PackageRemovedInfo(); 14315 final boolean res; 14316 14317 final UserHandle removeForUser = (flags & PackageManager.DELETE_ALL_USERS) != 0 14318 ? UserHandle.ALL : new UserHandle(userId); 14319 14320 if (isPackageDeviceAdmin(packageName, removeForUser.getIdentifier())) { 14321 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin"); 14322 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER; 14323 } 14324 14325 PackageSetting uninstalledPs = null; 14326 14327 // for the uninstall-updates case and restricted profiles, remember the per- 14328 // user handle installed state 14329 int[] allUsers; 14330 synchronized (mPackages) { 14331 uninstalledPs = mSettings.mPackages.get(packageName); 14332 if (uninstalledPs == null) { 14333 Slog.w(TAG, "Not removing non-existent package " + packageName); 14334 return PackageManager.DELETE_FAILED_INTERNAL_ERROR; 14335 } 14336 allUsers = sUserManager.getUserIds(); 14337 info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true); 14338 } 14339 14340 synchronized (mInstallLock) { 14341 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId); 14342 res = deletePackageLI(packageName, removeForUser, true, allUsers, 14343 flags | REMOVE_CHATTY, info, true, null); 14344 synchronized (mPackages) { 14345 if (res) { 14346 mEphemeralApplicationRegistry.onPackageUninstalledLPw(uninstalledPs.pkg); 14347 } 14348 } 14349 } 14350 14351 if (res) { 14352 final boolean killApp = (flags & PackageManager.INSTALL_DONT_KILL_APP) == 0; 14353 info.sendPackageRemovedBroadcasts(killApp); 14354 info.sendSystemPackageUpdatedBroadcasts(); 14355 info.sendSystemPackageAppearedBroadcasts(); 14356 } 14357 // Force a gc here. 14358 Runtime.getRuntime().gc(); 14359 // Delete the resources here after sending the broadcast to let 14360 // other processes clean up before deleting resources. 14361 if (info.args != null) { 14362 synchronized (mInstallLock) { 14363 info.args.doPostDeleteLI(true); 14364 } 14365 } 14366 14367 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR; 14368 } 14369 14370 class PackageRemovedInfo { 14371 String removedPackage; 14372 int uid = -1; 14373 int removedAppId = -1; 14374 int[] origUsers; 14375 int[] removedUsers = null; 14376 boolean isRemovedPackageSystemUpdate = false; 14377 boolean isUpdate; 14378 boolean dataRemoved; 14379 boolean removedForAllUsers; 14380 // Clean up resources deleted packages. 14381 InstallArgs args = null; 14382 ArrayMap<String, PackageRemovedInfo> removedChildPackages; 14383 ArrayMap<String, PackageInstalledInfo> appearedChildPackages; 14384 14385 void sendPackageRemovedBroadcasts(boolean killApp) { 14386 sendPackageRemovedBroadcastInternal(killApp); 14387 final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0; 14388 for (int i = 0; i < childCount; i++) { 14389 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i); 14390 childInfo.sendPackageRemovedBroadcastInternal(killApp); 14391 } 14392 } 14393 14394 void sendSystemPackageUpdatedBroadcasts() { 14395 if (isRemovedPackageSystemUpdate) { 14396 sendSystemPackageUpdatedBroadcastsInternal(); 14397 final int childCount = (removedChildPackages != null) 14398 ? removedChildPackages.size() : 0; 14399 for (int i = 0; i < childCount; i++) { 14400 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i); 14401 if (childInfo.isRemovedPackageSystemUpdate) { 14402 childInfo.sendSystemPackageUpdatedBroadcastsInternal(); 14403 } 14404 } 14405 } 14406 } 14407 14408 void sendSystemPackageAppearedBroadcasts() { 14409 final int packageCount = (appearedChildPackages != null) 14410 ? appearedChildPackages.size() : 0; 14411 for (int i = 0; i < packageCount; i++) { 14412 PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i); 14413 for (int userId : installedInfo.newUsers) { 14414 sendPackageAddedForUser(installedInfo.name, true, 14415 UserHandle.getAppId(installedInfo.uid), userId); 14416 } 14417 } 14418 } 14419 14420 private void sendSystemPackageUpdatedBroadcastsInternal() { 14421 Bundle extras = new Bundle(2); 14422 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 14423 extras.putBoolean(Intent.EXTRA_REPLACING, true); 14424 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, removedPackage, 14425 extras, 0, null, null, null); 14426 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, removedPackage, 14427 extras, 0, null, null, null); 14428 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null, 14429 null, 0, removedPackage, null, null); 14430 } 14431 14432 private void sendPackageRemovedBroadcastInternal(boolean killApp) { 14433 Bundle extras = new Bundle(2); 14434 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 14435 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved); 14436 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp); 14437 if (isUpdate || isRemovedPackageSystemUpdate) { 14438 extras.putBoolean(Intent.EXTRA_REPLACING, true); 14439 } 14440 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers); 14441 if (removedPackage != null) { 14442 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, 14443 extras, 0, null, null, removedUsers); 14444 if (dataRemoved && !isRemovedPackageSystemUpdate) { 14445 sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, 14446 removedPackage, extras, 0, null, null, removedUsers); 14447 } 14448 } 14449 if (removedAppId >= 0) { 14450 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, 0, null, null, 14451 removedUsers); 14452 } 14453 } 14454 } 14455 14456 /* 14457 * This method deletes the package from internal data structures. If the DONT_DELETE_DATA 14458 * flag is not set, the data directory is removed as well. 14459 * make sure this flag is set for partially installed apps. If not its meaningless to 14460 * delete a partially installed application. 14461 */ 14462 private void removePackageDataLI(PackageSetting ps, int[] allUserHandles, 14463 PackageRemovedInfo outInfo, int flags, boolean writeSettings) { 14464 String packageName = ps.name; 14465 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps); 14466 removePackageLI(ps, (flags&REMOVE_CHATTY) != 0); 14467 // Retrieve object to delete permissions for shared user later on 14468 final PackageSetting deletedPs; 14469 // reader 14470 synchronized (mPackages) { 14471 deletedPs = mSettings.mPackages.get(packageName); 14472 if (outInfo != null) { 14473 outInfo.removedPackage = packageName; 14474 outInfo.removedUsers = deletedPs != null 14475 ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true) 14476 : null; 14477 } 14478 } 14479 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 14480 removeDataDirsLI(ps.volumeUuid, packageName); 14481 if (outInfo != null) { 14482 outInfo.dataRemoved = true; 14483 } 14484 schedulePackageCleaning(packageName, UserHandle.USER_ALL, true); 14485 } 14486 // writer 14487 synchronized (mPackages) { 14488 if (deletedPs != null) { 14489 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 14490 clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL); 14491 clearDefaultBrowserIfNeeded(packageName); 14492 if (outInfo != null) { 14493 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName); 14494 outInfo.removedAppId = mSettings.removePackageLPw(packageName); 14495 } 14496 updatePermissionsLPw(deletedPs.name, null, 0); 14497 if (deletedPs.sharedUser != null) { 14498 // Remove permissions associated with package. Since runtime 14499 // permissions are per user we have to kill the removed package 14500 // or packages running under the shared user of the removed 14501 // package if revoking the permissions requested only by the removed 14502 // package is successful and this causes a change in gids. 14503 for (int userId : UserManagerService.getInstance().getUserIds()) { 14504 final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs, 14505 userId); 14506 if (userIdToKill == UserHandle.USER_ALL 14507 || userIdToKill >= UserHandle.USER_SYSTEM) { 14508 // If gids changed for this user, kill all affected packages. 14509 mHandler.post(new Runnable() { 14510 @Override 14511 public void run() { 14512 // This has to happen with no lock held. 14513 killApplication(deletedPs.name, deletedPs.appId, 14514 KILL_APP_REASON_GIDS_CHANGED); 14515 } 14516 }); 14517 break; 14518 } 14519 } 14520 } 14521 clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL); 14522 } 14523 // make sure to preserve per-user disabled state if this removal was just 14524 // a downgrade of a system app to the factory package 14525 if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) { 14526 if (DEBUG_REMOVE) { 14527 Slog.d(TAG, "Propagating install state across downgrade"); 14528 } 14529 for (int userId : allUserHandles) { 14530 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId); 14531 if (DEBUG_REMOVE) { 14532 Slog.d(TAG, " user " + userId + " => " + installed); 14533 } 14534 ps.setInstalled(installed, userId); 14535 } 14536 } 14537 } 14538 // can downgrade to reader 14539 if (writeSettings) { 14540 // Save settings now 14541 mSettings.writeLPr(); 14542 } 14543 } 14544 if (outInfo != null) { 14545 // A user ID was deleted here. Go through all users and remove it 14546 // from KeyStore. 14547 removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId); 14548 } 14549 } 14550 14551 static boolean locationIsPrivileged(File path) { 14552 try { 14553 final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app") 14554 .getCanonicalPath(); 14555 return path.getCanonicalPath().startsWith(privilegedAppDir); 14556 } catch (IOException e) { 14557 Slog.e(TAG, "Unable to access code path " + path); 14558 } 14559 return false; 14560 } 14561 14562 /* 14563 * Tries to delete system package. 14564 */ 14565 private boolean deleteSystemPackageLI(PackageParser.Package deletedPkg, 14566 PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo, 14567 boolean writeSettings) { 14568 if (deletedPs.parentPackageName != null) { 14569 Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName); 14570 return false; 14571 } 14572 14573 final boolean applyUserRestrictions 14574 = (allUserHandles != null) && (outInfo.origUsers != null); 14575 final PackageSetting disabledPs; 14576 // Confirm if the system package has been updated 14577 // An updated system app can be deleted. This will also have to restore 14578 // the system pkg from system partition 14579 // reader 14580 synchronized (mPackages) { 14581 disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name); 14582 } 14583 14584 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName 14585 + " disabledPs=" + disabledPs); 14586 14587 if (disabledPs == null) { 14588 Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName); 14589 return false; 14590 } else if (DEBUG_REMOVE) { 14591 Slog.d(TAG, "Deleting system pkg from data partition"); 14592 } 14593 14594 if (DEBUG_REMOVE) { 14595 if (applyUserRestrictions) { 14596 Slog.d(TAG, "Remembering install states:"); 14597 for (int userId : allUserHandles) { 14598 final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId); 14599 Slog.d(TAG, " u=" + userId + " inst=" + finstalled); 14600 } 14601 } 14602 } 14603 14604 // Delete the updated package 14605 outInfo.isRemovedPackageSystemUpdate = true; 14606 if (outInfo.removedChildPackages != null) { 14607 final int childCount = (deletedPs.childPackageNames != null) 14608 ? deletedPs.childPackageNames.size() : 0; 14609 for (int i = 0; i < childCount; i++) { 14610 String childPackageName = deletedPs.childPackageNames.get(i); 14611 if (disabledPs.childPackageNames != null && disabledPs.childPackageNames 14612 .contains(childPackageName)) { 14613 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get( 14614 childPackageName); 14615 if (childInfo != null) { 14616 childInfo.isRemovedPackageSystemUpdate = true; 14617 } 14618 } 14619 } 14620 } 14621 14622 if (disabledPs.versionCode < deletedPs.versionCode) { 14623 // Delete data for downgrades 14624 flags &= ~PackageManager.DELETE_KEEP_DATA; 14625 } else { 14626 // Preserve data by setting flag 14627 flags |= PackageManager.DELETE_KEEP_DATA; 14628 } 14629 14630 boolean ret = deleteInstalledPackageLI(deletedPs, true, flags, allUserHandles, 14631 outInfo, writeSettings, disabledPs.pkg); 14632 if (!ret) { 14633 return false; 14634 } 14635 14636 // writer 14637 synchronized (mPackages) { 14638 // Reinstate the old system package 14639 enableSystemPackageLPw(disabledPs.pkg); 14640 // Remove any native libraries from the upgraded package. 14641 removeNativeBinariesLI(deletedPs); 14642 } 14643 14644 // Install the system package 14645 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs); 14646 int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM; 14647 if (locationIsPrivileged(disabledPs.codePath)) { 14648 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 14649 } 14650 14651 final PackageParser.Package newPkg; 14652 try { 14653 newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null); 14654 } catch (PackageManagerException e) { 14655 Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": " 14656 + e.getMessage()); 14657 return false; 14658 } 14659 14660 prepareAppDataAfterInstall(newPkg); 14661 14662 // writer 14663 synchronized (mPackages) { 14664 PackageSetting ps = mSettings.mPackages.get(newPkg.packageName); 14665 14666 // Propagate the permissions state as we do not want to drop on the floor 14667 // runtime permissions. The update permissions method below will take 14668 // care of removing obsolete permissions and grant install permissions. 14669 ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState()); 14670 updatePermissionsLPw(newPkg.packageName, newPkg, 14671 UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG); 14672 14673 if (applyUserRestrictions) { 14674 if (DEBUG_REMOVE) { 14675 Slog.d(TAG, "Propagating install state across reinstall"); 14676 } 14677 for (int userId : allUserHandles) { 14678 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId); 14679 if (DEBUG_REMOVE) { 14680 Slog.d(TAG, " user " + userId + " => " + installed); 14681 } 14682 ps.setInstalled(installed, userId); 14683 14684 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 14685 } 14686 // Regardless of writeSettings we need to ensure that this restriction 14687 // state propagation is persisted 14688 mSettings.writeAllUsersPackageRestrictionsLPr(); 14689 } 14690 // can downgrade to reader here 14691 if (writeSettings) { 14692 mSettings.writeLPr(); 14693 } 14694 } 14695 return true; 14696 } 14697 14698 private boolean deleteInstalledPackageLI(PackageSetting ps, 14699 boolean deleteCodeAndResources, int flags, int[] allUserHandles, 14700 PackageRemovedInfo outInfo, boolean writeSettings, 14701 PackageParser.Package replacingPackage) { 14702 synchronized (mPackages) { 14703 if (outInfo != null) { 14704 outInfo.uid = ps.appId; 14705 } 14706 14707 if (outInfo != null && outInfo.removedChildPackages != null) { 14708 final int childCount = (ps.childPackageNames != null) 14709 ? ps.childPackageNames.size() : 0; 14710 for (int i = 0; i < childCount; i++) { 14711 String childPackageName = ps.childPackageNames.get(i); 14712 PackageSetting childPs = mSettings.mPackages.get(childPackageName); 14713 if (childPs == null) { 14714 return false; 14715 } 14716 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get( 14717 childPackageName); 14718 if (childInfo != null) { 14719 childInfo.uid = childPs.appId; 14720 } 14721 } 14722 } 14723 } 14724 14725 // Delete package data from internal structures and also remove data if flag is set 14726 removePackageDataLI(ps, allUserHandles, outInfo, flags, writeSettings); 14727 14728 // Delete the child packages data 14729 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0; 14730 for (int i = 0; i < childCount; i++) { 14731 PackageSetting childPs; 14732 synchronized (mPackages) { 14733 childPs = mSettings.peekPackageLPr(ps.childPackageNames.get(i)); 14734 } 14735 if (childPs != null) { 14736 PackageRemovedInfo childOutInfo = (outInfo != null 14737 && outInfo.removedChildPackages != null) 14738 ? outInfo.removedChildPackages.get(childPs.name) : null; 14739 final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0 14740 && (replacingPackage != null 14741 && !replacingPackage.hasChildPackage(childPs.name)) 14742 ? flags & ~DELETE_KEEP_DATA : flags; 14743 removePackageDataLI(childPs, allUserHandles, childOutInfo, 14744 deleteFlags, writeSettings); 14745 } 14746 } 14747 14748 // Delete application code and resources only for parent packages 14749 if (ps.parentPackageName == null) { 14750 if (deleteCodeAndResources && (outInfo != null)) { 14751 outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 14752 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 14753 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args); 14754 } 14755 } 14756 14757 return true; 14758 } 14759 14760 @Override 14761 public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall, 14762 int userId) { 14763 mContext.enforceCallingOrSelfPermission( 14764 android.Manifest.permission.DELETE_PACKAGES, null); 14765 synchronized (mPackages) { 14766 PackageSetting ps = mSettings.mPackages.get(packageName); 14767 if (ps == null) { 14768 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName); 14769 return false; 14770 } 14771 if (!ps.getInstalled(userId)) { 14772 // Can't block uninstall for an app that is not installed or enabled. 14773 Log.i(TAG, "Package not installed in set block uninstall " + packageName); 14774 return false; 14775 } 14776 ps.setBlockUninstall(blockUninstall, userId); 14777 mSettings.writePackageRestrictionsLPr(userId); 14778 } 14779 return true; 14780 } 14781 14782 @Override 14783 public boolean getBlockUninstallForUser(String packageName, int userId) { 14784 synchronized (mPackages) { 14785 PackageSetting ps = mSettings.mPackages.get(packageName); 14786 if (ps == null) { 14787 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName); 14788 return false; 14789 } 14790 return ps.getBlockUninstall(userId); 14791 } 14792 } 14793 14794 @Override 14795 public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) { 14796 int callingUid = Binder.getCallingUid(); 14797 if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) { 14798 throw new SecurityException( 14799 "setRequiredForSystemUser can only be run by the system or root"); 14800 } 14801 synchronized (mPackages) { 14802 PackageSetting ps = mSettings.mPackages.get(packageName); 14803 if (ps == null) { 14804 Log.w(TAG, "Package doesn't exist: " + packageName); 14805 return false; 14806 } 14807 if (systemUserApp) { 14808 ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER; 14809 } else { 14810 ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER; 14811 } 14812 mSettings.writeLPr(); 14813 } 14814 return true; 14815 } 14816 14817 /* 14818 * This method handles package deletion in general 14819 */ 14820 private boolean deletePackageLI(String packageName, UserHandle user, 14821 boolean deleteCodeAndResources, int[] allUserHandles, int flags, 14822 PackageRemovedInfo outInfo, boolean writeSettings, 14823 PackageParser.Package replacingPackage) { 14824 if (packageName == null) { 14825 Slog.w(TAG, "Attempt to delete null packageName."); 14826 return false; 14827 } 14828 14829 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user); 14830 14831 PackageSetting ps; 14832 14833 synchronized (mPackages) { 14834 ps = mSettings.mPackages.get(packageName); 14835 if (ps == null) { 14836 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 14837 return false; 14838 } 14839 14840 if (ps.parentPackageName != null && (!isSystemApp(ps) 14841 || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) { 14842 if (DEBUG_REMOVE) { 14843 Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:" 14844 + ((user == null) ? UserHandle.USER_ALL : user)); 14845 } 14846 final int removedUserId = (user != null) ? user.getIdentifier() 14847 : UserHandle.USER_ALL; 14848 if (!clearPackageStateForUser(ps, removedUserId, outInfo)) { 14849 return false; 14850 } 14851 markPackageUninstalledForUserLPw(ps, user); 14852 scheduleWritePackageRestrictionsLocked(user); 14853 return true; 14854 } 14855 } 14856 14857 if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null 14858 && user.getIdentifier() != UserHandle.USER_ALL)) { 14859 // The caller is asking that the package only be deleted for a single 14860 // user. To do this, we just mark its uninstalled state and delete 14861 // its data. If this is a system app, we only allow this to happen if 14862 // they have set the special DELETE_SYSTEM_APP which requests different 14863 // semantics than normal for uninstalling system apps. 14864 markPackageUninstalledForUserLPw(ps, user); 14865 14866 if (!isSystemApp(ps)) { 14867 // Do not uninstall the APK if an app should be cached 14868 boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName); 14869 if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) { 14870 // Other user still have this package installed, so all 14871 // we need to do is clear this user's data and save that 14872 // it is uninstalled. 14873 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users"); 14874 if (!clearPackageStateForUser(ps, user.getIdentifier(), outInfo)) { 14875 return false; 14876 } 14877 scheduleWritePackageRestrictionsLocked(user); 14878 return true; 14879 } else { 14880 // We need to set it back to 'installed' so the uninstall 14881 // broadcasts will be sent correctly. 14882 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete"); 14883 ps.setInstalled(true, user.getIdentifier()); 14884 } 14885 } else { 14886 // This is a system app, so we assume that the 14887 // other users still have this package installed, so all 14888 // we need to do is clear this user's data and save that 14889 // it is uninstalled. 14890 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app"); 14891 if (!clearPackageStateForUser(ps, user.getIdentifier(), outInfo)) { 14892 return false; 14893 } 14894 scheduleWritePackageRestrictionsLocked(user); 14895 return true; 14896 } 14897 } 14898 14899 // If we are deleting a composite package for all users, keep track 14900 // of result for each child. 14901 if (ps.childPackageNames != null && outInfo != null) { 14902 synchronized (mPackages) { 14903 final int childCount = ps.childPackageNames.size(); 14904 outInfo.removedChildPackages = new ArrayMap<>(childCount); 14905 for (int i = 0; i < childCount; i++) { 14906 String childPackageName = ps.childPackageNames.get(i); 14907 PackageRemovedInfo childInfo = new PackageRemovedInfo(); 14908 childInfo.removedPackage = childPackageName; 14909 outInfo.removedChildPackages.put(childPackageName, childInfo); 14910 PackageSetting childPs = mSettings.peekPackageLPr(childPackageName); 14911 if (childPs != null) { 14912 childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true); 14913 } 14914 } 14915 } 14916 } 14917 14918 boolean ret = false; 14919 if (isSystemApp(ps)) { 14920 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name); 14921 // When an updated system application is deleted we delete the existing resources 14922 // as well and fall back to existing code in system partition 14923 ret = deleteSystemPackageLI(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings); 14924 } else { 14925 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name); 14926 // Kill application pre-emptively especially for apps on sd. 14927 final boolean killApp = (flags & PackageManager.DELETE_DONT_KILL_APP) == 0; 14928 if (killApp) { 14929 killApplication(packageName, ps.appId, "uninstall pkg"); 14930 } 14931 ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags, allUserHandles, 14932 outInfo, writeSettings, replacingPackage); 14933 } 14934 14935 // Take a note whether we deleted the package for all users 14936 if (outInfo != null) { 14937 outInfo.removedForAllUsers = mPackages.get(ps.name) == null; 14938 if (outInfo.removedChildPackages != null) { 14939 synchronized (mPackages) { 14940 final int childCount = outInfo.removedChildPackages.size(); 14941 for (int i = 0; i < childCount; i++) { 14942 PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i); 14943 if (childInfo != null) { 14944 childInfo.removedForAllUsers = mPackages.get( 14945 childInfo.removedPackage) == null; 14946 } 14947 } 14948 } 14949 } 14950 // If we uninstalled an update to a system app there may be some 14951 // child packages that appeared as they are declared in the system 14952 // app but were not declared in the update. 14953 if (isSystemApp(ps)) { 14954 synchronized (mPackages) { 14955 PackageSetting updatedPs = mSettings.peekPackageLPr(ps.name); 14956 final int childCount = (updatedPs.childPackageNames != null) 14957 ? updatedPs.childPackageNames.size() : 0; 14958 for (int i = 0; i < childCount; i++) { 14959 String childPackageName = updatedPs.childPackageNames.get(i); 14960 if (outInfo.removedChildPackages == null 14961 || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) { 14962 PackageSetting childPs = mSettings.peekPackageLPr(childPackageName); 14963 if (childPs == null) { 14964 continue; 14965 } 14966 PackageInstalledInfo installRes = new PackageInstalledInfo(); 14967 installRes.name = childPackageName; 14968 installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true); 14969 installRes.pkg = mPackages.get(childPackageName); 14970 installRes.uid = childPs.pkg.applicationInfo.uid; 14971 if (outInfo.appearedChildPackages == null) { 14972 outInfo.appearedChildPackages = new ArrayMap<>(); 14973 } 14974 outInfo.appearedChildPackages.put(childPackageName, installRes); 14975 } 14976 } 14977 } 14978 } 14979 } 14980 14981 return ret; 14982 } 14983 14984 private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) { 14985 final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL) 14986 ? sUserManager.getUserIds() : new int[] {user.getIdentifier()}; 14987 for (int nextUserId : userIds) { 14988 if (DEBUG_REMOVE) { 14989 Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId); 14990 } 14991 ps.setUserState(nextUserId, COMPONENT_ENABLED_STATE_DEFAULT, 14992 false /*installed*/, true /*stopped*/, true /*notLaunched*/, 14993 false /*hidden*/, false /*suspended*/, null, null, null, 14994 false /*blockUninstall*/, 14995 ps.readUserState(nextUserId).domainVerificationStatus, 0); 14996 } 14997 } 14998 14999 private boolean clearPackageStateForUser(PackageSetting ps, int userId, 15000 PackageRemovedInfo outInfo) { 15001 final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() 15002 : new int[] {userId}; 15003 for (int nextUserId : userIds) { 15004 if (DEBUG_REMOVE) { 15005 Slog.d(TAG, "Updating package:" + ps.name + " install state for user:" 15006 + nextUserId); 15007 } 15008 final int flags = StorageManager.FLAG_STORAGE_CE| StorageManager.FLAG_STORAGE_DE; 15009 try { 15010 mInstaller.destroyAppData(ps.volumeUuid, ps.name, nextUserId, flags); 15011 } catch (InstallerException e) { 15012 Slog.w(TAG, "Couldn't remove cache files for package " + ps.name, e); 15013 return false; 15014 } 15015 removeKeystoreDataIfNeeded(nextUserId, ps.appId); 15016 schedulePackageCleaning(ps.name, nextUserId, false); 15017 synchronized (mPackages) { 15018 if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) { 15019 scheduleWritePackageRestrictionsLocked(nextUserId); 15020 } 15021 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId); 15022 } 15023 } 15024 15025 if (outInfo != null) { 15026 outInfo.removedPackage = ps.name; 15027 outInfo.removedAppId = ps.appId; 15028 outInfo.removedUsers = userIds; 15029 } 15030 15031 return true; 15032 } 15033 15034 private final class ClearStorageConnection implements ServiceConnection { 15035 IMediaContainerService mContainerService; 15036 15037 @Override 15038 public void onServiceConnected(ComponentName name, IBinder service) { 15039 synchronized (this) { 15040 mContainerService = IMediaContainerService.Stub.asInterface(service); 15041 notifyAll(); 15042 } 15043 } 15044 15045 @Override 15046 public void onServiceDisconnected(ComponentName name) { 15047 } 15048 } 15049 15050 private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) { 15051 final boolean mounted; 15052 if (Environment.isExternalStorageEmulated()) { 15053 mounted = true; 15054 } else { 15055 final String status = Environment.getExternalStorageState(); 15056 15057 mounted = status.equals(Environment.MEDIA_MOUNTED) 15058 || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY); 15059 } 15060 15061 if (!mounted) { 15062 return; 15063 } 15064 15065 final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 15066 int[] users; 15067 if (userId == UserHandle.USER_ALL) { 15068 users = sUserManager.getUserIds(); 15069 } else { 15070 users = new int[] { userId }; 15071 } 15072 final ClearStorageConnection conn = new ClearStorageConnection(); 15073 if (mContext.bindServiceAsUser( 15074 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) { 15075 try { 15076 for (int curUser : users) { 15077 long timeout = SystemClock.uptimeMillis() + 5000; 15078 synchronized (conn) { 15079 long now = SystemClock.uptimeMillis(); 15080 while (conn.mContainerService == null && now < timeout) { 15081 try { 15082 conn.wait(timeout - now); 15083 } catch (InterruptedException e) { 15084 } 15085 } 15086 } 15087 if (conn.mContainerService == null) { 15088 return; 15089 } 15090 15091 final UserEnvironment userEnv = new UserEnvironment(curUser); 15092 clearDirectory(conn.mContainerService, 15093 userEnv.buildExternalStorageAppCacheDirs(packageName)); 15094 if (allData) { 15095 clearDirectory(conn.mContainerService, 15096 userEnv.buildExternalStorageAppDataDirs(packageName)); 15097 clearDirectory(conn.mContainerService, 15098 userEnv.buildExternalStorageAppMediaDirs(packageName)); 15099 } 15100 } 15101 } finally { 15102 mContext.unbindService(conn); 15103 } 15104 } 15105 } 15106 15107 @Override 15108 public void clearApplicationUserData(final String packageName, 15109 final IPackageDataObserver observer, final int userId) { 15110 mContext.enforceCallingOrSelfPermission( 15111 android.Manifest.permission.CLEAR_APP_USER_DATA, null); 15112 enforceCrossUserPermission(Binder.getCallingUid(), userId, 15113 true /* requireFullPermission */, false /* checkShell */, "clear application data"); 15114 // Queue up an async operation since the package deletion may take a little while. 15115 mHandler.post(new Runnable() { 15116 public void run() { 15117 mHandler.removeCallbacks(this); 15118 final boolean succeeded; 15119 synchronized (mInstallLock) { 15120 succeeded = clearApplicationUserDataLI(packageName, userId); 15121 } 15122 clearExternalStorageDataSync(packageName, userId, true); 15123 if (succeeded) { 15124 // invoke DeviceStorageMonitor's update method to clear any notifications 15125 DeviceStorageMonitorInternal 15126 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 15127 if (dsm != null) { 15128 dsm.checkMemory(); 15129 } 15130 } 15131 if(observer != null) { 15132 try { 15133 observer.onRemoveCompleted(packageName, succeeded); 15134 } catch (RemoteException e) { 15135 Log.i(TAG, "Observer no longer exists."); 15136 } 15137 } //end if observer 15138 } //end run 15139 }); 15140 } 15141 15142 private boolean clearApplicationUserDataLI(String packageName, int userId) { 15143 if (packageName == null) { 15144 Slog.w(TAG, "Attempt to delete null packageName."); 15145 return false; 15146 } 15147 15148 // Try finding details about the requested package 15149 PackageParser.Package pkg; 15150 synchronized (mPackages) { 15151 pkg = mPackages.get(packageName); 15152 if (pkg == null) { 15153 final PackageSetting ps = mSettings.mPackages.get(packageName); 15154 if (ps != null) { 15155 pkg = ps.pkg; 15156 } 15157 } 15158 15159 if (pkg == null) { 15160 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 15161 return false; 15162 } 15163 15164 PackageSetting ps = (PackageSetting) pkg.mExtras; 15165 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 15166 } 15167 15168 // Always delete data directories for package, even if we found no other 15169 // record of app. This helps users recover from UID mismatches without 15170 // resorting to a full data wipe. 15171 // TODO: triage flags as part of 26466827 15172 final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE; 15173 try { 15174 mInstaller.clearAppData(pkg.volumeUuid, packageName, userId, flags); 15175 } catch (InstallerException e) { 15176 Slog.w(TAG, "Couldn't remove cache files for package " + packageName, e); 15177 return false; 15178 } 15179 15180 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); 15181 removeKeystoreDataIfNeeded(userId, appId); 15182 15183 // Create a native library symlink only if we have native libraries 15184 // and if the native libraries are 32 bit libraries. We do not provide 15185 // this symlink for 64 bit libraries. 15186 if (pkg.applicationInfo.primaryCpuAbi != null && 15187 !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) { 15188 final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir; 15189 try { 15190 mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName, 15191 nativeLibPath, userId); 15192 } catch (InstallerException e) { 15193 Slog.w(TAG, "Failed linking native library dir", e); 15194 return false; 15195 } 15196 } 15197 15198 return true; 15199 } 15200 15201 /** 15202 * Reverts user permission state changes (permissions and flags) in 15203 * all packages for a given user. 15204 * 15205 * @param userId The device user for which to do a reset. 15206 */ 15207 private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) { 15208 final int packageCount = mPackages.size(); 15209 for (int i = 0; i < packageCount; i++) { 15210 PackageParser.Package pkg = mPackages.valueAt(i); 15211 PackageSetting ps = (PackageSetting) pkg.mExtras; 15212 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 15213 } 15214 } 15215 15216 /** 15217 * Reverts user permission state changes (permissions and flags). 15218 * 15219 * @param ps The package for which to reset. 15220 * @param userId The device user for which to do a reset. 15221 */ 15222 private void resetUserChangesToRuntimePermissionsAndFlagsLPw( 15223 final PackageSetting ps, final int userId) { 15224 if (ps.pkg == null) { 15225 return; 15226 } 15227 15228 // These are flags that can change base on user actions. 15229 final int userSettableMask = FLAG_PERMISSION_USER_SET 15230 | FLAG_PERMISSION_USER_FIXED 15231 | FLAG_PERMISSION_REVOKE_ON_UPGRADE 15232 | FLAG_PERMISSION_REVIEW_REQUIRED; 15233 15234 final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED 15235 | FLAG_PERMISSION_POLICY_FIXED; 15236 15237 boolean writeInstallPermissions = false; 15238 boolean writeRuntimePermissions = false; 15239 15240 final int permissionCount = ps.pkg.requestedPermissions.size(); 15241 for (int i = 0; i < permissionCount; i++) { 15242 String permission = ps.pkg.requestedPermissions.get(i); 15243 15244 BasePermission bp = mSettings.mPermissions.get(permission); 15245 if (bp == null) { 15246 continue; 15247 } 15248 15249 // If shared user we just reset the state to which only this app contributed. 15250 if (ps.sharedUser != null) { 15251 boolean used = false; 15252 final int packageCount = ps.sharedUser.packages.size(); 15253 for (int j = 0; j < packageCount; j++) { 15254 PackageSetting pkg = ps.sharedUser.packages.valueAt(j); 15255 if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName) 15256 && pkg.pkg.requestedPermissions.contains(permission)) { 15257 used = true; 15258 break; 15259 } 15260 } 15261 if (used) { 15262 continue; 15263 } 15264 } 15265 15266 PermissionsState permissionsState = ps.getPermissionsState(); 15267 15268 final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId); 15269 15270 // Always clear the user settable flags. 15271 final boolean hasInstallState = permissionsState.getInstallPermissionState( 15272 bp.name) != null; 15273 // If permission review is enabled and this is a legacy app, mark the 15274 // permission as requiring a review as this is the initial state. 15275 int flags = 0; 15276 if (Build.PERMISSIONS_REVIEW_REQUIRED 15277 && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 15278 flags |= FLAG_PERMISSION_REVIEW_REQUIRED; 15279 } 15280 if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) { 15281 if (hasInstallState) { 15282 writeInstallPermissions = true; 15283 } else { 15284 writeRuntimePermissions = true; 15285 } 15286 } 15287 15288 // Below is only runtime permission handling. 15289 if (!bp.isRuntime()) { 15290 continue; 15291 } 15292 15293 // Never clobber system or policy. 15294 if ((oldFlags & policyOrSystemFlags) != 0) { 15295 continue; 15296 } 15297 15298 // If this permission was granted by default, make sure it is. 15299 if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) { 15300 if (permissionsState.grantRuntimePermission(bp, userId) 15301 != PERMISSION_OPERATION_FAILURE) { 15302 writeRuntimePermissions = true; 15303 } 15304 // If permission review is enabled the permissions for a legacy apps 15305 // are represented as constantly granted runtime ones, so don't revoke. 15306 } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) { 15307 // Otherwise, reset the permission. 15308 final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId); 15309 switch (revokeResult) { 15310 case PERMISSION_OPERATION_SUCCESS: { 15311 writeRuntimePermissions = true; 15312 } break; 15313 15314 case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 15315 writeRuntimePermissions = true; 15316 final int appId = ps.appId; 15317 mHandler.post(new Runnable() { 15318 @Override 15319 public void run() { 15320 killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED); 15321 } 15322 }); 15323 } break; 15324 } 15325 } 15326 } 15327 15328 // Synchronously write as we are taking permissions away. 15329 if (writeRuntimePermissions) { 15330 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 15331 } 15332 15333 // Synchronously write as we are taking permissions away. 15334 if (writeInstallPermissions) { 15335 mSettings.writeLPr(); 15336 } 15337 } 15338 15339 /** 15340 * Remove entries from the keystore daemon. Will only remove it if the 15341 * {@code appId} is valid. 15342 */ 15343 private static void removeKeystoreDataIfNeeded(int userId, int appId) { 15344 if (appId < 0) { 15345 return; 15346 } 15347 15348 final KeyStore keyStore = KeyStore.getInstance(); 15349 if (keyStore != null) { 15350 if (userId == UserHandle.USER_ALL) { 15351 for (final int individual : sUserManager.getUserIds()) { 15352 keyStore.clearUid(UserHandle.getUid(individual, appId)); 15353 } 15354 } else { 15355 keyStore.clearUid(UserHandle.getUid(userId, appId)); 15356 } 15357 } else { 15358 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId); 15359 } 15360 } 15361 15362 @Override 15363 public void deleteApplicationCacheFiles(final String packageName, 15364 final IPackageDataObserver observer) { 15365 mContext.enforceCallingOrSelfPermission( 15366 android.Manifest.permission.DELETE_CACHE_FILES, null); 15367 // Queue up an async operation since the package deletion may take a little while. 15368 final int userId = UserHandle.getCallingUserId(); 15369 mHandler.post(new Runnable() { 15370 public void run() { 15371 mHandler.removeCallbacks(this); 15372 final boolean succeded; 15373 synchronized (mInstallLock) { 15374 succeded = deleteApplicationCacheFilesLI(packageName, userId); 15375 } 15376 clearExternalStorageDataSync(packageName, userId, false); 15377 if (observer != null) { 15378 try { 15379 observer.onRemoveCompleted(packageName, succeded); 15380 } catch (RemoteException e) { 15381 Log.i(TAG, "Observer no longer exists."); 15382 } 15383 } //end if observer 15384 } //end run 15385 }); 15386 } 15387 15388 private boolean deleteApplicationCacheFilesLI(String packageName, int userId) { 15389 if (packageName == null) { 15390 Slog.w(TAG, "Attempt to delete null packageName."); 15391 return false; 15392 } 15393 PackageParser.Package p; 15394 synchronized (mPackages) { 15395 p = mPackages.get(packageName); 15396 } 15397 if (p == null) { 15398 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 15399 return false; 15400 } 15401 final ApplicationInfo applicationInfo = p.applicationInfo; 15402 if (applicationInfo == null) { 15403 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 15404 return false; 15405 } 15406 // TODO: triage flags as part of 26466827 15407 final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE; 15408 try { 15409 mInstaller.clearAppData(p.volumeUuid, packageName, userId, 15410 flags | Installer.FLAG_CLEAR_CACHE_ONLY); 15411 } catch (InstallerException e) { 15412 Slog.w(TAG, "Couldn't remove cache files for package " 15413 + packageName + " u" + userId, e); 15414 return false; 15415 } 15416 return true; 15417 } 15418 15419 @Override 15420 public void getPackageSizeInfo(final String packageName, int userHandle, 15421 final IPackageStatsObserver observer) { 15422 mContext.enforceCallingOrSelfPermission( 15423 android.Manifest.permission.GET_PACKAGE_SIZE, null); 15424 if (packageName == null) { 15425 throw new IllegalArgumentException("Attempt to get size of null packageName"); 15426 } 15427 15428 PackageStats stats = new PackageStats(packageName, userHandle); 15429 15430 /* 15431 * Queue up an async operation since the package measurement may take a 15432 * little while. 15433 */ 15434 Message msg = mHandler.obtainMessage(INIT_COPY); 15435 msg.obj = new MeasureParams(stats, observer); 15436 mHandler.sendMessage(msg); 15437 } 15438 15439 private boolean getPackageSizeInfoLI(String packageName, int userHandle, 15440 PackageStats pStats) { 15441 if (packageName == null) { 15442 Slog.w(TAG, "Attempt to get size of null packageName."); 15443 return false; 15444 } 15445 PackageParser.Package p; 15446 boolean dataOnly = false; 15447 String libDirRoot = null; 15448 String asecPath = null; 15449 PackageSetting ps = null; 15450 synchronized (mPackages) { 15451 p = mPackages.get(packageName); 15452 ps = mSettings.mPackages.get(packageName); 15453 if(p == null) { 15454 dataOnly = true; 15455 if((ps == null) || (ps.pkg == null)) { 15456 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 15457 return false; 15458 } 15459 p = ps.pkg; 15460 } 15461 if (ps != null) { 15462 libDirRoot = ps.legacyNativeLibraryPathString; 15463 } 15464 if (p != null && (p.isForwardLocked() || p.applicationInfo.isExternalAsec())) { 15465 final long token = Binder.clearCallingIdentity(); 15466 try { 15467 String secureContainerId = cidFromCodePath(p.applicationInfo.getBaseCodePath()); 15468 if (secureContainerId != null) { 15469 asecPath = PackageHelper.getSdFilesystem(secureContainerId); 15470 } 15471 } finally { 15472 Binder.restoreCallingIdentity(token); 15473 } 15474 } 15475 } 15476 String publicSrcDir = null; 15477 if(!dataOnly) { 15478 final ApplicationInfo applicationInfo = p.applicationInfo; 15479 if (applicationInfo == null) { 15480 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 15481 return false; 15482 } 15483 if (p.isForwardLocked()) { 15484 publicSrcDir = applicationInfo.getBaseResourcePath(); 15485 } 15486 } 15487 // TODO: extend to measure size of split APKs 15488 // TODO(multiArch): Extend getSizeInfo to look at the full subdirectory tree, 15489 // not just the first level. 15490 // TODO(multiArch): Extend getSizeInfo to look at *all* instruction sets, not 15491 // just the primary. 15492 String[] dexCodeInstructionSets = getDexCodeInstructionSets(getAppDexInstructionSets(ps)); 15493 15494 String apkPath; 15495 File packageDir = new File(p.codePath); 15496 15497 if (packageDir.isDirectory() && p.canHaveOatDir()) { 15498 apkPath = packageDir.getAbsolutePath(); 15499 // If libDirRoot is inside a package dir, set it to null to avoid it being counted twice 15500 if (libDirRoot != null && libDirRoot.startsWith(apkPath)) { 15501 libDirRoot = null; 15502 } 15503 } else { 15504 apkPath = p.baseCodePath; 15505 } 15506 15507 // TODO: triage flags as part of 26466827 15508 final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE; 15509 try { 15510 mInstaller.getAppSize(p.volumeUuid, packageName, userHandle, flags, apkPath, 15511 libDirRoot, publicSrcDir, asecPath, dexCodeInstructionSets, pStats); 15512 } catch (InstallerException e) { 15513 return false; 15514 } 15515 15516 // Fix-up for forward-locked applications in ASEC containers. 15517 if (!isExternal(p)) { 15518 pStats.codeSize += pStats.externalCodeSize; 15519 pStats.externalCodeSize = 0L; 15520 } 15521 15522 return true; 15523 } 15524 15525 15526 @Override 15527 public void addPackageToPreferred(String packageName) { 15528 Slog.w(TAG, "addPackageToPreferred: this is now a no-op"); 15529 } 15530 15531 @Override 15532 public void removePackageFromPreferred(String packageName) { 15533 Slog.w(TAG, "removePackageFromPreferred: this is now a no-op"); 15534 } 15535 15536 @Override 15537 public List<PackageInfo> getPreferredPackages(int flags) { 15538 return new ArrayList<PackageInfo>(); 15539 } 15540 15541 private int getUidTargetSdkVersionLockedLPr(int uid) { 15542 Object obj = mSettings.getUserIdLPr(uid); 15543 if (obj instanceof SharedUserSetting) { 15544 final SharedUserSetting sus = (SharedUserSetting) obj; 15545 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT; 15546 final Iterator<PackageSetting> it = sus.packages.iterator(); 15547 while (it.hasNext()) { 15548 final PackageSetting ps = it.next(); 15549 if (ps.pkg != null) { 15550 int v = ps.pkg.applicationInfo.targetSdkVersion; 15551 if (v < vers) vers = v; 15552 } 15553 } 15554 return vers; 15555 } else if (obj instanceof PackageSetting) { 15556 final PackageSetting ps = (PackageSetting) obj; 15557 if (ps.pkg != null) { 15558 return ps.pkg.applicationInfo.targetSdkVersion; 15559 } 15560 } 15561 return Build.VERSION_CODES.CUR_DEVELOPMENT; 15562 } 15563 15564 @Override 15565 public void addPreferredActivity(IntentFilter filter, int match, 15566 ComponentName[] set, ComponentName activity, int userId) { 15567 addPreferredActivityInternal(filter, match, set, activity, true, userId, 15568 "Adding preferred"); 15569 } 15570 15571 private void addPreferredActivityInternal(IntentFilter filter, int match, 15572 ComponentName[] set, ComponentName activity, boolean always, int userId, 15573 String opname) { 15574 // writer 15575 int callingUid = Binder.getCallingUid(); 15576 enforceCrossUserPermission(callingUid, userId, 15577 true /* requireFullPermission */, false /* checkShell */, "add preferred activity"); 15578 if (filter.countActions() == 0) { 15579 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 15580 return; 15581 } 15582 synchronized (mPackages) { 15583 if (mContext.checkCallingOrSelfPermission( 15584 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 15585 != PackageManager.PERMISSION_GRANTED) { 15586 if (getUidTargetSdkVersionLockedLPr(callingUid) 15587 < Build.VERSION_CODES.FROYO) { 15588 Slog.w(TAG, "Ignoring addPreferredActivity() from uid " 15589 + callingUid); 15590 return; 15591 } 15592 mContext.enforceCallingOrSelfPermission( 15593 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 15594 } 15595 15596 PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId); 15597 Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user " 15598 + userId + ":"); 15599 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 15600 pir.addFilter(new PreferredActivity(filter, match, set, activity, always)); 15601 scheduleWritePackageRestrictionsLocked(userId); 15602 } 15603 } 15604 15605 @Override 15606 public void replacePreferredActivity(IntentFilter filter, int match, 15607 ComponentName[] set, ComponentName activity, int userId) { 15608 if (filter.countActions() != 1) { 15609 throw new IllegalArgumentException( 15610 "replacePreferredActivity expects filter to have only 1 action."); 15611 } 15612 if (filter.countDataAuthorities() != 0 15613 || filter.countDataPaths() != 0 15614 || filter.countDataSchemes() > 1 15615 || filter.countDataTypes() != 0) { 15616 throw new IllegalArgumentException( 15617 "replacePreferredActivity expects filter to have no data authorities, " + 15618 "paths, or types; and at most one scheme."); 15619 } 15620 15621 final int callingUid = Binder.getCallingUid(); 15622 enforceCrossUserPermission(callingUid, userId, 15623 true /* requireFullPermission */, false /* checkShell */, 15624 "replace preferred activity"); 15625 synchronized (mPackages) { 15626 if (mContext.checkCallingOrSelfPermission( 15627 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 15628 != PackageManager.PERMISSION_GRANTED) { 15629 if (getUidTargetSdkVersionLockedLPr(callingUid) 15630 < Build.VERSION_CODES.FROYO) { 15631 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid " 15632 + Binder.getCallingUid()); 15633 return; 15634 } 15635 mContext.enforceCallingOrSelfPermission( 15636 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 15637 } 15638 15639 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 15640 if (pir != null) { 15641 // Get all of the existing entries that exactly match this filter. 15642 ArrayList<PreferredActivity> existing = pir.findFilters(filter); 15643 if (existing != null && existing.size() == 1) { 15644 PreferredActivity cur = existing.get(0); 15645 if (DEBUG_PREFERRED) { 15646 Slog.i(TAG, "Checking replace of preferred:"); 15647 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 15648 if (!cur.mPref.mAlways) { 15649 Slog.i(TAG, " -- CUR; not mAlways!"); 15650 } else { 15651 Slog.i(TAG, " -- CUR: mMatch=" + cur.mPref.mMatch); 15652 Slog.i(TAG, " -- CUR: mSet=" 15653 + Arrays.toString(cur.mPref.mSetComponents)); 15654 Slog.i(TAG, " -- CUR: mComponent=" + cur.mPref.mShortComponent); 15655 Slog.i(TAG, " -- NEW: mMatch=" 15656 + (match&IntentFilter.MATCH_CATEGORY_MASK)); 15657 Slog.i(TAG, " -- CUR: mSet=" + Arrays.toString(set)); 15658 Slog.i(TAG, " -- CUR: mComponent=" + activity.flattenToShortString()); 15659 } 15660 } 15661 if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity) 15662 && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK) 15663 && cur.mPref.sameSet(set)) { 15664 // Setting the preferred activity to what it happens to be already 15665 if (DEBUG_PREFERRED) { 15666 Slog.i(TAG, "Replacing with same preferred activity " 15667 + cur.mPref.mShortComponent + " for user " 15668 + userId + ":"); 15669 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 15670 } 15671 return; 15672 } 15673 } 15674 15675 if (existing != null) { 15676 if (DEBUG_PREFERRED) { 15677 Slog.i(TAG, existing.size() + " existing preferred matches for:"); 15678 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 15679 } 15680 for (int i = 0; i < existing.size(); i++) { 15681 PreferredActivity pa = existing.get(i); 15682 if (DEBUG_PREFERRED) { 15683 Slog.i(TAG, "Removing existing preferred activity " 15684 + pa.mPref.mComponent + ":"); 15685 pa.dump(new LogPrinter(Log.INFO, TAG), " "); 15686 } 15687 pir.removeFilter(pa); 15688 } 15689 } 15690 } 15691 addPreferredActivityInternal(filter, match, set, activity, true, userId, 15692 "Replacing preferred"); 15693 } 15694 } 15695 15696 @Override 15697 public void clearPackagePreferredActivities(String packageName) { 15698 final int uid = Binder.getCallingUid(); 15699 // writer 15700 synchronized (mPackages) { 15701 PackageParser.Package pkg = mPackages.get(packageName); 15702 if (pkg == null || pkg.applicationInfo.uid != uid) { 15703 if (mContext.checkCallingOrSelfPermission( 15704 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 15705 != PackageManager.PERMISSION_GRANTED) { 15706 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid()) 15707 < Build.VERSION_CODES.FROYO) { 15708 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid " 15709 + Binder.getCallingUid()); 15710 return; 15711 } 15712 mContext.enforceCallingOrSelfPermission( 15713 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 15714 } 15715 } 15716 15717 int user = UserHandle.getCallingUserId(); 15718 if (clearPackagePreferredActivitiesLPw(packageName, user)) { 15719 scheduleWritePackageRestrictionsLocked(user); 15720 } 15721 } 15722 } 15723 15724 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 15725 boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) { 15726 ArrayList<PreferredActivity> removed = null; 15727 boolean changed = false; 15728 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 15729 final int thisUserId = mSettings.mPreferredActivities.keyAt(i); 15730 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 15731 if (userId != UserHandle.USER_ALL && userId != thisUserId) { 15732 continue; 15733 } 15734 Iterator<PreferredActivity> it = pir.filterIterator(); 15735 while (it.hasNext()) { 15736 PreferredActivity pa = it.next(); 15737 // Mark entry for removal only if it matches the package name 15738 // and the entry is of type "always". 15739 if (packageName == null || 15740 (pa.mPref.mComponent.getPackageName().equals(packageName) 15741 && pa.mPref.mAlways)) { 15742 if (removed == null) { 15743 removed = new ArrayList<PreferredActivity>(); 15744 } 15745 removed.add(pa); 15746 } 15747 } 15748 if (removed != null) { 15749 for (int j=0; j<removed.size(); j++) { 15750 PreferredActivity pa = removed.get(j); 15751 pir.removeFilter(pa); 15752 } 15753 changed = true; 15754 } 15755 } 15756 return changed; 15757 } 15758 15759 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 15760 private void clearIntentFilterVerificationsLPw(int userId) { 15761 final int packageCount = mPackages.size(); 15762 for (int i = 0; i < packageCount; i++) { 15763 PackageParser.Package pkg = mPackages.valueAt(i); 15764 clearIntentFilterVerificationsLPw(pkg.packageName, userId); 15765 } 15766 } 15767 15768 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 15769 void clearIntentFilterVerificationsLPw(String packageName, int userId) { 15770 if (userId == UserHandle.USER_ALL) { 15771 if (mSettings.removeIntentFilterVerificationLPw(packageName, 15772 sUserManager.getUserIds())) { 15773 for (int oneUserId : sUserManager.getUserIds()) { 15774 scheduleWritePackageRestrictionsLocked(oneUserId); 15775 } 15776 } 15777 } else { 15778 if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) { 15779 scheduleWritePackageRestrictionsLocked(userId); 15780 } 15781 } 15782 } 15783 15784 void clearDefaultBrowserIfNeeded(String packageName) { 15785 for (int oneUserId : sUserManager.getUserIds()) { 15786 String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId); 15787 if (TextUtils.isEmpty(defaultBrowserPackageName)) continue; 15788 if (packageName.equals(defaultBrowserPackageName)) { 15789 setDefaultBrowserPackageName(null, oneUserId); 15790 } 15791 } 15792 } 15793 15794 @Override 15795 public void resetApplicationPreferences(int userId) { 15796 mContext.enforceCallingOrSelfPermission( 15797 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 15798 // writer 15799 synchronized (mPackages) { 15800 final long identity = Binder.clearCallingIdentity(); 15801 try { 15802 clearPackagePreferredActivitiesLPw(null, userId); 15803 mSettings.applyDefaultPreferredAppsLPw(this, userId); 15804 // TODO: We have to reset the default SMS and Phone. This requires 15805 // significant refactoring to keep all default apps in the package 15806 // manager (cleaner but more work) or have the services provide 15807 // callbacks to the package manager to request a default app reset. 15808 applyFactoryDefaultBrowserLPw(userId); 15809 clearIntentFilterVerificationsLPw(userId); 15810 primeDomainVerificationsLPw(userId); 15811 resetUserChangesToRuntimePermissionsAndFlagsLPw(userId); 15812 scheduleWritePackageRestrictionsLocked(userId); 15813 } finally { 15814 Binder.restoreCallingIdentity(identity); 15815 } 15816 } 15817 } 15818 15819 @Override 15820 public int getPreferredActivities(List<IntentFilter> outFilters, 15821 List<ComponentName> outActivities, String packageName) { 15822 15823 int num = 0; 15824 final int userId = UserHandle.getCallingUserId(); 15825 // reader 15826 synchronized (mPackages) { 15827 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 15828 if (pir != null) { 15829 final Iterator<PreferredActivity> it = pir.filterIterator(); 15830 while (it.hasNext()) { 15831 final PreferredActivity pa = it.next(); 15832 if (packageName == null 15833 || (pa.mPref.mComponent.getPackageName().equals(packageName) 15834 && pa.mPref.mAlways)) { 15835 if (outFilters != null) { 15836 outFilters.add(new IntentFilter(pa)); 15837 } 15838 if (outActivities != null) { 15839 outActivities.add(pa.mPref.mComponent); 15840 } 15841 } 15842 } 15843 } 15844 } 15845 15846 return num; 15847 } 15848 15849 @Override 15850 public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity, 15851 int userId) { 15852 int callingUid = Binder.getCallingUid(); 15853 if (callingUid != Process.SYSTEM_UID) { 15854 throw new SecurityException( 15855 "addPersistentPreferredActivity can only be run by the system"); 15856 } 15857 if (filter.countActions() == 0) { 15858 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 15859 return; 15860 } 15861 synchronized (mPackages) { 15862 Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId + 15863 ":"); 15864 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 15865 mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter( 15866 new PersistentPreferredActivity(filter, activity)); 15867 scheduleWritePackageRestrictionsLocked(userId); 15868 } 15869 } 15870 15871 @Override 15872 public void clearPackagePersistentPreferredActivities(String packageName, int userId) { 15873 int callingUid = Binder.getCallingUid(); 15874 if (callingUid != Process.SYSTEM_UID) { 15875 throw new SecurityException( 15876 "clearPackagePersistentPreferredActivities can only be run by the system"); 15877 } 15878 ArrayList<PersistentPreferredActivity> removed = null; 15879 boolean changed = false; 15880 synchronized (mPackages) { 15881 for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) { 15882 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i); 15883 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 15884 .valueAt(i); 15885 if (userId != thisUserId) { 15886 continue; 15887 } 15888 Iterator<PersistentPreferredActivity> it = ppir.filterIterator(); 15889 while (it.hasNext()) { 15890 PersistentPreferredActivity ppa = it.next(); 15891 // Mark entry for removal only if it matches the package name. 15892 if (ppa.mComponent.getPackageName().equals(packageName)) { 15893 if (removed == null) { 15894 removed = new ArrayList<PersistentPreferredActivity>(); 15895 } 15896 removed.add(ppa); 15897 } 15898 } 15899 if (removed != null) { 15900 for (int j=0; j<removed.size(); j++) { 15901 PersistentPreferredActivity ppa = removed.get(j); 15902 ppir.removeFilter(ppa); 15903 } 15904 changed = true; 15905 } 15906 } 15907 15908 if (changed) { 15909 scheduleWritePackageRestrictionsLocked(userId); 15910 } 15911 } 15912 } 15913 15914 /** 15915 * Common machinery for picking apart a restored XML blob and passing 15916 * it to a caller-supplied functor to be applied to the running system. 15917 */ 15918 private void restoreFromXml(XmlPullParser parser, int userId, 15919 String expectedStartTag, BlobXmlRestorer functor) 15920 throws IOException, XmlPullParserException { 15921 int type; 15922 while ((type = parser.next()) != XmlPullParser.START_TAG 15923 && type != XmlPullParser.END_DOCUMENT) { 15924 } 15925 if (type != XmlPullParser.START_TAG) { 15926 // oops didn't find a start tag?! 15927 if (DEBUG_BACKUP) { 15928 Slog.e(TAG, "Didn't find start tag during restore"); 15929 } 15930 return; 15931 } 15932Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName()); 15933 // this is supposed to be TAG_PREFERRED_BACKUP 15934 if (!expectedStartTag.equals(parser.getName())) { 15935 if (DEBUG_BACKUP) { 15936 Slog.e(TAG, "Found unexpected tag " + parser.getName()); 15937 } 15938 return; 15939 } 15940 15941 // skip interfering stuff, then we're aligned with the backing implementation 15942 while ((type = parser.next()) == XmlPullParser.TEXT) { } 15943Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); 15944 functor.apply(parser, userId); 15945 } 15946 15947 private interface BlobXmlRestorer { 15948 public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException; 15949 } 15950 15951 /** 15952 * Non-Binder method, support for the backup/restore mechanism: write the 15953 * full set of preferred activities in its canonical XML format. Returns the 15954 * XML output as a byte array, or null if there is none. 15955 */ 15956 @Override 15957 public byte[] getPreferredActivityBackup(int userId) { 15958 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 15959 throw new SecurityException("Only the system may call getPreferredActivityBackup()"); 15960 } 15961 15962 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 15963 try { 15964 final XmlSerializer serializer = new FastXmlSerializer(); 15965 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 15966 serializer.startDocument(null, true); 15967 serializer.startTag(null, TAG_PREFERRED_BACKUP); 15968 15969 synchronized (mPackages) { 15970 mSettings.writePreferredActivitiesLPr(serializer, userId, true); 15971 } 15972 15973 serializer.endTag(null, TAG_PREFERRED_BACKUP); 15974 serializer.endDocument(); 15975 serializer.flush(); 15976 } catch (Exception e) { 15977 if (DEBUG_BACKUP) { 15978 Slog.e(TAG, "Unable to write preferred activities for backup", e); 15979 } 15980 return null; 15981 } 15982 15983 return dataStream.toByteArray(); 15984 } 15985 15986 @Override 15987 public void restorePreferredActivities(byte[] backup, int userId) { 15988 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 15989 throw new SecurityException("Only the system may call restorePreferredActivities()"); 15990 } 15991 15992 try { 15993 final XmlPullParser parser = Xml.newPullParser(); 15994 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 15995 restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP, 15996 new BlobXmlRestorer() { 15997 @Override 15998 public void apply(XmlPullParser parser, int userId) 15999 throws XmlPullParserException, IOException { 16000 synchronized (mPackages) { 16001 mSettings.readPreferredActivitiesLPw(parser, userId); 16002 } 16003 } 16004 } ); 16005 } catch (Exception e) { 16006 if (DEBUG_BACKUP) { 16007 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 16008 } 16009 } 16010 } 16011 16012 /** 16013 * Non-Binder method, support for the backup/restore mechanism: write the 16014 * default browser (etc) settings in its canonical XML format. Returns the default 16015 * browser XML representation as a byte array, or null if there is none. 16016 */ 16017 @Override 16018 public byte[] getDefaultAppsBackup(int userId) { 16019 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16020 throw new SecurityException("Only the system may call getDefaultAppsBackup()"); 16021 } 16022 16023 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 16024 try { 16025 final XmlSerializer serializer = new FastXmlSerializer(); 16026 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 16027 serializer.startDocument(null, true); 16028 serializer.startTag(null, TAG_DEFAULT_APPS); 16029 16030 synchronized (mPackages) { 16031 mSettings.writeDefaultAppsLPr(serializer, userId); 16032 } 16033 16034 serializer.endTag(null, TAG_DEFAULT_APPS); 16035 serializer.endDocument(); 16036 serializer.flush(); 16037 } catch (Exception e) { 16038 if (DEBUG_BACKUP) { 16039 Slog.e(TAG, "Unable to write default apps for backup", e); 16040 } 16041 return null; 16042 } 16043 16044 return dataStream.toByteArray(); 16045 } 16046 16047 @Override 16048 public void restoreDefaultApps(byte[] backup, int userId) { 16049 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16050 throw new SecurityException("Only the system may call restoreDefaultApps()"); 16051 } 16052 16053 try { 16054 final XmlPullParser parser = Xml.newPullParser(); 16055 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 16056 restoreFromXml(parser, userId, TAG_DEFAULT_APPS, 16057 new BlobXmlRestorer() { 16058 @Override 16059 public void apply(XmlPullParser parser, int userId) 16060 throws XmlPullParserException, IOException { 16061 synchronized (mPackages) { 16062 mSettings.readDefaultAppsLPw(parser, userId); 16063 } 16064 } 16065 } ); 16066 } catch (Exception e) { 16067 if (DEBUG_BACKUP) { 16068 Slog.e(TAG, "Exception restoring default apps: " + e.getMessage()); 16069 } 16070 } 16071 } 16072 16073 @Override 16074 public byte[] getIntentFilterVerificationBackup(int userId) { 16075 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16076 throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()"); 16077 } 16078 16079 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 16080 try { 16081 final XmlSerializer serializer = new FastXmlSerializer(); 16082 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 16083 serializer.startDocument(null, true); 16084 serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION); 16085 16086 synchronized (mPackages) { 16087 mSettings.writeAllDomainVerificationsLPr(serializer, userId); 16088 } 16089 16090 serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION); 16091 serializer.endDocument(); 16092 serializer.flush(); 16093 } catch (Exception e) { 16094 if (DEBUG_BACKUP) { 16095 Slog.e(TAG, "Unable to write default apps for backup", e); 16096 } 16097 return null; 16098 } 16099 16100 return dataStream.toByteArray(); 16101 } 16102 16103 @Override 16104 public void restoreIntentFilterVerification(byte[] backup, int userId) { 16105 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16106 throw new SecurityException("Only the system may call restorePreferredActivities()"); 16107 } 16108 16109 try { 16110 final XmlPullParser parser = Xml.newPullParser(); 16111 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 16112 restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION, 16113 new BlobXmlRestorer() { 16114 @Override 16115 public void apply(XmlPullParser parser, int userId) 16116 throws XmlPullParserException, IOException { 16117 synchronized (mPackages) { 16118 mSettings.readAllDomainVerificationsLPr(parser, userId); 16119 mSettings.writeLPr(); 16120 } 16121 } 16122 } ); 16123 } catch (Exception e) { 16124 if (DEBUG_BACKUP) { 16125 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 16126 } 16127 } 16128 } 16129 16130 @Override 16131 public byte[] getPermissionGrantBackup(int userId) { 16132 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16133 throw new SecurityException("Only the system may call getPermissionGrantBackup()"); 16134 } 16135 16136 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 16137 try { 16138 final XmlSerializer serializer = new FastXmlSerializer(); 16139 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 16140 serializer.startDocument(null, true); 16141 serializer.startTag(null, TAG_PERMISSION_BACKUP); 16142 16143 synchronized (mPackages) { 16144 serializeRuntimePermissionGrantsLPr(serializer, userId); 16145 } 16146 16147 serializer.endTag(null, TAG_PERMISSION_BACKUP); 16148 serializer.endDocument(); 16149 serializer.flush(); 16150 } catch (Exception e) { 16151 if (DEBUG_BACKUP) { 16152 Slog.e(TAG, "Unable to write default apps for backup", e); 16153 } 16154 return null; 16155 } 16156 16157 return dataStream.toByteArray(); 16158 } 16159 16160 @Override 16161 public void restorePermissionGrants(byte[] backup, int userId) { 16162 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16163 throw new SecurityException("Only the system may call restorePermissionGrants()"); 16164 } 16165 16166 try { 16167 final XmlPullParser parser = Xml.newPullParser(); 16168 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 16169 restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP, 16170 new BlobXmlRestorer() { 16171 @Override 16172 public void apply(XmlPullParser parser, int userId) 16173 throws XmlPullParserException, IOException { 16174 synchronized (mPackages) { 16175 processRestoredPermissionGrantsLPr(parser, userId); 16176 } 16177 } 16178 } ); 16179 } catch (Exception e) { 16180 if (DEBUG_BACKUP) { 16181 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 16182 } 16183 } 16184 } 16185 16186 private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId) 16187 throws IOException { 16188 serializer.startTag(null, TAG_ALL_GRANTS); 16189 16190 final int N = mSettings.mPackages.size(); 16191 for (int i = 0; i < N; i++) { 16192 final PackageSetting ps = mSettings.mPackages.valueAt(i); 16193 boolean pkgGrantsKnown = false; 16194 16195 PermissionsState packagePerms = ps.getPermissionsState(); 16196 16197 for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) { 16198 final int grantFlags = state.getFlags(); 16199 // only look at grants that are not system/policy fixed 16200 if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) { 16201 final boolean isGranted = state.isGranted(); 16202 // And only back up the user-twiddled state bits 16203 if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) { 16204 final String packageName = mSettings.mPackages.keyAt(i); 16205 if (!pkgGrantsKnown) { 16206 serializer.startTag(null, TAG_GRANT); 16207 serializer.attribute(null, ATTR_PACKAGE_NAME, packageName); 16208 pkgGrantsKnown = true; 16209 } 16210 16211 final boolean userSet = 16212 (grantFlags & FLAG_PERMISSION_USER_SET) != 0; 16213 final boolean userFixed = 16214 (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0; 16215 final boolean revoke = 16216 (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0; 16217 16218 serializer.startTag(null, TAG_PERMISSION); 16219 serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName()); 16220 if (isGranted) { 16221 serializer.attribute(null, ATTR_IS_GRANTED, "true"); 16222 } 16223 if (userSet) { 16224 serializer.attribute(null, ATTR_USER_SET, "true"); 16225 } 16226 if (userFixed) { 16227 serializer.attribute(null, ATTR_USER_FIXED, "true"); 16228 } 16229 if (revoke) { 16230 serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true"); 16231 } 16232 serializer.endTag(null, TAG_PERMISSION); 16233 } 16234 } 16235 } 16236 16237 if (pkgGrantsKnown) { 16238 serializer.endTag(null, TAG_GRANT); 16239 } 16240 } 16241 16242 serializer.endTag(null, TAG_ALL_GRANTS); 16243 } 16244 16245 private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId) 16246 throws XmlPullParserException, IOException { 16247 String pkgName = null; 16248 int outerDepth = parser.getDepth(); 16249 int type; 16250 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 16251 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 16252 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 16253 continue; 16254 } 16255 16256 final String tagName = parser.getName(); 16257 if (tagName.equals(TAG_GRANT)) { 16258 pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME); 16259 if (DEBUG_BACKUP) { 16260 Slog.v(TAG, "+++ Restoring grants for package " + pkgName); 16261 } 16262 } else if (tagName.equals(TAG_PERMISSION)) { 16263 16264 final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED)); 16265 final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME); 16266 16267 int newFlagSet = 0; 16268 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) { 16269 newFlagSet |= FLAG_PERMISSION_USER_SET; 16270 } 16271 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) { 16272 newFlagSet |= FLAG_PERMISSION_USER_FIXED; 16273 } 16274 if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) { 16275 newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE; 16276 } 16277 if (DEBUG_BACKUP) { 16278 Slog.v(TAG, " + Restoring grant: pkg=" + pkgName + " perm=" + permName 16279 + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet)); 16280 } 16281 final PackageSetting ps = mSettings.mPackages.get(pkgName); 16282 if (ps != null) { 16283 // Already installed so we apply the grant immediately 16284 if (DEBUG_BACKUP) { 16285 Slog.v(TAG, " + already installed; applying"); 16286 } 16287 PermissionsState perms = ps.getPermissionsState(); 16288 BasePermission bp = mSettings.mPermissions.get(permName); 16289 if (bp != null) { 16290 if (isGranted) { 16291 perms.grantRuntimePermission(bp, userId); 16292 } 16293 if (newFlagSet != 0) { 16294 perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet); 16295 } 16296 } 16297 } else { 16298 // Need to wait for post-restore install to apply the grant 16299 if (DEBUG_BACKUP) { 16300 Slog.v(TAG, " - not yet installed; saving for later"); 16301 } 16302 mSettings.processRestoredPermissionGrantLPr(pkgName, permName, 16303 isGranted, newFlagSet, userId); 16304 } 16305 } else { 16306 PackageManagerService.reportSettingsProblem(Log.WARN, 16307 "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName); 16308 XmlUtils.skipCurrentTag(parser); 16309 } 16310 } 16311 16312 scheduleWriteSettingsLocked(); 16313 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 16314 } 16315 16316 @Override 16317 public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage, 16318 int sourceUserId, int targetUserId, int flags) { 16319 mContext.enforceCallingOrSelfPermission( 16320 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 16321 int callingUid = Binder.getCallingUid(); 16322 enforceOwnerRights(ownerPackage, callingUid); 16323 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 16324 if (intentFilter.countActions() == 0) { 16325 Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions"); 16326 return; 16327 } 16328 synchronized (mPackages) { 16329 CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter, 16330 ownerPackage, targetUserId, flags); 16331 CrossProfileIntentResolver resolver = 16332 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 16333 ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter); 16334 // We have all those whose filter is equal. Now checking if the rest is equal as well. 16335 if (existing != null) { 16336 int size = existing.size(); 16337 for (int i = 0; i < size; i++) { 16338 if (newFilter.equalsIgnoreFilter(existing.get(i))) { 16339 return; 16340 } 16341 } 16342 } 16343 resolver.addFilter(newFilter); 16344 scheduleWritePackageRestrictionsLocked(sourceUserId); 16345 } 16346 } 16347 16348 @Override 16349 public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) { 16350 mContext.enforceCallingOrSelfPermission( 16351 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 16352 int callingUid = Binder.getCallingUid(); 16353 enforceOwnerRights(ownerPackage, callingUid); 16354 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 16355 synchronized (mPackages) { 16356 CrossProfileIntentResolver resolver = 16357 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 16358 ArraySet<CrossProfileIntentFilter> set = 16359 new ArraySet<CrossProfileIntentFilter>(resolver.filterSet()); 16360 for (CrossProfileIntentFilter filter : set) { 16361 if (filter.getOwnerPackage().equals(ownerPackage)) { 16362 resolver.removeFilter(filter); 16363 } 16364 } 16365 scheduleWritePackageRestrictionsLocked(sourceUserId); 16366 } 16367 } 16368 16369 // Enforcing that callingUid is owning pkg on userId 16370 private void enforceOwnerRights(String pkg, int callingUid) { 16371 // The system owns everything. 16372 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) { 16373 return; 16374 } 16375 int callingUserId = UserHandle.getUserId(callingUid); 16376 PackageInfo pi = getPackageInfo(pkg, 0, callingUserId); 16377 if (pi == null) { 16378 throw new IllegalArgumentException("Unknown package " + pkg + " on user " 16379 + callingUserId); 16380 } 16381 if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) { 16382 throw new SecurityException("Calling uid " + callingUid 16383 + " does not own package " + pkg); 16384 } 16385 } 16386 16387 @Override 16388 public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) { 16389 Intent intent = new Intent(Intent.ACTION_MAIN); 16390 intent.addCategory(Intent.CATEGORY_HOME); 16391 16392 final int callingUserId = UserHandle.getCallingUserId(); 16393 List<ResolveInfo> list = queryIntentActivities(intent, null, 16394 PackageManager.GET_META_DATA, callingUserId); 16395 ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0, 16396 true, false, false, callingUserId); 16397 16398 allHomeCandidates.clear(); 16399 if (list != null) { 16400 for (ResolveInfo ri : list) { 16401 allHomeCandidates.add(ri); 16402 } 16403 } 16404 return (preferred == null || preferred.activityInfo == null) 16405 ? null 16406 : new ComponentName(preferred.activityInfo.packageName, 16407 preferred.activityInfo.name); 16408 } 16409 16410 @Override 16411 public void setApplicationEnabledSetting(String appPackageName, 16412 int newState, int flags, int userId, String callingPackage) { 16413 if (!sUserManager.exists(userId)) return; 16414 if (callingPackage == null) { 16415 callingPackage = Integer.toString(Binder.getCallingUid()); 16416 } 16417 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage); 16418 } 16419 16420 @Override 16421 public void setComponentEnabledSetting(ComponentName componentName, 16422 int newState, int flags, int userId) { 16423 if (!sUserManager.exists(userId)) return; 16424 setEnabledSetting(componentName.getPackageName(), 16425 componentName.getClassName(), newState, flags, userId, null); 16426 } 16427 16428 private void setEnabledSetting(final String packageName, String className, int newState, 16429 final int flags, int userId, String callingPackage) { 16430 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT 16431 || newState == COMPONENT_ENABLED_STATE_ENABLED 16432 || newState == COMPONENT_ENABLED_STATE_DISABLED 16433 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER 16434 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) { 16435 throw new IllegalArgumentException("Invalid new component state: " 16436 + newState); 16437 } 16438 PackageSetting pkgSetting; 16439 final int uid = Binder.getCallingUid(); 16440 final int permission = mContext.checkCallingOrSelfPermission( 16441 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 16442 enforceCrossUserPermission(uid, userId, 16443 false /* requireFullPermission */, true /* checkShell */, "set enabled"); 16444 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 16445 boolean sendNow = false; 16446 boolean isApp = (className == null); 16447 String componentName = isApp ? packageName : className; 16448 int packageUid = -1; 16449 ArrayList<String> components; 16450 16451 // writer 16452 synchronized (mPackages) { 16453 pkgSetting = mSettings.mPackages.get(packageName); 16454 if (pkgSetting == null) { 16455 if (className == null) { 16456 throw new IllegalArgumentException("Unknown package: " + packageName); 16457 } 16458 throw new IllegalArgumentException( 16459 "Unknown component: " + packageName + "/" + className); 16460 } 16461 // Allow root and verify that userId is not being specified by a different user 16462 if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) { 16463 throw new SecurityException( 16464 "Permission Denial: attempt to change component state from pid=" 16465 + Binder.getCallingPid() 16466 + ", uid=" + uid + ", package uid=" + pkgSetting.appId); 16467 } 16468 if (className == null) { 16469 // We're dealing with an application/package level state change 16470 if (pkgSetting.getEnabled(userId) == newState) { 16471 // Nothing to do 16472 return; 16473 } 16474 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT 16475 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { 16476 // Don't care about who enables an app. 16477 callingPackage = null; 16478 } 16479 pkgSetting.setEnabled(newState, userId, callingPackage); 16480 // pkgSetting.pkg.mSetEnabled = newState; 16481 } else { 16482 // We're dealing with a component level state change 16483 // First, verify that this is a valid class name. 16484 PackageParser.Package pkg = pkgSetting.pkg; 16485 if (pkg == null || !pkg.hasComponentClassName(className)) { 16486 if (pkg != null && 16487 pkg.applicationInfo.targetSdkVersion >= 16488 Build.VERSION_CODES.JELLY_BEAN) { 16489 throw new IllegalArgumentException("Component class " + className 16490 + " does not exist in " + packageName); 16491 } else { 16492 Slog.w(TAG, "Failed setComponentEnabledSetting: component class " 16493 + className + " does not exist in " + packageName); 16494 } 16495 } 16496 switch (newState) { 16497 case COMPONENT_ENABLED_STATE_ENABLED: 16498 if (!pkgSetting.enableComponentLPw(className, userId)) { 16499 return; 16500 } 16501 break; 16502 case COMPONENT_ENABLED_STATE_DISABLED: 16503 if (!pkgSetting.disableComponentLPw(className, userId)) { 16504 return; 16505 } 16506 break; 16507 case COMPONENT_ENABLED_STATE_DEFAULT: 16508 if (!pkgSetting.restoreComponentLPw(className, userId)) { 16509 return; 16510 } 16511 break; 16512 default: 16513 Slog.e(TAG, "Invalid new component state: " + newState); 16514 return; 16515 } 16516 } 16517 scheduleWritePackageRestrictionsLocked(userId); 16518 components = mPendingBroadcasts.get(userId, packageName); 16519 final boolean newPackage = components == null; 16520 if (newPackage) { 16521 components = new ArrayList<String>(); 16522 } 16523 if (!components.contains(componentName)) { 16524 components.add(componentName); 16525 } 16526 if ((flags&PackageManager.DONT_KILL_APP) == 0) { 16527 sendNow = true; 16528 // Purge entry from pending broadcast list if another one exists already 16529 // since we are sending one right away. 16530 mPendingBroadcasts.remove(userId, packageName); 16531 } else { 16532 if (newPackage) { 16533 mPendingBroadcasts.put(userId, packageName, components); 16534 } 16535 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) { 16536 // Schedule a message 16537 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY); 16538 } 16539 } 16540 } 16541 16542 long callingId = Binder.clearCallingIdentity(); 16543 try { 16544 if (sendNow) { 16545 packageUid = UserHandle.getUid(userId, pkgSetting.appId); 16546 sendPackageChangedBroadcast(packageName, 16547 (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid); 16548 } 16549 } finally { 16550 Binder.restoreCallingIdentity(callingId); 16551 } 16552 } 16553 16554 private void sendPackageChangedBroadcast(String packageName, 16555 boolean killFlag, ArrayList<String> componentNames, int packageUid) { 16556 if (DEBUG_INSTALL) 16557 Log.v(TAG, "Sending package changed: package=" + packageName + " components=" 16558 + componentNames); 16559 Bundle extras = new Bundle(4); 16560 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0)); 16561 String nameList[] = new String[componentNames.size()]; 16562 componentNames.toArray(nameList); 16563 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList); 16564 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag); 16565 extras.putInt(Intent.EXTRA_UID, packageUid); 16566 // If this is not reporting a change of the overall package, then only send it 16567 // to registered receivers. We don't want to launch a swath of apps for every 16568 // little component state change. 16569 final int flags = !componentNames.contains(packageName) 16570 ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0; 16571 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, flags, null, null, 16572 new int[] {UserHandle.getUserId(packageUid)}); 16573 } 16574 16575 @Override 16576 public void setPackageStoppedState(String packageName, boolean stopped, int userId) { 16577 if (!sUserManager.exists(userId)) return; 16578 final int uid = Binder.getCallingUid(); 16579 final int permission = mContext.checkCallingOrSelfPermission( 16580 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 16581 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 16582 enforceCrossUserPermission(uid, userId, 16583 true /* requireFullPermission */, true /* checkShell */, "stop package"); 16584 // writer 16585 synchronized (mPackages) { 16586 if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped, 16587 allowedByPermission, uid, userId)) { 16588 scheduleWritePackageRestrictionsLocked(userId); 16589 } 16590 } 16591 } 16592 16593 @Override 16594 public String getInstallerPackageName(String packageName) { 16595 // reader 16596 synchronized (mPackages) { 16597 return mSettings.getInstallerPackageNameLPr(packageName); 16598 } 16599 } 16600 16601 @Override 16602 public int getApplicationEnabledSetting(String packageName, int userId) { 16603 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 16604 int uid = Binder.getCallingUid(); 16605 enforceCrossUserPermission(uid, userId, 16606 false /* requireFullPermission */, false /* checkShell */, "get enabled"); 16607 // reader 16608 synchronized (mPackages) { 16609 return mSettings.getApplicationEnabledSettingLPr(packageName, userId); 16610 } 16611 } 16612 16613 @Override 16614 public int getComponentEnabledSetting(ComponentName componentName, int userId) { 16615 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 16616 int uid = Binder.getCallingUid(); 16617 enforceCrossUserPermission(uid, userId, 16618 false /* requireFullPermission */, false /* checkShell */, "get component enabled"); 16619 // reader 16620 synchronized (mPackages) { 16621 return mSettings.getComponentEnabledSettingLPr(componentName, userId); 16622 } 16623 } 16624 16625 @Override 16626 public void enterSafeMode() { 16627 enforceSystemOrRoot("Only the system can request entering safe mode"); 16628 16629 if (!mSystemReady) { 16630 mSafeMode = true; 16631 } 16632 } 16633 16634 @Override 16635 public void systemReady() { 16636 mSystemReady = true; 16637 16638 // Read the compatibilty setting when the system is ready. 16639 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt( 16640 mContext.getContentResolver(), 16641 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1; 16642 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled); 16643 if (DEBUG_SETTINGS) { 16644 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled); 16645 } 16646 16647 int[] grantPermissionsUserIds = EMPTY_INT_ARRAY; 16648 16649 synchronized (mPackages) { 16650 // Verify that all of the preferred activity components actually 16651 // exist. It is possible for applications to be updated and at 16652 // that point remove a previously declared activity component that 16653 // had been set as a preferred activity. We try to clean this up 16654 // the next time we encounter that preferred activity, but it is 16655 // possible for the user flow to never be able to return to that 16656 // situation so here we do a sanity check to make sure we haven't 16657 // left any junk around. 16658 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>(); 16659 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 16660 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 16661 removed.clear(); 16662 for (PreferredActivity pa : pir.filterSet()) { 16663 if (mActivities.mActivities.get(pa.mPref.mComponent) == null) { 16664 removed.add(pa); 16665 } 16666 } 16667 if (removed.size() > 0) { 16668 for (int r=0; r<removed.size(); r++) { 16669 PreferredActivity pa = removed.get(r); 16670 Slog.w(TAG, "Removing dangling preferred activity: " 16671 + pa.mPref.mComponent); 16672 pir.removeFilter(pa); 16673 } 16674 mSettings.writePackageRestrictionsLPr( 16675 mSettings.mPreferredActivities.keyAt(i)); 16676 } 16677 } 16678 16679 for (int userId : UserManagerService.getInstance().getUserIds()) { 16680 if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) { 16681 grantPermissionsUserIds = ArrayUtils.appendInt( 16682 grantPermissionsUserIds, userId); 16683 } 16684 } 16685 } 16686 sUserManager.systemReady(); 16687 16688 // If we upgraded grant all default permissions before kicking off. 16689 for (int userId : grantPermissionsUserIds) { 16690 mDefaultPermissionPolicy.grantDefaultPermissions(userId); 16691 } 16692 16693 // Kick off any messages waiting for system ready 16694 if (mPostSystemReadyMessages != null) { 16695 for (Message msg : mPostSystemReadyMessages) { 16696 msg.sendToTarget(); 16697 } 16698 mPostSystemReadyMessages = null; 16699 } 16700 16701 // Watch for external volumes that come and go over time 16702 final StorageManager storage = mContext.getSystemService(StorageManager.class); 16703 storage.registerListener(mStorageListener); 16704 16705 mInstallerService.systemReady(); 16706 mPackageDexOptimizer.systemReady(); 16707 16708 MountServiceInternal mountServiceInternal = LocalServices.getService( 16709 MountServiceInternal.class); 16710 mountServiceInternal.addExternalStoragePolicy( 16711 new MountServiceInternal.ExternalStorageMountPolicy() { 16712 @Override 16713 public int getMountMode(int uid, String packageName) { 16714 if (Process.isIsolated(uid)) { 16715 return Zygote.MOUNT_EXTERNAL_NONE; 16716 } 16717 if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) { 16718 return Zygote.MOUNT_EXTERNAL_DEFAULT; 16719 } 16720 if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { 16721 return Zygote.MOUNT_EXTERNAL_DEFAULT; 16722 } 16723 if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { 16724 return Zygote.MOUNT_EXTERNAL_READ; 16725 } 16726 return Zygote.MOUNT_EXTERNAL_WRITE; 16727 } 16728 16729 @Override 16730 public boolean hasExternalStorage(int uid, String packageName) { 16731 return true; 16732 } 16733 }); 16734 } 16735 16736 @Override 16737 public boolean isSafeMode() { 16738 return mSafeMode; 16739 } 16740 16741 @Override 16742 public boolean hasSystemUidErrors() { 16743 return mHasSystemUidErrors; 16744 } 16745 16746 static String arrayToString(int[] array) { 16747 StringBuffer buf = new StringBuffer(128); 16748 buf.append('['); 16749 if (array != null) { 16750 for (int i=0; i<array.length; i++) { 16751 if (i > 0) buf.append(", "); 16752 buf.append(array[i]); 16753 } 16754 } 16755 buf.append(']'); 16756 return buf.toString(); 16757 } 16758 16759 static class DumpState { 16760 public static final int DUMP_LIBS = 1 << 0; 16761 public static final int DUMP_FEATURES = 1 << 1; 16762 public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2; 16763 public static final int DUMP_SERVICE_RESOLVERS = 1 << 3; 16764 public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4; 16765 public static final int DUMP_CONTENT_RESOLVERS = 1 << 5; 16766 public static final int DUMP_PERMISSIONS = 1 << 6; 16767 public static final int DUMP_PACKAGES = 1 << 7; 16768 public static final int DUMP_SHARED_USERS = 1 << 8; 16769 public static final int DUMP_MESSAGES = 1 << 9; 16770 public static final int DUMP_PROVIDERS = 1 << 10; 16771 public static final int DUMP_VERIFIERS = 1 << 11; 16772 public static final int DUMP_PREFERRED = 1 << 12; 16773 public static final int DUMP_PREFERRED_XML = 1 << 13; 16774 public static final int DUMP_KEYSETS = 1 << 14; 16775 public static final int DUMP_VERSION = 1 << 15; 16776 public static final int DUMP_INSTALLS = 1 << 16; 16777 public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17; 16778 public static final int DUMP_DOMAIN_PREFERRED = 1 << 18; 16779 16780 public static final int OPTION_SHOW_FILTERS = 1 << 0; 16781 16782 private int mTypes; 16783 16784 private int mOptions; 16785 16786 private boolean mTitlePrinted; 16787 16788 private SharedUserSetting mSharedUser; 16789 16790 public boolean isDumping(int type) { 16791 if (mTypes == 0 && type != DUMP_PREFERRED_XML) { 16792 return true; 16793 } 16794 16795 return (mTypes & type) != 0; 16796 } 16797 16798 public void setDump(int type) { 16799 mTypes |= type; 16800 } 16801 16802 public boolean isOptionEnabled(int option) { 16803 return (mOptions & option) != 0; 16804 } 16805 16806 public void setOptionEnabled(int option) { 16807 mOptions |= option; 16808 } 16809 16810 public boolean onTitlePrinted() { 16811 final boolean printed = mTitlePrinted; 16812 mTitlePrinted = true; 16813 return printed; 16814 } 16815 16816 public boolean getTitlePrinted() { 16817 return mTitlePrinted; 16818 } 16819 16820 public void setTitlePrinted(boolean enabled) { 16821 mTitlePrinted = enabled; 16822 } 16823 16824 public SharedUserSetting getSharedUser() { 16825 return mSharedUser; 16826 } 16827 16828 public void setSharedUser(SharedUserSetting user) { 16829 mSharedUser = user; 16830 } 16831 } 16832 16833 @Override 16834 public void onShellCommand(FileDescriptor in, FileDescriptor out, 16835 FileDescriptor err, String[] args, ResultReceiver resultReceiver) { 16836 (new PackageManagerShellCommand(this)).exec( 16837 this, in, out, err, args, resultReceiver); 16838 } 16839 16840 @Override 16841 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 16842 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 16843 != PackageManager.PERMISSION_GRANTED) { 16844 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 16845 + Binder.getCallingPid() 16846 + ", uid=" + Binder.getCallingUid() 16847 + " without permission " 16848 + android.Manifest.permission.DUMP); 16849 return; 16850 } 16851 16852 DumpState dumpState = new DumpState(); 16853 boolean fullPreferred = false; 16854 boolean checkin = false; 16855 16856 String packageName = null; 16857 ArraySet<String> permissionNames = null; 16858 16859 int opti = 0; 16860 while (opti < args.length) { 16861 String opt = args[opti]; 16862 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 16863 break; 16864 } 16865 opti++; 16866 16867 if ("-a".equals(opt)) { 16868 // Right now we only know how to print all. 16869 } else if ("-h".equals(opt)) { 16870 pw.println("Package manager dump options:"); 16871 pw.println(" [-h] [-f] [--checkin] [cmd] ..."); 16872 pw.println(" --checkin: dump for a checkin"); 16873 pw.println(" -f: print details of intent filters"); 16874 pw.println(" -h: print this help"); 16875 pw.println(" cmd may be one of:"); 16876 pw.println(" l[ibraries]: list known shared libraries"); 16877 pw.println(" f[eatures]: list device features"); 16878 pw.println(" k[eysets]: print known keysets"); 16879 pw.println(" r[esolvers] [activity|service|receiver|content]: dump intent resolvers"); 16880 pw.println(" perm[issions]: dump permissions"); 16881 pw.println(" permission [name ...]: dump declaration and use of given permission"); 16882 pw.println(" pref[erred]: print preferred package settings"); 16883 pw.println(" preferred-xml [--full]: print preferred package settings as xml"); 16884 pw.println(" prov[iders]: dump content providers"); 16885 pw.println(" p[ackages]: dump installed packages"); 16886 pw.println(" s[hared-users]: dump shared user IDs"); 16887 pw.println(" m[essages]: print collected runtime messages"); 16888 pw.println(" v[erifiers]: print package verifier info"); 16889 pw.println(" d[omain-preferred-apps]: print domains preferred apps"); 16890 pw.println(" i[ntent-filter-verifiers]|ifv: print intent filter verifier info"); 16891 pw.println(" version: print database version info"); 16892 pw.println(" write: write current settings now"); 16893 pw.println(" installs: details about install sessions"); 16894 pw.println(" check-permission <permission> <package> [<user>]: does pkg hold perm?"); 16895 pw.println(" <package.name>: info about given package"); 16896 return; 16897 } else if ("--checkin".equals(opt)) { 16898 checkin = true; 16899 } else if ("-f".equals(opt)) { 16900 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 16901 } else { 16902 pw.println("Unknown argument: " + opt + "; use -h for help"); 16903 } 16904 } 16905 16906 // Is the caller requesting to dump a particular piece of data? 16907 if (opti < args.length) { 16908 String cmd = args[opti]; 16909 opti++; 16910 // Is this a package name? 16911 if ("android".equals(cmd) || cmd.contains(".")) { 16912 packageName = cmd; 16913 // When dumping a single package, we always dump all of its 16914 // filter information since the amount of data will be reasonable. 16915 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 16916 } else if ("check-permission".equals(cmd)) { 16917 if (opti >= args.length) { 16918 pw.println("Error: check-permission missing permission argument"); 16919 return; 16920 } 16921 String perm = args[opti]; 16922 opti++; 16923 if (opti >= args.length) { 16924 pw.println("Error: check-permission missing package argument"); 16925 return; 16926 } 16927 String pkg = args[opti]; 16928 opti++; 16929 int user = UserHandle.getUserId(Binder.getCallingUid()); 16930 if (opti < args.length) { 16931 try { 16932 user = Integer.parseInt(args[opti]); 16933 } catch (NumberFormatException e) { 16934 pw.println("Error: check-permission user argument is not a number: " 16935 + args[opti]); 16936 return; 16937 } 16938 } 16939 pw.println(checkPermission(perm, pkg, user)); 16940 return; 16941 } else if ("l".equals(cmd) || "libraries".equals(cmd)) { 16942 dumpState.setDump(DumpState.DUMP_LIBS); 16943 } else if ("f".equals(cmd) || "features".equals(cmd)) { 16944 dumpState.setDump(DumpState.DUMP_FEATURES); 16945 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) { 16946 if (opti >= args.length) { 16947 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS 16948 | DumpState.DUMP_SERVICE_RESOLVERS 16949 | DumpState.DUMP_RECEIVER_RESOLVERS 16950 | DumpState.DUMP_CONTENT_RESOLVERS); 16951 } else { 16952 while (opti < args.length) { 16953 String name = args[opti]; 16954 if ("a".equals(name) || "activity".equals(name)) { 16955 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS); 16956 } else if ("s".equals(name) || "service".equals(name)) { 16957 dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS); 16958 } else if ("r".equals(name) || "receiver".equals(name)) { 16959 dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS); 16960 } else if ("c".equals(name) || "content".equals(name)) { 16961 dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS); 16962 } else { 16963 pw.println("Error: unknown resolver table type: " + name); 16964 return; 16965 } 16966 opti++; 16967 } 16968 } 16969 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) { 16970 dumpState.setDump(DumpState.DUMP_PERMISSIONS); 16971 } else if ("permission".equals(cmd)) { 16972 if (opti >= args.length) { 16973 pw.println("Error: permission requires permission name"); 16974 return; 16975 } 16976 permissionNames = new ArraySet<>(); 16977 while (opti < args.length) { 16978 permissionNames.add(args[opti]); 16979 opti++; 16980 } 16981 dumpState.setDump(DumpState.DUMP_PERMISSIONS 16982 | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS); 16983 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) { 16984 dumpState.setDump(DumpState.DUMP_PREFERRED); 16985 } else if ("preferred-xml".equals(cmd)) { 16986 dumpState.setDump(DumpState.DUMP_PREFERRED_XML); 16987 if (opti < args.length && "--full".equals(args[opti])) { 16988 fullPreferred = true; 16989 opti++; 16990 } 16991 } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) { 16992 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED); 16993 } else if ("p".equals(cmd) || "packages".equals(cmd)) { 16994 dumpState.setDump(DumpState.DUMP_PACKAGES); 16995 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) { 16996 dumpState.setDump(DumpState.DUMP_SHARED_USERS); 16997 } else if ("prov".equals(cmd) || "providers".equals(cmd)) { 16998 dumpState.setDump(DumpState.DUMP_PROVIDERS); 16999 } else if ("m".equals(cmd) || "messages".equals(cmd)) { 17000 dumpState.setDump(DumpState.DUMP_MESSAGES); 17001 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) { 17002 dumpState.setDump(DumpState.DUMP_VERIFIERS); 17003 } else if ("i".equals(cmd) || "ifv".equals(cmd) 17004 || "intent-filter-verifiers".equals(cmd)) { 17005 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS); 17006 } else if ("version".equals(cmd)) { 17007 dumpState.setDump(DumpState.DUMP_VERSION); 17008 } else if ("k".equals(cmd) || "keysets".equals(cmd)) { 17009 dumpState.setDump(DumpState.DUMP_KEYSETS); 17010 } else if ("installs".equals(cmd)) { 17011 dumpState.setDump(DumpState.DUMP_INSTALLS); 17012 } else if ("write".equals(cmd)) { 17013 synchronized (mPackages) { 17014 mSettings.writeLPr(); 17015 pw.println("Settings written."); 17016 return; 17017 } 17018 } 17019 } 17020 17021 if (checkin) { 17022 pw.println("vers,1"); 17023 } 17024 17025 // reader 17026 synchronized (mPackages) { 17027 if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) { 17028 if (!checkin) { 17029 if (dumpState.onTitlePrinted()) 17030 pw.println(); 17031 pw.println("Database versions:"); 17032 mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, " ")); 17033 } 17034 } 17035 17036 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) { 17037 if (!checkin) { 17038 if (dumpState.onTitlePrinted()) 17039 pw.println(); 17040 pw.println("Verifiers:"); 17041 pw.print(" Required: "); 17042 pw.print(mRequiredVerifierPackage); 17043 pw.print(" (uid="); 17044 pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 17045 UserHandle.USER_SYSTEM)); 17046 pw.println(")"); 17047 } else if (mRequiredVerifierPackage != null) { 17048 pw.print("vrfy,"); pw.print(mRequiredVerifierPackage); 17049 pw.print(","); 17050 pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 17051 UserHandle.USER_SYSTEM)); 17052 } 17053 } 17054 17055 if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) && 17056 packageName == null) { 17057 if (mIntentFilterVerifierComponent != null) { 17058 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName(); 17059 if (!checkin) { 17060 if (dumpState.onTitlePrinted()) 17061 pw.println(); 17062 pw.println("Intent Filter Verifier:"); 17063 pw.print(" Using: "); 17064 pw.print(verifierPackageName); 17065 pw.print(" (uid="); 17066 pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING, 17067 UserHandle.USER_SYSTEM)); 17068 pw.println(")"); 17069 } else if (verifierPackageName != null) { 17070 pw.print("ifv,"); pw.print(verifierPackageName); 17071 pw.print(","); 17072 pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING, 17073 UserHandle.USER_SYSTEM)); 17074 } 17075 } else { 17076 pw.println(); 17077 pw.println("No Intent Filter Verifier available!"); 17078 } 17079 } 17080 17081 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) { 17082 boolean printedHeader = false; 17083 final Iterator<String> it = mSharedLibraries.keySet().iterator(); 17084 while (it.hasNext()) { 17085 String name = it.next(); 17086 SharedLibraryEntry ent = mSharedLibraries.get(name); 17087 if (!checkin) { 17088 if (!printedHeader) { 17089 if (dumpState.onTitlePrinted()) 17090 pw.println(); 17091 pw.println("Libraries:"); 17092 printedHeader = true; 17093 } 17094 pw.print(" "); 17095 } else { 17096 pw.print("lib,"); 17097 } 17098 pw.print(name); 17099 if (!checkin) { 17100 pw.print(" -> "); 17101 } 17102 if (ent.path != null) { 17103 if (!checkin) { 17104 pw.print("(jar) "); 17105 pw.print(ent.path); 17106 } else { 17107 pw.print(",jar,"); 17108 pw.print(ent.path); 17109 } 17110 } else { 17111 if (!checkin) { 17112 pw.print("(apk) "); 17113 pw.print(ent.apk); 17114 } else { 17115 pw.print(",apk,"); 17116 pw.print(ent.apk); 17117 } 17118 } 17119 pw.println(); 17120 } 17121 } 17122 17123 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) { 17124 if (dumpState.onTitlePrinted()) 17125 pw.println(); 17126 if (!checkin) { 17127 pw.println("Features:"); 17128 } 17129 17130 for (FeatureInfo feat : mAvailableFeatures.values()) { 17131 if (checkin) { 17132 pw.print("feat,"); 17133 pw.print(feat.name); 17134 pw.print(","); 17135 pw.println(feat.version); 17136 } else { 17137 pw.print(" "); 17138 pw.print(feat.name); 17139 if (feat.version > 0) { 17140 pw.print(" version="); 17141 pw.print(feat.version); 17142 } 17143 pw.println(); 17144 } 17145 } 17146 } 17147 17148 if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) { 17149 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:" 17150 : "Activity Resolver Table:", " ", packageName, 17151 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 17152 dumpState.setTitlePrinted(true); 17153 } 17154 } 17155 if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) { 17156 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:" 17157 : "Receiver Resolver Table:", " ", packageName, 17158 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 17159 dumpState.setTitlePrinted(true); 17160 } 17161 } 17162 if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) { 17163 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:" 17164 : "Service Resolver Table:", " ", packageName, 17165 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 17166 dumpState.setTitlePrinted(true); 17167 } 17168 } 17169 if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) { 17170 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:" 17171 : "Provider Resolver Table:", " ", packageName, 17172 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 17173 dumpState.setTitlePrinted(true); 17174 } 17175 } 17176 17177 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) { 17178 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 17179 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 17180 int user = mSettings.mPreferredActivities.keyAt(i); 17181 if (pir.dump(pw, 17182 dumpState.getTitlePrinted() 17183 ? "\nPreferred Activities User " + user + ":" 17184 : "Preferred Activities User " + user + ":", " ", 17185 packageName, true, false)) { 17186 dumpState.setTitlePrinted(true); 17187 } 17188 } 17189 } 17190 17191 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) { 17192 pw.flush(); 17193 FileOutputStream fout = new FileOutputStream(fd); 17194 BufferedOutputStream str = new BufferedOutputStream(fout); 17195 XmlSerializer serializer = new FastXmlSerializer(); 17196 try { 17197 serializer.setOutput(str, StandardCharsets.UTF_8.name()); 17198 serializer.startDocument(null, true); 17199 serializer.setFeature( 17200 "http://xmlpull.org/v1/doc/features.html#indent-output", true); 17201 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred); 17202 serializer.endDocument(); 17203 serializer.flush(); 17204 } catch (IllegalArgumentException e) { 17205 pw.println("Failed writing: " + e); 17206 } catch (IllegalStateException e) { 17207 pw.println("Failed writing: " + e); 17208 } catch (IOException e) { 17209 pw.println("Failed writing: " + e); 17210 } 17211 } 17212 17213 if (!checkin 17214 && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED) 17215 && packageName == null) { 17216 pw.println(); 17217 int count = mSettings.mPackages.size(); 17218 if (count == 0) { 17219 pw.println("No applications!"); 17220 pw.println(); 17221 } else { 17222 final String prefix = " "; 17223 Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values(); 17224 if (allPackageSettings.size() == 0) { 17225 pw.println("No domain preferred apps!"); 17226 pw.println(); 17227 } else { 17228 pw.println("App verification status:"); 17229 pw.println(); 17230 count = 0; 17231 for (PackageSetting ps : allPackageSettings) { 17232 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo(); 17233 if (ivi == null || ivi.getPackageName() == null) continue; 17234 pw.println(prefix + "Package: " + ivi.getPackageName()); 17235 pw.println(prefix + "Domains: " + ivi.getDomainsString()); 17236 pw.println(prefix + "Status: " + ivi.getStatusString()); 17237 pw.println(); 17238 count++; 17239 } 17240 if (count == 0) { 17241 pw.println(prefix + "No app verification established."); 17242 pw.println(); 17243 } 17244 for (int userId : sUserManager.getUserIds()) { 17245 pw.println("App linkages for user " + userId + ":"); 17246 pw.println(); 17247 count = 0; 17248 for (PackageSetting ps : allPackageSettings) { 17249 final long status = ps.getDomainVerificationStatusForUser(userId); 17250 if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 17251 continue; 17252 } 17253 pw.println(prefix + "Package: " + ps.name); 17254 pw.println(prefix + "Domains: " + dumpDomainString(ps.name)); 17255 String statusStr = IntentFilterVerificationInfo. 17256 getStatusStringFromValue(status); 17257 pw.println(prefix + "Status: " + statusStr); 17258 pw.println(); 17259 count++; 17260 } 17261 if (count == 0) { 17262 pw.println(prefix + "No configured app linkages."); 17263 pw.println(); 17264 } 17265 } 17266 } 17267 } 17268 } 17269 17270 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) { 17271 mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState); 17272 if (packageName == null && permissionNames == null) { 17273 for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) { 17274 if (iperm == 0) { 17275 if (dumpState.onTitlePrinted()) 17276 pw.println(); 17277 pw.println("AppOp Permissions:"); 17278 } 17279 pw.print(" AppOp Permission "); 17280 pw.print(mAppOpPermissionPackages.keyAt(iperm)); 17281 pw.println(":"); 17282 ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm); 17283 for (int ipkg=0; ipkg<pkgs.size(); ipkg++) { 17284 pw.print(" "); pw.println(pkgs.valueAt(ipkg)); 17285 } 17286 } 17287 } 17288 } 17289 17290 if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) { 17291 boolean printedSomething = false; 17292 for (PackageParser.Provider p : mProviders.mProviders.values()) { 17293 if (packageName != null && !packageName.equals(p.info.packageName)) { 17294 continue; 17295 } 17296 if (!printedSomething) { 17297 if (dumpState.onTitlePrinted()) 17298 pw.println(); 17299 pw.println("Registered ContentProviders:"); 17300 printedSomething = true; 17301 } 17302 pw.print(" "); p.printComponentShortName(pw); pw.println(":"); 17303 pw.print(" "); pw.println(p.toString()); 17304 } 17305 printedSomething = false; 17306 for (Map.Entry<String, PackageParser.Provider> entry : 17307 mProvidersByAuthority.entrySet()) { 17308 PackageParser.Provider p = entry.getValue(); 17309 if (packageName != null && !packageName.equals(p.info.packageName)) { 17310 continue; 17311 } 17312 if (!printedSomething) { 17313 if (dumpState.onTitlePrinted()) 17314 pw.println(); 17315 pw.println("ContentProvider Authorities:"); 17316 printedSomething = true; 17317 } 17318 pw.print(" ["); pw.print(entry.getKey()); pw.println("]:"); 17319 pw.print(" "); pw.println(p.toString()); 17320 if (p.info != null && p.info.applicationInfo != null) { 17321 final String appInfo = p.info.applicationInfo.toString(); 17322 pw.print(" applicationInfo="); pw.println(appInfo); 17323 } 17324 } 17325 } 17326 17327 if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) { 17328 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState); 17329 } 17330 17331 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) { 17332 mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin); 17333 } 17334 17335 if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) { 17336 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin); 17337 } 17338 17339 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) { 17340 mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState); 17341 } 17342 17343 if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) { 17344 // XXX should handle packageName != null by dumping only install data that 17345 // the given package is involved with. 17346 if (dumpState.onTitlePrinted()) pw.println(); 17347 mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120)); 17348 } 17349 17350 if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) { 17351 if (dumpState.onTitlePrinted()) pw.println(); 17352 mSettings.dumpReadMessagesLPr(pw, dumpState); 17353 17354 pw.println(); 17355 pw.println("Package warning messages:"); 17356 BufferedReader in = null; 17357 String line = null; 17358 try { 17359 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 17360 while ((line = in.readLine()) != null) { 17361 if (line.contains("ignored: updated version")) continue; 17362 pw.println(line); 17363 } 17364 } catch (IOException ignored) { 17365 } finally { 17366 IoUtils.closeQuietly(in); 17367 } 17368 } 17369 17370 if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) { 17371 BufferedReader in = null; 17372 String line = null; 17373 try { 17374 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 17375 while ((line = in.readLine()) != null) { 17376 if (line.contains("ignored: updated version")) continue; 17377 pw.print("msg,"); 17378 pw.println(line); 17379 } 17380 } catch (IOException ignored) { 17381 } finally { 17382 IoUtils.closeQuietly(in); 17383 } 17384 } 17385 } 17386 } 17387 17388 private String dumpDomainString(String packageName) { 17389 List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName); 17390 List<IntentFilter> filters = getAllIntentFilters(packageName); 17391 17392 ArraySet<String> result = new ArraySet<>(); 17393 if (iviList.size() > 0) { 17394 for (IntentFilterVerificationInfo ivi : iviList) { 17395 for (String host : ivi.getDomains()) { 17396 result.add(host); 17397 } 17398 } 17399 } 17400 if (filters != null && filters.size() > 0) { 17401 for (IntentFilter filter : filters) { 17402 if (filter.hasCategory(Intent.CATEGORY_BROWSABLE) 17403 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 17404 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) { 17405 result.addAll(filter.getHostsList()); 17406 } 17407 } 17408 } 17409 17410 StringBuilder sb = new StringBuilder(result.size() * 16); 17411 for (String domain : result) { 17412 if (sb.length() > 0) sb.append(" "); 17413 sb.append(domain); 17414 } 17415 return sb.toString(); 17416 } 17417 17418 // ------- apps on sdcard specific code ------- 17419 static final boolean DEBUG_SD_INSTALL = false; 17420 17421 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD"; 17422 17423 private static final String SD_ENCRYPTION_ALGORITHM = "AES"; 17424 17425 private boolean mMediaMounted = false; 17426 17427 static String getEncryptKey() { 17428 try { 17429 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString( 17430 SD_ENCRYPTION_KEYSTORE_NAME); 17431 if (sdEncKey == null) { 17432 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128, 17433 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME); 17434 if (sdEncKey == null) { 17435 Slog.e(TAG, "Failed to create encryption keys"); 17436 return null; 17437 } 17438 } 17439 return sdEncKey; 17440 } catch (NoSuchAlgorithmException nsae) { 17441 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae); 17442 return null; 17443 } catch (IOException ioe) { 17444 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe); 17445 return null; 17446 } 17447 } 17448 17449 /* 17450 * Update media status on PackageManager. 17451 */ 17452 @Override 17453 public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) { 17454 int callingUid = Binder.getCallingUid(); 17455 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 17456 throw new SecurityException("Media status can only be updated by the system"); 17457 } 17458 // reader; this apparently protects mMediaMounted, but should probably 17459 // be a different lock in that case. 17460 synchronized (mPackages) { 17461 Log.i(TAG, "Updating external media status from " 17462 + (mMediaMounted ? "mounted" : "unmounted") + " to " 17463 + (mediaStatus ? "mounted" : "unmounted")); 17464 if (DEBUG_SD_INSTALL) 17465 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus 17466 + ", mMediaMounted=" + mMediaMounted); 17467 if (mediaStatus == mMediaMounted) { 17468 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 17469 : 0, -1); 17470 mHandler.sendMessage(msg); 17471 return; 17472 } 17473 mMediaMounted = mediaStatus; 17474 } 17475 // Queue up an async operation since the package installation may take a 17476 // little while. 17477 mHandler.post(new Runnable() { 17478 public void run() { 17479 updateExternalMediaStatusInner(mediaStatus, reportStatus, true); 17480 } 17481 }); 17482 } 17483 17484 /** 17485 * Called by MountService when the initial ASECs to scan are available. 17486 * Should block until all the ASEC containers are finished being scanned. 17487 */ 17488 public void scanAvailableAsecs() { 17489 updateExternalMediaStatusInner(true, false, false); 17490 } 17491 17492 /* 17493 * Collect information of applications on external media, map them against 17494 * existing containers and update information based on current mount status. 17495 * Please note that we always have to report status if reportStatus has been 17496 * set to true especially when unloading packages. 17497 */ 17498 private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus, 17499 boolean externalStorage) { 17500 ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>(); 17501 int[] uidArr = EmptyArray.INT; 17502 17503 final String[] list = PackageHelper.getSecureContainerList(); 17504 if (ArrayUtils.isEmpty(list)) { 17505 Log.i(TAG, "No secure containers found"); 17506 } else { 17507 // Process list of secure containers and categorize them 17508 // as active or stale based on their package internal state. 17509 17510 // reader 17511 synchronized (mPackages) { 17512 for (String cid : list) { 17513 // Leave stages untouched for now; installer service owns them 17514 if (PackageInstallerService.isStageName(cid)) continue; 17515 17516 if (DEBUG_SD_INSTALL) 17517 Log.i(TAG, "Processing container " + cid); 17518 String pkgName = getAsecPackageName(cid); 17519 if (pkgName == null) { 17520 Slog.i(TAG, "Found stale container " + cid + " with no package name"); 17521 continue; 17522 } 17523 if (DEBUG_SD_INSTALL) 17524 Log.i(TAG, "Looking for pkg : " + pkgName); 17525 17526 final PackageSetting ps = mSettings.mPackages.get(pkgName); 17527 if (ps == null) { 17528 Slog.i(TAG, "Found stale container " + cid + " with no matching settings"); 17529 continue; 17530 } 17531 17532 /* 17533 * Skip packages that are not external if we're unmounting 17534 * external storage. 17535 */ 17536 if (externalStorage && !isMounted && !isExternal(ps)) { 17537 continue; 17538 } 17539 17540 final AsecInstallArgs args = new AsecInstallArgs(cid, 17541 getAppDexInstructionSets(ps), ps.isForwardLocked()); 17542 // The package status is changed only if the code path 17543 // matches between settings and the container id. 17544 if (ps.codePathString != null 17545 && ps.codePathString.startsWith(args.getCodePath())) { 17546 if (DEBUG_SD_INSTALL) { 17547 Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName 17548 + " at code path: " + ps.codePathString); 17549 } 17550 17551 // We do have a valid package installed on sdcard 17552 processCids.put(args, ps.codePathString); 17553 final int uid = ps.appId; 17554 if (uid != -1) { 17555 uidArr = ArrayUtils.appendInt(uidArr, uid); 17556 } 17557 } else { 17558 Slog.i(TAG, "Found stale container " + cid + ": expected codePath=" 17559 + ps.codePathString); 17560 } 17561 } 17562 } 17563 17564 Arrays.sort(uidArr); 17565 } 17566 17567 // Process packages with valid entries. 17568 if (isMounted) { 17569 if (DEBUG_SD_INSTALL) 17570 Log.i(TAG, "Loading packages"); 17571 loadMediaPackages(processCids, uidArr, externalStorage); 17572 startCleaningPackages(); 17573 mInstallerService.onSecureContainersAvailable(); 17574 } else { 17575 if (DEBUG_SD_INSTALL) 17576 Log.i(TAG, "Unloading packages"); 17577 unloadMediaPackages(processCids, uidArr, reportStatus); 17578 } 17579 } 17580 17581 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 17582 ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) { 17583 final int size = infos.size(); 17584 final String[] packageNames = new String[size]; 17585 final int[] packageUids = new int[size]; 17586 for (int i = 0; i < size; i++) { 17587 final ApplicationInfo info = infos.get(i); 17588 packageNames[i] = info.packageName; 17589 packageUids[i] = info.uid; 17590 } 17591 sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids, 17592 finishedReceiver); 17593 } 17594 17595 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 17596 ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 17597 sendResourcesChangedBroadcast(mediaStatus, replacing, 17598 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver); 17599 } 17600 17601 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 17602 String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 17603 int size = pkgList.length; 17604 if (size > 0) { 17605 // Send broadcasts here 17606 Bundle extras = new Bundle(); 17607 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 17608 if (uidArr != null) { 17609 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr); 17610 } 17611 if (replacing) { 17612 extras.putBoolean(Intent.EXTRA_REPLACING, replacing); 17613 } 17614 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE 17615 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE; 17616 sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null); 17617 } 17618 } 17619 17620 /* 17621 * Look at potentially valid container ids from processCids If package 17622 * information doesn't match the one on record or package scanning fails, 17623 * the cid is added to list of removeCids. We currently don't delete stale 17624 * containers. 17625 */ 17626 private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr, 17627 boolean externalStorage) { 17628 ArrayList<String> pkgList = new ArrayList<String>(); 17629 Set<AsecInstallArgs> keys = processCids.keySet(); 17630 17631 for (AsecInstallArgs args : keys) { 17632 String codePath = processCids.get(args); 17633 if (DEBUG_SD_INSTALL) 17634 Log.i(TAG, "Loading container : " + args.cid); 17635 int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 17636 try { 17637 // Make sure there are no container errors first. 17638 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) { 17639 Slog.e(TAG, "Failed to mount cid : " + args.cid 17640 + " when installing from sdcard"); 17641 continue; 17642 } 17643 // Check code path here. 17644 if (codePath == null || !codePath.startsWith(args.getCodePath())) { 17645 Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath() 17646 + " does not match one in settings " + codePath); 17647 continue; 17648 } 17649 // Parse package 17650 int parseFlags = mDefParseFlags; 17651 if (args.isExternalAsec()) { 17652 parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE; 17653 } 17654 if (args.isFwdLocked()) { 17655 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 17656 } 17657 17658 synchronized (mInstallLock) { 17659 PackageParser.Package pkg = null; 17660 try { 17661 pkg = scanPackageTracedLI(new File(codePath), parseFlags, 0, 0, null); 17662 } catch (PackageManagerException e) { 17663 Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage()); 17664 } 17665 // Scan the package 17666 if (pkg != null) { 17667 /* 17668 * TODO why is the lock being held? doPostInstall is 17669 * called in other places without the lock. This needs 17670 * to be straightened out. 17671 */ 17672 // writer 17673 synchronized (mPackages) { 17674 retCode = PackageManager.INSTALL_SUCCEEDED; 17675 pkgList.add(pkg.packageName); 17676 // Post process args 17677 args.doPostInstall(PackageManager.INSTALL_SUCCEEDED, 17678 pkg.applicationInfo.uid); 17679 } 17680 } else { 17681 Slog.i(TAG, "Failed to install pkg from " + codePath + " from sdcard"); 17682 } 17683 } 17684 17685 } finally { 17686 if (retCode != PackageManager.INSTALL_SUCCEEDED) { 17687 Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode); 17688 } 17689 } 17690 } 17691 // writer 17692 synchronized (mPackages) { 17693 // If the platform SDK has changed since the last time we booted, 17694 // we need to re-grant app permission to catch any new ones that 17695 // appear. This is really a hack, and means that apps can in some 17696 // cases get permissions that the user didn't initially explicitly 17697 // allow... it would be nice to have some better way to handle 17698 // this situation. 17699 final VersionInfo ver = externalStorage ? mSettings.getExternalVersion() 17700 : mSettings.getInternalVersion(); 17701 final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL 17702 : StorageManager.UUID_PRIVATE_INTERNAL; 17703 17704 int updateFlags = UPDATE_PERMISSIONS_ALL; 17705 if (ver.sdkVersion != mSdkVersion) { 17706 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " 17707 + mSdkVersion + "; regranting permissions for external"); 17708 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 17709 } 17710 updatePermissionsLPw(null, null, volumeUuid, updateFlags); 17711 17712 // Yay, everything is now upgraded 17713 ver.forceCurrent(); 17714 17715 // can downgrade to reader 17716 // Persist settings 17717 mSettings.writeLPr(); 17718 } 17719 // Send a broadcast to let everyone know we are done processing 17720 if (pkgList.size() > 0) { 17721 sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null); 17722 } 17723 } 17724 17725 /* 17726 * Utility method to unload a list of specified containers 17727 */ 17728 private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) { 17729 // Just unmount all valid containers. 17730 for (AsecInstallArgs arg : cidArgs) { 17731 synchronized (mInstallLock) { 17732 arg.doPostDeleteLI(false); 17733 } 17734 } 17735 } 17736 17737 /* 17738 * Unload packages mounted on external media. This involves deleting package 17739 * data from internal structures, sending broadcasts about disabled packages, 17740 * gc'ing to free up references, unmounting all secure containers 17741 * corresponding to packages on external media, and posting a 17742 * UPDATED_MEDIA_STATUS message if status has been requested. Please note 17743 * that we always have to post this message if status has been requested no 17744 * matter what. 17745 */ 17746 private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[], 17747 final boolean reportStatus) { 17748 if (DEBUG_SD_INSTALL) 17749 Log.i(TAG, "unloading media packages"); 17750 ArrayList<String> pkgList = new ArrayList<String>(); 17751 ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>(); 17752 final Set<AsecInstallArgs> keys = processCids.keySet(); 17753 for (AsecInstallArgs args : keys) { 17754 String pkgName = args.getPackageName(); 17755 if (DEBUG_SD_INSTALL) 17756 Log.i(TAG, "Trying to unload pkg : " + pkgName); 17757 // Delete package internally 17758 PackageRemovedInfo outInfo = new PackageRemovedInfo(); 17759 synchronized (mInstallLock) { 17760 boolean res = deletePackageLI(pkgName, null, false, null, 17761 PackageManager.DELETE_KEEP_DATA, outInfo, false, null); 17762 if (res) { 17763 pkgList.add(pkgName); 17764 } else { 17765 Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName); 17766 failedList.add(args); 17767 } 17768 } 17769 } 17770 17771 // reader 17772 synchronized (mPackages) { 17773 // We didn't update the settings after removing each package; 17774 // write them now for all packages. 17775 mSettings.writeLPr(); 17776 } 17777 17778 // We have to absolutely send UPDATED_MEDIA_STATUS only 17779 // after confirming that all the receivers processed the ordered 17780 // broadcast when packages get disabled, force a gc to clean things up. 17781 // and unload all the containers. 17782 if (pkgList.size() > 0) { 17783 sendResourcesChangedBroadcast(false, false, pkgList, uidArr, 17784 new IIntentReceiver.Stub() { 17785 public void performReceive(Intent intent, int resultCode, String data, 17786 Bundle extras, boolean ordered, boolean sticky, 17787 int sendingUser) throws RemoteException { 17788 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, 17789 reportStatus ? 1 : 0, 1, keys); 17790 mHandler.sendMessage(msg); 17791 } 17792 }); 17793 } else { 17794 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1, 17795 keys); 17796 mHandler.sendMessage(msg); 17797 } 17798 } 17799 17800 private void loadPrivatePackages(final VolumeInfo vol) { 17801 mHandler.post(new Runnable() { 17802 @Override 17803 public void run() { 17804 loadPrivatePackagesInner(vol); 17805 } 17806 }); 17807 } 17808 17809 private void loadPrivatePackagesInner(VolumeInfo vol) { 17810 final String volumeUuid = vol.fsUuid; 17811 if (TextUtils.isEmpty(volumeUuid)) { 17812 Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring"); 17813 return; 17814 } 17815 17816 final ArrayList<ApplicationInfo> loaded = new ArrayList<>(); 17817 final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE; 17818 17819 final VersionInfo ver; 17820 final List<PackageSetting> packages; 17821 synchronized (mPackages) { 17822 ver = mSettings.findOrCreateVersion(volumeUuid); 17823 packages = mSettings.getVolumePackagesLPr(volumeUuid); 17824 } 17825 17826 // TODO: introduce a new concept similar to "frozen" to prevent these 17827 // apps from being launched until after data has been fully reconciled 17828 for (PackageSetting ps : packages) { 17829 synchronized (mInstallLock) { 17830 final PackageParser.Package pkg; 17831 try { 17832 pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null); 17833 loaded.add(pkg.applicationInfo); 17834 17835 } catch (PackageManagerException e) { 17836 Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage()); 17837 } 17838 17839 if (!Build.FINGERPRINT.equals(ver.fingerprint)) { 17840 deleteCodeCacheDirsLI(ps.volumeUuid, ps.name); 17841 } 17842 } 17843 } 17844 17845 // Reconcile app data for all started/unlocked users 17846 final StorageManager sm = mContext.getSystemService(StorageManager.class); 17847 final UserManager um = mContext.getSystemService(UserManager.class); 17848 for (UserInfo user : um.getUsers()) { 17849 final int flags; 17850 if (um.isUserUnlocked(user.id)) { 17851 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 17852 } else if (um.isUserRunning(user.id)) { 17853 flags = StorageManager.FLAG_STORAGE_DE; 17854 } else { 17855 continue; 17856 } 17857 17858 sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags); 17859 reconcileAppsData(volumeUuid, user.id, flags); 17860 } 17861 17862 synchronized (mPackages) { 17863 int updateFlags = UPDATE_PERMISSIONS_ALL; 17864 if (ver.sdkVersion != mSdkVersion) { 17865 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " 17866 + mSdkVersion + "; regranting permissions for " + volumeUuid); 17867 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 17868 } 17869 updatePermissionsLPw(null, null, volumeUuid, updateFlags); 17870 17871 // Yay, everything is now upgraded 17872 ver.forceCurrent(); 17873 17874 mSettings.writeLPr(); 17875 } 17876 17877 if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded); 17878 sendResourcesChangedBroadcast(true, false, loaded, null); 17879 } 17880 17881 private void unloadPrivatePackages(final VolumeInfo vol) { 17882 mHandler.post(new Runnable() { 17883 @Override 17884 public void run() { 17885 unloadPrivatePackagesInner(vol); 17886 } 17887 }); 17888 } 17889 17890 private void unloadPrivatePackagesInner(VolumeInfo vol) { 17891 final String volumeUuid = vol.fsUuid; 17892 if (TextUtils.isEmpty(volumeUuid)) { 17893 Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring"); 17894 return; 17895 } 17896 17897 final ArrayList<ApplicationInfo> unloaded = new ArrayList<>(); 17898 synchronized (mInstallLock) { 17899 synchronized (mPackages) { 17900 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid); 17901 for (PackageSetting ps : packages) { 17902 if (ps.pkg == null) continue; 17903 17904 final ApplicationInfo info = ps.pkg.applicationInfo; 17905 final PackageRemovedInfo outInfo = new PackageRemovedInfo(); 17906 if (deletePackageLI(ps.name, null, false, null, 17907 PackageManager.DELETE_KEEP_DATA, outInfo, false, null)) { 17908 unloaded.add(info); 17909 } else { 17910 Slog.w(TAG, "Failed to unload " + ps.codePath); 17911 } 17912 } 17913 17914 mSettings.writeLPr(); 17915 } 17916 } 17917 17918 if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded); 17919 sendResourcesChangedBroadcast(false, false, unloaded, null); 17920 } 17921 17922 /** 17923 * Examine all users present on given mounted volume, and destroy data 17924 * belonging to users that are no longer valid, or whose user ID has been 17925 * recycled. 17926 */ 17927 private void reconcileUsers(String volumeUuid) { 17928 // TODO: also reconcile DE directories 17929 final File[] files = FileUtils 17930 .listFilesOrEmpty(Environment.getDataUserCeDirectory(volumeUuid)); 17931 for (File file : files) { 17932 if (!file.isDirectory()) continue; 17933 17934 final int userId; 17935 final UserInfo info; 17936 try { 17937 userId = Integer.parseInt(file.getName()); 17938 info = sUserManager.getUserInfo(userId); 17939 } catch (NumberFormatException e) { 17940 Slog.w(TAG, "Invalid user directory " + file); 17941 continue; 17942 } 17943 17944 boolean destroyUser = false; 17945 if (info == null) { 17946 logCriticalInfo(Log.WARN, "Destroying user directory " + file 17947 + " because no matching user was found"); 17948 destroyUser = true; 17949 } else { 17950 try { 17951 UserManagerService.enforceSerialNumber(file, info.serialNumber); 17952 } catch (IOException e) { 17953 logCriticalInfo(Log.WARN, "Destroying user directory " + file 17954 + " because we failed to enforce serial number: " + e); 17955 destroyUser = true; 17956 } 17957 } 17958 17959 if (destroyUser) { 17960 synchronized (mInstallLock) { 17961 try { 17962 mInstaller.removeUserDataDirs(volumeUuid, userId); 17963 } catch (InstallerException e) { 17964 Slog.w(TAG, "Failed to clean up user dirs", e); 17965 } 17966 } 17967 } 17968 } 17969 } 17970 17971 private void assertPackageKnown(String volumeUuid, String packageName) 17972 throws PackageManagerException { 17973 synchronized (mPackages) { 17974 final PackageSetting ps = mSettings.mPackages.get(packageName); 17975 if (ps == null) { 17976 throw new PackageManagerException("Package " + packageName + " is unknown"); 17977 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) { 17978 throw new PackageManagerException( 17979 "Package " + packageName + " found on unknown volume " + volumeUuid 17980 + "; expected volume " + ps.volumeUuid); 17981 } 17982 } 17983 } 17984 17985 private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId) 17986 throws PackageManagerException { 17987 synchronized (mPackages) { 17988 final PackageSetting ps = mSettings.mPackages.get(packageName); 17989 if (ps == null) { 17990 throw new PackageManagerException("Package " + packageName + " is unknown"); 17991 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) { 17992 throw new PackageManagerException( 17993 "Package " + packageName + " found on unknown volume " + volumeUuid 17994 + "; expected volume " + ps.volumeUuid); 17995 } else if (!ps.getInstalled(userId)) { 17996 throw new PackageManagerException( 17997 "Package " + packageName + " not installed for user " + userId); 17998 } 17999 } 18000 } 18001 18002 /** 18003 * Examine all apps present on given mounted volume, and destroy apps that 18004 * aren't expected, either due to uninstallation or reinstallation on 18005 * another volume. 18006 */ 18007 private void reconcileApps(String volumeUuid) { 18008 final File[] files = FileUtils 18009 .listFilesOrEmpty(Environment.getDataAppDirectory(volumeUuid)); 18010 for (File file : files) { 18011 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 18012 && !PackageInstallerService.isStageName(file.getName()); 18013 if (!isPackage) { 18014 // Ignore entries which are not packages 18015 continue; 18016 } 18017 18018 try { 18019 final PackageLite pkg = PackageParser.parsePackageLite(file, 18020 PackageParser.PARSE_MUST_BE_APK); 18021 assertPackageKnown(volumeUuid, pkg.packageName); 18022 18023 } catch (PackageParserException | PackageManagerException e) { 18024 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 18025 synchronized (mInstallLock) { 18026 removeCodePathLI(file); 18027 } 18028 } 18029 } 18030 } 18031 18032 /** 18033 * Reconcile all app data for the given user. 18034 * <p> 18035 * Verifies that directories exist and that ownership and labeling is 18036 * correct for all installed apps on all mounted volumes. 18037 */ 18038 void reconcileAppsData(int userId, int flags) { 18039 final StorageManager storage = mContext.getSystemService(StorageManager.class); 18040 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 18041 final String volumeUuid = vol.getFsUuid(); 18042 reconcileAppsData(volumeUuid, userId, flags); 18043 } 18044 } 18045 18046 /** 18047 * Reconcile all app data on given mounted volume. 18048 * <p> 18049 * Destroys app data that isn't expected, either due to uninstallation or 18050 * reinstallation on another volume. 18051 * <p> 18052 * Verifies that directories exist and that ownership and labeling is 18053 * correct for all installed apps. 18054 */ 18055 private void reconcileAppsData(String volumeUuid, int userId, int flags) { 18056 Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x" 18057 + Integer.toHexString(flags)); 18058 18059 final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId); 18060 final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId); 18061 18062 boolean restoreconNeeded = false; 18063 18064 // First look for stale data that doesn't belong, and check if things 18065 // have changed since we did our last restorecon 18066 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 18067 if (!isUserKeyUnlocked(userId)) { 18068 throw new RuntimeException( 18069 "Yikes, someone asked us to reconcile CE storage while " + userId 18070 + " was still locked; this would have caused massive data loss!"); 18071 } 18072 18073 restoreconNeeded |= SELinuxMMAC.isRestoreconNeeded(ceDir); 18074 18075 final File[] files = FileUtils.listFilesOrEmpty(ceDir); 18076 for (File file : files) { 18077 final String packageName = file.getName(); 18078 try { 18079 assertPackageKnownAndInstalled(volumeUuid, packageName, userId); 18080 } catch (PackageManagerException e) { 18081 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 18082 synchronized (mInstallLock) { 18083 destroyAppDataLI(volumeUuid, packageName, userId, 18084 StorageManager.FLAG_STORAGE_CE); 18085 } 18086 } 18087 } 18088 } 18089 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) { 18090 restoreconNeeded |= SELinuxMMAC.isRestoreconNeeded(deDir); 18091 18092 final File[] files = FileUtils.listFilesOrEmpty(deDir); 18093 for (File file : files) { 18094 final String packageName = file.getName(); 18095 try { 18096 assertPackageKnownAndInstalled(volumeUuid, packageName, userId); 18097 } catch (PackageManagerException e) { 18098 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 18099 synchronized (mInstallLock) { 18100 destroyAppDataLI(volumeUuid, packageName, userId, 18101 StorageManager.FLAG_STORAGE_DE); 18102 } 18103 } 18104 } 18105 } 18106 18107 // Ensure that data directories are ready to roll for all packages 18108 // installed for this volume and user 18109 final List<PackageSetting> packages; 18110 synchronized (mPackages) { 18111 packages = mSettings.getVolumePackagesLPr(volumeUuid); 18112 } 18113 int preparedCount = 0; 18114 for (PackageSetting ps : packages) { 18115 final String packageName = ps.name; 18116 if (ps.pkg == null) { 18117 Slog.w(TAG, "Odd, missing scanned package " + packageName); 18118 // TODO: might be due to legacy ASEC apps; we should circle back 18119 // and reconcile again once they're scanned 18120 continue; 18121 } 18122 18123 if (ps.getInstalled(userId)) { 18124 prepareAppData(volumeUuid, userId, flags, ps.pkg, restoreconNeeded); 18125 18126 if (maybeMigrateAppData(volumeUuid, userId, ps.pkg)) { 18127 // We may have just shuffled around app data directories, so 18128 // prepare them one more time 18129 prepareAppData(volumeUuid, userId, flags, ps.pkg, restoreconNeeded); 18130 } 18131 18132 preparedCount++; 18133 } 18134 } 18135 18136 if (restoreconNeeded) { 18137 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 18138 SELinuxMMAC.setRestoreconDone(ceDir); 18139 } 18140 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) { 18141 SELinuxMMAC.setRestoreconDone(deDir); 18142 } 18143 } 18144 18145 Slog.v(TAG, "reconcileAppsData finished " + preparedCount 18146 + " packages; restoreconNeeded was " + restoreconNeeded); 18147 } 18148 18149 /** 18150 * Prepare app data for the given app just after it was installed or 18151 * upgraded. This method carefully only touches users that it's installed 18152 * for, and it forces a restorecon to handle any seinfo changes. 18153 * <p> 18154 * Verifies that directories exist and that ownership and labeling is 18155 * correct for all installed apps. If there is an ownership mismatch, it 18156 * will try recovering system apps by wiping data; third-party app data is 18157 * left intact. 18158 * <p> 18159 * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em> 18160 */ 18161 private void prepareAppDataAfterInstall(PackageParser.Package pkg) { 18162 prepareAppDataAfterInstallInternal(pkg); 18163 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 18164 for (int i = 0; i < childCount; i++) { 18165 PackageParser.Package childPackage = pkg.childPackages.get(i); 18166 prepareAppDataAfterInstallInternal(childPackage); 18167 } 18168 } 18169 18170 private void prepareAppDataAfterInstallInternal(PackageParser.Package pkg) { 18171 final PackageSetting ps; 18172 synchronized (mPackages) { 18173 ps = mSettings.mPackages.get(pkg.packageName); 18174 mSettings.writeKernelMappingLPr(ps); 18175 } 18176 18177 final UserManager um = mContext.getSystemService(UserManager.class); 18178 for (UserInfo user : um.getUsers()) { 18179 final int flags; 18180 if (um.isUserUnlocked(user.id)) { 18181 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 18182 } else if (um.isUserRunning(user.id)) { 18183 flags = StorageManager.FLAG_STORAGE_DE; 18184 } else { 18185 continue; 18186 } 18187 18188 if (ps.getInstalled(user.id)) { 18189 // Whenever an app changes, force a restorecon of its data 18190 // TODO: when user data is locked, mark that we're still dirty 18191 prepareAppData(pkg.volumeUuid, user.id, flags, pkg, true); 18192 } 18193 } 18194 } 18195 18196 /** 18197 * Prepare app data for the given app. 18198 * <p> 18199 * Verifies that directories exist and that ownership and labeling is 18200 * correct for all installed apps. If there is an ownership mismatch, this 18201 * will try recovering system apps by wiping data; third-party app data is 18202 * left intact. 18203 */ 18204 private void prepareAppData(String volumeUuid, int userId, int flags, 18205 PackageParser.Package pkg, boolean restoreconNeeded) { 18206 if (DEBUG_APP_DATA) { 18207 Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x" 18208 + Integer.toHexString(flags) + (restoreconNeeded ? " restoreconNeeded" : "")); 18209 } 18210 18211 final String packageName = pkg.packageName; 18212 final ApplicationInfo app = pkg.applicationInfo; 18213 final int appId = UserHandle.getAppId(app.uid); 18214 18215 Preconditions.checkNotNull(app.seinfo); 18216 18217 synchronized (mInstallLock) { 18218 try { 18219 mInstaller.createAppData(volumeUuid, packageName, userId, flags, 18220 appId, app.seinfo, app.targetSdkVersion); 18221 } catch (InstallerException e) { 18222 if (app.isSystemApp()) { 18223 logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName 18224 + ", but trying to recover: " + e); 18225 destroyAppDataLI(volumeUuid, packageName, userId, flags); 18226 try { 18227 mInstaller.createAppData(volumeUuid, packageName, userId, flags, 18228 appId, app.seinfo, app.targetSdkVersion); 18229 logCriticalInfo(Log.DEBUG, "Recovery succeeded!"); 18230 } catch (InstallerException e2) { 18231 logCriticalInfo(Log.DEBUG, "Recovery failed!"); 18232 } 18233 } else { 18234 Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e); 18235 } 18236 } 18237 18238 if (restoreconNeeded) { 18239 restoreconAppDataLI(volumeUuid, packageName, userId, flags, appId, app.seinfo); 18240 } 18241 18242 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 18243 // Create a native library symlink only if we have native libraries 18244 // and if the native libraries are 32 bit libraries. We do not provide 18245 // this symlink for 64 bit libraries. 18246 if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) { 18247 final String nativeLibPath = app.nativeLibraryDir; 18248 try { 18249 mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName, 18250 nativeLibPath, userId); 18251 } catch (InstallerException e) { 18252 Slog.e(TAG, "Failed to link native for " + packageName + ": " + e); 18253 } 18254 } 18255 } 18256 } 18257 } 18258 18259 /** 18260 * For system apps on non-FBE devices, this method migrates any existing 18261 * CE/DE data to match the {@code forceDeviceEncrypted} flag requested by 18262 * the app. 18263 */ 18264 private boolean maybeMigrateAppData(String volumeUuid, int userId, PackageParser.Package pkg) { 18265 if (pkg.isSystemApp() && !StorageManager.isFileBasedEncryptionEnabled() 18266 && PackageManager.APPLY_FORCE_DEVICE_ENCRYPTED) { 18267 final int storageTarget = pkg.applicationInfo.isForceDeviceEncrypted() 18268 ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE; 18269 synchronized (mInstallLock) { 18270 try { 18271 mInstaller.migrateAppData(volumeUuid, pkg.packageName, userId, storageTarget); 18272 } catch (InstallerException e) { 18273 logCriticalInfo(Log.WARN, 18274 "Failed to migrate " + pkg.packageName + ": " + e.getMessage()); 18275 } 18276 } 18277 return true; 18278 } else { 18279 return false; 18280 } 18281 } 18282 18283 private void unfreezePackage(String packageName) { 18284 synchronized (mPackages) { 18285 final PackageSetting ps = mSettings.mPackages.get(packageName); 18286 if (ps != null) { 18287 ps.frozen = false; 18288 } 18289 } 18290 } 18291 18292 @Override 18293 public int movePackage(final String packageName, final String volumeUuid) { 18294 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 18295 18296 final int moveId = mNextMoveId.getAndIncrement(); 18297 mHandler.post(new Runnable() { 18298 @Override 18299 public void run() { 18300 try { 18301 movePackageInternal(packageName, volumeUuid, moveId); 18302 } catch (PackageManagerException e) { 18303 Slog.w(TAG, "Failed to move " + packageName, e); 18304 mMoveCallbacks.notifyStatusChanged(moveId, 18305 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 18306 } 18307 } 18308 }); 18309 return moveId; 18310 } 18311 18312 private void movePackageInternal(final String packageName, final String volumeUuid, 18313 final int moveId) throws PackageManagerException { 18314 final UserHandle user = new UserHandle(UserHandle.getCallingUserId()); 18315 final StorageManager storage = mContext.getSystemService(StorageManager.class); 18316 final PackageManager pm = mContext.getPackageManager(); 18317 18318 final boolean currentAsec; 18319 final String currentVolumeUuid; 18320 final File codeFile; 18321 final String installerPackageName; 18322 final String packageAbiOverride; 18323 final int appId; 18324 final String seinfo; 18325 final String label; 18326 final int targetSdkVersion; 18327 18328 // reader 18329 synchronized (mPackages) { 18330 final PackageParser.Package pkg = mPackages.get(packageName); 18331 final PackageSetting ps = mSettings.mPackages.get(packageName); 18332 if (pkg == null || ps == null) { 18333 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package"); 18334 } 18335 18336 if (pkg.applicationInfo.isSystemApp()) { 18337 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE, 18338 "Cannot move system application"); 18339 } 18340 18341 if (pkg.applicationInfo.isExternalAsec()) { 18342 currentAsec = true; 18343 currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL; 18344 } else if (pkg.applicationInfo.isForwardLocked()) { 18345 currentAsec = true; 18346 currentVolumeUuid = "forward_locked"; 18347 } else { 18348 currentAsec = false; 18349 currentVolumeUuid = ps.volumeUuid; 18350 18351 final File probe = new File(pkg.codePath); 18352 final File probeOat = new File(probe, "oat"); 18353 if (!probe.isDirectory() || !probeOat.isDirectory()) { 18354 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 18355 "Move only supported for modern cluster style installs"); 18356 } 18357 } 18358 18359 if (Objects.equals(currentVolumeUuid, volumeUuid)) { 18360 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 18361 "Package already moved to " + volumeUuid); 18362 } 18363 if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) { 18364 throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN, 18365 "Device admin cannot be moved"); 18366 } 18367 18368 if (ps.frozen) { 18369 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING, 18370 "Failed to move already frozen package"); 18371 } 18372 ps.frozen = true; 18373 18374 codeFile = new File(pkg.codePath); 18375 installerPackageName = ps.installerPackageName; 18376 packageAbiOverride = ps.cpuAbiOverrideString; 18377 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 18378 seinfo = pkg.applicationInfo.seinfo; 18379 label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo)); 18380 targetSdkVersion = pkg.applicationInfo.targetSdkVersion; 18381 } 18382 18383 // Now that we're guarded by frozen state, kill app during move 18384 final long token = Binder.clearCallingIdentity(); 18385 try { 18386 killApplication(packageName, appId, "move pkg"); 18387 } finally { 18388 Binder.restoreCallingIdentity(token); 18389 } 18390 18391 final Bundle extras = new Bundle(); 18392 extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName); 18393 extras.putString(Intent.EXTRA_TITLE, label); 18394 mMoveCallbacks.notifyCreated(moveId, extras); 18395 18396 int installFlags; 18397 final boolean moveCompleteApp; 18398 final File measurePath; 18399 18400 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) { 18401 installFlags = INSTALL_INTERNAL; 18402 moveCompleteApp = !currentAsec; 18403 measurePath = Environment.getDataAppDirectory(volumeUuid); 18404 } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) { 18405 installFlags = INSTALL_EXTERNAL; 18406 moveCompleteApp = false; 18407 measurePath = storage.getPrimaryPhysicalVolume().getPath(); 18408 } else { 18409 final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid); 18410 if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE 18411 || !volume.isMountedWritable()) { 18412 unfreezePackage(packageName); 18413 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 18414 "Move location not mounted private volume"); 18415 } 18416 18417 Preconditions.checkState(!currentAsec); 18418 18419 installFlags = INSTALL_INTERNAL; 18420 moveCompleteApp = true; 18421 measurePath = Environment.getDataAppDirectory(volumeUuid); 18422 } 18423 18424 final PackageStats stats = new PackageStats(null, -1); 18425 synchronized (mInstaller) { 18426 if (!getPackageSizeInfoLI(packageName, -1, stats)) { 18427 unfreezePackage(packageName); 18428 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 18429 "Failed to measure package size"); 18430 } 18431 } 18432 18433 if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size " 18434 + stats.dataSize); 18435 18436 final long startFreeBytes = measurePath.getFreeSpace(); 18437 final long sizeBytes; 18438 if (moveCompleteApp) { 18439 sizeBytes = stats.codeSize + stats.dataSize; 18440 } else { 18441 sizeBytes = stats.codeSize; 18442 } 18443 18444 if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) { 18445 unfreezePackage(packageName); 18446 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 18447 "Not enough free space to move"); 18448 } 18449 18450 mMoveCallbacks.notifyStatusChanged(moveId, 10); 18451 18452 final CountDownLatch installedLatch = new CountDownLatch(1); 18453 final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() { 18454 @Override 18455 public void onUserActionRequired(Intent intent) throws RemoteException { 18456 throw new IllegalStateException(); 18457 } 18458 18459 @Override 18460 public void onPackageInstalled(String basePackageName, int returnCode, String msg, 18461 Bundle extras) throws RemoteException { 18462 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: " 18463 + PackageManager.installStatusToString(returnCode, msg)); 18464 18465 installedLatch.countDown(); 18466 18467 // Regardless of success or failure of the move operation, 18468 // always unfreeze the package 18469 unfreezePackage(packageName); 18470 18471 final int status = PackageManager.installStatusToPublicStatus(returnCode); 18472 switch (status) { 18473 case PackageInstaller.STATUS_SUCCESS: 18474 mMoveCallbacks.notifyStatusChanged(moveId, 18475 PackageManager.MOVE_SUCCEEDED); 18476 break; 18477 case PackageInstaller.STATUS_FAILURE_STORAGE: 18478 mMoveCallbacks.notifyStatusChanged(moveId, 18479 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE); 18480 break; 18481 default: 18482 mMoveCallbacks.notifyStatusChanged(moveId, 18483 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 18484 break; 18485 } 18486 } 18487 }; 18488 18489 final MoveInfo move; 18490 if (moveCompleteApp) { 18491 // Kick off a thread to report progress estimates 18492 new Thread() { 18493 @Override 18494 public void run() { 18495 while (true) { 18496 try { 18497 if (installedLatch.await(1, TimeUnit.SECONDS)) { 18498 break; 18499 } 18500 } catch (InterruptedException ignored) { 18501 } 18502 18503 final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace(); 18504 final int progress = 10 + (int) MathUtils.constrain( 18505 ((deltaFreeBytes * 80) / sizeBytes), 0, 80); 18506 mMoveCallbacks.notifyStatusChanged(moveId, progress); 18507 } 18508 } 18509 }.start(); 18510 18511 final String dataAppName = codeFile.getName(); 18512 move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName, 18513 dataAppName, appId, seinfo, targetSdkVersion); 18514 } else { 18515 move = null; 18516 } 18517 18518 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 18519 18520 final Message msg = mHandler.obtainMessage(INIT_COPY); 18521 final OriginInfo origin = OriginInfo.fromExistingFile(codeFile); 18522 final InstallParams params = new InstallParams(origin, move, installObserver, installFlags, 18523 installerPackageName, volumeUuid, null /*verificationInfo*/, user, 18524 packageAbiOverride, null); 18525 params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params)); 18526 msg.obj = params; 18527 18528 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage", 18529 System.identityHashCode(msg.obj)); 18530 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 18531 System.identityHashCode(msg.obj)); 18532 18533 mHandler.sendMessage(msg); 18534 } 18535 18536 @Override 18537 public int movePrimaryStorage(String volumeUuid) throws RemoteException { 18538 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 18539 18540 final int realMoveId = mNextMoveId.getAndIncrement(); 18541 final Bundle extras = new Bundle(); 18542 extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid); 18543 mMoveCallbacks.notifyCreated(realMoveId, extras); 18544 18545 final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() { 18546 @Override 18547 public void onCreated(int moveId, Bundle extras) { 18548 // Ignored 18549 } 18550 18551 @Override 18552 public void onStatusChanged(int moveId, int status, long estMillis) { 18553 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis); 18554 } 18555 }; 18556 18557 final StorageManager storage = mContext.getSystemService(StorageManager.class); 18558 storage.setPrimaryStorageUuid(volumeUuid, callback); 18559 return realMoveId; 18560 } 18561 18562 @Override 18563 public int getMoveStatus(int moveId) { 18564 mContext.enforceCallingOrSelfPermission( 18565 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 18566 return mMoveCallbacks.mLastStatus.get(moveId); 18567 } 18568 18569 @Override 18570 public void registerMoveCallback(IPackageMoveObserver callback) { 18571 mContext.enforceCallingOrSelfPermission( 18572 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 18573 mMoveCallbacks.register(callback); 18574 } 18575 18576 @Override 18577 public void unregisterMoveCallback(IPackageMoveObserver callback) { 18578 mContext.enforceCallingOrSelfPermission( 18579 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 18580 mMoveCallbacks.unregister(callback); 18581 } 18582 18583 @Override 18584 public boolean setInstallLocation(int loc) { 18585 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, 18586 null); 18587 if (getInstallLocation() == loc) { 18588 return true; 18589 } 18590 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL 18591 || loc == PackageHelper.APP_INSTALL_EXTERNAL) { 18592 android.provider.Settings.Global.putInt(mContext.getContentResolver(), 18593 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc); 18594 return true; 18595 } 18596 return false; 18597 } 18598 18599 @Override 18600 public int getInstallLocation() { 18601 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 18602 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, 18603 PackageHelper.APP_INSTALL_AUTO); 18604 } 18605 18606 /** Called by UserManagerService */ 18607 void cleanUpUser(UserManagerService userManager, int userHandle) { 18608 synchronized (mPackages) { 18609 mDirtyUsers.remove(userHandle); 18610 mUserNeedsBadging.delete(userHandle); 18611 mSettings.removeUserLPw(userHandle); 18612 mPendingBroadcasts.remove(userHandle); 18613 mEphemeralApplicationRegistry.onUserRemovedLPw(userHandle); 18614 } 18615 synchronized (mInstallLock) { 18616 final StorageManager storage = mContext.getSystemService(StorageManager.class); 18617 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 18618 final String volumeUuid = vol.getFsUuid(); 18619 if (DEBUG_INSTALL) Slog.d(TAG, "Removing user data on volume " + volumeUuid); 18620 try { 18621 mInstaller.removeUserDataDirs(volumeUuid, userHandle); 18622 } catch (InstallerException e) { 18623 Slog.w(TAG, "Failed to remove user data", e); 18624 } 18625 } 18626 synchronized (mPackages) { 18627 removeUnusedPackagesLILPw(userManager, userHandle); 18628 } 18629 } 18630 } 18631 18632 /** 18633 * We're removing userHandle and would like to remove any downloaded packages 18634 * that are no longer in use by any other user. 18635 * @param userHandle the user being removed 18636 */ 18637 private void removeUnusedPackagesLILPw(UserManagerService userManager, final int userHandle) { 18638 final boolean DEBUG_CLEAN_APKS = false; 18639 int [] users = userManager.getUserIds(); 18640 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 18641 while (psit.hasNext()) { 18642 PackageSetting ps = psit.next(); 18643 if (ps.pkg == null) { 18644 continue; 18645 } 18646 final String packageName = ps.pkg.packageName; 18647 // Skip over if system app 18648 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) { 18649 continue; 18650 } 18651 if (DEBUG_CLEAN_APKS) { 18652 Slog.i(TAG, "Checking package " + packageName); 18653 } 18654 boolean keep = shouldKeepUninstalledPackageLPr(packageName); 18655 if (keep) { 18656 if (DEBUG_CLEAN_APKS) { 18657 Slog.i(TAG, " Keeping package " + packageName + " - requested by DO"); 18658 } 18659 } else { 18660 for (int i = 0; i < users.length; i++) { 18661 if (users[i] != userHandle && ps.getInstalled(users[i])) { 18662 keep = true; 18663 if (DEBUG_CLEAN_APKS) { 18664 Slog.i(TAG, " Keeping package " + packageName + " for user " 18665 + users[i]); 18666 } 18667 break; 18668 } 18669 } 18670 } 18671 if (!keep) { 18672 if (DEBUG_CLEAN_APKS) { 18673 Slog.i(TAG, " Removing package " + packageName); 18674 } 18675 mHandler.post(new Runnable() { 18676 public void run() { 18677 deletePackageX(packageName, userHandle, 0); 18678 } //end run 18679 }); 18680 } 18681 } 18682 } 18683 18684 /** Called by UserManagerService */ 18685 void createNewUser(int userHandle) { 18686 synchronized (mInstallLock) { 18687 try { 18688 mInstaller.createUserConfig(userHandle); 18689 } catch (InstallerException e) { 18690 Slog.w(TAG, "Failed to create user config", e); 18691 } 18692 mSettings.createNewUserLI(this, mInstaller, userHandle); 18693 } 18694 synchronized (mPackages) { 18695 applyFactoryDefaultBrowserLPw(userHandle); 18696 primeDomainVerificationsLPw(userHandle); 18697 } 18698 } 18699 18700 void newUserCreated(final int userHandle) { 18701 mDefaultPermissionPolicy.grantDefaultPermissions(userHandle); 18702 // If permission review for legacy apps is required, we represent 18703 // dagerous permissions for such apps as always granted runtime 18704 // permissions to keep per user flag state whether review is needed. 18705 // Hence, if a new user is added we have to propagate dangerous 18706 // permission grants for these legacy apps. 18707 if (Build.PERMISSIONS_REVIEW_REQUIRED) { 18708 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL 18709 | UPDATE_PERMISSIONS_REPLACE_ALL); 18710 } 18711 } 18712 18713 @Override 18714 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException { 18715 mContext.enforceCallingOrSelfPermission( 18716 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 18717 "Only package verification agents can read the verifier device identity"); 18718 18719 synchronized (mPackages) { 18720 return mSettings.getVerifierDeviceIdentityLPw(); 18721 } 18722 } 18723 18724 @Override 18725 public void setPermissionEnforced(String permission, boolean enforced) { 18726 // TODO: Now that we no longer change GID for storage, this should to away. 18727 mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 18728 "setPermissionEnforced"); 18729 if (READ_EXTERNAL_STORAGE.equals(permission)) { 18730 synchronized (mPackages) { 18731 if (mSettings.mReadExternalStorageEnforced == null 18732 || mSettings.mReadExternalStorageEnforced != enforced) { 18733 mSettings.mReadExternalStorageEnforced = enforced; 18734 mSettings.writeLPr(); 18735 } 18736 } 18737 // kill any non-foreground processes so we restart them and 18738 // grant/revoke the GID. 18739 final IActivityManager am = ActivityManagerNative.getDefault(); 18740 if (am != null) { 18741 final long token = Binder.clearCallingIdentity(); 18742 try { 18743 am.killProcessesBelowForeground("setPermissionEnforcement"); 18744 } catch (RemoteException e) { 18745 } finally { 18746 Binder.restoreCallingIdentity(token); 18747 } 18748 } 18749 } else { 18750 throw new IllegalArgumentException("No selective enforcement for " + permission); 18751 } 18752 } 18753 18754 @Override 18755 @Deprecated 18756 public boolean isPermissionEnforced(String permission) { 18757 return true; 18758 } 18759 18760 @Override 18761 public boolean isStorageLow() { 18762 final long token = Binder.clearCallingIdentity(); 18763 try { 18764 final DeviceStorageMonitorInternal 18765 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 18766 if (dsm != null) { 18767 return dsm.isMemoryLow(); 18768 } else { 18769 return false; 18770 } 18771 } finally { 18772 Binder.restoreCallingIdentity(token); 18773 } 18774 } 18775 18776 @Override 18777 public IPackageInstaller getPackageInstaller() { 18778 return mInstallerService; 18779 } 18780 18781 private boolean userNeedsBadging(int userId) { 18782 int index = mUserNeedsBadging.indexOfKey(userId); 18783 if (index < 0) { 18784 final UserInfo userInfo; 18785 final long token = Binder.clearCallingIdentity(); 18786 try { 18787 userInfo = sUserManager.getUserInfo(userId); 18788 } finally { 18789 Binder.restoreCallingIdentity(token); 18790 } 18791 final boolean b; 18792 if (userInfo != null && userInfo.isManagedProfile()) { 18793 b = true; 18794 } else { 18795 b = false; 18796 } 18797 mUserNeedsBadging.put(userId, b); 18798 return b; 18799 } 18800 return mUserNeedsBadging.valueAt(index); 18801 } 18802 18803 @Override 18804 public KeySet getKeySetByAlias(String packageName, String alias) { 18805 if (packageName == null || alias == null) { 18806 return null; 18807 } 18808 synchronized(mPackages) { 18809 final PackageParser.Package pkg = mPackages.get(packageName); 18810 if (pkg == null) { 18811 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 18812 throw new IllegalArgumentException("Unknown package: " + packageName); 18813 } 18814 KeySetManagerService ksms = mSettings.mKeySetManagerService; 18815 return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias)); 18816 } 18817 } 18818 18819 @Override 18820 public KeySet getSigningKeySet(String packageName) { 18821 if (packageName == null) { 18822 return null; 18823 } 18824 synchronized(mPackages) { 18825 final PackageParser.Package pkg = mPackages.get(packageName); 18826 if (pkg == null) { 18827 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 18828 throw new IllegalArgumentException("Unknown package: " + packageName); 18829 } 18830 if (pkg.applicationInfo.uid != Binder.getCallingUid() 18831 && Process.SYSTEM_UID != Binder.getCallingUid()) { 18832 throw new SecurityException("May not access signing KeySet of other apps."); 18833 } 18834 KeySetManagerService ksms = mSettings.mKeySetManagerService; 18835 return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName)); 18836 } 18837 } 18838 18839 @Override 18840 public boolean isPackageSignedByKeySet(String packageName, KeySet ks) { 18841 if (packageName == null || ks == null) { 18842 return false; 18843 } 18844 synchronized(mPackages) { 18845 final PackageParser.Package pkg = mPackages.get(packageName); 18846 if (pkg == null) { 18847 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 18848 throw new IllegalArgumentException("Unknown package: " + packageName); 18849 } 18850 IBinder ksh = ks.getToken(); 18851 if (ksh instanceof KeySetHandle) { 18852 KeySetManagerService ksms = mSettings.mKeySetManagerService; 18853 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh); 18854 } 18855 return false; 18856 } 18857 } 18858 18859 @Override 18860 public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) { 18861 if (packageName == null || ks == null) { 18862 return false; 18863 } 18864 synchronized(mPackages) { 18865 final PackageParser.Package pkg = mPackages.get(packageName); 18866 if (pkg == null) { 18867 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 18868 throw new IllegalArgumentException("Unknown package: " + packageName); 18869 } 18870 IBinder ksh = ks.getToken(); 18871 if (ksh instanceof KeySetHandle) { 18872 KeySetManagerService ksms = mSettings.mKeySetManagerService; 18873 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh); 18874 } 18875 return false; 18876 } 18877 } 18878 18879 private void deletePackageIfUnusedLPr(final String packageName) { 18880 PackageSetting ps = mSettings.mPackages.get(packageName); 18881 if (ps == null) { 18882 return; 18883 } 18884 if (!ps.isAnyInstalled(sUserManager.getUserIds())) { 18885 // TODO Implement atomic delete if package is unused 18886 // It is currently possible that the package will be deleted even if it is installed 18887 // after this method returns. 18888 mHandler.post(new Runnable() { 18889 public void run() { 18890 deletePackageX(packageName, 0, PackageManager.DELETE_ALL_USERS); 18891 } 18892 }); 18893 } 18894 } 18895 18896 /** 18897 * Check and throw if the given before/after packages would be considered a 18898 * downgrade. 18899 */ 18900 private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after) 18901 throws PackageManagerException { 18902 if (after.versionCode < before.mVersionCode) { 18903 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 18904 "Update version code " + after.versionCode + " is older than current " 18905 + before.mVersionCode); 18906 } else if (after.versionCode == before.mVersionCode) { 18907 if (after.baseRevisionCode < before.baseRevisionCode) { 18908 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 18909 "Update base revision code " + after.baseRevisionCode 18910 + " is older than current " + before.baseRevisionCode); 18911 } 18912 18913 if (!ArrayUtils.isEmpty(after.splitNames)) { 18914 for (int i = 0; i < after.splitNames.length; i++) { 18915 final String splitName = after.splitNames[i]; 18916 final int j = ArrayUtils.indexOf(before.splitNames, splitName); 18917 if (j != -1) { 18918 if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) { 18919 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 18920 "Update split " + splitName + " revision code " 18921 + after.splitRevisionCodes[i] + " is older than current " 18922 + before.splitRevisionCodes[j]); 18923 } 18924 } 18925 } 18926 } 18927 } 18928 } 18929 18930 private static class MoveCallbacks extends Handler { 18931 private static final int MSG_CREATED = 1; 18932 private static final int MSG_STATUS_CHANGED = 2; 18933 18934 private final RemoteCallbackList<IPackageMoveObserver> 18935 mCallbacks = new RemoteCallbackList<>(); 18936 18937 private final SparseIntArray mLastStatus = new SparseIntArray(); 18938 18939 public MoveCallbacks(Looper looper) { 18940 super(looper); 18941 } 18942 18943 public void register(IPackageMoveObserver callback) { 18944 mCallbacks.register(callback); 18945 } 18946 18947 public void unregister(IPackageMoveObserver callback) { 18948 mCallbacks.unregister(callback); 18949 } 18950 18951 @Override 18952 public void handleMessage(Message msg) { 18953 final SomeArgs args = (SomeArgs) msg.obj; 18954 final int n = mCallbacks.beginBroadcast(); 18955 for (int i = 0; i < n; i++) { 18956 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i); 18957 try { 18958 invokeCallback(callback, msg.what, args); 18959 } catch (RemoteException ignored) { 18960 } 18961 } 18962 mCallbacks.finishBroadcast(); 18963 args.recycle(); 18964 } 18965 18966 private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args) 18967 throws RemoteException { 18968 switch (what) { 18969 case MSG_CREATED: { 18970 callback.onCreated(args.argi1, (Bundle) args.arg2); 18971 break; 18972 } 18973 case MSG_STATUS_CHANGED: { 18974 callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3); 18975 break; 18976 } 18977 } 18978 } 18979 18980 private void notifyCreated(int moveId, Bundle extras) { 18981 Slog.v(TAG, "Move " + moveId + " created " + extras.toString()); 18982 18983 final SomeArgs args = SomeArgs.obtain(); 18984 args.argi1 = moveId; 18985 args.arg2 = extras; 18986 obtainMessage(MSG_CREATED, args).sendToTarget(); 18987 } 18988 18989 private void notifyStatusChanged(int moveId, int status) { 18990 notifyStatusChanged(moveId, status, -1); 18991 } 18992 18993 private void notifyStatusChanged(int moveId, int status, long estMillis) { 18994 Slog.v(TAG, "Move " + moveId + " status " + status); 18995 18996 final SomeArgs args = SomeArgs.obtain(); 18997 args.argi1 = moveId; 18998 args.argi2 = status; 18999 args.arg3 = estMillis; 19000 obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget(); 19001 19002 synchronized (mLastStatus) { 19003 mLastStatus.put(moveId, status); 19004 } 19005 } 19006 } 19007 19008 private final static class OnPermissionChangeListeners extends Handler { 19009 private static final int MSG_ON_PERMISSIONS_CHANGED = 1; 19010 19011 private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners = 19012 new RemoteCallbackList<>(); 19013 19014 public OnPermissionChangeListeners(Looper looper) { 19015 super(looper); 19016 } 19017 19018 @Override 19019 public void handleMessage(Message msg) { 19020 switch (msg.what) { 19021 case MSG_ON_PERMISSIONS_CHANGED: { 19022 final int uid = msg.arg1; 19023 handleOnPermissionsChanged(uid); 19024 } break; 19025 } 19026 } 19027 19028 public void addListenerLocked(IOnPermissionsChangeListener listener) { 19029 mPermissionListeners.register(listener); 19030 19031 } 19032 19033 public void removeListenerLocked(IOnPermissionsChangeListener listener) { 19034 mPermissionListeners.unregister(listener); 19035 } 19036 19037 public void onPermissionsChanged(int uid) { 19038 if (mPermissionListeners.getRegisteredCallbackCount() > 0) { 19039 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget(); 19040 } 19041 } 19042 19043 private void handleOnPermissionsChanged(int uid) { 19044 final int count = mPermissionListeners.beginBroadcast(); 19045 try { 19046 for (int i = 0; i < count; i++) { 19047 IOnPermissionsChangeListener callback = mPermissionListeners 19048 .getBroadcastItem(i); 19049 try { 19050 callback.onPermissionsChanged(uid); 19051 } catch (RemoteException e) { 19052 Log.e(TAG, "Permission listener is dead", e); 19053 } 19054 } 19055 } finally { 19056 mPermissionListeners.finishBroadcast(); 19057 } 19058 } 19059 } 19060 19061 private class PackageManagerInternalImpl extends PackageManagerInternal { 19062 @Override 19063 public void setLocationPackagesProvider(PackagesProvider provider) { 19064 synchronized (mPackages) { 19065 mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider); 19066 } 19067 } 19068 19069 @Override 19070 public void setVoiceInteractionPackagesProvider(PackagesProvider provider) { 19071 synchronized (mPackages) { 19072 mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider); 19073 } 19074 } 19075 19076 @Override 19077 public void setSmsAppPackagesProvider(PackagesProvider provider) { 19078 synchronized (mPackages) { 19079 mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider); 19080 } 19081 } 19082 19083 @Override 19084 public void setDialerAppPackagesProvider(PackagesProvider provider) { 19085 synchronized (mPackages) { 19086 mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider); 19087 } 19088 } 19089 19090 @Override 19091 public void setSimCallManagerPackagesProvider(PackagesProvider provider) { 19092 synchronized (mPackages) { 19093 mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider); 19094 } 19095 } 19096 19097 @Override 19098 public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) { 19099 synchronized (mPackages) { 19100 mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider); 19101 } 19102 } 19103 19104 @Override 19105 public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) { 19106 synchronized (mPackages) { 19107 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr( 19108 packageName, userId); 19109 } 19110 } 19111 19112 @Override 19113 public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) { 19114 synchronized (mPackages) { 19115 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr( 19116 packageName, userId); 19117 } 19118 } 19119 19120 @Override 19121 public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) { 19122 synchronized (mPackages) { 19123 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr( 19124 packageName, userId); 19125 } 19126 } 19127 19128 @Override 19129 public void setKeepUninstalledPackages(final List<String> packageList) { 19130 Preconditions.checkNotNull(packageList); 19131 List<String> removedFromList = null; 19132 synchronized (mPackages) { 19133 if (mKeepUninstalledPackages != null) { 19134 final int packagesCount = mKeepUninstalledPackages.size(); 19135 for (int i = 0; i < packagesCount; i++) { 19136 String oldPackage = mKeepUninstalledPackages.get(i); 19137 if (packageList != null && packageList.contains(oldPackage)) { 19138 continue; 19139 } 19140 if (removedFromList == null) { 19141 removedFromList = new ArrayList<>(); 19142 } 19143 removedFromList.add(oldPackage); 19144 } 19145 } 19146 mKeepUninstalledPackages = new ArrayList<>(packageList); 19147 if (removedFromList != null) { 19148 final int removedCount = removedFromList.size(); 19149 for (int i = 0; i < removedCount; i++) { 19150 deletePackageIfUnusedLPr(removedFromList.get(i)); 19151 } 19152 } 19153 } 19154 } 19155 19156 @Override 19157 public boolean isPermissionsReviewRequired(String packageName, int userId) { 19158 synchronized (mPackages) { 19159 // If we do not support permission review, done. 19160 if (!Build.PERMISSIONS_REVIEW_REQUIRED) { 19161 return false; 19162 } 19163 19164 PackageSetting packageSetting = mSettings.mPackages.get(packageName); 19165 if (packageSetting == null) { 19166 return false; 19167 } 19168 19169 // Permission review applies only to apps not supporting the new permission model. 19170 if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) { 19171 return false; 19172 } 19173 19174 // Legacy apps have the permission and get user consent on launch. 19175 PermissionsState permissionsState = packageSetting.getPermissionsState(); 19176 return permissionsState.isPermissionReviewRequired(userId); 19177 } 19178 } 19179 19180 @Override 19181 public ApplicationInfo getApplicationInfo(String packageName, int userId) { 19182 return PackageManagerService.this.getApplicationInfo(packageName, 0 /*flags*/, userId); 19183 } 19184 } 19185 19186 @Override 19187 public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) { 19188 enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps"); 19189 synchronized (mPackages) { 19190 final long identity = Binder.clearCallingIdentity(); 19191 try { 19192 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr( 19193 packageNames, userId); 19194 } finally { 19195 Binder.restoreCallingIdentity(identity); 19196 } 19197 } 19198 } 19199 19200 private static void enforceSystemOrPhoneCaller(String tag) { 19201 int callingUid = Binder.getCallingUid(); 19202 if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) { 19203 throw new SecurityException( 19204 "Cannot call " + tag + " from UID " + callingUid); 19205 } 19206 } 19207 19208 boolean isHistoricalPackageUsageAvailable() { 19209 return mPackageUsage.isHistoricalPackageUsageAvailable(); 19210 } 19211} 19212