PackageManagerService.java revision e1fd7f09d5149055b8ad7bcf24846ecd8d87027a
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; 66import static android.content.pm.PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE; 67import static android.content.pm.PackageManager.MATCH_ENCRYPTION_UNAWARE; 68import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY; 69import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES; 70import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN; 71import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST; 72import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR; 73import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING; 74import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE; 75import static android.content.pm.PackageManager.PERMISSION_DENIED; 76import static android.content.pm.PackageManager.PERMISSION_GRANTED; 77import static android.content.pm.PackageParser.PARSE_IS_PRIVILEGED; 78import static android.content.pm.PackageParser.isApkFile; 79import static android.os.Process.PACKAGE_INFO_GID; 80import static android.os.Process.SYSTEM_UID; 81import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; 82import static android.system.OsConstants.O_CREAT; 83import static android.system.OsConstants.O_RDWR; 84 85import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE; 86import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT; 87import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME; 88import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME; 89import static com.android.internal.util.ArrayUtils.appendInt; 90import static com.android.server.pm.Installer.DEXOPT_PUBLIC; 91import static com.android.server.pm.InstructionSets.getAppDexInstructionSets; 92import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet; 93import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets; 94import static com.android.server.pm.InstructionSets.getPreferredInstructionSet; 95import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet; 96import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE; 97import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS; 98import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED; 99 100import android.Manifest; 101import android.annotation.NonNull; 102import android.annotation.Nullable; 103import android.app.ActivityManager; 104import android.app.ActivityManagerNative; 105import android.app.IActivityManager; 106import android.app.admin.DevicePolicyManagerInternal; 107import android.app.admin.IDevicePolicyManager; 108import android.app.backup.IBackupManager; 109import android.content.BroadcastReceiver; 110import android.content.ComponentName; 111import android.content.Context; 112import android.content.IIntentReceiver; 113import android.content.Intent; 114import android.content.IntentFilter; 115import android.content.IntentSender; 116import android.content.IntentSender.SendIntentException; 117import android.content.ServiceConnection; 118import android.content.pm.ActivityInfo; 119import android.content.pm.ApplicationInfo; 120import android.content.pm.AppsQueryHelper; 121import android.content.pm.ComponentInfo; 122import android.content.pm.EphemeralApplicationInfo; 123import android.content.pm.EphemeralResolveInfo; 124import android.content.pm.EphemeralResolveInfo.EphemeralResolveIntentInfo; 125import android.content.pm.FeatureInfo; 126import android.content.pm.IOnPermissionsChangeListener; 127import android.content.pm.IPackageDataObserver; 128import android.content.pm.IPackageDeleteObserver; 129import android.content.pm.IPackageDeleteObserver2; 130import android.content.pm.IPackageInstallObserver2; 131import android.content.pm.IPackageInstaller; 132import android.content.pm.IPackageManager; 133import android.content.pm.IPackageMoveObserver; 134import android.content.pm.IPackageStatsObserver; 135import android.content.pm.InstrumentationInfo; 136import android.content.pm.IntentFilterVerificationInfo; 137import android.content.pm.KeySet; 138import android.content.pm.PackageCleanItem; 139import android.content.pm.PackageInfo; 140import android.content.pm.PackageInfoLite; 141import android.content.pm.PackageInstaller; 142import android.content.pm.PackageManager; 143import android.content.pm.PackageManager.LegacyPackageDeleteObserver; 144import android.content.pm.PackageManagerInternal; 145import android.content.pm.PackageParser; 146import android.content.pm.PackageParser.ActivityIntentInfo; 147import android.content.pm.PackageParser.PackageLite; 148import android.content.pm.PackageParser.PackageParserException; 149import android.content.pm.PackageStats; 150import android.content.pm.PackageUserState; 151import android.content.pm.ParceledListSlice; 152import android.content.pm.PermissionGroupInfo; 153import android.content.pm.PermissionInfo; 154import android.content.pm.ProviderInfo; 155import android.content.pm.ResolveInfo; 156import android.content.pm.ServiceInfo; 157import android.content.pm.Signature; 158import android.content.pm.UserInfo; 159import android.content.pm.VerifierDeviceIdentity; 160import android.content.pm.VerifierInfo; 161import android.content.res.Resources; 162import android.graphics.Bitmap; 163import android.hardware.display.DisplayManager; 164import android.net.Uri; 165import android.os.Binder; 166import android.os.Build; 167import android.os.Bundle; 168import android.os.Debug; 169import android.os.Environment; 170import android.os.Environment.UserEnvironment; 171import android.os.FileUtils; 172import android.os.Handler; 173import android.os.IBinder; 174import android.os.Looper; 175import android.os.Message; 176import android.os.Parcel; 177import android.os.ParcelFileDescriptor; 178import android.os.Parcelable; 179import android.os.Process; 180import android.os.RemoteCallbackList; 181import android.os.RemoteException; 182import android.os.ResultReceiver; 183import android.os.SELinux; 184import android.os.ServiceManager; 185import android.os.SystemClock; 186import android.os.SystemProperties; 187import android.os.Trace; 188import android.os.UserHandle; 189import android.os.UserManager; 190import android.os.storage.IMountService; 191import android.os.storage.MountServiceInternal; 192import android.os.storage.StorageEventListener; 193import android.os.storage.StorageManager; 194import android.os.storage.VolumeInfo; 195import android.os.storage.VolumeRecord; 196import android.security.KeyStore; 197import android.security.SystemKeyStore; 198import android.system.ErrnoException; 199import android.system.Os; 200import android.text.TextUtils; 201import android.text.format.DateUtils; 202import android.util.ArrayMap; 203import android.util.ArraySet; 204import android.util.AtomicFile; 205import android.util.DisplayMetrics; 206import android.util.EventLog; 207import android.util.ExceptionUtils; 208import android.util.Log; 209import android.util.LogPrinter; 210import android.util.MathUtils; 211import android.util.PrintStreamPrinter; 212import android.util.Slog; 213import android.util.SparseArray; 214import android.util.SparseBooleanArray; 215import android.util.SparseIntArray; 216import android.util.Xml; 217import android.view.Display; 218 219import com.android.internal.R; 220import com.android.internal.annotations.GuardedBy; 221import com.android.internal.app.IMediaContainerService; 222import com.android.internal.app.ResolverActivity; 223import com.android.internal.content.NativeLibraryHelper; 224import com.android.internal.content.PackageHelper; 225import com.android.internal.os.IParcelFileDescriptorFactory; 226import com.android.internal.os.InstallerConnection.InstallerException; 227import com.android.internal.os.SomeArgs; 228import com.android.internal.os.Zygote; 229import com.android.internal.util.ArrayUtils; 230import com.android.internal.util.FastPrintWriter; 231import com.android.internal.util.FastXmlSerializer; 232import com.android.internal.util.IndentingPrintWriter; 233import com.android.internal.util.Preconditions; 234import com.android.internal.util.XmlUtils; 235import com.android.server.EventLogTags; 236import com.android.server.FgThread; 237import com.android.server.IntentResolver; 238import com.android.server.LocalServices; 239import com.android.server.ServiceThread; 240import com.android.server.SystemConfig; 241import com.android.server.Watchdog; 242import com.android.server.pm.PermissionsState.PermissionState; 243import com.android.server.pm.Settings.DatabaseVersion; 244import com.android.server.pm.Settings.VersionInfo; 245import com.android.server.storage.DeviceStorageMonitorInternal; 246 247import dalvik.system.DexFile; 248import dalvik.system.VMRuntime; 249 250import libcore.io.IoUtils; 251import libcore.util.EmptyArray; 252 253import org.xmlpull.v1.XmlPullParser; 254import org.xmlpull.v1.XmlPullParserException; 255import org.xmlpull.v1.XmlSerializer; 256 257import java.io.BufferedInputStream; 258import java.io.BufferedOutputStream; 259import java.io.BufferedReader; 260import java.io.ByteArrayInputStream; 261import java.io.ByteArrayOutputStream; 262import java.io.File; 263import java.io.FileDescriptor; 264import java.io.FileNotFoundException; 265import java.io.FileOutputStream; 266import java.io.FileReader; 267import java.io.FilenameFilter; 268import java.io.IOException; 269import java.io.InputStream; 270import java.io.PrintWriter; 271import java.nio.charset.StandardCharsets; 272import java.security.MessageDigest; 273import java.security.NoSuchAlgorithmException; 274import java.security.PublicKey; 275import java.security.cert.CertificateEncodingException; 276import java.security.cert.CertificateException; 277import java.text.SimpleDateFormat; 278import java.util.ArrayList; 279import java.util.Arrays; 280import java.util.Collection; 281import java.util.Collections; 282import java.util.Comparator; 283import java.util.Date; 284import java.util.HashSet; 285import java.util.Iterator; 286import java.util.List; 287import java.util.Map; 288import java.util.Objects; 289import java.util.Set; 290import java.util.concurrent.CountDownLatch; 291import java.util.concurrent.TimeUnit; 292import java.util.concurrent.atomic.AtomicBoolean; 293import java.util.concurrent.atomic.AtomicInteger; 294import java.util.concurrent.atomic.AtomicLong; 295 296/** 297 * Keep track of all those .apks everywhere. 298 * 299 * This is very central to the platform's security; please run the unit 300 * tests whenever making modifications here: 301 * 302runtest -c android.content.pm.PackageManagerTests frameworks-core 303 * 304 * {@hide} 305 */ 306public class PackageManagerService extends IPackageManager.Stub { 307 static final String TAG = "PackageManager"; 308 static final boolean DEBUG_SETTINGS = false; 309 static final boolean DEBUG_PREFERRED = false; 310 static final boolean DEBUG_UPGRADE = false; 311 static final boolean DEBUG_DOMAIN_VERIFICATION = false; 312 private static final boolean DEBUG_BACKUP = false; 313 private static final boolean DEBUG_INSTALL = false; 314 private static final boolean DEBUG_REMOVE = false; 315 private static final boolean DEBUG_BROADCASTS = false; 316 private static final boolean DEBUG_SHOW_INFO = false; 317 private static final boolean DEBUG_PACKAGE_INFO = false; 318 private static final boolean DEBUG_INTENT_MATCHING = false; 319 private static final boolean DEBUG_PACKAGE_SCANNING = false; 320 private static final boolean DEBUG_VERIFY = false; 321 322 // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService 323 // and PackageDexOptimizer. All these classes have their own flag to allow switching a single 324 // user, but by default initialize to this. 325 static final boolean DEBUG_DEXOPT = false; 326 327 private static final boolean DEBUG_ABI_SELECTION = false; 328 private static final boolean DEBUG_EPHEMERAL = false; 329 private static final boolean DEBUG_TRIAGED_MISSING = false; 330 private static final boolean DEBUG_APP_DATA = false; 331 332 static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false; 333 334 private static final boolean DISABLE_EPHEMERAL_APPS = true; 335 336 private static final int RADIO_UID = Process.PHONE_UID; 337 private static final int LOG_UID = Process.LOG_UID; 338 private static final int NFC_UID = Process.NFC_UID; 339 private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID; 340 private static final int SHELL_UID = Process.SHELL_UID; 341 342 // Cap the size of permission trees that 3rd party apps can define 343 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768; // characters of text 344 345 // Suffix used during package installation when copying/moving 346 // package apks to install directory. 347 private static final String INSTALL_PACKAGE_SUFFIX = "-"; 348 349 static final int SCAN_NO_DEX = 1<<1; 350 static final int SCAN_FORCE_DEX = 1<<2; 351 static final int SCAN_UPDATE_SIGNATURE = 1<<3; 352 static final int SCAN_NEW_INSTALL = 1<<4; 353 static final int SCAN_NO_PATHS = 1<<5; 354 static final int SCAN_UPDATE_TIME = 1<<6; 355 static final int SCAN_DEFER_DEX = 1<<7; 356 static final int SCAN_BOOTING = 1<<8; 357 static final int SCAN_TRUSTED_OVERLAY = 1<<9; 358 static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10; 359 static final int SCAN_REPLACING = 1<<11; 360 static final int SCAN_REQUIRE_KNOWN = 1<<12; 361 static final int SCAN_MOVE = 1<<13; 362 static final int SCAN_INITIAL = 1<<14; 363 static final int SCAN_CHECK_ONLY = 1<<15; 364 static final int SCAN_DONT_KILL_APP = 1<<17; 365 366 static final int REMOVE_CHATTY = 1<<16; 367 368 private static final int[] EMPTY_INT_ARRAY = new int[0]; 369 370 /** 371 * Timeout (in milliseconds) after which the watchdog should declare that 372 * our handler thread is wedged. The usual default for such things is one 373 * minute but we sometimes do very lengthy I/O operations on this thread, 374 * such as installing multi-gigabyte applications, so ours needs to be longer. 375 */ 376 private static final long WATCHDOG_TIMEOUT = 1000*60*10; // ten minutes 377 378 /** 379 * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim 380 * be run on this device. We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL 381 * settings entry if available, otherwise we use the hardcoded default. If it's been 382 * more than this long since the last fstrim, we force one during the boot sequence. 383 * 384 * This backstops other fstrim scheduling: if the device is alive at midnight+idle, 385 * one gets run at the next available charging+idle time. This final mandatory 386 * no-fstrim check kicks in only of the other scheduling criteria is never met. 387 */ 388 private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS; 389 390 /** 391 * Whether verification is enabled by default. 392 */ 393 private static final boolean DEFAULT_VERIFY_ENABLE = true; 394 395 /** 396 * The default maximum time to wait for the verification agent to return in 397 * milliseconds. 398 */ 399 private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000; 400 401 /** 402 * The default response for package verification timeout. 403 * 404 * This can be either PackageManager.VERIFICATION_ALLOW or 405 * PackageManager.VERIFICATION_REJECT. 406 */ 407 private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW; 408 409 static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer"; 410 411 static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName( 412 DEFAULT_CONTAINER_PACKAGE, 413 "com.android.defcontainer.DefaultContainerService"); 414 415 private static final String KILL_APP_REASON_GIDS_CHANGED = 416 "permission grant or revoke changed gids"; 417 418 private static final String KILL_APP_REASON_PERMISSIONS_REVOKED = 419 "permissions revoked"; 420 421 private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive"; 422 423 private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay"; 424 425 /** Permission grant: not grant the permission. */ 426 private static final int GRANT_DENIED = 1; 427 428 /** Permission grant: grant the permission as an install permission. */ 429 private static final int GRANT_INSTALL = 2; 430 431 /** Permission grant: grant the permission as a runtime one. */ 432 private static final int GRANT_RUNTIME = 3; 433 434 /** Permission grant: grant as runtime a permission that was granted as an install time one. */ 435 private static final int GRANT_UPGRADE = 4; 436 437 /** Canonical intent used to identify what counts as a "web browser" app */ 438 private static final Intent sBrowserIntent; 439 static { 440 sBrowserIntent = new Intent(); 441 sBrowserIntent.setAction(Intent.ACTION_VIEW); 442 sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE); 443 sBrowserIntent.setData(Uri.parse("http:")); 444 } 445 446 final ServiceThread mHandlerThread; 447 448 final PackageHandler mHandler; 449 450 /** 451 * Messages for {@link #mHandler} that need to wait for system ready before 452 * being dispatched. 453 */ 454 private ArrayList<Message> mPostSystemReadyMessages; 455 456 final int mSdkVersion = Build.VERSION.SDK_INT; 457 458 final Context mContext; 459 final boolean mFactoryTest; 460 final boolean mOnlyCore; 461 final DisplayMetrics mMetrics; 462 final int mDefParseFlags; 463 final String[] mSeparateProcesses; 464 final boolean mIsUpgrade; 465 466 /** The location for ASEC container files on internal storage. */ 467 final String mAsecInternalPath; 468 469 // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages 470 // LOCK HELD. Can be called with mInstallLock held. 471 @GuardedBy("mInstallLock") 472 final Installer mInstaller; 473 474 /** Directory where installed third-party apps stored */ 475 final File mAppInstallDir; 476 final File mEphemeralInstallDir; 477 478 /** 479 * Directory to which applications installed internally have their 480 * 32 bit native libraries copied. 481 */ 482 private File mAppLib32InstallDir; 483 484 // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked 485 // apps. 486 final File mDrmAppPrivateInstallDir; 487 488 // ---------------------------------------------------------------- 489 490 // Lock for state used when installing and doing other long running 491 // operations. Methods that must be called with this lock held have 492 // the suffix "LI". 493 final Object mInstallLock = new Object(); 494 495 // ---------------------------------------------------------------- 496 497 // Keys are String (package name), values are Package. This also serves 498 // as the lock for the global state. Methods that must be called with 499 // this lock held have the prefix "LP". 500 @GuardedBy("mPackages") 501 final ArrayMap<String, PackageParser.Package> mPackages = 502 new ArrayMap<String, PackageParser.Package>(); 503 504 final ArrayMap<String, Set<String>> mKnownCodebase = 505 new ArrayMap<String, Set<String>>(); 506 507 // Tracks available target package names -> overlay package paths. 508 final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays = 509 new ArrayMap<String, ArrayMap<String, PackageParser.Package>>(); 510 511 /** 512 * Tracks new system packages [received in an OTA] that we expect to 513 * find updated user-installed versions. Keys are package name, values 514 * are package location. 515 */ 516 final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>(); 517 518 /** 519 * Tracks existing system packages prior to receiving an OTA. Keys are package name. 520 */ 521 final private ArraySet<String> mExistingSystemPackages = new ArraySet<>(); 522 /** 523 * Whether or not system app permissions should be promoted from install to runtime. 524 */ 525 boolean mPromoteSystemApps; 526 527 final Settings mSettings; 528 boolean mRestoredSettings; 529 530 // System configuration read by SystemConfig. 531 final int[] mGlobalGids; 532 final SparseArray<ArraySet<String>> mSystemPermissions; 533 final ArrayMap<String, FeatureInfo> mAvailableFeatures; 534 535 // If mac_permissions.xml was found for seinfo labeling. 536 boolean mFoundPolicyFile; 537 538 private final EphemeralApplicationRegistry mEphemeralApplicationRegistry; 539 540 public static final class SharedLibraryEntry { 541 public final String path; 542 public final String apk; 543 544 SharedLibraryEntry(String _path, String _apk) { 545 path = _path; 546 apk = _apk; 547 } 548 } 549 550 // Currently known shared libraries. 551 final ArrayMap<String, SharedLibraryEntry> mSharedLibraries = 552 new ArrayMap<String, SharedLibraryEntry>(); 553 554 // All available activities, for your resolving pleasure. 555 final ActivityIntentResolver mActivities = 556 new ActivityIntentResolver(); 557 558 // All available receivers, for your resolving pleasure. 559 final ActivityIntentResolver mReceivers = 560 new ActivityIntentResolver(); 561 562 // All available services, for your resolving pleasure. 563 final ServiceIntentResolver mServices = new ServiceIntentResolver(); 564 565 // All available providers, for your resolving pleasure. 566 final ProviderIntentResolver mProviders = new ProviderIntentResolver(); 567 568 // Mapping from provider base names (first directory in content URI codePath) 569 // to the provider information. 570 final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority = 571 new ArrayMap<String, PackageParser.Provider>(); 572 573 // Mapping from instrumentation class names to info about them. 574 final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation = 575 new ArrayMap<ComponentName, PackageParser.Instrumentation>(); 576 577 // Mapping from permission names to info about them. 578 final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups = 579 new ArrayMap<String, PackageParser.PermissionGroup>(); 580 581 // Packages whose data we have transfered into another package, thus 582 // should no longer exist. 583 final ArraySet<String> mTransferedPackages = new ArraySet<String>(); 584 585 // Broadcast actions that are only available to the system. 586 final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>(); 587 588 /** List of packages waiting for verification. */ 589 final SparseArray<PackageVerificationState> mPendingVerification 590 = new SparseArray<PackageVerificationState>(); 591 592 /** Set of packages associated with each app op permission. */ 593 final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>(); 594 595 final PackageInstallerService mInstallerService; 596 597 private final PackageDexOptimizer mPackageDexOptimizer; 598 599 private AtomicInteger mNextMoveId = new AtomicInteger(); 600 private final MoveCallbacks mMoveCallbacks; 601 602 private final OnPermissionChangeListeners mOnPermissionChangeListeners; 603 604 // Cache of users who need badging. 605 SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray(); 606 607 /** Token for keys in mPendingVerification. */ 608 private int mPendingVerificationToken = 0; 609 610 volatile boolean mSystemReady; 611 volatile boolean mSafeMode; 612 volatile boolean mHasSystemUidErrors; 613 614 ApplicationInfo mAndroidApplication; 615 final ActivityInfo mResolveActivity = new ActivityInfo(); 616 final ResolveInfo mResolveInfo = new ResolveInfo(); 617 ComponentName mResolveComponentName; 618 PackageParser.Package mPlatformPackage; 619 ComponentName mCustomResolverComponentName; 620 621 boolean mResolverReplaced = false; 622 623 private final @Nullable ComponentName mIntentFilterVerifierComponent; 624 private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier; 625 626 private int mIntentFilterVerificationToken = 0; 627 628 /** Component that knows whether or not an ephemeral application exists */ 629 final ComponentName mEphemeralResolverComponent; 630 /** The service connection to the ephemeral resolver */ 631 final EphemeralResolverConnection mEphemeralResolverConnection; 632 633 /** Component used to install ephemeral applications */ 634 final ComponentName mEphemeralInstallerComponent; 635 final ActivityInfo mEphemeralInstallerActivity = new ActivityInfo(); 636 final ResolveInfo mEphemeralInstallerInfo = new ResolveInfo(); 637 638 final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates 639 = new SparseArray<IntentFilterVerificationState>(); 640 641 final DefaultPermissionGrantPolicy mDefaultPermissionPolicy = 642 new DefaultPermissionGrantPolicy(this); 643 644 // List of packages names to keep cached, even if they are uninstalled for all users 645 private List<String> mKeepUninstalledPackages; 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 // Shared libraries do not have profiles so we perform a full 2170 // AOT compilation (if needed). 2171 int dexoptNeeded = DexFile.getDexOptNeeded( 2172 lib, dexCodeInstructionSet, 2173 DexFile.COMPILATION_TYPE_FULL); 2174 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { 2175 mInstaller.dexopt(lib, Process.SYSTEM_UID, dexCodeInstructionSet, 2176 dexoptNeeded, DEXOPT_PUBLIC /*dexFlags*/, 2177 StorageManager.UUID_PRIVATE_INTERNAL, 2178 false /*useProfiles*/); 2179 } 2180 } catch (FileNotFoundException e) { 2181 Slog.w(TAG, "Library not found: " + lib); 2182 } catch (IOException | InstallerException e) { 2183 Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? " 2184 + e.getMessage()); 2185 } 2186 } 2187 } 2188 } 2189 2190 File frameworkDir = new File(Environment.getRootDirectory(), "framework"); 2191 2192 final VersionInfo ver = mSettings.getInternalVersion(); 2193 mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint); 2194 // when upgrading from pre-M, promote system app permissions from install to runtime 2195 mPromoteSystemApps = 2196 mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1; 2197 2198 // save off the names of pre-existing system packages prior to scanning; we don't 2199 // want to automatically grant runtime permissions for new system apps 2200 if (mPromoteSystemApps) { 2201 Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator(); 2202 while (pkgSettingIter.hasNext()) { 2203 PackageSetting ps = pkgSettingIter.next(); 2204 if (isSystemApp(ps)) { 2205 mExistingSystemPackages.add(ps.name); 2206 } 2207 } 2208 } 2209 2210 // Collect vendor overlay packages. 2211 // (Do this before scanning any apps.) 2212 // For security and version matching reason, only consider 2213 // overlay packages if they reside in VENDOR_OVERLAY_DIR. 2214 File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR); 2215 scanDirTracedLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM 2216 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0); 2217 2218 // Find base frameworks (resource packages without code). 2219 scanDirTracedLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM 2220 | PackageParser.PARSE_IS_SYSTEM_DIR 2221 | PackageParser.PARSE_IS_PRIVILEGED, 2222 scanFlags | SCAN_NO_DEX, 0); 2223 2224 // Collected privileged system packages. 2225 final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app"); 2226 scanDirTracedLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM 2227 | PackageParser.PARSE_IS_SYSTEM_DIR 2228 | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0); 2229 2230 // Collect ordinary system packages. 2231 final File systemAppDir = new File(Environment.getRootDirectory(), "app"); 2232 scanDirTracedLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM 2233 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2234 2235 // Collect all vendor packages. 2236 File vendorAppDir = new File("/vendor/app"); 2237 try { 2238 vendorAppDir = vendorAppDir.getCanonicalFile(); 2239 } catch (IOException e) { 2240 // failed to look up canonical path, continue with original one 2241 } 2242 scanDirTracedLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM 2243 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2244 2245 // Collect all OEM packages. 2246 final File oemAppDir = new File(Environment.getOemDirectory(), "app"); 2247 scanDirTracedLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM 2248 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2249 2250 // Prune any system packages that no longer exist. 2251 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>(); 2252 if (!mOnlyCore) { 2253 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 2254 while (psit.hasNext()) { 2255 PackageSetting ps = psit.next(); 2256 2257 /* 2258 * If this is not a system app, it can't be a 2259 * disable system app. 2260 */ 2261 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) { 2262 continue; 2263 } 2264 2265 /* 2266 * If the package is scanned, it's not erased. 2267 */ 2268 final PackageParser.Package scannedPkg = mPackages.get(ps.name); 2269 if (scannedPkg != null) { 2270 /* 2271 * If the system app is both scanned and in the 2272 * disabled packages list, then it must have been 2273 * added via OTA. Remove it from the currently 2274 * scanned package so the previously user-installed 2275 * application can be scanned. 2276 */ 2277 if (mSettings.isDisabledSystemPackageLPr(ps.name)) { 2278 logCriticalInfo(Log.WARN, "Expecting better updated system app for " 2279 + ps.name + "; removing system app. Last known codePath=" 2280 + ps.codePathString + ", installStatus=" + ps.installStatus 2281 + ", versionCode=" + ps.versionCode + "; scanned versionCode=" 2282 + scannedPkg.mVersionCode); 2283 removePackageLI(scannedPkg, true); 2284 mExpectingBetter.put(ps.name, ps.codePath); 2285 } 2286 2287 continue; 2288 } 2289 2290 if (!mSettings.isDisabledSystemPackageLPr(ps.name)) { 2291 psit.remove(); 2292 logCriticalInfo(Log.WARN, "System package " + ps.name 2293 + " no longer exists; wiping its data"); 2294 removeDataDirsLI(null, ps.name); 2295 } else { 2296 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name); 2297 if (disabledPs.codePath == null || !disabledPs.codePath.exists()) { 2298 possiblyDeletedUpdatedSystemApps.add(ps.name); 2299 } 2300 } 2301 } 2302 } 2303 2304 //look for any incomplete package installations 2305 ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr(); 2306 //clean up list 2307 for(int i = 0; i < deletePkgsList.size(); i++) { 2308 //clean up here 2309 cleanupInstallFailedPackage(deletePkgsList.get(i)); 2310 } 2311 //delete tmp files 2312 deleteTempPackageFiles(); 2313 2314 // Remove any shared userIDs that have no associated packages 2315 mSettings.pruneSharedUsersLPw(); 2316 2317 if (!mOnlyCore) { 2318 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START, 2319 SystemClock.uptimeMillis()); 2320 scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0); 2321 2322 scanDirTracedLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK, 2323 scanFlags | SCAN_REQUIRE_KNOWN, 0); 2324 2325 scanDirLI(mEphemeralInstallDir, PackageParser.PARSE_IS_EPHEMERAL, 2326 scanFlags | SCAN_REQUIRE_KNOWN, 0); 2327 2328 /** 2329 * Remove disable package settings for any updated system 2330 * apps that were removed via an OTA. If they're not a 2331 * previously-updated app, remove them completely. 2332 * Otherwise, just revoke their system-level permissions. 2333 */ 2334 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) { 2335 PackageParser.Package deletedPkg = mPackages.get(deletedAppName); 2336 mSettings.removeDisabledSystemPackageLPw(deletedAppName); 2337 2338 String msg; 2339 if (deletedPkg == null) { 2340 msg = "Updated system package " + deletedAppName 2341 + " no longer exists; wiping its data"; 2342 removeDataDirsLI(null, deletedAppName); 2343 } else { 2344 msg = "Updated system app + " + deletedAppName 2345 + " no longer present; removing system privileges for " 2346 + deletedAppName; 2347 2348 deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM; 2349 2350 PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName); 2351 deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM; 2352 } 2353 logCriticalInfo(Log.WARN, msg); 2354 } 2355 2356 /** 2357 * Make sure all system apps that we expected to appear on 2358 * the userdata partition actually showed up. If they never 2359 * appeared, crawl back and revive the system version. 2360 */ 2361 for (int i = 0; i < mExpectingBetter.size(); i++) { 2362 final String packageName = mExpectingBetter.keyAt(i); 2363 if (!mPackages.containsKey(packageName)) { 2364 final File scanFile = mExpectingBetter.valueAt(i); 2365 2366 logCriticalInfo(Log.WARN, "Expected better " + packageName 2367 + " but never showed up; reverting to system"); 2368 2369 final int reparseFlags; 2370 if (FileUtils.contains(privilegedAppDir, scanFile)) { 2371 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2372 | PackageParser.PARSE_IS_SYSTEM_DIR 2373 | PackageParser.PARSE_IS_PRIVILEGED; 2374 } else if (FileUtils.contains(systemAppDir, scanFile)) { 2375 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2376 | PackageParser.PARSE_IS_SYSTEM_DIR; 2377 } else if (FileUtils.contains(vendorAppDir, scanFile)) { 2378 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2379 | PackageParser.PARSE_IS_SYSTEM_DIR; 2380 } else if (FileUtils.contains(oemAppDir, scanFile)) { 2381 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2382 | PackageParser.PARSE_IS_SYSTEM_DIR; 2383 } else { 2384 Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile); 2385 continue; 2386 } 2387 2388 mSettings.enableSystemPackageLPw(packageName); 2389 2390 try { 2391 scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null); 2392 } catch (PackageManagerException e) { 2393 Slog.e(TAG, "Failed to parse original system package: " 2394 + e.getMessage()); 2395 } 2396 } 2397 } 2398 } 2399 mExpectingBetter.clear(); 2400 2401 // Now that we know all of the shared libraries, update all clients to have 2402 // the correct library paths. 2403 updateAllSharedLibrariesLPw(); 2404 2405 for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) { 2406 // NOTE: We ignore potential failures here during a system scan (like 2407 // the rest of the commands above) because there's precious little we 2408 // can do about it. A settings error is reported, though. 2409 adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */, 2410 false /* boot complete */); 2411 } 2412 2413 // Now that we know all the packages we are keeping, 2414 // read and update their last usage times. 2415 mPackageUsage.readLP(); 2416 2417 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END, 2418 SystemClock.uptimeMillis()); 2419 Slog.i(TAG, "Time to scan packages: " 2420 + ((SystemClock.uptimeMillis()-startTime)/1000f) 2421 + " seconds"); 2422 2423 // If the platform SDK has changed since the last time we booted, 2424 // we need to re-grant app permission to catch any new ones that 2425 // appear. This is really a hack, and means that apps can in some 2426 // cases get permissions that the user didn't initially explicitly 2427 // allow... it would be nice to have some better way to handle 2428 // this situation. 2429 int updateFlags = UPDATE_PERMISSIONS_ALL; 2430 if (ver.sdkVersion != mSdkVersion) { 2431 Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to " 2432 + mSdkVersion + "; regranting permissions for internal storage"); 2433 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 2434 } 2435 updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags); 2436 ver.sdkVersion = mSdkVersion; 2437 2438 // If this is the first boot or an update from pre-M, and it is a normal 2439 // boot, then we need to initialize the default preferred apps across 2440 // all defined users. 2441 if (!onlyCore && (mPromoteSystemApps || !mRestoredSettings)) { 2442 for (UserInfo user : sUserManager.getUsers(true)) { 2443 mSettings.applyDefaultPreferredAppsLPw(this, user.id); 2444 applyFactoryDefaultBrowserLPw(user.id); 2445 primeDomainVerificationsLPw(user.id); 2446 } 2447 } 2448 2449 // Prepare storage for system user really early during boot, 2450 // since core system apps like SettingsProvider and SystemUI 2451 // can't wait for user to start 2452 final int storageFlags; 2453 if (StorageManager.isFileBasedEncryptionEnabled()) { 2454 storageFlags = StorageManager.FLAG_STORAGE_DE; 2455 } else { 2456 storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 2457 } 2458 reconcileAppsData(StorageManager.UUID_PRIVATE_INTERNAL, UserHandle.USER_SYSTEM, 2459 storageFlags); 2460 2461 // If this is first boot after an OTA, and a normal boot, then 2462 // we need to clear code cache directories. 2463 if (mIsUpgrade && !onlyCore) { 2464 Slog.i(TAG, "Build fingerprint changed; clearing code caches"); 2465 for (int i = 0; i < mSettings.mPackages.size(); i++) { 2466 final PackageSetting ps = mSettings.mPackages.valueAt(i); 2467 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) { 2468 deleteCodeCacheDirsLI(ps.volumeUuid, ps.name); 2469 } 2470 } 2471 ver.fingerprint = Build.FINGERPRINT; 2472 } 2473 2474 checkDefaultBrowser(); 2475 2476 // clear only after permissions and other defaults have been updated 2477 mExistingSystemPackages.clear(); 2478 mPromoteSystemApps = false; 2479 2480 // All the changes are done during package scanning. 2481 ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION; 2482 2483 // can downgrade to reader 2484 mSettings.writeLPr(); 2485 2486 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY, 2487 SystemClock.uptimeMillis()); 2488 2489 if (!mOnlyCore) { 2490 mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr(); 2491 mRequiredInstallerPackage = getRequiredInstallerLPr(); 2492 mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr(); 2493 mIntentFilterVerifier = new IntentVerifierProxy(mContext, 2494 mIntentFilterVerifierComponent); 2495 } else { 2496 mRequiredVerifierPackage = null; 2497 mRequiredInstallerPackage = null; 2498 mIntentFilterVerifierComponent = null; 2499 mIntentFilterVerifier = null; 2500 } 2501 2502 mInstallerService = new PackageInstallerService(context, this); 2503 2504 final ComponentName ephemeralResolverComponent = getEphemeralResolverLPr(); 2505 final ComponentName ephemeralInstallerComponent = getEphemeralInstallerLPr(); 2506 // both the installer and resolver must be present to enable ephemeral 2507 if (ephemeralInstallerComponent != null && ephemeralResolverComponent != null) { 2508 if (DEBUG_EPHEMERAL) { 2509 Slog.i(TAG, "Ephemeral activated; resolver: " + ephemeralResolverComponent 2510 + " installer:" + ephemeralInstallerComponent); 2511 } 2512 mEphemeralResolverComponent = ephemeralResolverComponent; 2513 mEphemeralInstallerComponent = ephemeralInstallerComponent; 2514 setUpEphemeralInstallerActivityLP(mEphemeralInstallerComponent); 2515 mEphemeralResolverConnection = 2516 new EphemeralResolverConnection(mContext, mEphemeralResolverComponent); 2517 } else { 2518 if (DEBUG_EPHEMERAL) { 2519 final String missingComponent = 2520 (ephemeralResolverComponent == null) 2521 ? (ephemeralInstallerComponent == null) 2522 ? "resolver and installer" 2523 : "resolver" 2524 : "installer"; 2525 Slog.i(TAG, "Ephemeral deactivated; missing " + missingComponent); 2526 } 2527 mEphemeralResolverComponent = null; 2528 mEphemeralInstallerComponent = null; 2529 mEphemeralResolverConnection = null; 2530 } 2531 2532 mEphemeralApplicationRegistry = new EphemeralApplicationRegistry(this); 2533 } // synchronized (mPackages) 2534 } // synchronized (mInstallLock) 2535 2536 // Now after opening every single application zip, make sure they 2537 // are all flushed. Not really needed, but keeps things nice and 2538 // tidy. 2539 Runtime.getRuntime().gc(); 2540 2541 // The initial scanning above does many calls into installd while 2542 // holding the mPackages lock, but we're mostly interested in yelling 2543 // once we have a booted system. 2544 mInstaller.setWarnIfHeld(mPackages); 2545 2546 // Expose private service for system components to use. 2547 LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl()); 2548 } 2549 2550 @Override 2551 public boolean isFirstBoot() { 2552 return !mRestoredSettings; 2553 } 2554 2555 @Override 2556 public boolean isOnlyCoreApps() { 2557 return mOnlyCore; 2558 } 2559 2560 @Override 2561 public boolean isUpgrade() { 2562 return mIsUpgrade; 2563 } 2564 2565 private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() { 2566 final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 2567 2568 final List<ResolveInfo> matches = queryIntentReceivers(intent, PACKAGE_MIME_TYPE, 2569 MATCH_SYSTEM_ONLY | MATCH_ENCRYPTION_AWARE_AND_UNAWARE, UserHandle.USER_SYSTEM); 2570 if (matches.size() == 1) { 2571 return matches.get(0).getComponentInfo().packageName; 2572 } else { 2573 Log.e(TAG, "There should probably be exactly one verifier; found " + matches); 2574 return null; 2575 } 2576 } 2577 2578 private @NonNull String getRequiredInstallerLPr() { 2579 final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE); 2580 intent.addCategory(Intent.CATEGORY_DEFAULT); 2581 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE); 2582 2583 final List<ResolveInfo> matches = queryIntentActivities(intent, PACKAGE_MIME_TYPE, 2584 MATCH_SYSTEM_ONLY | MATCH_ENCRYPTION_AWARE_AND_UNAWARE, UserHandle.USER_SYSTEM); 2585 if (matches.size() == 1) { 2586 return matches.get(0).getComponentInfo().packageName; 2587 } else { 2588 throw new RuntimeException("There must be exactly one installer; found " + matches); 2589 } 2590 } 2591 2592 private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() { 2593 final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 2594 2595 final List<ResolveInfo> matches = queryIntentReceivers(intent, PACKAGE_MIME_TYPE, 2596 MATCH_SYSTEM_ONLY | MATCH_ENCRYPTION_AWARE_AND_UNAWARE, UserHandle.USER_SYSTEM); 2597 ResolveInfo best = null; 2598 final int N = matches.size(); 2599 for (int i = 0; i < N; i++) { 2600 final ResolveInfo cur = matches.get(i); 2601 final String packageName = cur.getComponentInfo().packageName; 2602 if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 2603 packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) { 2604 continue; 2605 } 2606 2607 if (best == null || cur.priority > best.priority) { 2608 best = cur; 2609 } 2610 } 2611 2612 if (best != null) { 2613 return best.getComponentInfo().getComponentName(); 2614 } else { 2615 throw new RuntimeException("There must be at least one intent filter verifier"); 2616 } 2617 } 2618 2619 private @Nullable ComponentName getEphemeralResolverLPr() { 2620 final String[] packageArray = 2621 mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage); 2622 if (packageArray.length == 0) { 2623 if (DEBUG_EPHEMERAL) { 2624 Slog.d(TAG, "Ephemeral resolver NOT found; empty package list"); 2625 } 2626 return null; 2627 } 2628 2629 final Intent resolverIntent = new Intent(Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE); 2630 final List<ResolveInfo> resolvers = queryIntentServices(resolverIntent, null, 2631 MATCH_SYSTEM_ONLY | MATCH_ENCRYPTION_AWARE_AND_UNAWARE, UserHandle.USER_SYSTEM); 2632 2633 final int N = resolvers.size(); 2634 if (N == 0) { 2635 if (DEBUG_EPHEMERAL) { 2636 Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters"); 2637 } 2638 return null; 2639 } 2640 2641 final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray)); 2642 for (int i = 0; i < N; i++) { 2643 final ResolveInfo info = resolvers.get(i); 2644 2645 if (info.serviceInfo == null) { 2646 continue; 2647 } 2648 2649 final String packageName = info.serviceInfo.packageName; 2650 if (!possiblePackages.contains(packageName)) { 2651 if (DEBUG_EPHEMERAL) { 2652 Slog.d(TAG, "Ephemeral resolver not in allowed package list;" 2653 + " pkg: " + packageName + ", info:" + info); 2654 } 2655 continue; 2656 } 2657 2658 if (DEBUG_EPHEMERAL) { 2659 Slog.v(TAG, "Ephemeral resolver found;" 2660 + " pkg: " + packageName + ", info:" + info); 2661 } 2662 return new ComponentName(packageName, info.serviceInfo.name); 2663 } 2664 if (DEBUG_EPHEMERAL) { 2665 Slog.v(TAG, "Ephemeral resolver NOT found"); 2666 } 2667 return null; 2668 } 2669 2670 private @Nullable ComponentName getEphemeralInstallerLPr() { 2671 final Intent intent = new Intent(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE); 2672 intent.addCategory(Intent.CATEGORY_DEFAULT); 2673 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE); 2674 2675 final List<ResolveInfo> matches = queryIntentActivities(intent, PACKAGE_MIME_TYPE, 2676 MATCH_SYSTEM_ONLY | MATCH_ENCRYPTION_AWARE_AND_UNAWARE, UserHandle.USER_SYSTEM); 2677 if (matches.size() == 0) { 2678 return null; 2679 } else if (matches.size() == 1) { 2680 return matches.get(0).getComponentInfo().getComponentName(); 2681 } else { 2682 throw new RuntimeException( 2683 "There must be at most one ephemeral installer; found " + matches); 2684 } 2685 } 2686 2687 private void primeDomainVerificationsLPw(int userId) { 2688 if (DEBUG_DOMAIN_VERIFICATION) { 2689 Slog.d(TAG, "Priming domain verifications in user " + userId); 2690 } 2691 2692 SystemConfig systemConfig = SystemConfig.getInstance(); 2693 ArraySet<String> packages = systemConfig.getLinkedApps(); 2694 ArraySet<String> domains = new ArraySet<String>(); 2695 2696 for (String packageName : packages) { 2697 PackageParser.Package pkg = mPackages.get(packageName); 2698 if (pkg != null) { 2699 if (!pkg.isSystemApp()) { 2700 Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>"); 2701 continue; 2702 } 2703 2704 domains.clear(); 2705 for (PackageParser.Activity a : pkg.activities) { 2706 for (ActivityIntentInfo filter : a.intents) { 2707 if (hasValidDomains(filter)) { 2708 domains.addAll(filter.getHostsList()); 2709 } 2710 } 2711 } 2712 2713 if (domains.size() > 0) { 2714 if (DEBUG_DOMAIN_VERIFICATION) { 2715 Slog.v(TAG, " + " + packageName); 2716 } 2717 // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual 2718 // state w.r.t. the formal app-linkage "no verification attempted" state; 2719 // and then 'always' in the per-user state actually used for intent resolution. 2720 final IntentFilterVerificationInfo ivi; 2721 ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, 2722 new ArrayList<String>(domains)); 2723 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED); 2724 mSettings.updateIntentFilterVerificationStatusLPw(packageName, 2725 INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId); 2726 } else { 2727 Slog.w(TAG, "Sysconfig <app-link> package '" + packageName 2728 + "' does not handle web links"); 2729 } 2730 } else { 2731 Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>"); 2732 } 2733 } 2734 2735 scheduleWritePackageRestrictionsLocked(userId); 2736 scheduleWriteSettingsLocked(); 2737 } 2738 2739 private void applyFactoryDefaultBrowserLPw(int userId) { 2740 // The default browser app's package name is stored in a string resource, 2741 // with a product-specific overlay used for vendor customization. 2742 String browserPkg = mContext.getResources().getString( 2743 com.android.internal.R.string.default_browser); 2744 if (!TextUtils.isEmpty(browserPkg)) { 2745 // non-empty string => required to be a known package 2746 PackageSetting ps = mSettings.mPackages.get(browserPkg); 2747 if (ps == null) { 2748 Slog.e(TAG, "Product default browser app does not exist: " + browserPkg); 2749 browserPkg = null; 2750 } else { 2751 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId); 2752 } 2753 } 2754 2755 // Nothing valid explicitly set? Make the factory-installed browser the explicit 2756 // default. If there's more than one, just leave everything alone. 2757 if (browserPkg == null) { 2758 calculateDefaultBrowserLPw(userId); 2759 } 2760 } 2761 2762 private void calculateDefaultBrowserLPw(int userId) { 2763 List<String> allBrowsers = resolveAllBrowserApps(userId); 2764 final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null; 2765 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId); 2766 } 2767 2768 private List<String> resolveAllBrowserApps(int userId) { 2769 // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set 2770 List<ResolveInfo> list = queryIntentActivities(sBrowserIntent, null, 2771 PackageManager.MATCH_ALL, userId); 2772 2773 final int count = list.size(); 2774 List<String> result = new ArrayList<String>(count); 2775 for (int i=0; i<count; i++) { 2776 ResolveInfo info = list.get(i); 2777 if (info.activityInfo == null 2778 || !info.handleAllWebDataURI 2779 || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0 2780 || result.contains(info.activityInfo.packageName)) { 2781 continue; 2782 } 2783 result.add(info.activityInfo.packageName); 2784 } 2785 2786 return result; 2787 } 2788 2789 private boolean packageIsBrowser(String packageName, int userId) { 2790 List<ResolveInfo> list = queryIntentActivities(sBrowserIntent, null, 2791 PackageManager.MATCH_ALL, userId); 2792 final int N = list.size(); 2793 for (int i = 0; i < N; i++) { 2794 ResolveInfo info = list.get(i); 2795 if (packageName.equals(info.activityInfo.packageName)) { 2796 return true; 2797 } 2798 } 2799 return false; 2800 } 2801 2802 private void checkDefaultBrowser() { 2803 final int myUserId = UserHandle.myUserId(); 2804 final String packageName = getDefaultBrowserPackageName(myUserId); 2805 if (packageName != null) { 2806 PackageInfo info = getPackageInfo(packageName, 0, myUserId); 2807 if (info == null) { 2808 Slog.w(TAG, "Default browser no longer installed: " + packageName); 2809 synchronized (mPackages) { 2810 applyFactoryDefaultBrowserLPw(myUserId); // leaves ambiguous when > 1 2811 } 2812 } 2813 } 2814 } 2815 2816 @Override 2817 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2818 throws RemoteException { 2819 try { 2820 return super.onTransact(code, data, reply, flags); 2821 } catch (RuntimeException e) { 2822 if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) { 2823 Slog.wtf(TAG, "Package Manager Crash", e); 2824 } 2825 throw e; 2826 } 2827 } 2828 2829 void cleanupInstallFailedPackage(PackageSetting ps) { 2830 logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + ps.name); 2831 2832 removeDataDirsLI(ps.volumeUuid, ps.name); 2833 if (ps.codePath != null) { 2834 removeCodePathLI(ps.codePath); 2835 } 2836 if (ps.resourcePath != null && !ps.resourcePath.equals(ps.codePath)) { 2837 if (ps.resourcePath.isDirectory()) { 2838 FileUtils.deleteContents(ps.resourcePath); 2839 } 2840 ps.resourcePath.delete(); 2841 } 2842 mSettings.removePackageLPw(ps.name); 2843 } 2844 2845 static int[] appendInts(int[] cur, int[] add) { 2846 if (add == null) return cur; 2847 if (cur == null) return add; 2848 final int N = add.length; 2849 for (int i=0; i<N; i++) { 2850 cur = appendInt(cur, add[i]); 2851 } 2852 return cur; 2853 } 2854 2855 PackageInfo generatePackageInfo(PackageParser.Package p, int flags, int userId) { 2856 if (!sUserManager.exists(userId)) return null; 2857 final PackageSetting ps = (PackageSetting) p.mExtras; 2858 if (ps == null) { 2859 return null; 2860 } 2861 2862 final PermissionsState permissionsState = ps.getPermissionsState(); 2863 2864 final int[] gids = permissionsState.computeGids(userId); 2865 final Set<String> permissions = permissionsState.getPermissions(userId); 2866 final PackageUserState state = ps.readUserState(userId); 2867 2868 return PackageParser.generatePackageInfo(p, gids, flags, 2869 ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId); 2870 } 2871 2872 @Override 2873 public void checkPackageStartable(String packageName, int userId) { 2874 final boolean userKeyUnlocked = isUserKeyUnlocked(userId); 2875 2876 synchronized (mPackages) { 2877 final PackageSetting ps = mSettings.mPackages.get(packageName); 2878 if (ps == null) { 2879 throw new SecurityException("Package " + packageName + " was not found!"); 2880 } 2881 2882 if (mSafeMode && !ps.isSystem()) { 2883 throw new SecurityException("Package " + packageName + " not a system app!"); 2884 } 2885 2886 if (ps.frozen) { 2887 throw new SecurityException("Package " + packageName + " is currently frozen!"); 2888 } 2889 2890 if (!userKeyUnlocked && !(ps.pkg.applicationInfo.isEncryptionAware() 2891 || ps.pkg.applicationInfo.isPartiallyEncryptionAware())) { 2892 throw new SecurityException("Package " + packageName + " is not encryption aware!"); 2893 } 2894 } 2895 } 2896 2897 @Override 2898 public boolean isPackageAvailable(String packageName, int userId) { 2899 if (!sUserManager.exists(userId)) return false; 2900 enforceCrossUserPermission(Binder.getCallingUid(), userId, 2901 false /* requireFullPermission */, false /* checkShell */, "is package available"); 2902 synchronized (mPackages) { 2903 PackageParser.Package p = mPackages.get(packageName); 2904 if (p != null) { 2905 final PackageSetting ps = (PackageSetting) p.mExtras; 2906 if (ps != null) { 2907 final PackageUserState state = ps.readUserState(userId); 2908 if (state != null) { 2909 return PackageParser.isAvailable(state); 2910 } 2911 } 2912 } 2913 } 2914 return false; 2915 } 2916 2917 @Override 2918 public PackageInfo getPackageInfo(String packageName, int flags, int userId) { 2919 if (!sUserManager.exists(userId)) return null; 2920 flags = updateFlagsForPackage(flags, userId, packageName); 2921 enforceCrossUserPermission(Binder.getCallingUid(), userId, 2922 false /* requireFullPermission */, false /* checkShell */, "get package info"); 2923 // reader 2924 synchronized (mPackages) { 2925 PackageParser.Package p = mPackages.get(packageName); 2926 if (DEBUG_PACKAGE_INFO) 2927 Log.v(TAG, "getPackageInfo " + packageName + ": " + p); 2928 if (p != null) { 2929 return generatePackageInfo(p, flags, userId); 2930 } 2931 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 2932 return generatePackageInfoFromSettingsLPw(packageName, flags, userId); 2933 } 2934 } 2935 return null; 2936 } 2937 2938 @Override 2939 public String[] currentToCanonicalPackageNames(String[] names) { 2940 String[] out = new String[names.length]; 2941 // reader 2942 synchronized (mPackages) { 2943 for (int i=names.length-1; i>=0; i--) { 2944 PackageSetting ps = mSettings.mPackages.get(names[i]); 2945 out[i] = ps != null && ps.realName != null ? ps.realName : names[i]; 2946 } 2947 } 2948 return out; 2949 } 2950 2951 @Override 2952 public String[] canonicalToCurrentPackageNames(String[] names) { 2953 String[] out = new String[names.length]; 2954 // reader 2955 synchronized (mPackages) { 2956 for (int i=names.length-1; i>=0; i--) { 2957 String cur = mSettings.mRenamedPackages.get(names[i]); 2958 out[i] = cur != null ? cur : names[i]; 2959 } 2960 } 2961 return out; 2962 } 2963 2964 @Override 2965 public int getPackageUid(String packageName, int flags, int userId) { 2966 if (!sUserManager.exists(userId)) return -1; 2967 flags = updateFlagsForPackage(flags, userId, packageName); 2968 enforceCrossUserPermission(Binder.getCallingUid(), userId, 2969 false /* requireFullPermission */, false /* checkShell */, "get package uid"); 2970 2971 // reader 2972 synchronized (mPackages) { 2973 final PackageParser.Package p = mPackages.get(packageName); 2974 if (p != null && p.isMatch(flags)) { 2975 return UserHandle.getUid(userId, p.applicationInfo.uid); 2976 } 2977 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 2978 final PackageSetting ps = mSettings.mPackages.get(packageName); 2979 if (ps != null && ps.isMatch(flags)) { 2980 return UserHandle.getUid(userId, ps.appId); 2981 } 2982 } 2983 } 2984 2985 return -1; 2986 } 2987 2988 @Override 2989 public int[] getPackageGids(String packageName, int flags, int userId) { 2990 if (!sUserManager.exists(userId)) return null; 2991 flags = updateFlagsForPackage(flags, userId, packageName); 2992 enforceCrossUserPermission(Binder.getCallingUid(), userId, 2993 false /* requireFullPermission */, false /* checkShell */, 2994 "getPackageGids"); 2995 2996 // reader 2997 synchronized (mPackages) { 2998 final PackageParser.Package p = mPackages.get(packageName); 2999 if (p != null && p.isMatch(flags)) { 3000 PackageSetting ps = (PackageSetting) p.mExtras; 3001 return ps.getPermissionsState().computeGids(userId); 3002 } 3003 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 3004 final PackageSetting ps = mSettings.mPackages.get(packageName); 3005 if (ps != null && ps.isMatch(flags)) { 3006 return ps.getPermissionsState().computeGids(userId); 3007 } 3008 } 3009 } 3010 3011 return null; 3012 } 3013 3014 static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) { 3015 if (bp.perm != null) { 3016 return PackageParser.generatePermissionInfo(bp.perm, flags); 3017 } 3018 PermissionInfo pi = new PermissionInfo(); 3019 pi.name = bp.name; 3020 pi.packageName = bp.sourcePackage; 3021 pi.nonLocalizedLabel = bp.name; 3022 pi.protectionLevel = bp.protectionLevel; 3023 return pi; 3024 } 3025 3026 @Override 3027 public PermissionInfo getPermissionInfo(String name, int flags) { 3028 // reader 3029 synchronized (mPackages) { 3030 final BasePermission p = mSettings.mPermissions.get(name); 3031 if (p != null) { 3032 return generatePermissionInfo(p, flags); 3033 } 3034 return null; 3035 } 3036 } 3037 3038 @Override 3039 public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) { 3040 // reader 3041 synchronized (mPackages) { 3042 ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10); 3043 for (BasePermission p : mSettings.mPermissions.values()) { 3044 if (group == null) { 3045 if (p.perm == null || p.perm.info.group == null) { 3046 out.add(generatePermissionInfo(p, flags)); 3047 } 3048 } else { 3049 if (p.perm != null && group.equals(p.perm.info.group)) { 3050 out.add(PackageParser.generatePermissionInfo(p.perm, flags)); 3051 } 3052 } 3053 } 3054 3055 if (out.size() > 0) { 3056 return out; 3057 } 3058 return mPermissionGroups.containsKey(group) ? out : null; 3059 } 3060 } 3061 3062 @Override 3063 public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) { 3064 // reader 3065 synchronized (mPackages) { 3066 return PackageParser.generatePermissionGroupInfo( 3067 mPermissionGroups.get(name), flags); 3068 } 3069 } 3070 3071 @Override 3072 public List<PermissionGroupInfo> getAllPermissionGroups(int flags) { 3073 // reader 3074 synchronized (mPackages) { 3075 final int N = mPermissionGroups.size(); 3076 ArrayList<PermissionGroupInfo> out 3077 = new ArrayList<PermissionGroupInfo>(N); 3078 for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) { 3079 out.add(PackageParser.generatePermissionGroupInfo(pg, flags)); 3080 } 3081 return out; 3082 } 3083 } 3084 3085 private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags, 3086 int userId) { 3087 if (!sUserManager.exists(userId)) return null; 3088 PackageSetting ps = mSettings.mPackages.get(packageName); 3089 if (ps != null) { 3090 if (ps.pkg == null) { 3091 PackageInfo pInfo = generatePackageInfoFromSettingsLPw(packageName, 3092 flags, userId); 3093 if (pInfo != null) { 3094 return pInfo.applicationInfo; 3095 } 3096 return null; 3097 } 3098 return PackageParser.generateApplicationInfo(ps.pkg, flags, 3099 ps.readUserState(userId), userId); 3100 } 3101 return null; 3102 } 3103 3104 private PackageInfo generatePackageInfoFromSettingsLPw(String packageName, int flags, 3105 int userId) { 3106 if (!sUserManager.exists(userId)) return null; 3107 PackageSetting ps = mSettings.mPackages.get(packageName); 3108 if (ps != null) { 3109 PackageParser.Package pkg = ps.pkg; 3110 if (pkg == null) { 3111 if ((flags & MATCH_UNINSTALLED_PACKAGES) == 0) { 3112 return null; 3113 } 3114 // Only data remains, so we aren't worried about code paths 3115 pkg = new PackageParser.Package(packageName); 3116 pkg.applicationInfo.packageName = packageName; 3117 pkg.applicationInfo.flags = ps.pkgFlags | ApplicationInfo.FLAG_IS_DATA_ONLY; 3118 pkg.applicationInfo.privateFlags = ps.pkgPrivateFlags; 3119 pkg.applicationInfo.uid = ps.appId; 3120 pkg.applicationInfo.initForUser(userId); 3121 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString; 3122 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString; 3123 } 3124 return generatePackageInfo(pkg, flags, userId); 3125 } 3126 return null; 3127 } 3128 3129 @Override 3130 public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) { 3131 if (!sUserManager.exists(userId)) return null; 3132 flags = updateFlagsForApplication(flags, userId, packageName); 3133 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3134 false /* requireFullPermission */, false /* checkShell */, "get application info"); 3135 // writer 3136 synchronized (mPackages) { 3137 PackageParser.Package p = mPackages.get(packageName); 3138 if (DEBUG_PACKAGE_INFO) Log.v( 3139 TAG, "getApplicationInfo " + packageName 3140 + ": " + p); 3141 if (p != null) { 3142 PackageSetting ps = mSettings.mPackages.get(packageName); 3143 if (ps == null) return null; 3144 // Note: isEnabledLP() does not apply here - always return info 3145 return PackageParser.generateApplicationInfo( 3146 p, flags, ps.readUserState(userId), userId); 3147 } 3148 if ("android".equals(packageName)||"system".equals(packageName)) { 3149 return mAndroidApplication; 3150 } 3151 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 3152 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId); 3153 } 3154 } 3155 return null; 3156 } 3157 3158 @Override 3159 public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize, 3160 final IPackageDataObserver observer) { 3161 mContext.enforceCallingOrSelfPermission( 3162 android.Manifest.permission.CLEAR_APP_CACHE, null); 3163 // Queue up an async operation since clearing cache may take a little while. 3164 mHandler.post(new Runnable() { 3165 public void run() { 3166 mHandler.removeCallbacks(this); 3167 boolean success = true; 3168 synchronized (mInstallLock) { 3169 try { 3170 mInstaller.freeCache(volumeUuid, freeStorageSize); 3171 } catch (InstallerException e) { 3172 Slog.w(TAG, "Couldn't clear application caches: " + e); 3173 success = false; 3174 } 3175 } 3176 if (observer != null) { 3177 try { 3178 observer.onRemoveCompleted(null, success); 3179 } catch (RemoteException e) { 3180 Slog.w(TAG, "RemoveException when invoking call back"); 3181 } 3182 } 3183 } 3184 }); 3185 } 3186 3187 @Override 3188 public void freeStorage(final String volumeUuid, final long freeStorageSize, 3189 final IntentSender pi) { 3190 mContext.enforceCallingOrSelfPermission( 3191 android.Manifest.permission.CLEAR_APP_CACHE, null); 3192 // Queue up an async operation since clearing cache may take a little while. 3193 mHandler.post(new Runnable() { 3194 public void run() { 3195 mHandler.removeCallbacks(this); 3196 boolean success = true; 3197 synchronized (mInstallLock) { 3198 try { 3199 mInstaller.freeCache(volumeUuid, freeStorageSize); 3200 } catch (InstallerException e) { 3201 Slog.w(TAG, "Couldn't clear application caches: " + e); 3202 success = false; 3203 } 3204 } 3205 if(pi != null) { 3206 try { 3207 // Callback via pending intent 3208 int code = success ? 1 : 0; 3209 pi.sendIntent(null, code, null, 3210 null, null); 3211 } catch (SendIntentException e1) { 3212 Slog.i(TAG, "Failed to send pending intent"); 3213 } 3214 } 3215 } 3216 }); 3217 } 3218 3219 void freeStorage(String volumeUuid, long freeStorageSize) throws IOException { 3220 synchronized (mInstallLock) { 3221 try { 3222 mInstaller.freeCache(volumeUuid, freeStorageSize); 3223 } catch (InstallerException e) { 3224 throw new IOException("Failed to free enough space", e); 3225 } 3226 } 3227 } 3228 3229 /** 3230 * Return if the user key is currently unlocked. 3231 */ 3232 private boolean isUserKeyUnlocked(int userId) { 3233 if (StorageManager.isFileBasedEncryptionEnabled()) { 3234 final IMountService mount = IMountService.Stub 3235 .asInterface(ServiceManager.getService("mount")); 3236 if (mount == null) { 3237 Slog.w(TAG, "Early during boot, assuming locked"); 3238 return false; 3239 } 3240 final long token = Binder.clearCallingIdentity(); 3241 try { 3242 return mount.isUserKeyUnlocked(userId); 3243 } catch (RemoteException e) { 3244 throw e.rethrowAsRuntimeException(); 3245 } finally { 3246 Binder.restoreCallingIdentity(token); 3247 } 3248 } else { 3249 return true; 3250 } 3251 } 3252 3253 /** 3254 * Update given flags based on encryption status of current user. 3255 */ 3256 private int updateFlags(int flags, int userId) { 3257 if ((flags & (PackageManager.MATCH_ENCRYPTION_UNAWARE 3258 | PackageManager.MATCH_ENCRYPTION_AWARE)) != 0) { 3259 // Caller expressed an explicit opinion about what encryption 3260 // aware/unaware components they want to see, so fall through and 3261 // give them what they want 3262 } else { 3263 // Caller expressed no opinion, so match based on user state 3264 if (isUserKeyUnlocked(userId)) { 3265 flags |= PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE; 3266 } else { 3267 flags |= PackageManager.MATCH_ENCRYPTION_AWARE; 3268 } 3269 } 3270 return flags; 3271 } 3272 3273 /** 3274 * Update given flags when being used to request {@link PackageInfo}. 3275 */ 3276 private int updateFlagsForPackage(int flags, int userId, Object cookie) { 3277 boolean triaged = true; 3278 if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS 3279 | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) { 3280 // Caller is asking for component details, so they'd better be 3281 // asking for specific encryption matching behavior, or be triaged 3282 if ((flags & (PackageManager.MATCH_ENCRYPTION_UNAWARE 3283 | PackageManager.MATCH_ENCRYPTION_AWARE 3284 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3285 triaged = false; 3286 } 3287 } 3288 if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES 3289 | PackageManager.MATCH_SYSTEM_ONLY 3290 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3291 triaged = false; 3292 } 3293 if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) { 3294 Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie 3295 + " with flags 0x" + Integer.toHexString(flags), new Throwable()); 3296 } 3297 return updateFlags(flags, userId); 3298 } 3299 3300 /** 3301 * Update given flags when being used to request {@link ApplicationInfo}. 3302 */ 3303 private int updateFlagsForApplication(int flags, int userId, Object cookie) { 3304 return updateFlagsForPackage(flags, userId, cookie); 3305 } 3306 3307 /** 3308 * Update given flags when being used to request {@link ComponentInfo}. 3309 */ 3310 private int updateFlagsForComponent(int flags, int userId, Object cookie) { 3311 if (cookie instanceof Intent) { 3312 if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) { 3313 flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING; 3314 } 3315 } 3316 3317 boolean triaged = true; 3318 // Caller is asking for component details, so they'd better be 3319 // asking for specific encryption matching behavior, or be triaged 3320 if ((flags & (PackageManager.MATCH_ENCRYPTION_UNAWARE 3321 | PackageManager.MATCH_ENCRYPTION_AWARE 3322 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3323 triaged = false; 3324 } 3325 if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) { 3326 Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie 3327 + " with flags 0x" + Integer.toHexString(flags), new Throwable()); 3328 } 3329 3330 return updateFlags(flags, userId); 3331 } 3332 3333 /** 3334 * Update given flags when being used to request {@link ResolveInfo}. 3335 */ 3336 int updateFlagsForResolve(int flags, int userId, Object cookie) { 3337 // Safe mode means we shouldn't match any third-party components 3338 if (mSafeMode) { 3339 flags |= PackageManager.MATCH_SYSTEM_ONLY; 3340 } 3341 3342 return updateFlagsForComponent(flags, userId, cookie); 3343 } 3344 3345 @Override 3346 public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) { 3347 if (!sUserManager.exists(userId)) return null; 3348 flags = updateFlagsForComponent(flags, userId, component); 3349 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3350 false /* requireFullPermission */, false /* checkShell */, "get activity info"); 3351 synchronized (mPackages) { 3352 PackageParser.Activity a = mActivities.mActivities.get(component); 3353 3354 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a); 3355 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) { 3356 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3357 if (ps == null) return null; 3358 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 3359 userId); 3360 } 3361 if (mResolveComponentName.equals(component)) { 3362 return PackageParser.generateActivityInfo(mResolveActivity, flags, 3363 new PackageUserState(), userId); 3364 } 3365 } 3366 return null; 3367 } 3368 3369 @Override 3370 public boolean activitySupportsIntent(ComponentName component, Intent intent, 3371 String resolvedType) { 3372 synchronized (mPackages) { 3373 if (component.equals(mResolveComponentName)) { 3374 // The resolver supports EVERYTHING! 3375 return true; 3376 } 3377 PackageParser.Activity a = mActivities.mActivities.get(component); 3378 if (a == null) { 3379 return false; 3380 } 3381 for (int i=0; i<a.intents.size(); i++) { 3382 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(), 3383 intent.getData(), intent.getCategories(), TAG) >= 0) { 3384 return true; 3385 } 3386 } 3387 return false; 3388 } 3389 } 3390 3391 @Override 3392 public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) { 3393 if (!sUserManager.exists(userId)) return null; 3394 flags = updateFlagsForComponent(flags, userId, component); 3395 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3396 false /* requireFullPermission */, false /* checkShell */, "get receiver info"); 3397 synchronized (mPackages) { 3398 PackageParser.Activity a = mReceivers.mActivities.get(component); 3399 if (DEBUG_PACKAGE_INFO) Log.v( 3400 TAG, "getReceiverInfo " + component + ": " + a); 3401 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) { 3402 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3403 if (ps == null) return null; 3404 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 3405 userId); 3406 } 3407 } 3408 return null; 3409 } 3410 3411 @Override 3412 public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) { 3413 if (!sUserManager.exists(userId)) return null; 3414 flags = updateFlagsForComponent(flags, userId, component); 3415 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3416 false /* requireFullPermission */, false /* checkShell */, "get service info"); 3417 synchronized (mPackages) { 3418 PackageParser.Service s = mServices.mServices.get(component); 3419 if (DEBUG_PACKAGE_INFO) Log.v( 3420 TAG, "getServiceInfo " + component + ": " + s); 3421 if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) { 3422 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3423 if (ps == null) return null; 3424 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId), 3425 userId); 3426 } 3427 } 3428 return null; 3429 } 3430 3431 @Override 3432 public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) { 3433 if (!sUserManager.exists(userId)) return null; 3434 flags = updateFlagsForComponent(flags, userId, component); 3435 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3436 false /* requireFullPermission */, false /* checkShell */, "get provider info"); 3437 synchronized (mPackages) { 3438 PackageParser.Provider p = mProviders.mProviders.get(component); 3439 if (DEBUG_PACKAGE_INFO) Log.v( 3440 TAG, "getProviderInfo " + component + ": " + p); 3441 if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) { 3442 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3443 if (ps == null) return null; 3444 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId), 3445 userId); 3446 } 3447 } 3448 return null; 3449 } 3450 3451 @Override 3452 public String[] getSystemSharedLibraryNames() { 3453 Set<String> libSet; 3454 synchronized (mPackages) { 3455 libSet = mSharedLibraries.keySet(); 3456 int size = libSet.size(); 3457 if (size > 0) { 3458 String[] libs = new String[size]; 3459 libSet.toArray(libs); 3460 return libs; 3461 } 3462 } 3463 return null; 3464 } 3465 3466 @Override 3467 public @Nullable String getServicesSystemSharedLibraryPackageName() { 3468 synchronized (mPackages) { 3469 SharedLibraryEntry libraryEntry = mSharedLibraries.get( 3470 PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES); 3471 if (libraryEntry != null) { 3472 return libraryEntry.apk; 3473 } 3474 } 3475 return null; 3476 } 3477 3478 @Override 3479 public FeatureInfo[] getSystemAvailableFeatures() { 3480 Collection<FeatureInfo> featSet; 3481 synchronized (mPackages) { 3482 featSet = mAvailableFeatures.values(); 3483 int size = featSet.size(); 3484 if (size > 0) { 3485 FeatureInfo[] features = new FeatureInfo[size+1]; 3486 featSet.toArray(features); 3487 FeatureInfo fi = new FeatureInfo(); 3488 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version", 3489 FeatureInfo.GL_ES_VERSION_UNDEFINED); 3490 features[size] = fi; 3491 return features; 3492 } 3493 } 3494 return null; 3495 } 3496 3497 @Override 3498 public boolean hasSystemFeature(String name, int version) { 3499 synchronized (mPackages) { 3500 final FeatureInfo feat = mAvailableFeatures.get(name); 3501 if (feat == null) { 3502 return false; 3503 } else { 3504 return feat.version >= version; 3505 } 3506 } 3507 } 3508 3509 @Override 3510 public int checkPermission(String permName, String pkgName, int userId) { 3511 if (!sUserManager.exists(userId)) { 3512 return PackageManager.PERMISSION_DENIED; 3513 } 3514 3515 synchronized (mPackages) { 3516 final PackageParser.Package p = mPackages.get(pkgName); 3517 if (p != null && p.mExtras != null) { 3518 final PackageSetting ps = (PackageSetting) p.mExtras; 3519 final PermissionsState permissionsState = ps.getPermissionsState(); 3520 if (permissionsState.hasPermission(permName, userId)) { 3521 return PackageManager.PERMISSION_GRANTED; 3522 } 3523 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION 3524 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState 3525 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { 3526 return PackageManager.PERMISSION_GRANTED; 3527 } 3528 } 3529 } 3530 3531 return PackageManager.PERMISSION_DENIED; 3532 } 3533 3534 @Override 3535 public int checkUidPermission(String permName, int uid) { 3536 final int userId = UserHandle.getUserId(uid); 3537 3538 if (!sUserManager.exists(userId)) { 3539 return PackageManager.PERMISSION_DENIED; 3540 } 3541 3542 synchronized (mPackages) { 3543 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 3544 if (obj != null) { 3545 final SettingBase ps = (SettingBase) obj; 3546 final PermissionsState permissionsState = ps.getPermissionsState(); 3547 if (permissionsState.hasPermission(permName, userId)) { 3548 return PackageManager.PERMISSION_GRANTED; 3549 } 3550 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION 3551 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState 3552 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { 3553 return PackageManager.PERMISSION_GRANTED; 3554 } 3555 } else { 3556 ArraySet<String> perms = mSystemPermissions.get(uid); 3557 if (perms != null) { 3558 if (perms.contains(permName)) { 3559 return PackageManager.PERMISSION_GRANTED; 3560 } 3561 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms 3562 .contains(Manifest.permission.ACCESS_FINE_LOCATION)) { 3563 return PackageManager.PERMISSION_GRANTED; 3564 } 3565 } 3566 } 3567 } 3568 3569 return PackageManager.PERMISSION_DENIED; 3570 } 3571 3572 @Override 3573 public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) { 3574 if (UserHandle.getCallingUserId() != userId) { 3575 mContext.enforceCallingPermission( 3576 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 3577 "isPermissionRevokedByPolicy for user " + userId); 3578 } 3579 3580 if (checkPermission(permission, packageName, userId) 3581 == PackageManager.PERMISSION_GRANTED) { 3582 return false; 3583 } 3584 3585 final long identity = Binder.clearCallingIdentity(); 3586 try { 3587 final int flags = getPermissionFlags(permission, packageName, userId); 3588 return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0; 3589 } finally { 3590 Binder.restoreCallingIdentity(identity); 3591 } 3592 } 3593 3594 @Override 3595 public String getPermissionControllerPackageName() { 3596 synchronized (mPackages) { 3597 return mRequiredInstallerPackage; 3598 } 3599 } 3600 3601 /** 3602 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS 3603 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller. 3604 * @param checkShell whether to prevent shell from access if there's a debugging restriction 3605 * @param message the message to log on security exception 3606 */ 3607 void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, 3608 boolean checkShell, String message) { 3609 if (userId < 0) { 3610 throw new IllegalArgumentException("Invalid userId " + userId); 3611 } 3612 if (checkShell) { 3613 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); 3614 } 3615 if (userId == UserHandle.getUserId(callingUid)) return; 3616 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 3617 if (requireFullPermission) { 3618 mContext.enforceCallingOrSelfPermission( 3619 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 3620 } else { 3621 try { 3622 mContext.enforceCallingOrSelfPermission( 3623 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 3624 } catch (SecurityException se) { 3625 mContext.enforceCallingOrSelfPermission( 3626 android.Manifest.permission.INTERACT_ACROSS_USERS, message); 3627 } 3628 } 3629 } 3630 } 3631 3632 void enforceShellRestriction(String restriction, int callingUid, int userHandle) { 3633 if (callingUid == Process.SHELL_UID) { 3634 if (userHandle >= 0 3635 && sUserManager.hasUserRestriction(restriction, userHandle)) { 3636 throw new SecurityException("Shell does not have permission to access user " 3637 + userHandle); 3638 } else if (userHandle < 0) { 3639 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t" 3640 + Debug.getCallers(3)); 3641 } 3642 } 3643 } 3644 3645 private BasePermission findPermissionTreeLP(String permName) { 3646 for(BasePermission bp : mSettings.mPermissionTrees.values()) { 3647 if (permName.startsWith(bp.name) && 3648 permName.length() > bp.name.length() && 3649 permName.charAt(bp.name.length()) == '.') { 3650 return bp; 3651 } 3652 } 3653 return null; 3654 } 3655 3656 private BasePermission checkPermissionTreeLP(String permName) { 3657 if (permName != null) { 3658 BasePermission bp = findPermissionTreeLP(permName); 3659 if (bp != null) { 3660 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) { 3661 return bp; 3662 } 3663 throw new SecurityException("Calling uid " 3664 + Binder.getCallingUid() 3665 + " is not allowed to add to permission tree " 3666 + bp.name + " owned by uid " + bp.uid); 3667 } 3668 } 3669 throw new SecurityException("No permission tree found for " + permName); 3670 } 3671 3672 static boolean compareStrings(CharSequence s1, CharSequence s2) { 3673 if (s1 == null) { 3674 return s2 == null; 3675 } 3676 if (s2 == null) { 3677 return false; 3678 } 3679 if (s1.getClass() != s2.getClass()) { 3680 return false; 3681 } 3682 return s1.equals(s2); 3683 } 3684 3685 static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) { 3686 if (pi1.icon != pi2.icon) return false; 3687 if (pi1.logo != pi2.logo) return false; 3688 if (pi1.protectionLevel != pi2.protectionLevel) return false; 3689 if (!compareStrings(pi1.name, pi2.name)) return false; 3690 if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false; 3691 // We'll take care of setting this one. 3692 if (!compareStrings(pi1.packageName, pi2.packageName)) return false; 3693 // These are not currently stored in settings. 3694 //if (!compareStrings(pi1.group, pi2.group)) return false; 3695 //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false; 3696 //if (pi1.labelRes != pi2.labelRes) return false; 3697 //if (pi1.descriptionRes != pi2.descriptionRes) return false; 3698 return true; 3699 } 3700 3701 int permissionInfoFootprint(PermissionInfo info) { 3702 int size = info.name.length(); 3703 if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length(); 3704 if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length(); 3705 return size; 3706 } 3707 3708 int calculateCurrentPermissionFootprintLocked(BasePermission tree) { 3709 int size = 0; 3710 for (BasePermission perm : mSettings.mPermissions.values()) { 3711 if (perm.uid == tree.uid) { 3712 size += perm.name.length() + permissionInfoFootprint(perm.perm.info); 3713 } 3714 } 3715 return size; 3716 } 3717 3718 void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) { 3719 // We calculate the max size of permissions defined by this uid and throw 3720 // if that plus the size of 'info' would exceed our stated maximum. 3721 if (tree.uid != Process.SYSTEM_UID) { 3722 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree); 3723 if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) { 3724 throw new SecurityException("Permission tree size cap exceeded"); 3725 } 3726 } 3727 } 3728 3729 boolean addPermissionLocked(PermissionInfo info, boolean async) { 3730 if (info.labelRes == 0 && info.nonLocalizedLabel == null) { 3731 throw new SecurityException("Label must be specified in permission"); 3732 } 3733 BasePermission tree = checkPermissionTreeLP(info.name); 3734 BasePermission bp = mSettings.mPermissions.get(info.name); 3735 boolean added = bp == null; 3736 boolean changed = true; 3737 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel); 3738 if (added) { 3739 enforcePermissionCapLocked(info, tree); 3740 bp = new BasePermission(info.name, tree.sourcePackage, 3741 BasePermission.TYPE_DYNAMIC); 3742 } else if (bp.type != BasePermission.TYPE_DYNAMIC) { 3743 throw new SecurityException( 3744 "Not allowed to modify non-dynamic permission " 3745 + info.name); 3746 } else { 3747 if (bp.protectionLevel == fixedLevel 3748 && bp.perm.owner.equals(tree.perm.owner) 3749 && bp.uid == tree.uid 3750 && comparePermissionInfos(bp.perm.info, info)) { 3751 changed = false; 3752 } 3753 } 3754 bp.protectionLevel = fixedLevel; 3755 info = new PermissionInfo(info); 3756 info.protectionLevel = fixedLevel; 3757 bp.perm = new PackageParser.Permission(tree.perm.owner, info); 3758 bp.perm.info.packageName = tree.perm.info.packageName; 3759 bp.uid = tree.uid; 3760 if (added) { 3761 mSettings.mPermissions.put(info.name, bp); 3762 } 3763 if (changed) { 3764 if (!async) { 3765 mSettings.writeLPr(); 3766 } else { 3767 scheduleWriteSettingsLocked(); 3768 } 3769 } 3770 return added; 3771 } 3772 3773 @Override 3774 public boolean addPermission(PermissionInfo info) { 3775 synchronized (mPackages) { 3776 return addPermissionLocked(info, false); 3777 } 3778 } 3779 3780 @Override 3781 public boolean addPermissionAsync(PermissionInfo info) { 3782 synchronized (mPackages) { 3783 return addPermissionLocked(info, true); 3784 } 3785 } 3786 3787 @Override 3788 public void removePermission(String name) { 3789 synchronized (mPackages) { 3790 checkPermissionTreeLP(name); 3791 BasePermission bp = mSettings.mPermissions.get(name); 3792 if (bp != null) { 3793 if (bp.type != BasePermission.TYPE_DYNAMIC) { 3794 throw new SecurityException( 3795 "Not allowed to modify non-dynamic permission " 3796 + name); 3797 } 3798 mSettings.mPermissions.remove(name); 3799 mSettings.writeLPr(); 3800 } 3801 } 3802 } 3803 3804 private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg, 3805 BasePermission bp) { 3806 int index = pkg.requestedPermissions.indexOf(bp.name); 3807 if (index == -1) { 3808 throw new SecurityException("Package " + pkg.packageName 3809 + " has not requested permission " + bp.name); 3810 } 3811 if (!bp.isRuntime() && !bp.isDevelopment()) { 3812 throw new SecurityException("Permission " + bp.name 3813 + " is not a changeable permission type"); 3814 } 3815 } 3816 3817 @Override 3818 public void grantRuntimePermission(String packageName, String name, final int userId) { 3819 if (!sUserManager.exists(userId)) { 3820 Log.e(TAG, "No such user:" + userId); 3821 return; 3822 } 3823 3824 mContext.enforceCallingOrSelfPermission( 3825 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 3826 "grantRuntimePermission"); 3827 3828 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3829 true /* requireFullPermission */, true /* checkShell */, 3830 "grantRuntimePermission"); 3831 3832 final int uid; 3833 final SettingBase sb; 3834 3835 synchronized (mPackages) { 3836 final PackageParser.Package pkg = mPackages.get(packageName); 3837 if (pkg == null) { 3838 throw new IllegalArgumentException("Unknown package: " + packageName); 3839 } 3840 3841 final BasePermission bp = mSettings.mPermissions.get(name); 3842 if (bp == null) { 3843 throw new IllegalArgumentException("Unknown permission: " + name); 3844 } 3845 3846 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp); 3847 3848 // If a permission review is required for legacy apps we represent 3849 // their permissions as always granted runtime ones since we need 3850 // to keep the review required permission flag per user while an 3851 // install permission's state is shared across all users. 3852 if (Build.PERMISSIONS_REVIEW_REQUIRED 3853 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M 3854 && bp.isRuntime()) { 3855 return; 3856 } 3857 3858 uid = UserHandle.getUid(userId, pkg.applicationInfo.uid); 3859 sb = (SettingBase) pkg.mExtras; 3860 if (sb == null) { 3861 throw new IllegalArgumentException("Unknown package: " + packageName); 3862 } 3863 3864 final PermissionsState permissionsState = sb.getPermissionsState(); 3865 3866 final int flags = permissionsState.getPermissionFlags(name, userId); 3867 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 3868 throw new SecurityException("Cannot grant system fixed permission " 3869 + name + " for package " + packageName); 3870 } 3871 3872 if (bp.isDevelopment()) { 3873 // Development permissions must be handled specially, since they are not 3874 // normal runtime permissions. For now they apply to all users. 3875 if (permissionsState.grantInstallPermission(bp) != 3876 PermissionsState.PERMISSION_OPERATION_FAILURE) { 3877 scheduleWriteSettingsLocked(); 3878 } 3879 return; 3880 } 3881 3882 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 3883 Slog.w(TAG, "Cannot grant runtime permission to a legacy app"); 3884 return; 3885 } 3886 3887 final int result = permissionsState.grantRuntimePermission(bp, userId); 3888 switch (result) { 3889 case PermissionsState.PERMISSION_OPERATION_FAILURE: { 3890 return; 3891 } 3892 3893 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 3894 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); 3895 mHandler.post(new Runnable() { 3896 @Override 3897 public void run() { 3898 killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED); 3899 } 3900 }); 3901 } 3902 break; 3903 } 3904 3905 mOnPermissionChangeListeners.onPermissionsChanged(uid); 3906 3907 // Not critical if that is lost - app has to request again. 3908 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 3909 } 3910 3911 // Only need to do this if user is initialized. Otherwise it's a new user 3912 // and there are no processes running as the user yet and there's no need 3913 // to make an expensive call to remount processes for the changed permissions. 3914 if (READ_EXTERNAL_STORAGE.equals(name) 3915 || WRITE_EXTERNAL_STORAGE.equals(name)) { 3916 final long token = Binder.clearCallingIdentity(); 3917 try { 3918 if (sUserManager.isInitialized(userId)) { 3919 MountServiceInternal mountServiceInternal = LocalServices.getService( 3920 MountServiceInternal.class); 3921 mountServiceInternal.onExternalStoragePolicyChanged(uid, packageName); 3922 } 3923 } finally { 3924 Binder.restoreCallingIdentity(token); 3925 } 3926 } 3927 } 3928 3929 @Override 3930 public void revokeRuntimePermission(String packageName, String name, int userId) { 3931 if (!sUserManager.exists(userId)) { 3932 Log.e(TAG, "No such user:" + userId); 3933 return; 3934 } 3935 3936 mContext.enforceCallingOrSelfPermission( 3937 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 3938 "revokeRuntimePermission"); 3939 3940 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3941 true /* requireFullPermission */, true /* checkShell */, 3942 "revokeRuntimePermission"); 3943 3944 final int appId; 3945 3946 synchronized (mPackages) { 3947 final PackageParser.Package pkg = mPackages.get(packageName); 3948 if (pkg == null) { 3949 throw new IllegalArgumentException("Unknown package: " + packageName); 3950 } 3951 3952 final BasePermission bp = mSettings.mPermissions.get(name); 3953 if (bp == null) { 3954 throw new IllegalArgumentException("Unknown permission: " + name); 3955 } 3956 3957 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp); 3958 3959 // If a permission review is required for legacy apps we represent 3960 // their permissions as always granted runtime ones since we need 3961 // to keep the review required permission flag per user while an 3962 // install permission's state is shared across all users. 3963 if (Build.PERMISSIONS_REVIEW_REQUIRED 3964 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M 3965 && bp.isRuntime()) { 3966 return; 3967 } 3968 3969 SettingBase sb = (SettingBase) pkg.mExtras; 3970 if (sb == null) { 3971 throw new IllegalArgumentException("Unknown package: " + packageName); 3972 } 3973 3974 final PermissionsState permissionsState = sb.getPermissionsState(); 3975 3976 final int flags = permissionsState.getPermissionFlags(name, userId); 3977 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 3978 throw new SecurityException("Cannot revoke system fixed permission " 3979 + name + " for package " + packageName); 3980 } 3981 3982 if (bp.isDevelopment()) { 3983 // Development permissions must be handled specially, since they are not 3984 // normal runtime permissions. For now they apply to all users. 3985 if (permissionsState.revokeInstallPermission(bp) != 3986 PermissionsState.PERMISSION_OPERATION_FAILURE) { 3987 scheduleWriteSettingsLocked(); 3988 } 3989 return; 3990 } 3991 3992 if (permissionsState.revokeRuntimePermission(bp, userId) == 3993 PermissionsState.PERMISSION_OPERATION_FAILURE) { 3994 return; 3995 } 3996 3997 mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid); 3998 3999 // Critical, after this call app should never have the permission. 4000 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 4001 4002 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 4003 } 4004 4005 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED); 4006 } 4007 4008 @Override 4009 public void resetRuntimePermissions() { 4010 mContext.enforceCallingOrSelfPermission( 4011 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 4012 "revokeRuntimePermission"); 4013 4014 int callingUid = Binder.getCallingUid(); 4015 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 4016 mContext.enforceCallingOrSelfPermission( 4017 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 4018 "resetRuntimePermissions"); 4019 } 4020 4021 synchronized (mPackages) { 4022 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL); 4023 for (int userId : UserManagerService.getInstance().getUserIds()) { 4024 final int packageCount = mPackages.size(); 4025 for (int i = 0; i < packageCount; i++) { 4026 PackageParser.Package pkg = mPackages.valueAt(i); 4027 if (!(pkg.mExtras instanceof PackageSetting)) { 4028 continue; 4029 } 4030 PackageSetting ps = (PackageSetting) pkg.mExtras; 4031 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 4032 } 4033 } 4034 } 4035 } 4036 4037 @Override 4038 public int getPermissionFlags(String name, String packageName, int userId) { 4039 if (!sUserManager.exists(userId)) { 4040 return 0; 4041 } 4042 4043 enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags"); 4044 4045 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4046 true /* requireFullPermission */, false /* checkShell */, 4047 "getPermissionFlags"); 4048 4049 synchronized (mPackages) { 4050 final PackageParser.Package pkg = mPackages.get(packageName); 4051 if (pkg == null) { 4052 throw new IllegalArgumentException("Unknown package: " + packageName); 4053 } 4054 4055 final BasePermission bp = mSettings.mPermissions.get(name); 4056 if (bp == null) { 4057 throw new IllegalArgumentException("Unknown permission: " + name); 4058 } 4059 4060 SettingBase sb = (SettingBase) pkg.mExtras; 4061 if (sb == null) { 4062 throw new IllegalArgumentException("Unknown package: " + packageName); 4063 } 4064 4065 PermissionsState permissionsState = sb.getPermissionsState(); 4066 return permissionsState.getPermissionFlags(name, userId); 4067 } 4068 } 4069 4070 @Override 4071 public void updatePermissionFlags(String name, String packageName, int flagMask, 4072 int flagValues, int userId) { 4073 if (!sUserManager.exists(userId)) { 4074 return; 4075 } 4076 4077 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags"); 4078 4079 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4080 true /* requireFullPermission */, true /* checkShell */, 4081 "updatePermissionFlags"); 4082 4083 // Only the system can change these flags and nothing else. 4084 if (getCallingUid() != Process.SYSTEM_UID) { 4085 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4086 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4087 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 4088 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 4089 flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 4090 } 4091 4092 synchronized (mPackages) { 4093 final PackageParser.Package pkg = mPackages.get(packageName); 4094 if (pkg == null) { 4095 throw new IllegalArgumentException("Unknown package: " + packageName); 4096 } 4097 4098 final BasePermission bp = mSettings.mPermissions.get(name); 4099 if (bp == null) { 4100 throw new IllegalArgumentException("Unknown permission: " + name); 4101 } 4102 4103 SettingBase sb = (SettingBase) pkg.mExtras; 4104 if (sb == null) { 4105 throw new IllegalArgumentException("Unknown package: " + packageName); 4106 } 4107 4108 PermissionsState permissionsState = sb.getPermissionsState(); 4109 4110 boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null; 4111 4112 if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) { 4113 // Install and runtime permissions are stored in different places, 4114 // so figure out what permission changed and persist the change. 4115 if (permissionsState.getInstallPermissionState(name) != null) { 4116 scheduleWriteSettingsLocked(); 4117 } else if (permissionsState.getRuntimePermissionState(name, userId) != null 4118 || hadState) { 4119 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 4120 } 4121 } 4122 } 4123 } 4124 4125 /** 4126 * Update the permission flags for all packages and runtime permissions of a user in order 4127 * to allow device or profile owner to remove POLICY_FIXED. 4128 */ 4129 @Override 4130 public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) { 4131 if (!sUserManager.exists(userId)) { 4132 return; 4133 } 4134 4135 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps"); 4136 4137 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4138 true /* requireFullPermission */, true /* checkShell */, 4139 "updatePermissionFlagsForAllApps"); 4140 4141 // Only the system can change system fixed flags. 4142 if (getCallingUid() != Process.SYSTEM_UID) { 4143 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4144 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4145 } 4146 4147 synchronized (mPackages) { 4148 boolean changed = false; 4149 final int packageCount = mPackages.size(); 4150 for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) { 4151 final PackageParser.Package pkg = mPackages.valueAt(pkgIndex); 4152 SettingBase sb = (SettingBase) pkg.mExtras; 4153 if (sb == null) { 4154 continue; 4155 } 4156 PermissionsState permissionsState = sb.getPermissionsState(); 4157 changed |= permissionsState.updatePermissionFlagsForAllPermissions( 4158 userId, flagMask, flagValues); 4159 } 4160 if (changed) { 4161 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 4162 } 4163 } 4164 } 4165 4166 private void enforceGrantRevokeRuntimePermissionPermissions(String message) { 4167 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS) 4168 != PackageManager.PERMISSION_GRANTED 4169 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) 4170 != PackageManager.PERMISSION_GRANTED) { 4171 throw new SecurityException(message + " requires " 4172 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or " 4173 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS); 4174 } 4175 } 4176 4177 @Override 4178 public boolean shouldShowRequestPermissionRationale(String permissionName, 4179 String packageName, int userId) { 4180 if (UserHandle.getCallingUserId() != userId) { 4181 mContext.enforceCallingPermission( 4182 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 4183 "canShowRequestPermissionRationale for user " + userId); 4184 } 4185 4186 final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId); 4187 if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) { 4188 return false; 4189 } 4190 4191 if (checkPermission(permissionName, packageName, userId) 4192 == PackageManager.PERMISSION_GRANTED) { 4193 return false; 4194 } 4195 4196 final int flags; 4197 4198 final long identity = Binder.clearCallingIdentity(); 4199 try { 4200 flags = getPermissionFlags(permissionName, 4201 packageName, userId); 4202 } finally { 4203 Binder.restoreCallingIdentity(identity); 4204 } 4205 4206 final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 4207 | PackageManager.FLAG_PERMISSION_POLICY_FIXED 4208 | PackageManager.FLAG_PERMISSION_USER_FIXED; 4209 4210 if ((flags & fixedFlags) != 0) { 4211 return false; 4212 } 4213 4214 return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0; 4215 } 4216 4217 @Override 4218 public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 4219 mContext.enforceCallingOrSelfPermission( 4220 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS, 4221 "addOnPermissionsChangeListener"); 4222 4223 synchronized (mPackages) { 4224 mOnPermissionChangeListeners.addListenerLocked(listener); 4225 } 4226 } 4227 4228 @Override 4229 public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 4230 synchronized (mPackages) { 4231 mOnPermissionChangeListeners.removeListenerLocked(listener); 4232 } 4233 } 4234 4235 @Override 4236 public boolean isProtectedBroadcast(String actionName) { 4237 synchronized (mPackages) { 4238 if (mProtectedBroadcasts.contains(actionName)) { 4239 return true; 4240 } else if (actionName != null) { 4241 // TODO: remove these terrible hacks 4242 if (actionName.startsWith("android.net.netmon.lingerExpired") 4243 || actionName.startsWith("com.android.server.sip.SipWakeupTimer") 4244 || actionName.startsWith("com.android.internal.telephony.data-reconnect") 4245 || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) { 4246 return true; 4247 } 4248 } 4249 } 4250 return false; 4251 } 4252 4253 @Override 4254 public int checkSignatures(String pkg1, String pkg2) { 4255 synchronized (mPackages) { 4256 final PackageParser.Package p1 = mPackages.get(pkg1); 4257 final PackageParser.Package p2 = mPackages.get(pkg2); 4258 if (p1 == null || p1.mExtras == null 4259 || p2 == null || p2.mExtras == null) { 4260 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4261 } 4262 return compareSignatures(p1.mSignatures, p2.mSignatures); 4263 } 4264 } 4265 4266 @Override 4267 public int checkUidSignatures(int uid1, int uid2) { 4268 // Map to base uids. 4269 uid1 = UserHandle.getAppId(uid1); 4270 uid2 = UserHandle.getAppId(uid2); 4271 // reader 4272 synchronized (mPackages) { 4273 Signature[] s1; 4274 Signature[] s2; 4275 Object obj = mSettings.getUserIdLPr(uid1); 4276 if (obj != null) { 4277 if (obj instanceof SharedUserSetting) { 4278 s1 = ((SharedUserSetting)obj).signatures.mSignatures; 4279 } else if (obj instanceof PackageSetting) { 4280 s1 = ((PackageSetting)obj).signatures.mSignatures; 4281 } else { 4282 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4283 } 4284 } else { 4285 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4286 } 4287 obj = mSettings.getUserIdLPr(uid2); 4288 if (obj != null) { 4289 if (obj instanceof SharedUserSetting) { 4290 s2 = ((SharedUserSetting)obj).signatures.mSignatures; 4291 } else if (obj instanceof PackageSetting) { 4292 s2 = ((PackageSetting)obj).signatures.mSignatures; 4293 } else { 4294 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4295 } 4296 } else { 4297 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4298 } 4299 return compareSignatures(s1, s2); 4300 } 4301 } 4302 4303 private void killUid(int appId, int userId, String reason) { 4304 final long identity = Binder.clearCallingIdentity(); 4305 try { 4306 IActivityManager am = ActivityManagerNative.getDefault(); 4307 if (am != null) { 4308 try { 4309 am.killUid(appId, userId, reason); 4310 } catch (RemoteException e) { 4311 /* ignore - same process */ 4312 } 4313 } 4314 } finally { 4315 Binder.restoreCallingIdentity(identity); 4316 } 4317 } 4318 4319 /** 4320 * Compares two sets of signatures. Returns: 4321 * <br /> 4322 * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null, 4323 * <br /> 4324 * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null, 4325 * <br /> 4326 * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null, 4327 * <br /> 4328 * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical, 4329 * <br /> 4330 * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ. 4331 */ 4332 static int compareSignatures(Signature[] s1, Signature[] s2) { 4333 if (s1 == null) { 4334 return s2 == null 4335 ? PackageManager.SIGNATURE_NEITHER_SIGNED 4336 : PackageManager.SIGNATURE_FIRST_NOT_SIGNED; 4337 } 4338 4339 if (s2 == null) { 4340 return PackageManager.SIGNATURE_SECOND_NOT_SIGNED; 4341 } 4342 4343 if (s1.length != s2.length) { 4344 return PackageManager.SIGNATURE_NO_MATCH; 4345 } 4346 4347 // Since both signature sets are of size 1, we can compare without HashSets. 4348 if (s1.length == 1) { 4349 return s1[0].equals(s2[0]) ? 4350 PackageManager.SIGNATURE_MATCH : 4351 PackageManager.SIGNATURE_NO_MATCH; 4352 } 4353 4354 ArraySet<Signature> set1 = new ArraySet<Signature>(); 4355 for (Signature sig : s1) { 4356 set1.add(sig); 4357 } 4358 ArraySet<Signature> set2 = new ArraySet<Signature>(); 4359 for (Signature sig : s2) { 4360 set2.add(sig); 4361 } 4362 // Make sure s2 contains all signatures in s1. 4363 if (set1.equals(set2)) { 4364 return PackageManager.SIGNATURE_MATCH; 4365 } 4366 return PackageManager.SIGNATURE_NO_MATCH; 4367 } 4368 4369 /** 4370 * If the database version for this type of package (internal storage or 4371 * external storage) is less than the version where package signatures 4372 * were updated, return true. 4373 */ 4374 private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 4375 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); 4376 return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY; 4377 } 4378 4379 /** 4380 * Used for backward compatibility to make sure any packages with 4381 * certificate chains get upgraded to the new style. {@code existingSigs} 4382 * will be in the old format (since they were stored on disk from before the 4383 * system upgrade) and {@code scannedSigs} will be in the newer format. 4384 */ 4385 private int compareSignaturesCompat(PackageSignatures existingSigs, 4386 PackageParser.Package scannedPkg) { 4387 if (!isCompatSignatureUpdateNeeded(scannedPkg)) { 4388 return PackageManager.SIGNATURE_NO_MATCH; 4389 } 4390 4391 ArraySet<Signature> existingSet = new ArraySet<Signature>(); 4392 for (Signature sig : existingSigs.mSignatures) { 4393 existingSet.add(sig); 4394 } 4395 ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>(); 4396 for (Signature sig : scannedPkg.mSignatures) { 4397 try { 4398 Signature[] chainSignatures = sig.getChainSignatures(); 4399 for (Signature chainSig : chainSignatures) { 4400 scannedCompatSet.add(chainSig); 4401 } 4402 } catch (CertificateEncodingException e) { 4403 scannedCompatSet.add(sig); 4404 } 4405 } 4406 /* 4407 * Make sure the expanded scanned set contains all signatures in the 4408 * existing one. 4409 */ 4410 if (scannedCompatSet.equals(existingSet)) { 4411 // Migrate the old signatures to the new scheme. 4412 existingSigs.assignSignatures(scannedPkg.mSignatures); 4413 // The new KeySets will be re-added later in the scanning process. 4414 synchronized (mPackages) { 4415 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName); 4416 } 4417 return PackageManager.SIGNATURE_MATCH; 4418 } 4419 return PackageManager.SIGNATURE_NO_MATCH; 4420 } 4421 4422 private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 4423 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); 4424 return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER; 4425 } 4426 4427 private int compareSignaturesRecover(PackageSignatures existingSigs, 4428 PackageParser.Package scannedPkg) { 4429 if (!isRecoverSignatureUpdateNeeded(scannedPkg)) { 4430 return PackageManager.SIGNATURE_NO_MATCH; 4431 } 4432 4433 String msg = null; 4434 try { 4435 if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) { 4436 logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for " 4437 + scannedPkg.packageName); 4438 return PackageManager.SIGNATURE_MATCH; 4439 } 4440 } catch (CertificateException e) { 4441 msg = e.getMessage(); 4442 } 4443 4444 logCriticalInfo(Log.INFO, 4445 "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg); 4446 return PackageManager.SIGNATURE_NO_MATCH; 4447 } 4448 4449 @Override 4450 public String[] getPackagesForUid(int uid) { 4451 uid = UserHandle.getAppId(uid); 4452 // reader 4453 synchronized (mPackages) { 4454 Object obj = mSettings.getUserIdLPr(uid); 4455 if (obj instanceof SharedUserSetting) { 4456 final SharedUserSetting sus = (SharedUserSetting) obj; 4457 final int N = sus.packages.size(); 4458 final String[] res = new String[N]; 4459 final Iterator<PackageSetting> it = sus.packages.iterator(); 4460 int i = 0; 4461 while (it.hasNext()) { 4462 res[i++] = it.next().name; 4463 } 4464 return res; 4465 } else if (obj instanceof PackageSetting) { 4466 final PackageSetting ps = (PackageSetting) obj; 4467 return new String[] { ps.name }; 4468 } 4469 } 4470 return null; 4471 } 4472 4473 @Override 4474 public String getNameForUid(int uid) { 4475 // reader 4476 synchronized (mPackages) { 4477 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4478 if (obj instanceof SharedUserSetting) { 4479 final SharedUserSetting sus = (SharedUserSetting) obj; 4480 return sus.name + ":" + sus.userId; 4481 } else if (obj instanceof PackageSetting) { 4482 final PackageSetting ps = (PackageSetting) obj; 4483 return ps.name; 4484 } 4485 } 4486 return null; 4487 } 4488 4489 @Override 4490 public int getUidForSharedUser(String sharedUserName) { 4491 if(sharedUserName == null) { 4492 return -1; 4493 } 4494 // reader 4495 synchronized (mPackages) { 4496 final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false); 4497 if (suid == null) { 4498 return -1; 4499 } 4500 return suid.userId; 4501 } 4502 } 4503 4504 @Override 4505 public int getFlagsForUid(int uid) { 4506 synchronized (mPackages) { 4507 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4508 if (obj instanceof SharedUserSetting) { 4509 final SharedUserSetting sus = (SharedUserSetting) obj; 4510 return sus.pkgFlags; 4511 } else if (obj instanceof PackageSetting) { 4512 final PackageSetting ps = (PackageSetting) obj; 4513 return ps.pkgFlags; 4514 } 4515 } 4516 return 0; 4517 } 4518 4519 @Override 4520 public int getPrivateFlagsForUid(int uid) { 4521 synchronized (mPackages) { 4522 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4523 if (obj instanceof SharedUserSetting) { 4524 final SharedUserSetting sus = (SharedUserSetting) obj; 4525 return sus.pkgPrivateFlags; 4526 } else if (obj instanceof PackageSetting) { 4527 final PackageSetting ps = (PackageSetting) obj; 4528 return ps.pkgPrivateFlags; 4529 } 4530 } 4531 return 0; 4532 } 4533 4534 @Override 4535 public boolean isUidPrivileged(int uid) { 4536 uid = UserHandle.getAppId(uid); 4537 // reader 4538 synchronized (mPackages) { 4539 Object obj = mSettings.getUserIdLPr(uid); 4540 if (obj instanceof SharedUserSetting) { 4541 final SharedUserSetting sus = (SharedUserSetting) obj; 4542 final Iterator<PackageSetting> it = sus.packages.iterator(); 4543 while (it.hasNext()) { 4544 if (it.next().isPrivileged()) { 4545 return true; 4546 } 4547 } 4548 } else if (obj instanceof PackageSetting) { 4549 final PackageSetting ps = (PackageSetting) obj; 4550 return ps.isPrivileged(); 4551 } 4552 } 4553 return false; 4554 } 4555 4556 @Override 4557 public String[] getAppOpPermissionPackages(String permissionName) { 4558 synchronized (mPackages) { 4559 ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName); 4560 if (pkgs == null) { 4561 return null; 4562 } 4563 return pkgs.toArray(new String[pkgs.size()]); 4564 } 4565 } 4566 4567 @Override 4568 public ResolveInfo resolveIntent(Intent intent, String resolvedType, 4569 int flags, int userId) { 4570 if (!sUserManager.exists(userId)) return null; 4571 flags = updateFlagsForResolve(flags, userId, intent); 4572 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4573 false /* requireFullPermission */, false /* checkShell */, "resolve intent"); 4574 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 4575 final ResolveInfo bestChoice = 4576 chooseBestActivity(intent, resolvedType, flags, query, userId); 4577 4578 if (isEphemeralAllowed(intent, query, userId)) { 4579 final EphemeralResolveInfo ai = 4580 getEphemeralResolveInfo(intent, resolvedType, userId); 4581 if (ai != null) { 4582 if (DEBUG_EPHEMERAL) { 4583 Slog.v(TAG, "Returning an EphemeralResolveInfo"); 4584 } 4585 bestChoice.ephemeralInstaller = mEphemeralInstallerInfo; 4586 bestChoice.ephemeralResolveInfo = ai; 4587 } 4588 } 4589 return bestChoice; 4590 } 4591 4592 @Override 4593 public void setLastChosenActivity(Intent intent, String resolvedType, int flags, 4594 IntentFilter filter, int match, ComponentName activity) { 4595 final int userId = UserHandle.getCallingUserId(); 4596 if (DEBUG_PREFERRED) { 4597 Log.v(TAG, "setLastChosenActivity intent=" + intent 4598 + " resolvedType=" + resolvedType 4599 + " flags=" + flags 4600 + " filter=" + filter 4601 + " match=" + match 4602 + " activity=" + activity); 4603 filter.dump(new PrintStreamPrinter(System.out), " "); 4604 } 4605 intent.setComponent(null); 4606 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 4607 // Find any earlier preferred or last chosen entries and nuke them 4608 findPreferredActivity(intent, resolvedType, 4609 flags, query, 0, false, true, false, userId); 4610 // Add the new activity as the last chosen for this filter 4611 addPreferredActivityInternal(filter, match, null, activity, false, userId, 4612 "Setting last chosen"); 4613 } 4614 4615 @Override 4616 public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) { 4617 final int userId = UserHandle.getCallingUserId(); 4618 if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent); 4619 List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); 4620 return findPreferredActivity(intent, resolvedType, flags, query, 0, 4621 false, false, false, userId); 4622 } 4623 4624 4625 private boolean isEphemeralAllowed( 4626 Intent intent, List<ResolveInfo> resolvedActivites, int userId) { 4627 // Short circuit and return early if possible. 4628 if (DISABLE_EPHEMERAL_APPS) { 4629 return false; 4630 } 4631 final int callingUser = UserHandle.getCallingUserId(); 4632 if (callingUser != UserHandle.USER_SYSTEM) { 4633 return false; 4634 } 4635 if (mEphemeralResolverConnection == null) { 4636 return false; 4637 } 4638 if (intent.getComponent() != null) { 4639 return false; 4640 } 4641 if (intent.getPackage() != null) { 4642 return false; 4643 } 4644 final boolean isWebUri = hasWebURI(intent); 4645 if (!isWebUri) { 4646 return false; 4647 } 4648 // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution. 4649 synchronized (mPackages) { 4650 final int count = resolvedActivites.size(); 4651 for (int n = 0; n < count; n++) { 4652 ResolveInfo info = resolvedActivites.get(n); 4653 String packageName = info.activityInfo.packageName; 4654 PackageSetting ps = mSettings.mPackages.get(packageName); 4655 if (ps != null) { 4656 // Try to get the status from User settings first 4657 long packedStatus = getDomainVerificationStatusLPr(ps, userId); 4658 int status = (int) (packedStatus >> 32); 4659 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS 4660 || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) { 4661 if (DEBUG_EPHEMERAL) { 4662 Slog.v(TAG, "DENY ephemeral apps;" 4663 + " pkg: " + packageName + ", status: " + status); 4664 } 4665 return false; 4666 } 4667 } 4668 } 4669 } 4670 // We've exhausted all ways to deny ephemeral application; let the system look for them. 4671 return true; 4672 } 4673 4674 private EphemeralResolveInfo getEphemeralResolveInfo(Intent intent, String resolvedType, 4675 int userId) { 4676 MessageDigest digest = null; 4677 try { 4678 digest = MessageDigest.getInstance(EphemeralResolveInfo.SHA_ALGORITHM); 4679 } catch (NoSuchAlgorithmException e) { 4680 // If we can't create a digest, ignore ephemeral apps. 4681 return null; 4682 } 4683 4684 final byte[] hostBytes = intent.getData().getHost().getBytes(); 4685 final byte[] digestBytes = digest.digest(hostBytes); 4686 int shaPrefix = 4687 digestBytes[0] << 24 4688 | digestBytes[1] << 16 4689 | digestBytes[2] << 8 4690 | digestBytes[3] << 0; 4691 final List<EphemeralResolveInfo> ephemeralResolveInfoList = 4692 mEphemeralResolverConnection.getEphemeralResolveInfoList(shaPrefix); 4693 if (ephemeralResolveInfoList == null || ephemeralResolveInfoList.size() == 0) { 4694 // No hash prefix match; there are no ephemeral apps for this domain. 4695 return null; 4696 } 4697 for (int i = ephemeralResolveInfoList.size() - 1; i >= 0; --i) { 4698 EphemeralResolveInfo ephemeralApplication = ephemeralResolveInfoList.get(i); 4699 if (!Arrays.equals(digestBytes, ephemeralApplication.getDigestBytes())) { 4700 continue; 4701 } 4702 final List<IntentFilter> filters = ephemeralApplication.getFilters(); 4703 // No filters; this should never happen. 4704 if (filters.isEmpty()) { 4705 continue; 4706 } 4707 // We have a domain match; resolve the filters to see if anything matches. 4708 final EphemeralIntentResolver ephemeralResolver = new EphemeralIntentResolver(); 4709 for (int j = filters.size() - 1; j >= 0; --j) { 4710 final EphemeralResolveIntentInfo intentInfo = 4711 new EphemeralResolveIntentInfo(filters.get(j), ephemeralApplication); 4712 ephemeralResolver.addFilter(intentInfo); 4713 } 4714 List<EphemeralResolveInfo> matchedResolveInfoList = ephemeralResolver.queryIntent( 4715 intent, resolvedType, false /*defaultOnly*/, userId); 4716 if (!matchedResolveInfoList.isEmpty()) { 4717 return matchedResolveInfoList.get(0); 4718 } 4719 } 4720 // Hash or filter mis-match; no ephemeral apps for this domain. 4721 return null; 4722 } 4723 4724 private ResolveInfo chooseBestActivity(Intent intent, String resolvedType, 4725 int flags, List<ResolveInfo> query, int userId) { 4726 if (query != null) { 4727 final int N = query.size(); 4728 if (N == 1) { 4729 return query.get(0); 4730 } else if (N > 1) { 4731 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 4732 // If there is more than one activity with the same priority, 4733 // then let the user decide between them. 4734 ResolveInfo r0 = query.get(0); 4735 ResolveInfo r1 = query.get(1); 4736 if (DEBUG_INTENT_MATCHING || debug) { 4737 Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs " 4738 + r1.activityInfo.name + "=" + r1.priority); 4739 } 4740 // If the first activity has a higher priority, or a different 4741 // default, then it is always desirable to pick it. 4742 if (r0.priority != r1.priority 4743 || r0.preferredOrder != r1.preferredOrder 4744 || r0.isDefault != r1.isDefault) { 4745 return query.get(0); 4746 } 4747 // If we have saved a preference for a preferred activity for 4748 // this Intent, use that. 4749 ResolveInfo ri = findPreferredActivity(intent, resolvedType, 4750 flags, query, r0.priority, true, false, debug, userId); 4751 if (ri != null) { 4752 return ri; 4753 } 4754 ri = new ResolveInfo(mResolveInfo); 4755 ri.activityInfo = new ActivityInfo(ri.activityInfo); 4756 ri.activityInfo.applicationInfo = new ApplicationInfo( 4757 ri.activityInfo.applicationInfo); 4758 if (userId != 0) { 4759 ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId, 4760 UserHandle.getAppId(ri.activityInfo.applicationInfo.uid)); 4761 } 4762 // Make sure that the resolver is displayable in car mode 4763 if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle(); 4764 ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true); 4765 return ri; 4766 } 4767 } 4768 return null; 4769 } 4770 4771 private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType, 4772 int flags, List<ResolveInfo> query, boolean debug, int userId) { 4773 final int N = query.size(); 4774 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 4775 .get(userId); 4776 // Get the list of persistent preferred activities that handle the intent 4777 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities..."); 4778 List<PersistentPreferredActivity> pprefs = ppir != null 4779 ? ppir.queryIntent(intent, resolvedType, 4780 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 4781 : null; 4782 if (pprefs != null && pprefs.size() > 0) { 4783 final int M = pprefs.size(); 4784 for (int i=0; i<M; i++) { 4785 final PersistentPreferredActivity ppa = pprefs.get(i); 4786 if (DEBUG_PREFERRED || debug) { 4787 Slog.v(TAG, "Checking PersistentPreferredActivity ds=" 4788 + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>") 4789 + "\n component=" + ppa.mComponent); 4790 ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4791 } 4792 final ActivityInfo ai = getActivityInfo(ppa.mComponent, 4793 flags | MATCH_DISABLED_COMPONENTS, userId); 4794 if (DEBUG_PREFERRED || debug) { 4795 Slog.v(TAG, "Found persistent preferred activity:"); 4796 if (ai != null) { 4797 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4798 } else { 4799 Slog.v(TAG, " null"); 4800 } 4801 } 4802 if (ai == null) { 4803 // This previously registered persistent preferred activity 4804 // component is no longer known. Ignore it and do NOT remove it. 4805 continue; 4806 } 4807 for (int j=0; j<N; j++) { 4808 final ResolveInfo ri = query.get(j); 4809 if (!ri.activityInfo.applicationInfo.packageName 4810 .equals(ai.applicationInfo.packageName)) { 4811 continue; 4812 } 4813 if (!ri.activityInfo.name.equals(ai.name)) { 4814 continue; 4815 } 4816 // Found a persistent preference that can handle the intent. 4817 if (DEBUG_PREFERRED || debug) { 4818 Slog.v(TAG, "Returning persistent preferred activity: " + 4819 ri.activityInfo.packageName + "/" + ri.activityInfo.name); 4820 } 4821 return ri; 4822 } 4823 } 4824 } 4825 return null; 4826 } 4827 4828 // TODO: handle preferred activities missing while user has amnesia 4829 ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags, 4830 List<ResolveInfo> query, int priority, boolean always, 4831 boolean removeMatches, boolean debug, int userId) { 4832 if (!sUserManager.exists(userId)) return null; 4833 flags = updateFlagsForResolve(flags, userId, intent); 4834 // writer 4835 synchronized (mPackages) { 4836 if (intent.getSelector() != null) { 4837 intent = intent.getSelector(); 4838 } 4839 if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION); 4840 4841 // Try to find a matching persistent preferred activity. 4842 ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query, 4843 debug, userId); 4844 4845 // If a persistent preferred activity matched, use it. 4846 if (pri != null) { 4847 return pri; 4848 } 4849 4850 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 4851 // Get the list of preferred activities that handle the intent 4852 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities..."); 4853 List<PreferredActivity> prefs = pir != null 4854 ? pir.queryIntent(intent, resolvedType, 4855 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 4856 : null; 4857 if (prefs != null && prefs.size() > 0) { 4858 boolean changed = false; 4859 try { 4860 // First figure out how good the original match set is. 4861 // We will only allow preferred activities that came 4862 // from the same match quality. 4863 int match = 0; 4864 4865 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match..."); 4866 4867 final int N = query.size(); 4868 for (int j=0; j<N; j++) { 4869 final ResolveInfo ri = query.get(j); 4870 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo 4871 + ": 0x" + Integer.toHexString(match)); 4872 if (ri.match > match) { 4873 match = ri.match; 4874 } 4875 } 4876 4877 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x" 4878 + Integer.toHexString(match)); 4879 4880 match &= IntentFilter.MATCH_CATEGORY_MASK; 4881 final int M = prefs.size(); 4882 for (int i=0; i<M; i++) { 4883 final PreferredActivity pa = prefs.get(i); 4884 if (DEBUG_PREFERRED || debug) { 4885 Slog.v(TAG, "Checking PreferredActivity ds=" 4886 + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>") 4887 + "\n component=" + pa.mPref.mComponent); 4888 pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4889 } 4890 if (pa.mPref.mMatch != match) { 4891 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match " 4892 + Integer.toHexString(pa.mPref.mMatch)); 4893 continue; 4894 } 4895 // If it's not an "always" type preferred activity and that's what we're 4896 // looking for, skip it. 4897 if (always && !pa.mPref.mAlways) { 4898 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry"); 4899 continue; 4900 } 4901 final ActivityInfo ai = getActivityInfo(pa.mPref.mComponent, 4902 flags | MATCH_DISABLED_COMPONENTS, userId); 4903 if (DEBUG_PREFERRED || debug) { 4904 Slog.v(TAG, "Found preferred activity:"); 4905 if (ai != null) { 4906 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4907 } else { 4908 Slog.v(TAG, " null"); 4909 } 4910 } 4911 if (ai == null) { 4912 // This previously registered preferred activity 4913 // component is no longer known. Most likely an update 4914 // to the app was installed and in the new version this 4915 // component no longer exists. Clean it up by removing 4916 // it from the preferred activities list, and skip it. 4917 Slog.w(TAG, "Removing dangling preferred activity: " 4918 + pa.mPref.mComponent); 4919 pir.removeFilter(pa); 4920 changed = true; 4921 continue; 4922 } 4923 for (int j=0; j<N; j++) { 4924 final ResolveInfo ri = query.get(j); 4925 if (!ri.activityInfo.applicationInfo.packageName 4926 .equals(ai.applicationInfo.packageName)) { 4927 continue; 4928 } 4929 if (!ri.activityInfo.name.equals(ai.name)) { 4930 continue; 4931 } 4932 4933 if (removeMatches) { 4934 pir.removeFilter(pa); 4935 changed = true; 4936 if (DEBUG_PREFERRED) { 4937 Slog.v(TAG, "Removing match " + pa.mPref.mComponent); 4938 } 4939 break; 4940 } 4941 4942 // Okay we found a previously set preferred or last chosen app. 4943 // If the result set is different from when this 4944 // was created, we need to clear it and re-ask the 4945 // user their preference, if we're looking for an "always" type entry. 4946 if (always && !pa.mPref.sameSet(query)) { 4947 Slog.i(TAG, "Result set changed, dropping preferred activity for " 4948 + intent + " type " + resolvedType); 4949 if (DEBUG_PREFERRED) { 4950 Slog.v(TAG, "Removing preferred activity since set changed " 4951 + pa.mPref.mComponent); 4952 } 4953 pir.removeFilter(pa); 4954 // Re-add the filter as a "last chosen" entry (!always) 4955 PreferredActivity lastChosen = new PreferredActivity( 4956 pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false); 4957 pir.addFilter(lastChosen); 4958 changed = true; 4959 return null; 4960 } 4961 4962 // Yay! Either the set matched or we're looking for the last chosen 4963 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: " 4964 + ri.activityInfo.packageName + "/" + ri.activityInfo.name); 4965 return ri; 4966 } 4967 } 4968 } finally { 4969 if (changed) { 4970 if (DEBUG_PREFERRED) { 4971 Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions"); 4972 } 4973 scheduleWritePackageRestrictionsLocked(userId); 4974 } 4975 } 4976 } 4977 } 4978 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return"); 4979 return null; 4980 } 4981 4982 /* 4983 * Returns if intent can be forwarded from the sourceUserId to the targetUserId 4984 */ 4985 @Override 4986 public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId, 4987 int targetUserId) { 4988 mContext.enforceCallingOrSelfPermission( 4989 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 4990 List<CrossProfileIntentFilter> matches = 4991 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId); 4992 if (matches != null) { 4993 int size = matches.size(); 4994 for (int i = 0; i < size; i++) { 4995 if (matches.get(i).getTargetUserId() == targetUserId) return true; 4996 } 4997 } 4998 if (hasWebURI(intent)) { 4999 // cross-profile app linking works only towards the parent. 5000 final UserInfo parent = getProfileParent(sourceUserId); 5001 synchronized(mPackages) { 5002 int flags = updateFlagsForResolve(0, parent.id, intent); 5003 CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr( 5004 intent, resolvedType, flags, sourceUserId, parent.id); 5005 return xpDomainInfo != null; 5006 } 5007 } 5008 return false; 5009 } 5010 5011 private UserInfo getProfileParent(int userId) { 5012 final long identity = Binder.clearCallingIdentity(); 5013 try { 5014 return sUserManager.getProfileParent(userId); 5015 } finally { 5016 Binder.restoreCallingIdentity(identity); 5017 } 5018 } 5019 5020 private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent, 5021 String resolvedType, int userId) { 5022 CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId); 5023 if (resolver != null) { 5024 return resolver.queryIntent(intent, resolvedType, false, userId); 5025 } 5026 return null; 5027 } 5028 5029 @Override 5030 public List<ResolveInfo> queryIntentActivities(Intent intent, 5031 String resolvedType, int flags, int userId) { 5032 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5033 flags = updateFlagsForResolve(flags, userId, intent); 5034 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5035 false /* requireFullPermission */, false /* checkShell */, 5036 "query intent activities"); 5037 ComponentName comp = intent.getComponent(); 5038 if (comp == null) { 5039 if (intent.getSelector() != null) { 5040 intent = intent.getSelector(); 5041 comp = intent.getComponent(); 5042 } 5043 } 5044 5045 if (comp != null) { 5046 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5047 final ActivityInfo ai = getActivityInfo(comp, flags, userId); 5048 if (ai != null) { 5049 final ResolveInfo ri = new ResolveInfo(); 5050 ri.activityInfo = ai; 5051 list.add(ri); 5052 } 5053 return list; 5054 } 5055 5056 // reader 5057 synchronized (mPackages) { 5058 final String pkgName = intent.getPackage(); 5059 if (pkgName == null) { 5060 List<CrossProfileIntentFilter> matchingFilters = 5061 getMatchingCrossProfileIntentFilters(intent, resolvedType, userId); 5062 // Check for results that need to skip the current profile. 5063 ResolveInfo xpResolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent, 5064 resolvedType, flags, userId); 5065 if (xpResolveInfo != null) { 5066 List<ResolveInfo> result = new ArrayList<ResolveInfo>(1); 5067 result.add(xpResolveInfo); 5068 return filterIfNotSystemUser(result, userId); 5069 } 5070 5071 // Check for results in the current profile. 5072 List<ResolveInfo> result = mActivities.queryIntent( 5073 intent, resolvedType, flags, userId); 5074 result = filterIfNotSystemUser(result, userId); 5075 5076 // Check for cross profile results. 5077 boolean hasNonNegativePriorityResult = hasNonNegativePriority(result); 5078 xpResolveInfo = queryCrossProfileIntents( 5079 matchingFilters, intent, resolvedType, flags, userId, 5080 hasNonNegativePriorityResult); 5081 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) { 5082 boolean isVisibleToUser = filterIfNotSystemUser( 5083 Collections.singletonList(xpResolveInfo), userId).size() > 0; 5084 if (isVisibleToUser) { 5085 result.add(xpResolveInfo); 5086 Collections.sort(result, mResolvePrioritySorter); 5087 } 5088 } 5089 if (hasWebURI(intent)) { 5090 CrossProfileDomainInfo xpDomainInfo = null; 5091 final UserInfo parent = getProfileParent(userId); 5092 if (parent != null) { 5093 xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType, 5094 flags, userId, parent.id); 5095 } 5096 if (xpDomainInfo != null) { 5097 if (xpResolveInfo != null) { 5098 // If we didn't remove it, the cross-profile ResolveInfo would be twice 5099 // in the result. 5100 result.remove(xpResolveInfo); 5101 } 5102 if (result.size() == 0) { 5103 result.add(xpDomainInfo.resolveInfo); 5104 return result; 5105 } 5106 } else if (result.size() <= 1) { 5107 return result; 5108 } 5109 result = filterCandidatesWithDomainPreferredActivitiesLPr(intent, flags, result, 5110 xpDomainInfo, userId); 5111 Collections.sort(result, mResolvePrioritySorter); 5112 } 5113 return result; 5114 } 5115 final PackageParser.Package pkg = mPackages.get(pkgName); 5116 if (pkg != null) { 5117 return filterIfNotSystemUser( 5118 mActivities.queryIntentForPackage( 5119 intent, resolvedType, flags, pkg.activities, userId), 5120 userId); 5121 } 5122 return new ArrayList<ResolveInfo>(); 5123 } 5124 } 5125 5126 private static class CrossProfileDomainInfo { 5127 /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */ 5128 ResolveInfo resolveInfo; 5129 /* Best domain verification status of the activities found in the other profile */ 5130 int bestDomainVerificationStatus; 5131 } 5132 5133 private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent, 5134 String resolvedType, int flags, int sourceUserId, int parentUserId) { 5135 if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING, 5136 sourceUserId)) { 5137 return null; 5138 } 5139 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 5140 resolvedType, flags, parentUserId); 5141 5142 if (resultTargetUser == null || resultTargetUser.isEmpty()) { 5143 return null; 5144 } 5145 CrossProfileDomainInfo result = null; 5146 int size = resultTargetUser.size(); 5147 for (int i = 0; i < size; i++) { 5148 ResolveInfo riTargetUser = resultTargetUser.get(i); 5149 // Intent filter verification is only for filters that specify a host. So don't return 5150 // those that handle all web uris. 5151 if (riTargetUser.handleAllWebDataURI) { 5152 continue; 5153 } 5154 String packageName = riTargetUser.activityInfo.packageName; 5155 PackageSetting ps = mSettings.mPackages.get(packageName); 5156 if (ps == null) { 5157 continue; 5158 } 5159 long verificationState = getDomainVerificationStatusLPr(ps, parentUserId); 5160 int status = (int)(verificationState >> 32); 5161 if (result == null) { 5162 result = new CrossProfileDomainInfo(); 5163 result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(), 5164 sourceUserId, parentUserId); 5165 result.bestDomainVerificationStatus = status; 5166 } else { 5167 result.bestDomainVerificationStatus = bestDomainVerificationStatus(status, 5168 result.bestDomainVerificationStatus); 5169 } 5170 } 5171 // Don't consider matches with status NEVER across profiles. 5172 if (result != null && result.bestDomainVerificationStatus 5173 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5174 return null; 5175 } 5176 return result; 5177 } 5178 5179 /** 5180 * Verification statuses are ordered from the worse to the best, except for 5181 * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse. 5182 */ 5183 private int bestDomainVerificationStatus(int status1, int status2) { 5184 if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5185 return status2; 5186 } 5187 if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5188 return status1; 5189 } 5190 return (int) MathUtils.max(status1, status2); 5191 } 5192 5193 private boolean isUserEnabled(int userId) { 5194 long callingId = Binder.clearCallingIdentity(); 5195 try { 5196 UserInfo userInfo = sUserManager.getUserInfo(userId); 5197 return userInfo != null && userInfo.isEnabled(); 5198 } finally { 5199 Binder.restoreCallingIdentity(callingId); 5200 } 5201 } 5202 5203 /** 5204 * Filter out activities with systemUserOnly flag set, when current user is not System. 5205 * 5206 * @return filtered list 5207 */ 5208 private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) { 5209 if (userId == UserHandle.USER_SYSTEM) { 5210 return resolveInfos; 5211 } 5212 for (int i = resolveInfos.size() - 1; i >= 0; i--) { 5213 ResolveInfo info = resolveInfos.get(i); 5214 if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) { 5215 resolveInfos.remove(i); 5216 } 5217 } 5218 return resolveInfos; 5219 } 5220 5221 /** 5222 * @param resolveInfos list of resolve infos in descending priority order 5223 * @return if the list contains a resolve info with non-negative priority 5224 */ 5225 private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) { 5226 return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0; 5227 } 5228 5229 private static boolean hasWebURI(Intent intent) { 5230 if (intent.getData() == null) { 5231 return false; 5232 } 5233 final String scheme = intent.getScheme(); 5234 if (TextUtils.isEmpty(scheme)) { 5235 return false; 5236 } 5237 return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS); 5238 } 5239 5240 private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent, 5241 int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo, 5242 int userId) { 5243 final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0; 5244 5245 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) { 5246 Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " + 5247 candidates.size()); 5248 } 5249 5250 ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>(); 5251 ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>(); 5252 ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>(); 5253 ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>(); 5254 ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>(); 5255 ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>(); 5256 5257 synchronized (mPackages) { 5258 final int count = candidates.size(); 5259 // First, try to use linked apps. Partition the candidates into four lists: 5260 // one for the final results, one for the "do not use ever", one for "undefined status" 5261 // and finally one for "browser app type". 5262 for (int n=0; n<count; n++) { 5263 ResolveInfo info = candidates.get(n); 5264 String packageName = info.activityInfo.packageName; 5265 PackageSetting ps = mSettings.mPackages.get(packageName); 5266 if (ps != null) { 5267 // Add to the special match all list (Browser use case) 5268 if (info.handleAllWebDataURI) { 5269 matchAllList.add(info); 5270 continue; 5271 } 5272 // Try to get the status from User settings first 5273 long packedStatus = getDomainVerificationStatusLPr(ps, userId); 5274 int status = (int)(packedStatus >> 32); 5275 int linkGeneration = (int)(packedStatus & 0xFFFFFFFF); 5276 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) { 5277 if (DEBUG_DOMAIN_VERIFICATION) { 5278 Slog.i(TAG, " + always: " + info.activityInfo.packageName 5279 + " : linkgen=" + linkGeneration); 5280 } 5281 // Use link-enabled generation as preferredOrder, i.e. 5282 // prefer newly-enabled over earlier-enabled. 5283 info.preferredOrder = linkGeneration; 5284 alwaysList.add(info); 5285 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5286 if (DEBUG_DOMAIN_VERIFICATION) { 5287 Slog.i(TAG, " + never: " + info.activityInfo.packageName); 5288 } 5289 neverList.add(info); 5290 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) { 5291 if (DEBUG_DOMAIN_VERIFICATION) { 5292 Slog.i(TAG, " + always-ask: " + info.activityInfo.packageName); 5293 } 5294 alwaysAskList.add(info); 5295 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED || 5296 status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) { 5297 if (DEBUG_DOMAIN_VERIFICATION) { 5298 Slog.i(TAG, " + ask: " + info.activityInfo.packageName); 5299 } 5300 undefinedList.add(info); 5301 } 5302 } 5303 } 5304 5305 // We'll want to include browser possibilities in a few cases 5306 boolean includeBrowser = false; 5307 5308 // First try to add the "always" resolution(s) for the current user, if any 5309 if (alwaysList.size() > 0) { 5310 result.addAll(alwaysList); 5311 } else { 5312 // Add all undefined apps as we want them to appear in the disambiguation dialog. 5313 result.addAll(undefinedList); 5314 // Maybe add one for the other profile. 5315 if (xpDomainInfo != null && ( 5316 xpDomainInfo.bestDomainVerificationStatus 5317 != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) { 5318 result.add(xpDomainInfo.resolveInfo); 5319 } 5320 includeBrowser = true; 5321 } 5322 5323 // The presence of any 'always ask' alternatives means we'll also offer browsers. 5324 // If there were 'always' entries their preferred order has been set, so we also 5325 // back that off to make the alternatives equivalent 5326 if (alwaysAskList.size() > 0) { 5327 for (ResolveInfo i : result) { 5328 i.preferredOrder = 0; 5329 } 5330 result.addAll(alwaysAskList); 5331 includeBrowser = true; 5332 } 5333 5334 if (includeBrowser) { 5335 // Also add browsers (all of them or only the default one) 5336 if (DEBUG_DOMAIN_VERIFICATION) { 5337 Slog.v(TAG, " ...including browsers in candidate set"); 5338 } 5339 if ((matchFlags & MATCH_ALL) != 0) { 5340 result.addAll(matchAllList); 5341 } else { 5342 // Browser/generic handling case. If there's a default browser, go straight 5343 // to that (but only if there is no other higher-priority match). 5344 final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId); 5345 int maxMatchPrio = 0; 5346 ResolveInfo defaultBrowserMatch = null; 5347 final int numCandidates = matchAllList.size(); 5348 for (int n = 0; n < numCandidates; n++) { 5349 ResolveInfo info = matchAllList.get(n); 5350 // track the highest overall match priority... 5351 if (info.priority > maxMatchPrio) { 5352 maxMatchPrio = info.priority; 5353 } 5354 // ...and the highest-priority default browser match 5355 if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) { 5356 if (defaultBrowserMatch == null 5357 || (defaultBrowserMatch.priority < info.priority)) { 5358 if (debug) { 5359 Slog.v(TAG, "Considering default browser match " + info); 5360 } 5361 defaultBrowserMatch = info; 5362 } 5363 } 5364 } 5365 if (defaultBrowserMatch != null 5366 && defaultBrowserMatch.priority >= maxMatchPrio 5367 && !TextUtils.isEmpty(defaultBrowserPackageName)) 5368 { 5369 if (debug) { 5370 Slog.v(TAG, "Default browser match " + defaultBrowserMatch); 5371 } 5372 result.add(defaultBrowserMatch); 5373 } else { 5374 result.addAll(matchAllList); 5375 } 5376 } 5377 5378 // If there is nothing selected, add all candidates and remove the ones that the user 5379 // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state 5380 if (result.size() == 0) { 5381 result.addAll(candidates); 5382 result.removeAll(neverList); 5383 } 5384 } 5385 } 5386 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) { 5387 Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " + 5388 result.size()); 5389 for (ResolveInfo info : result) { 5390 Slog.v(TAG, " + " + info.activityInfo); 5391 } 5392 } 5393 return result; 5394 } 5395 5396 // Returns a packed value as a long: 5397 // 5398 // high 'int'-sized word: link status: undefined/ask/never/always. 5399 // low 'int'-sized word: relative priority among 'always' results. 5400 private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) { 5401 long result = ps.getDomainVerificationStatusForUser(userId); 5402 // if none available, get the master status 5403 if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 5404 if (ps.getIntentFilterVerificationInfo() != null) { 5405 result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32; 5406 } 5407 } 5408 return result; 5409 } 5410 5411 private ResolveInfo querySkipCurrentProfileIntents( 5412 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 5413 int flags, int sourceUserId) { 5414 if (matchingFilters != null) { 5415 int size = matchingFilters.size(); 5416 for (int i = 0; i < size; i ++) { 5417 CrossProfileIntentFilter filter = matchingFilters.get(i); 5418 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) { 5419 // Checking if there are activities in the target user that can handle the 5420 // intent. 5421 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent, 5422 resolvedType, flags, sourceUserId); 5423 if (resolveInfo != null) { 5424 return resolveInfo; 5425 } 5426 } 5427 } 5428 } 5429 return null; 5430 } 5431 5432 // Return matching ResolveInfo in target user if any. 5433 private ResolveInfo queryCrossProfileIntents( 5434 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 5435 int flags, int sourceUserId, boolean matchInCurrentProfile) { 5436 if (matchingFilters != null) { 5437 // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and 5438 // match the same intent. For performance reasons, it is better not to 5439 // run queryIntent twice for the same userId 5440 SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray(); 5441 int size = matchingFilters.size(); 5442 for (int i = 0; i < size; i++) { 5443 CrossProfileIntentFilter filter = matchingFilters.get(i); 5444 int targetUserId = filter.getTargetUserId(); 5445 boolean skipCurrentProfile = 5446 (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0; 5447 boolean skipCurrentProfileIfNoMatchFound = 5448 (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0; 5449 if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId) 5450 && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) { 5451 // Checking if there are activities in the target user that can handle the 5452 // intent. 5453 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent, 5454 resolvedType, flags, sourceUserId); 5455 if (resolveInfo != null) return resolveInfo; 5456 alreadyTriedUserIds.put(targetUserId, true); 5457 } 5458 } 5459 } 5460 return null; 5461 } 5462 5463 /** 5464 * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that 5465 * will forward the intent to the filter's target user. 5466 * Otherwise, returns null. 5467 */ 5468 private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent, 5469 String resolvedType, int flags, int sourceUserId) { 5470 int targetUserId = filter.getTargetUserId(); 5471 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 5472 resolvedType, flags, targetUserId); 5473 if (resultTargetUser != null && isUserEnabled(targetUserId)) { 5474 // If all the matches in the target profile are suspended, return null. 5475 for (int i = resultTargetUser.size() - 1; i >= 0; i--) { 5476 if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags 5477 & ApplicationInfo.FLAG_SUSPENDED) == 0) { 5478 return createForwardingResolveInfoUnchecked(filter, sourceUserId, 5479 targetUserId); 5480 } 5481 } 5482 } 5483 return null; 5484 } 5485 5486 private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter, 5487 int sourceUserId, int targetUserId) { 5488 ResolveInfo forwardingResolveInfo = new ResolveInfo(); 5489 long ident = Binder.clearCallingIdentity(); 5490 boolean targetIsProfile; 5491 try { 5492 targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile(); 5493 } finally { 5494 Binder.restoreCallingIdentity(ident); 5495 } 5496 String className; 5497 if (targetIsProfile) { 5498 className = FORWARD_INTENT_TO_MANAGED_PROFILE; 5499 } else { 5500 className = FORWARD_INTENT_TO_PARENT; 5501 } 5502 ComponentName forwardingActivityComponentName = new ComponentName( 5503 mAndroidApplication.packageName, className); 5504 ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0, 5505 sourceUserId); 5506 if (!targetIsProfile) { 5507 forwardingActivityInfo.showUserIcon = targetUserId; 5508 forwardingResolveInfo.noResourceId = true; 5509 } 5510 forwardingResolveInfo.activityInfo = forwardingActivityInfo; 5511 forwardingResolveInfo.priority = 0; 5512 forwardingResolveInfo.preferredOrder = 0; 5513 forwardingResolveInfo.match = 0; 5514 forwardingResolveInfo.isDefault = true; 5515 forwardingResolveInfo.filter = filter; 5516 forwardingResolveInfo.targetUserId = targetUserId; 5517 return forwardingResolveInfo; 5518 } 5519 5520 @Override 5521 public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller, 5522 Intent[] specifics, String[] specificTypes, Intent intent, 5523 String resolvedType, int flags, int userId) { 5524 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5525 flags = updateFlagsForResolve(flags, userId, intent); 5526 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5527 false /* requireFullPermission */, false /* checkShell */, 5528 "query intent activity options"); 5529 final String resultsAction = intent.getAction(); 5530 5531 List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags 5532 | PackageManager.GET_RESOLVED_FILTER, userId); 5533 5534 if (DEBUG_INTENT_MATCHING) { 5535 Log.v(TAG, "Query " + intent + ": " + results); 5536 } 5537 5538 int specificsPos = 0; 5539 int N; 5540 5541 // todo: note that the algorithm used here is O(N^2). This 5542 // isn't a problem in our current environment, but if we start running 5543 // into situations where we have more than 5 or 10 matches then this 5544 // should probably be changed to something smarter... 5545 5546 // First we go through and resolve each of the specific items 5547 // that were supplied, taking care of removing any corresponding 5548 // duplicate items in the generic resolve list. 5549 if (specifics != null) { 5550 for (int i=0; i<specifics.length; i++) { 5551 final Intent sintent = specifics[i]; 5552 if (sintent == null) { 5553 continue; 5554 } 5555 5556 if (DEBUG_INTENT_MATCHING) { 5557 Log.v(TAG, "Specific #" + i + ": " + sintent); 5558 } 5559 5560 String action = sintent.getAction(); 5561 if (resultsAction != null && resultsAction.equals(action)) { 5562 // If this action was explicitly requested, then don't 5563 // remove things that have it. 5564 action = null; 5565 } 5566 5567 ResolveInfo ri = null; 5568 ActivityInfo ai = null; 5569 5570 ComponentName comp = sintent.getComponent(); 5571 if (comp == null) { 5572 ri = resolveIntent( 5573 sintent, 5574 specificTypes != null ? specificTypes[i] : null, 5575 flags, userId); 5576 if (ri == null) { 5577 continue; 5578 } 5579 if (ri == mResolveInfo) { 5580 // ACK! Must do something better with this. 5581 } 5582 ai = ri.activityInfo; 5583 comp = new ComponentName(ai.applicationInfo.packageName, 5584 ai.name); 5585 } else { 5586 ai = getActivityInfo(comp, flags, userId); 5587 if (ai == null) { 5588 continue; 5589 } 5590 } 5591 5592 // Look for any generic query activities that are duplicates 5593 // of this specific one, and remove them from the results. 5594 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai); 5595 N = results.size(); 5596 int j; 5597 for (j=specificsPos; j<N; j++) { 5598 ResolveInfo sri = results.get(j); 5599 if ((sri.activityInfo.name.equals(comp.getClassName()) 5600 && sri.activityInfo.applicationInfo.packageName.equals( 5601 comp.getPackageName())) 5602 || (action != null && sri.filter.matchAction(action))) { 5603 results.remove(j); 5604 if (DEBUG_INTENT_MATCHING) Log.v( 5605 TAG, "Removing duplicate item from " + j 5606 + " due to specific " + specificsPos); 5607 if (ri == null) { 5608 ri = sri; 5609 } 5610 j--; 5611 N--; 5612 } 5613 } 5614 5615 // Add this specific item to its proper place. 5616 if (ri == null) { 5617 ri = new ResolveInfo(); 5618 ri.activityInfo = ai; 5619 } 5620 results.add(specificsPos, ri); 5621 ri.specificIndex = i; 5622 specificsPos++; 5623 } 5624 } 5625 5626 // Now we go through the remaining generic results and remove any 5627 // duplicate actions that are found here. 5628 N = results.size(); 5629 for (int i=specificsPos; i<N-1; i++) { 5630 final ResolveInfo rii = results.get(i); 5631 if (rii.filter == null) { 5632 continue; 5633 } 5634 5635 // Iterate over all of the actions of this result's intent 5636 // filter... typically this should be just one. 5637 final Iterator<String> it = rii.filter.actionsIterator(); 5638 if (it == null) { 5639 continue; 5640 } 5641 while (it.hasNext()) { 5642 final String action = it.next(); 5643 if (resultsAction != null && resultsAction.equals(action)) { 5644 // If this action was explicitly requested, then don't 5645 // remove things that have it. 5646 continue; 5647 } 5648 for (int j=i+1; j<N; j++) { 5649 final ResolveInfo rij = results.get(j); 5650 if (rij.filter != null && rij.filter.hasAction(action)) { 5651 results.remove(j); 5652 if (DEBUG_INTENT_MATCHING) Log.v( 5653 TAG, "Removing duplicate item from " + j 5654 + " due to action " + action + " at " + i); 5655 j--; 5656 N--; 5657 } 5658 } 5659 } 5660 5661 // If the caller didn't request filter information, drop it now 5662 // so we don't have to marshall/unmarshall it. 5663 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 5664 rii.filter = null; 5665 } 5666 } 5667 5668 // Filter out the caller activity if so requested. 5669 if (caller != null) { 5670 N = results.size(); 5671 for (int i=0; i<N; i++) { 5672 ActivityInfo ainfo = results.get(i).activityInfo; 5673 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName) 5674 && caller.getClassName().equals(ainfo.name)) { 5675 results.remove(i); 5676 break; 5677 } 5678 } 5679 } 5680 5681 // If the caller didn't request filter information, 5682 // drop them now so we don't have to 5683 // marshall/unmarshall it. 5684 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 5685 N = results.size(); 5686 for (int i=0; i<N; i++) { 5687 results.get(i).filter = null; 5688 } 5689 } 5690 5691 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results); 5692 return results; 5693 } 5694 5695 @Override 5696 public List<ResolveInfo> queryIntentReceivers(Intent intent, String resolvedType, int flags, 5697 int userId) { 5698 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5699 flags = updateFlagsForResolve(flags, userId, intent); 5700 ComponentName comp = intent.getComponent(); 5701 if (comp == null) { 5702 if (intent.getSelector() != null) { 5703 intent = intent.getSelector(); 5704 comp = intent.getComponent(); 5705 } 5706 } 5707 if (comp != null) { 5708 List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5709 ActivityInfo ai = getReceiverInfo(comp, flags, userId); 5710 if (ai != null) { 5711 ResolveInfo ri = new ResolveInfo(); 5712 ri.activityInfo = ai; 5713 list.add(ri); 5714 } 5715 return list; 5716 } 5717 5718 // reader 5719 synchronized (mPackages) { 5720 String pkgName = intent.getPackage(); 5721 if (pkgName == null) { 5722 return mReceivers.queryIntent(intent, resolvedType, flags, userId); 5723 } 5724 final PackageParser.Package pkg = mPackages.get(pkgName); 5725 if (pkg != null) { 5726 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers, 5727 userId); 5728 } 5729 return null; 5730 } 5731 } 5732 5733 @Override 5734 public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) { 5735 if (!sUserManager.exists(userId)) return null; 5736 flags = updateFlagsForResolve(flags, userId, intent); 5737 List<ResolveInfo> query = queryIntentServices(intent, resolvedType, flags, userId); 5738 if (query != null) { 5739 if (query.size() >= 1) { 5740 // If there is more than one service with the same priority, 5741 // just arbitrarily pick the first one. 5742 return query.get(0); 5743 } 5744 } 5745 return null; 5746 } 5747 5748 @Override 5749 public List<ResolveInfo> queryIntentServices(Intent intent, String resolvedType, int flags, 5750 int userId) { 5751 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5752 flags = updateFlagsForResolve(flags, userId, intent); 5753 ComponentName comp = intent.getComponent(); 5754 if (comp == null) { 5755 if (intent.getSelector() != null) { 5756 intent = intent.getSelector(); 5757 comp = intent.getComponent(); 5758 } 5759 } 5760 if (comp != null) { 5761 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5762 final ServiceInfo si = getServiceInfo(comp, flags, userId); 5763 if (si != null) { 5764 final ResolveInfo ri = new ResolveInfo(); 5765 ri.serviceInfo = si; 5766 list.add(ri); 5767 } 5768 return list; 5769 } 5770 5771 // reader 5772 synchronized (mPackages) { 5773 String pkgName = intent.getPackage(); 5774 if (pkgName == null) { 5775 return mServices.queryIntent(intent, resolvedType, flags, userId); 5776 } 5777 final PackageParser.Package pkg = mPackages.get(pkgName); 5778 if (pkg != null) { 5779 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services, 5780 userId); 5781 } 5782 return null; 5783 } 5784 } 5785 5786 @Override 5787 public List<ResolveInfo> queryIntentContentProviders( 5788 Intent intent, String resolvedType, int flags, int userId) { 5789 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5790 flags = updateFlagsForResolve(flags, userId, intent); 5791 ComponentName comp = intent.getComponent(); 5792 if (comp == null) { 5793 if (intent.getSelector() != null) { 5794 intent = intent.getSelector(); 5795 comp = intent.getComponent(); 5796 } 5797 } 5798 if (comp != null) { 5799 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5800 final ProviderInfo pi = getProviderInfo(comp, flags, userId); 5801 if (pi != null) { 5802 final ResolveInfo ri = new ResolveInfo(); 5803 ri.providerInfo = pi; 5804 list.add(ri); 5805 } 5806 return list; 5807 } 5808 5809 // reader 5810 synchronized (mPackages) { 5811 String pkgName = intent.getPackage(); 5812 if (pkgName == null) { 5813 return mProviders.queryIntent(intent, resolvedType, flags, userId); 5814 } 5815 final PackageParser.Package pkg = mPackages.get(pkgName); 5816 if (pkg != null) { 5817 return mProviders.queryIntentForPackage( 5818 intent, resolvedType, flags, pkg.providers, userId); 5819 } 5820 return null; 5821 } 5822 } 5823 5824 @Override 5825 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) { 5826 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 5827 flags = updateFlagsForPackage(flags, userId, null); 5828 final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0; 5829 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5830 true /* requireFullPermission */, false /* checkShell */, 5831 "get installed packages"); 5832 5833 // writer 5834 synchronized (mPackages) { 5835 ArrayList<PackageInfo> list; 5836 if (listUninstalled) { 5837 list = new ArrayList<PackageInfo>(mSettings.mPackages.size()); 5838 for (PackageSetting ps : mSettings.mPackages.values()) { 5839 PackageInfo pi; 5840 if (ps.pkg != null) { 5841 pi = generatePackageInfo(ps.pkg, flags, userId); 5842 } else { 5843 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId); 5844 } 5845 if (pi != null) { 5846 list.add(pi); 5847 } 5848 } 5849 } else { 5850 list = new ArrayList<PackageInfo>(mPackages.size()); 5851 for (PackageParser.Package p : mPackages.values()) { 5852 PackageInfo pi = generatePackageInfo(p, flags, userId); 5853 if (pi != null) { 5854 list.add(pi); 5855 } 5856 } 5857 } 5858 5859 return new ParceledListSlice<PackageInfo>(list); 5860 } 5861 } 5862 5863 private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps, 5864 String[] permissions, boolean[] tmp, int flags, int userId) { 5865 int numMatch = 0; 5866 final PermissionsState permissionsState = ps.getPermissionsState(); 5867 for (int i=0; i<permissions.length; i++) { 5868 final String permission = permissions[i]; 5869 if (permissionsState.hasPermission(permission, userId)) { 5870 tmp[i] = true; 5871 numMatch++; 5872 } else { 5873 tmp[i] = false; 5874 } 5875 } 5876 if (numMatch == 0) { 5877 return; 5878 } 5879 PackageInfo pi; 5880 if (ps.pkg != null) { 5881 pi = generatePackageInfo(ps.pkg, flags, userId); 5882 } else { 5883 pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId); 5884 } 5885 // The above might return null in cases of uninstalled apps or install-state 5886 // skew across users/profiles. 5887 if (pi != null) { 5888 if ((flags&PackageManager.GET_PERMISSIONS) == 0) { 5889 if (numMatch == permissions.length) { 5890 pi.requestedPermissions = permissions; 5891 } else { 5892 pi.requestedPermissions = new String[numMatch]; 5893 numMatch = 0; 5894 for (int i=0; i<permissions.length; i++) { 5895 if (tmp[i]) { 5896 pi.requestedPermissions[numMatch] = permissions[i]; 5897 numMatch++; 5898 } 5899 } 5900 } 5901 } 5902 list.add(pi); 5903 } 5904 } 5905 5906 @Override 5907 public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions( 5908 String[] permissions, int flags, int userId) { 5909 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 5910 flags = updateFlagsForPackage(flags, userId, permissions); 5911 final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0; 5912 5913 // writer 5914 synchronized (mPackages) { 5915 ArrayList<PackageInfo> list = new ArrayList<PackageInfo>(); 5916 boolean[] tmpBools = new boolean[permissions.length]; 5917 if (listUninstalled) { 5918 for (PackageSetting ps : mSettings.mPackages.values()) { 5919 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId); 5920 } 5921 } else { 5922 for (PackageParser.Package pkg : mPackages.values()) { 5923 PackageSetting ps = (PackageSetting)pkg.mExtras; 5924 if (ps != null) { 5925 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, 5926 userId); 5927 } 5928 } 5929 } 5930 5931 return new ParceledListSlice<PackageInfo>(list); 5932 } 5933 } 5934 5935 @Override 5936 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) { 5937 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 5938 flags = updateFlagsForApplication(flags, userId, null); 5939 final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0; 5940 5941 // writer 5942 synchronized (mPackages) { 5943 ArrayList<ApplicationInfo> list; 5944 if (listUninstalled) { 5945 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size()); 5946 for (PackageSetting ps : mSettings.mPackages.values()) { 5947 ApplicationInfo ai; 5948 if (ps.pkg != null) { 5949 ai = PackageParser.generateApplicationInfo(ps.pkg, flags, 5950 ps.readUserState(userId), userId); 5951 } else { 5952 ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId); 5953 } 5954 if (ai != null) { 5955 list.add(ai); 5956 } 5957 } 5958 } else { 5959 list = new ArrayList<ApplicationInfo>(mPackages.size()); 5960 for (PackageParser.Package p : mPackages.values()) { 5961 if (p.mExtras != null) { 5962 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 5963 ((PackageSetting)p.mExtras).readUserState(userId), userId); 5964 if (ai != null) { 5965 list.add(ai); 5966 } 5967 } 5968 } 5969 } 5970 5971 return new ParceledListSlice<ApplicationInfo>(list); 5972 } 5973 } 5974 5975 @Override 5976 public ParceledListSlice<EphemeralApplicationInfo> getEphemeralApplications(int userId) { 5977 if (DISABLE_EPHEMERAL_APPS) { 5978 return null; 5979 } 5980 5981 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS, 5982 "getEphemeralApplications"); 5983 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5984 true /* requireFullPermission */, false /* checkShell */, 5985 "getEphemeralApplications"); 5986 synchronized (mPackages) { 5987 List<EphemeralApplicationInfo> ephemeralApps = mEphemeralApplicationRegistry 5988 .getEphemeralApplicationsLPw(userId); 5989 if (ephemeralApps != null) { 5990 return new ParceledListSlice<>(ephemeralApps); 5991 } 5992 } 5993 return null; 5994 } 5995 5996 @Override 5997 public boolean isEphemeralApplication(String packageName, int userId) { 5998 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5999 true /* requireFullPermission */, false /* checkShell */, 6000 "isEphemeral"); 6001 if (DISABLE_EPHEMERAL_APPS) { 6002 return false; 6003 } 6004 6005 if (!isCallerSameApp(packageName)) { 6006 return false; 6007 } 6008 synchronized (mPackages) { 6009 PackageParser.Package pkg = mPackages.get(packageName); 6010 if (pkg != null) { 6011 return pkg.applicationInfo.isEphemeralApp(); 6012 } 6013 } 6014 return false; 6015 } 6016 6017 @Override 6018 public byte[] getEphemeralApplicationCookie(String packageName, int userId) { 6019 if (DISABLE_EPHEMERAL_APPS) { 6020 return null; 6021 } 6022 6023 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6024 true /* requireFullPermission */, false /* checkShell */, 6025 "getCookie"); 6026 if (!isCallerSameApp(packageName)) { 6027 return null; 6028 } 6029 synchronized (mPackages) { 6030 return mEphemeralApplicationRegistry.getEphemeralApplicationCookieLPw( 6031 packageName, userId); 6032 } 6033 } 6034 6035 @Override 6036 public boolean setEphemeralApplicationCookie(String packageName, byte[] cookie, int userId) { 6037 if (DISABLE_EPHEMERAL_APPS) { 6038 return true; 6039 } 6040 6041 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6042 true /* requireFullPermission */, true /* checkShell */, 6043 "setCookie"); 6044 if (!isCallerSameApp(packageName)) { 6045 return false; 6046 } 6047 synchronized (mPackages) { 6048 return mEphemeralApplicationRegistry.setEphemeralApplicationCookieLPw( 6049 packageName, cookie, userId); 6050 } 6051 } 6052 6053 @Override 6054 public Bitmap getEphemeralApplicationIcon(String packageName, int userId) { 6055 if (DISABLE_EPHEMERAL_APPS) { 6056 return null; 6057 } 6058 6059 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS, 6060 "getEphemeralApplicationIcon"); 6061 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6062 true /* requireFullPermission */, false /* checkShell */, 6063 "getEphemeralApplicationIcon"); 6064 synchronized (mPackages) { 6065 return mEphemeralApplicationRegistry.getEphemeralApplicationIconLPw( 6066 packageName, userId); 6067 } 6068 } 6069 6070 private boolean isCallerSameApp(String packageName) { 6071 PackageParser.Package pkg = mPackages.get(packageName); 6072 return pkg != null 6073 && UserHandle.getAppId(Binder.getCallingUid()) == pkg.applicationInfo.uid; 6074 } 6075 6076 public List<ApplicationInfo> getPersistentApplications(int flags) { 6077 final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>(); 6078 6079 // reader 6080 synchronized (mPackages) { 6081 final Iterator<PackageParser.Package> i = mPackages.values().iterator(); 6082 final int userId = UserHandle.getCallingUserId(); 6083 while (i.hasNext()) { 6084 final PackageParser.Package p = i.next(); 6085 if (p.applicationInfo == null) continue; 6086 6087 final boolean matchesUnaware = ((flags & MATCH_ENCRYPTION_UNAWARE) != 0) 6088 && !p.applicationInfo.isEncryptionAware(); 6089 final boolean matchesAware = ((flags & MATCH_ENCRYPTION_AWARE) != 0) 6090 && p.applicationInfo.isEncryptionAware(); 6091 6092 if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0 6093 && (!mSafeMode || isSystemApp(p)) 6094 && (matchesUnaware || matchesAware)) { 6095 PackageSetting ps = mSettings.mPackages.get(p.packageName); 6096 if (ps != null) { 6097 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 6098 ps.readUserState(userId), userId); 6099 if (ai != null) { 6100 finalList.add(ai); 6101 } 6102 } 6103 } 6104 } 6105 } 6106 6107 return finalList; 6108 } 6109 6110 @Override 6111 public ProviderInfo resolveContentProvider(String name, int flags, int userId) { 6112 if (!sUserManager.exists(userId)) return null; 6113 flags = updateFlagsForComponent(flags, userId, name); 6114 // reader 6115 synchronized (mPackages) { 6116 final PackageParser.Provider provider = mProvidersByAuthority.get(name); 6117 PackageSetting ps = provider != null 6118 ? mSettings.mPackages.get(provider.owner.packageName) 6119 : null; 6120 return ps != null 6121 && mSettings.isEnabledAndMatchLPr(provider.info, flags, userId) 6122 ? PackageParser.generateProviderInfo(provider, flags, 6123 ps.readUserState(userId), userId) 6124 : null; 6125 } 6126 } 6127 6128 /** 6129 * @deprecated 6130 */ 6131 @Deprecated 6132 public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) { 6133 // reader 6134 synchronized (mPackages) { 6135 final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority 6136 .entrySet().iterator(); 6137 final int userId = UserHandle.getCallingUserId(); 6138 while (i.hasNext()) { 6139 Map.Entry<String, PackageParser.Provider> entry = i.next(); 6140 PackageParser.Provider p = entry.getValue(); 6141 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 6142 6143 if (ps != null && p.syncable 6144 && (!mSafeMode || (p.info.applicationInfo.flags 6145 &ApplicationInfo.FLAG_SYSTEM) != 0)) { 6146 ProviderInfo info = PackageParser.generateProviderInfo(p, 0, 6147 ps.readUserState(userId), userId); 6148 if (info != null) { 6149 outNames.add(entry.getKey()); 6150 outInfo.add(info); 6151 } 6152 } 6153 } 6154 } 6155 } 6156 6157 @Override 6158 public ParceledListSlice<ProviderInfo> queryContentProviders(String processName, 6159 int uid, int flags) { 6160 final int userId = processName != null ? UserHandle.getUserId(uid) 6161 : UserHandle.getCallingUserId(); 6162 if (!sUserManager.exists(userId)) return null; 6163 flags = updateFlagsForComponent(flags, userId, processName); 6164 6165 ArrayList<ProviderInfo> finalList = null; 6166 // reader 6167 synchronized (mPackages) { 6168 final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator(); 6169 while (i.hasNext()) { 6170 final PackageParser.Provider p = i.next(); 6171 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 6172 if (ps != null && p.info.authority != null 6173 && (processName == null 6174 || (p.info.processName.equals(processName) 6175 && UserHandle.isSameApp(p.info.applicationInfo.uid, uid))) 6176 && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) { 6177 if (finalList == null) { 6178 finalList = new ArrayList<ProviderInfo>(3); 6179 } 6180 ProviderInfo info = PackageParser.generateProviderInfo(p, flags, 6181 ps.readUserState(userId), userId); 6182 if (info != null) { 6183 finalList.add(info); 6184 } 6185 } 6186 } 6187 } 6188 6189 if (finalList != null) { 6190 Collections.sort(finalList, mProviderInitOrderSorter); 6191 return new ParceledListSlice<ProviderInfo>(finalList); 6192 } 6193 6194 return null; 6195 } 6196 6197 @Override 6198 public InstrumentationInfo getInstrumentationInfo(ComponentName name, int flags) { 6199 // reader 6200 synchronized (mPackages) { 6201 final PackageParser.Instrumentation i = mInstrumentation.get(name); 6202 return PackageParser.generateInstrumentationInfo(i, flags); 6203 } 6204 } 6205 6206 @Override 6207 public List<InstrumentationInfo> queryInstrumentation(String targetPackage, 6208 int flags) { 6209 ArrayList<InstrumentationInfo> finalList = 6210 new ArrayList<InstrumentationInfo>(); 6211 6212 // reader 6213 synchronized (mPackages) { 6214 final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator(); 6215 while (i.hasNext()) { 6216 final PackageParser.Instrumentation p = i.next(); 6217 if (targetPackage == null 6218 || targetPackage.equals(p.info.targetPackage)) { 6219 InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p, 6220 flags); 6221 if (ii != null) { 6222 finalList.add(ii); 6223 } 6224 } 6225 } 6226 } 6227 6228 return finalList; 6229 } 6230 6231 private void createIdmapsForPackageLI(PackageParser.Package pkg) { 6232 ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName); 6233 if (overlays == null) { 6234 Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages"); 6235 return; 6236 } 6237 for (PackageParser.Package opkg : overlays.values()) { 6238 // Not much to do if idmap fails: we already logged the error 6239 // and we certainly don't want to abort installation of pkg simply 6240 // because an overlay didn't fit properly. For these reasons, 6241 // ignore the return value of createIdmapForPackagePairLI. 6242 createIdmapForPackagePairLI(pkg, opkg); 6243 } 6244 } 6245 6246 private boolean createIdmapForPackagePairLI(PackageParser.Package pkg, 6247 PackageParser.Package opkg) { 6248 if (!opkg.mTrustedOverlay) { 6249 Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " + 6250 opkg.baseCodePath + ": overlay not trusted"); 6251 return false; 6252 } 6253 ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName); 6254 if (overlaySet == null) { 6255 Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " + 6256 opkg.baseCodePath + " but target package has no known overlays"); 6257 return false; 6258 } 6259 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 6260 // TODO: generate idmap for split APKs 6261 try { 6262 mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid); 6263 } catch (InstallerException e) { 6264 Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and " 6265 + opkg.baseCodePath); 6266 return false; 6267 } 6268 PackageParser.Package[] overlayArray = 6269 overlaySet.values().toArray(new PackageParser.Package[0]); 6270 Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() { 6271 public int compare(PackageParser.Package p1, PackageParser.Package p2) { 6272 return p1.mOverlayPriority - p2.mOverlayPriority; 6273 } 6274 }; 6275 Arrays.sort(overlayArray, cmp); 6276 6277 pkg.applicationInfo.resourceDirs = new String[overlayArray.length]; 6278 int i = 0; 6279 for (PackageParser.Package p : overlayArray) { 6280 pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath; 6281 } 6282 return true; 6283 } 6284 6285 private void scanDirTracedLI(File dir, int parseFlags, int scanFlags, long currentTime) { 6286 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir"); 6287 try { 6288 scanDirLI(dir, parseFlags, scanFlags, currentTime); 6289 } finally { 6290 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6291 } 6292 } 6293 6294 private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) { 6295 final File[] files = dir.listFiles(); 6296 if (ArrayUtils.isEmpty(files)) { 6297 Log.d(TAG, "No files in app dir " + dir); 6298 return; 6299 } 6300 6301 if (DEBUG_PACKAGE_SCANNING) { 6302 Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags 6303 + " flags=0x" + Integer.toHexString(parseFlags)); 6304 } 6305 6306 for (File file : files) { 6307 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 6308 && !PackageInstallerService.isStageName(file.getName()); 6309 if (!isPackage) { 6310 // Ignore entries which are not packages 6311 continue; 6312 } 6313 try { 6314 scanPackageTracedLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK, 6315 scanFlags, currentTime, null); 6316 } catch (PackageManagerException e) { 6317 Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage()); 6318 6319 // Delete invalid userdata apps 6320 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 && 6321 e.error == PackageManager.INSTALL_FAILED_INVALID_APK) { 6322 logCriticalInfo(Log.WARN, "Deleting invalid package at " + file); 6323 removeCodePathLI(file); 6324 } 6325 } 6326 } 6327 } 6328 6329 private static File getSettingsProblemFile() { 6330 File dataDir = Environment.getDataDirectory(); 6331 File systemDir = new File(dataDir, "system"); 6332 File fname = new File(systemDir, "uiderrors.txt"); 6333 return fname; 6334 } 6335 6336 static void reportSettingsProblem(int priority, String msg) { 6337 logCriticalInfo(priority, msg); 6338 } 6339 6340 static void logCriticalInfo(int priority, String msg) { 6341 Slog.println(priority, TAG, msg); 6342 EventLogTags.writePmCriticalInfo(msg); 6343 try { 6344 File fname = getSettingsProblemFile(); 6345 FileOutputStream out = new FileOutputStream(fname, true); 6346 PrintWriter pw = new FastPrintWriter(out); 6347 SimpleDateFormat formatter = new SimpleDateFormat(); 6348 String dateString = formatter.format(new Date(System.currentTimeMillis())); 6349 pw.println(dateString + ": " + msg); 6350 pw.close(); 6351 FileUtils.setPermissions( 6352 fname.toString(), 6353 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH, 6354 -1, -1); 6355 } catch (java.io.IOException e) { 6356 } 6357 } 6358 6359 private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile, 6360 int parseFlags) throws PackageManagerException { 6361 if (ps != null 6362 && ps.codePath.equals(srcFile) 6363 && ps.timeStamp == srcFile.lastModified() 6364 && !isCompatSignatureUpdateNeeded(pkg) 6365 && !isRecoverSignatureUpdateNeeded(pkg)) { 6366 long mSigningKeySetId = ps.keySetData.getProperSigningKeySet(); 6367 KeySetManagerService ksms = mSettings.mKeySetManagerService; 6368 ArraySet<PublicKey> signingKs; 6369 synchronized (mPackages) { 6370 signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId); 6371 } 6372 if (ps.signatures.mSignatures != null 6373 && ps.signatures.mSignatures.length != 0 6374 && signingKs != null) { 6375 // Optimization: reuse the existing cached certificates 6376 // if the package appears to be unchanged. 6377 pkg.mSignatures = ps.signatures.mSignatures; 6378 pkg.mSigningKeys = signingKs; 6379 return; 6380 } 6381 6382 Slog.w(TAG, "PackageSetting for " + ps.name 6383 + " is missing signatures. Collecting certs again to recover them."); 6384 } else { 6385 Log.i(TAG, srcFile.toString() + " changed; collecting certs"); 6386 } 6387 6388 try { 6389 PackageParser.collectCertificates(pkg, parseFlags); 6390 } catch (PackageParserException e) { 6391 throw PackageManagerException.from(e); 6392 } 6393 } 6394 6395 /** 6396 * Traces a package scan. 6397 * @see #scanPackageLI(File, int, int, long, UserHandle) 6398 */ 6399 private PackageParser.Package scanPackageTracedLI(File scanFile, int parseFlags, int scanFlags, 6400 long currentTime, UserHandle user) throws PackageManagerException { 6401 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage"); 6402 try { 6403 return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user); 6404 } finally { 6405 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6406 } 6407 } 6408 6409 /** 6410 * Scans a package and returns the newly parsed package. 6411 * Returns {@code null} in case of errors and the error code is stored in mLastScanError 6412 */ 6413 private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags, 6414 long currentTime, UserHandle user) throws PackageManagerException { 6415 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile); 6416 parseFlags |= mDefParseFlags; 6417 PackageParser pp = new PackageParser(); 6418 pp.setSeparateProcesses(mSeparateProcesses); 6419 pp.setOnlyCoreApps(mOnlyCore); 6420 pp.setDisplayMetrics(mMetrics); 6421 6422 if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) { 6423 parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY; 6424 } 6425 6426 final PackageParser.Package pkg; 6427 try { 6428 pkg = pp.parsePackage(scanFile, parseFlags); 6429 } catch (PackageParserException e) { 6430 throw PackageManagerException.from(e); 6431 } 6432 6433 return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user); 6434 } 6435 6436 /** 6437 * Scans a package and returns the newly parsed package. 6438 * @throws PackageManagerException on a parse error. 6439 */ 6440 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile, 6441 int parseFlags, int scanFlags, long currentTime, UserHandle user) 6442 throws PackageManagerException { 6443 // If the package has children and this is the first dive in the function 6444 // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all 6445 // packages (parent and children) would be successfully scanned before the 6446 // actual scan since scanning mutates internal state and we want to atomically 6447 // install the package and its children. 6448 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 6449 if (pkg.childPackages != null && pkg.childPackages.size() > 0) { 6450 scanFlags |= SCAN_CHECK_ONLY; 6451 } 6452 } else { 6453 scanFlags &= ~SCAN_CHECK_ONLY; 6454 } 6455 6456 // Scan the parent 6457 PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, parseFlags, 6458 scanFlags, currentTime, user); 6459 6460 // Scan the children 6461 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 6462 for (int i = 0; i < childCount; i++) { 6463 PackageParser.Package childPackage = pkg.childPackages.get(i); 6464 scanPackageInternalLI(childPackage, scanFile, parseFlags, scanFlags, 6465 currentTime, user); 6466 } 6467 6468 6469 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 6470 return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user); 6471 } 6472 6473 return scannedPkg; 6474 } 6475 6476 /** 6477 * Scans a package and returns the newly parsed package. 6478 * @throws PackageManagerException on a parse error. 6479 */ 6480 private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile, 6481 int parseFlags, int scanFlags, long currentTime, UserHandle user) 6482 throws PackageManagerException { 6483 PackageSetting ps = null; 6484 PackageSetting updatedPkg; 6485 // reader 6486 synchronized (mPackages) { 6487 // Look to see if we already know about this package. 6488 String oldName = mSettings.mRenamedPackages.get(pkg.packageName); 6489 if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) { 6490 // This package has been renamed to its original name. Let's 6491 // use that. 6492 ps = mSettings.peekPackageLPr(oldName); 6493 } 6494 // If there was no original package, see one for the real package name. 6495 if (ps == null) { 6496 ps = mSettings.peekPackageLPr(pkg.packageName); 6497 } 6498 // Check to see if this package could be hiding/updating a system 6499 // package. Must look for it either under the original or real 6500 // package name depending on our state. 6501 updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName); 6502 if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg); 6503 6504 // If this is a package we don't know about on the system partition, we 6505 // may need to remove disabled child packages on the system partition 6506 // or may need to not add child packages if the parent apk is updated 6507 // on the data partition and no longer defines this child package. 6508 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) != 0) { 6509 // If this is a parent package for an updated system app and this system 6510 // app got an OTA update which no longer defines some of the child packages 6511 // we have to prune them from the disabled system packages. 6512 PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName); 6513 if (disabledPs != null) { 6514 final int scannedChildCount = (pkg.childPackages != null) 6515 ? pkg.childPackages.size() : 0; 6516 final int disabledChildCount = disabledPs.childPackageNames != null 6517 ? disabledPs.childPackageNames.size() : 0; 6518 for (int i = 0; i < disabledChildCount; i++) { 6519 String disabledChildPackageName = disabledPs.childPackageNames.get(i); 6520 boolean disabledPackageAvailable = false; 6521 for (int j = 0; j < scannedChildCount; j++) { 6522 PackageParser.Package childPkg = pkg.childPackages.get(j); 6523 if (childPkg.packageName.equals(disabledChildPackageName)) { 6524 disabledPackageAvailable = true; 6525 break; 6526 } 6527 } 6528 if (!disabledPackageAvailable) { 6529 mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName); 6530 } 6531 } 6532 } 6533 } 6534 } 6535 6536 boolean updatedPkgBetter = false; 6537 // First check if this is a system package that may involve an update 6538 if (updatedPkg != null && (parseFlags & PackageParser.PARSE_IS_SYSTEM) != 0) { 6539 // If new package is not located in "/system/priv-app" (e.g. due to an OTA), 6540 // it needs to drop FLAG_PRIVILEGED. 6541 if (locationIsPrivileged(scanFile)) { 6542 updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 6543 } else { 6544 updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 6545 } 6546 6547 if (ps != null && !ps.codePath.equals(scanFile)) { 6548 // The path has changed from what was last scanned... check the 6549 // version of the new path against what we have stored to determine 6550 // what to do. 6551 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath); 6552 if (pkg.mVersionCode <= ps.versionCode) { 6553 // The system package has been updated and the code path does not match 6554 // Ignore entry. Skip it. 6555 if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile 6556 + " ignored: updated version " + ps.versionCode 6557 + " better than this " + pkg.mVersionCode); 6558 if (!updatedPkg.codePath.equals(scanFile)) { 6559 Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg " 6560 + ps.name + " changing from " + updatedPkg.codePathString 6561 + " to " + scanFile); 6562 updatedPkg.codePath = scanFile; 6563 updatedPkg.codePathString = scanFile.toString(); 6564 updatedPkg.resourcePath = scanFile; 6565 updatedPkg.resourcePathString = scanFile.toString(); 6566 } 6567 updatedPkg.pkg = pkg; 6568 updatedPkg.versionCode = pkg.mVersionCode; 6569 6570 // Update the disabled system child packages to point to the package too. 6571 final int childCount = updatedPkg.childPackageNames != null 6572 ? updatedPkg.childPackageNames.size() : 0; 6573 for (int i = 0; i < childCount; i++) { 6574 String childPackageName = updatedPkg.childPackageNames.get(i); 6575 PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr( 6576 childPackageName); 6577 if (updatedChildPkg != null) { 6578 updatedChildPkg.pkg = pkg; 6579 updatedChildPkg.versionCode = pkg.mVersionCode; 6580 } 6581 } 6582 6583 throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at " 6584 + scanFile + " ignored: updated version " + ps.versionCode 6585 + " better than this " + pkg.mVersionCode); 6586 } else { 6587 // The current app on the system partition is better than 6588 // what we have updated to on the data partition; switch 6589 // back to the system partition version. 6590 // At this point, its safely assumed that package installation for 6591 // apps in system partition will go through. If not there won't be a working 6592 // version of the app 6593 // writer 6594 synchronized (mPackages) { 6595 // Just remove the loaded entries from package lists. 6596 mPackages.remove(ps.name); 6597 } 6598 6599 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 6600 + " reverting from " + ps.codePathString 6601 + ": new version " + pkg.mVersionCode 6602 + " better than installed " + ps.versionCode); 6603 6604 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 6605 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 6606 synchronized (mInstallLock) { 6607 args.cleanUpResourcesLI(); 6608 } 6609 synchronized (mPackages) { 6610 mSettings.enableSystemPackageLPw(ps.name); 6611 } 6612 updatedPkgBetter = true; 6613 } 6614 } 6615 } 6616 6617 if (updatedPkg != null) { 6618 // An updated system app will not have the PARSE_IS_SYSTEM flag set 6619 // initially 6620 parseFlags |= PackageParser.PARSE_IS_SYSTEM; 6621 6622 // An updated privileged app will not have the PARSE_IS_PRIVILEGED 6623 // flag set initially 6624 if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) { 6625 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 6626 } 6627 } 6628 6629 // Verify certificates against what was last scanned 6630 collectCertificatesLI(ps, pkg, scanFile, parseFlags); 6631 6632 /* 6633 * A new system app appeared, but we already had a non-system one of the 6634 * same name installed earlier. 6635 */ 6636 boolean shouldHideSystemApp = false; 6637 if (updatedPkg == null && ps != null 6638 && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) { 6639 /* 6640 * Check to make sure the signatures match first. If they don't, 6641 * wipe the installed application and its data. 6642 */ 6643 if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures) 6644 != PackageManager.SIGNATURE_MATCH) { 6645 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but" 6646 + " signatures don't match existing userdata copy; removing"); 6647 deletePackageLI(pkg.packageName, null, true, null, 0, null, false, null); 6648 ps = null; 6649 } else { 6650 /* 6651 * If the newly-added system app is an older version than the 6652 * already installed version, hide it. It will be scanned later 6653 * and re-added like an update. 6654 */ 6655 if (pkg.mVersionCode <= ps.versionCode) { 6656 shouldHideSystemApp = true; 6657 logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile 6658 + " but new version " + pkg.mVersionCode + " better than installed " 6659 + ps.versionCode + "; hiding system"); 6660 } else { 6661 /* 6662 * The newly found system app is a newer version that the 6663 * one previously installed. Simply remove the 6664 * already-installed application and replace it with our own 6665 * while keeping the application data. 6666 */ 6667 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 6668 + " reverting from " + ps.codePathString + ": new version " 6669 + pkg.mVersionCode + " better than installed " + ps.versionCode); 6670 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 6671 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 6672 synchronized (mInstallLock) { 6673 args.cleanUpResourcesLI(); 6674 } 6675 } 6676 } 6677 } 6678 6679 // The apk is forward locked (not public) if its code and resources 6680 // are kept in different files. (except for app in either system or 6681 // vendor path). 6682 // TODO grab this value from PackageSettings 6683 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 6684 if (ps != null && !ps.codePath.equals(ps.resourcePath)) { 6685 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 6686 } 6687 } 6688 6689 // TODO: extend to support forward-locked splits 6690 String resourcePath = null; 6691 String baseResourcePath = null; 6692 if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) { 6693 if (ps != null && ps.resourcePathString != null) { 6694 resourcePath = ps.resourcePathString; 6695 baseResourcePath = ps.resourcePathString; 6696 } else { 6697 // Should not happen at all. Just log an error. 6698 Slog.e(TAG, "Resource path not set for package " + pkg.packageName); 6699 } 6700 } else { 6701 resourcePath = pkg.codePath; 6702 baseResourcePath = pkg.baseCodePath; 6703 } 6704 6705 // Set application objects path explicitly. 6706 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 6707 pkg.setApplicationInfoCodePath(pkg.codePath); 6708 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 6709 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 6710 pkg.setApplicationInfoResourcePath(resourcePath); 6711 pkg.setApplicationInfoBaseResourcePath(baseResourcePath); 6712 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 6713 6714 // Note that we invoke the following method only if we are about to unpack an application 6715 PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags 6716 | SCAN_UPDATE_SIGNATURE, currentTime, user); 6717 6718 /* 6719 * If the system app should be overridden by a previously installed 6720 * data, hide the system app now and let the /data/app scan pick it up 6721 * again. 6722 */ 6723 if (shouldHideSystemApp) { 6724 synchronized (mPackages) { 6725 mSettings.disableSystemPackageLPw(pkg.packageName, true); 6726 } 6727 } 6728 6729 return scannedPkg; 6730 } 6731 6732 private static String fixProcessName(String defProcessName, 6733 String processName, int uid) { 6734 if (processName == null) { 6735 return defProcessName; 6736 } 6737 return processName; 6738 } 6739 6740 private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg) 6741 throws PackageManagerException { 6742 if (pkgSetting.signatures.mSignatures != null) { 6743 // Already existing package. Make sure signatures match 6744 boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures) 6745 == PackageManager.SIGNATURE_MATCH; 6746 if (!match) { 6747 match = compareSignaturesCompat(pkgSetting.signatures, pkg) 6748 == PackageManager.SIGNATURE_MATCH; 6749 } 6750 if (!match) { 6751 match = compareSignaturesRecover(pkgSetting.signatures, pkg) 6752 == PackageManager.SIGNATURE_MATCH; 6753 } 6754 if (!match) { 6755 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 6756 + pkg.packageName + " signatures do not match the " 6757 + "previously installed version; ignoring!"); 6758 } 6759 } 6760 6761 // Check for shared user signatures 6762 if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) { 6763 // Already existing package. Make sure signatures match 6764 boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 6765 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 6766 if (!match) { 6767 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg) 6768 == PackageManager.SIGNATURE_MATCH; 6769 } 6770 if (!match) { 6771 match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg) 6772 == PackageManager.SIGNATURE_MATCH; 6773 } 6774 if (!match) { 6775 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 6776 "Package " + pkg.packageName 6777 + " has no signatures that match those in shared user " 6778 + pkgSetting.sharedUser.name + "; ignoring!"); 6779 } 6780 } 6781 } 6782 6783 /** 6784 * Enforces that only the system UID or root's UID can call a method exposed 6785 * via Binder. 6786 * 6787 * @param message used as message if SecurityException is thrown 6788 * @throws SecurityException if the caller is not system or root 6789 */ 6790 private static final void enforceSystemOrRoot(String message) { 6791 final int uid = Binder.getCallingUid(); 6792 if (uid != Process.SYSTEM_UID && uid != 0) { 6793 throw new SecurityException(message); 6794 } 6795 } 6796 6797 @Override 6798 public void performFstrimIfNeeded() { 6799 enforceSystemOrRoot("Only the system can request fstrim"); 6800 6801 // Before everything else, see whether we need to fstrim. 6802 try { 6803 IMountService ms = PackageHelper.getMountService(); 6804 if (ms != null) { 6805 final boolean isUpgrade = isUpgrade(); 6806 boolean doTrim = isUpgrade; 6807 if (doTrim) { 6808 Slog.w(TAG, "Running disk maintenance immediately due to system update"); 6809 } else { 6810 final long interval = android.provider.Settings.Global.getLong( 6811 mContext.getContentResolver(), 6812 android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL, 6813 DEFAULT_MANDATORY_FSTRIM_INTERVAL); 6814 if (interval > 0) { 6815 final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance(); 6816 if (timeSinceLast > interval) { 6817 doTrim = true; 6818 Slog.w(TAG, "No disk maintenance in " + timeSinceLast 6819 + "; running immediately"); 6820 } 6821 } 6822 } 6823 if (doTrim) { 6824 if (!isFirstBoot()) { 6825 try { 6826 ActivityManagerNative.getDefault().showBootMessage( 6827 mContext.getResources().getString( 6828 R.string.android_upgrading_fstrim), true); 6829 } catch (RemoteException e) { 6830 } 6831 } 6832 ms.runMaintenance(); 6833 } 6834 } else { 6835 Slog.e(TAG, "Mount service unavailable!"); 6836 } 6837 } catch (RemoteException e) { 6838 // Can't happen; MountService is local 6839 } 6840 } 6841 6842 @Override 6843 public void extractPackagesIfNeeded() { 6844 enforceSystemOrRoot("Only the system can request package extraction"); 6845 6846 // Extract pacakges only if profile-guided compilation is enabled because 6847 // otherwise BackgroundDexOptService will not dexopt them later. 6848 if (!isUpgrade()) { 6849 return; 6850 } 6851 6852 List<PackageParser.Package> pkgs; 6853 synchronized (mPackages) { 6854 pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this); 6855 } 6856 6857 int curr = 0; 6858 int total = pkgs.size(); 6859 for (PackageParser.Package pkg : pkgs) { 6860 curr++; 6861 6862 if (DEBUG_DEXOPT) { 6863 Log.i(TAG, "Extracting app " + curr + " of " + total + ": " + pkg.packageName); 6864 } 6865 6866 if (!isFirstBoot()) { 6867 try { 6868 ActivityManagerNative.getDefault().showBootMessage( 6869 mContext.getResources().getString(R.string.android_upgrading_apk, 6870 curr, total), true); 6871 } catch (RemoteException e) { 6872 } 6873 } 6874 6875 if (PackageDexOptimizer.canOptimizePackage(pkg)) { 6876 performDexOpt(pkg.packageName, null /* instructionSet */, 6877 false /* useProfiles */, true /* extractOnly */, false /* force */); 6878 } 6879 } 6880 } 6881 6882 @Override 6883 public void notifyPackageUse(String packageName) { 6884 synchronized (mPackages) { 6885 PackageParser.Package p = mPackages.get(packageName); 6886 if (p == null) { 6887 return; 6888 } 6889 p.mLastPackageUsageTimeInMills = System.currentTimeMillis(); 6890 } 6891 } 6892 6893 // TODO: this is not used nor needed. Delete it. 6894 @Override 6895 public boolean performDexOptIfNeeded(String packageName, String instructionSet) { 6896 return performDexOptTraced(packageName, instructionSet, false /* useProfiles */, 6897 false /* extractOnly */, false /* force */); 6898 } 6899 6900 @Override 6901 public boolean performDexOpt(String packageName, String instructionSet, boolean useProfiles, 6902 boolean extractOnly, boolean force) { 6903 return performDexOptTraced(packageName, instructionSet, useProfiles, extractOnly, force); 6904 } 6905 6906 private boolean performDexOptTraced(String packageName, String instructionSet, 6907 boolean useProfiles, boolean extractOnly, boolean force) { 6908 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 6909 try { 6910 return performDexOptInternal(packageName, instructionSet, useProfiles, extractOnly, 6911 force); 6912 } finally { 6913 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6914 } 6915 } 6916 6917 private boolean performDexOptInternal(String packageName, String instructionSet, 6918 boolean useProfiles, boolean extractOnly, boolean force) { 6919 PackageParser.Package p; 6920 final String targetInstructionSet; 6921 synchronized (mPackages) { 6922 p = mPackages.get(packageName); 6923 if (p == null) { 6924 return false; 6925 } 6926 mPackageUsage.write(false); 6927 6928 targetInstructionSet = instructionSet != null ? instructionSet : 6929 getPrimaryInstructionSet(p.applicationInfo); 6930 } 6931 long callingId = Binder.clearCallingIdentity(); 6932 try { 6933 synchronized (mInstallLock) { 6934 final String[] instructionSets = new String[] { targetInstructionSet }; 6935 int result = performDexOptInternalWithDependenciesLI(p, instructionSets, 6936 useProfiles, extractOnly, force); 6937 return result == PackageDexOptimizer.DEX_OPT_PERFORMED; 6938 } 6939 } finally { 6940 Binder.restoreCallingIdentity(callingId); 6941 } 6942 } 6943 6944 public ArraySet<String> getOptimizablePackages() { 6945 ArraySet<String> pkgs = new ArraySet<String>(); 6946 synchronized (mPackages) { 6947 for (PackageParser.Package p : mPackages.values()) { 6948 if (PackageDexOptimizer.canOptimizePackage(p)) { 6949 pkgs.add(p.packageName); 6950 } 6951 } 6952 } 6953 return pkgs; 6954 } 6955 6956 private int performDexOptInternalWithDependenciesLI(PackageParser.Package p, 6957 String instructionSets[], boolean useProfiles, boolean extractOnly, boolean force) { 6958 // Select the dex optimizer based on the force parameter. 6959 // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to 6960 // allocate an object here. 6961 PackageDexOptimizer pdo = force 6962 ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer) 6963 : mPackageDexOptimizer; 6964 6965 // Optimize all dependencies first. Note: we ignore the return value and march on 6966 // on errors. 6967 Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p); 6968 if (!deps.isEmpty()) { 6969 for (PackageParser.Package depPackage : deps) { 6970 // TODO: Analyze and investigate if we (should) profile libraries. 6971 // Currently this will do a full compilation of the library. 6972 pdo.performDexOpt(depPackage, instructionSets, false /* useProfiles */, 6973 false /* extractOnly */); 6974 } 6975 } 6976 6977 return pdo.performDexOpt(p, instructionSets, useProfiles, extractOnly); 6978 } 6979 6980 Collection<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) { 6981 if (p.usesLibraries != null || p.usesOptionalLibraries != null) { 6982 ArrayList<PackageParser.Package> retValue = new ArrayList<>(); 6983 Set<String> collectedNames = new HashSet<>(); 6984 findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames); 6985 6986 retValue.remove(p); 6987 6988 return retValue; 6989 } else { 6990 return Collections.emptyList(); 6991 } 6992 } 6993 6994 private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p, 6995 Collection<PackageParser.Package> collected, Set<String> collectedNames) { 6996 if (!collectedNames.contains(p.packageName)) { 6997 collectedNames.add(p.packageName); 6998 collected.add(p); 6999 7000 if (p.usesLibraries != null) { 7001 findSharedNonSystemLibrariesRecursive(p.usesLibraries, collected, collectedNames); 7002 } 7003 if (p.usesOptionalLibraries != null) { 7004 findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries, collected, 7005 collectedNames); 7006 } 7007 } 7008 } 7009 7010 private void findSharedNonSystemLibrariesRecursive(Collection<String> libs, 7011 Collection<PackageParser.Package> collected, Set<String> collectedNames) { 7012 for (String libName : libs) { 7013 PackageParser.Package libPkg = findSharedNonSystemLibrary(libName); 7014 if (libPkg != null) { 7015 findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames); 7016 } 7017 } 7018 } 7019 7020 private PackageParser.Package findSharedNonSystemLibrary(String libName) { 7021 synchronized (mPackages) { 7022 PackageManagerService.SharedLibraryEntry lib = mSharedLibraries.get(libName); 7023 if (lib != null && lib.apk != null) { 7024 return mPackages.get(lib.apk); 7025 } 7026 } 7027 return null; 7028 } 7029 7030 public void shutdown() { 7031 mPackageUsage.write(true); 7032 } 7033 7034 @Override 7035 public void forceDexOpt(String packageName) { 7036 enforceSystemOrRoot("forceDexOpt"); 7037 7038 PackageParser.Package pkg; 7039 synchronized (mPackages) { 7040 pkg = mPackages.get(packageName); 7041 if (pkg == null) { 7042 throw new IllegalArgumentException("Unknown package: " + packageName); 7043 } 7044 } 7045 7046 synchronized (mInstallLock) { 7047 final String[] instructionSets = new String[] { 7048 getPrimaryInstructionSet(pkg.applicationInfo) }; 7049 7050 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 7051 7052 // Whoever is calling forceDexOpt wants a fully compiled package. 7053 // Don't use profiles since that may cause compilation to be skipped. 7054 final int res = performDexOptInternalWithDependenciesLI(pkg, instructionSets, 7055 false /* useProfiles */, false /* extractOnly */, true /* force */); 7056 7057 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7058 if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) { 7059 throw new IllegalStateException("Failed to dexopt: " + res); 7060 } 7061 } 7062 } 7063 7064 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) { 7065 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) { 7066 Slog.w(TAG, "Unable to update from " + oldPkg.name 7067 + " to " + newPkg.packageName 7068 + ": old package not in system partition"); 7069 return false; 7070 } else if (mPackages.get(oldPkg.name) != null) { 7071 Slog.w(TAG, "Unable to update from " + oldPkg.name 7072 + " to " + newPkg.packageName 7073 + ": old package still exists"); 7074 return false; 7075 } 7076 return true; 7077 } 7078 7079 private boolean removeDataDirsLI(String volumeUuid, String packageName) { 7080 // TODO: triage flags as part of 26466827 7081 final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE; 7082 7083 boolean res = true; 7084 final int[] users = sUserManager.getUserIds(); 7085 for (int user : users) { 7086 try { 7087 mInstaller.destroyAppData(volumeUuid, packageName, user, flags); 7088 } catch (InstallerException e) { 7089 Slog.w(TAG, "Failed to delete data directory", e); 7090 res = false; 7091 } 7092 } 7093 return res; 7094 } 7095 7096 void removeCodePathLI(File codePath) { 7097 if (codePath.isDirectory()) { 7098 try { 7099 mInstaller.rmPackageDir(codePath.getAbsolutePath()); 7100 } catch (InstallerException e) { 7101 Slog.w(TAG, "Failed to remove code path", e); 7102 } 7103 } else { 7104 codePath.delete(); 7105 } 7106 } 7107 7108 void destroyAppDataLI(String volumeUuid, String packageName, int userId, int flags) { 7109 try { 7110 mInstaller.destroyAppData(volumeUuid, packageName, userId, flags); 7111 } catch (InstallerException e) { 7112 Slog.w(TAG, "Failed to destroy app data", e); 7113 } 7114 } 7115 7116 void restoreconAppDataLI(String volumeUuid, String packageName, int userId, int flags, 7117 int appId, String seinfo) { 7118 try { 7119 mInstaller.restoreconAppData(volumeUuid, packageName, userId, flags, appId, seinfo); 7120 } catch (InstallerException e) { 7121 Slog.e(TAG, "Failed to restorecon for " + packageName + ": " + e); 7122 } 7123 } 7124 7125 private void deleteCodeCacheDirsLI(String volumeUuid, String packageName) { 7126 final PackageParser.Package pkg; 7127 synchronized (mPackages) { 7128 pkg = mPackages.get(packageName); 7129 } 7130 if (pkg == null) { 7131 Slog.w(TAG, "Failed to delete code cache directory. No package: " + packageName); 7132 return; 7133 } 7134 deleteCodeCacheDirsLI(pkg); 7135 } 7136 7137 private void deleteCodeCacheDirsLI(PackageParser.Package pkg) { 7138 // TODO: triage flags as part of 26466827 7139 final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE; 7140 7141 int[] users = sUserManager.getUserIds(); 7142 int res = 0; 7143 for (int user : users) { 7144 // Remove the parent code cache 7145 try { 7146 mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, user, 7147 flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 7148 } catch (InstallerException e) { 7149 Slog.w(TAG, "Failed to delete code cache directory", e); 7150 } 7151 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7152 for (int i = 0; i < childCount; i++) { 7153 PackageParser.Package childPkg = pkg.childPackages.get(i); 7154 // Remove the child code cache 7155 try { 7156 mInstaller.clearAppData(childPkg.volumeUuid, childPkg.packageName, 7157 user, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 7158 } catch (InstallerException e) { 7159 Slog.w(TAG, "Failed to delete code cache directory", e); 7160 } 7161 } 7162 } 7163 } 7164 7165 private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime, 7166 long lastUpdateTime) { 7167 // Set parent install/update time 7168 PackageSetting ps = (PackageSetting) pkg.mExtras; 7169 if (ps != null) { 7170 ps.firstInstallTime = firstInstallTime; 7171 ps.lastUpdateTime = lastUpdateTime; 7172 } 7173 // Set children install/update time 7174 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7175 for (int i = 0; i < childCount; i++) { 7176 PackageParser.Package childPkg = pkg.childPackages.get(i); 7177 ps = (PackageSetting) childPkg.mExtras; 7178 if (ps != null) { 7179 ps.firstInstallTime = firstInstallTime; 7180 ps.lastUpdateTime = lastUpdateTime; 7181 } 7182 } 7183 } 7184 7185 private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file, 7186 PackageParser.Package changingLib) { 7187 if (file.path != null) { 7188 usesLibraryFiles.add(file.path); 7189 return; 7190 } 7191 PackageParser.Package p = mPackages.get(file.apk); 7192 if (changingLib != null && changingLib.packageName.equals(file.apk)) { 7193 // If we are doing this while in the middle of updating a library apk, 7194 // then we need to make sure to use that new apk for determining the 7195 // dependencies here. (We haven't yet finished committing the new apk 7196 // to the package manager state.) 7197 if (p == null || p.packageName.equals(changingLib.packageName)) { 7198 p = changingLib; 7199 } 7200 } 7201 if (p != null) { 7202 usesLibraryFiles.addAll(p.getAllCodePaths()); 7203 } 7204 } 7205 7206 private void updateSharedLibrariesLPw(PackageParser.Package pkg, 7207 PackageParser.Package changingLib) throws PackageManagerException { 7208 if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) { 7209 final ArraySet<String> usesLibraryFiles = new ArraySet<>(); 7210 int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0; 7211 for (int i=0; i<N; i++) { 7212 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i)); 7213 if (file == null) { 7214 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, 7215 "Package " + pkg.packageName + " requires unavailable shared library " 7216 + pkg.usesLibraries.get(i) + "; failing!"); 7217 } 7218 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 7219 } 7220 N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0; 7221 for (int i=0; i<N; i++) { 7222 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i)); 7223 if (file == null) { 7224 Slog.w(TAG, "Package " + pkg.packageName 7225 + " desires unavailable shared library " 7226 + pkg.usesOptionalLibraries.get(i) + "; ignoring!"); 7227 } else { 7228 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 7229 } 7230 } 7231 N = usesLibraryFiles.size(); 7232 if (N > 0) { 7233 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]); 7234 } else { 7235 pkg.usesLibraryFiles = null; 7236 } 7237 } 7238 } 7239 7240 private static boolean hasString(List<String> list, List<String> which) { 7241 if (list == null) { 7242 return false; 7243 } 7244 for (int i=list.size()-1; i>=0; i--) { 7245 for (int j=which.size()-1; j>=0; j--) { 7246 if (which.get(j).equals(list.get(i))) { 7247 return true; 7248 } 7249 } 7250 } 7251 return false; 7252 } 7253 7254 private void updateAllSharedLibrariesLPw() { 7255 for (PackageParser.Package pkg : mPackages.values()) { 7256 try { 7257 updateSharedLibrariesLPw(pkg, null); 7258 } catch (PackageManagerException e) { 7259 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 7260 } 7261 } 7262 } 7263 7264 private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw( 7265 PackageParser.Package changingPkg) { 7266 ArrayList<PackageParser.Package> res = null; 7267 for (PackageParser.Package pkg : mPackages.values()) { 7268 if (hasString(pkg.usesLibraries, changingPkg.libraryNames) 7269 || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) { 7270 if (res == null) { 7271 res = new ArrayList<PackageParser.Package>(); 7272 } 7273 res.add(pkg); 7274 try { 7275 updateSharedLibrariesLPw(pkg, changingPkg); 7276 } catch (PackageManagerException e) { 7277 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 7278 } 7279 } 7280 } 7281 return res; 7282 } 7283 7284 /** 7285 * Derive the value of the {@code cpuAbiOverride} based on the provided 7286 * value and an optional stored value from the package settings. 7287 */ 7288 private static String deriveAbiOverride(String abiOverride, PackageSetting settings) { 7289 String cpuAbiOverride = null; 7290 7291 if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) { 7292 cpuAbiOverride = null; 7293 } else if (abiOverride != null) { 7294 cpuAbiOverride = abiOverride; 7295 } else if (settings != null) { 7296 cpuAbiOverride = settings.cpuAbiOverrideString; 7297 } 7298 7299 return cpuAbiOverride; 7300 } 7301 7302 private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg, int parseFlags, 7303 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 7304 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage"); 7305 // If the package has children and this is the first dive in the function 7306 // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see 7307 // whether all packages (parent and children) would be successfully scanned 7308 // before the actual scan since scanning mutates internal state and we want 7309 // to atomically install the package and its children. 7310 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 7311 if (pkg.childPackages != null && pkg.childPackages.size() > 0) { 7312 scanFlags |= SCAN_CHECK_ONLY; 7313 } 7314 } else { 7315 scanFlags &= ~SCAN_CHECK_ONLY; 7316 } 7317 7318 final PackageParser.Package scannedPkg; 7319 try { 7320 // Scan the parent 7321 scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags, currentTime, user); 7322 // Scan the children 7323 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7324 for (int i = 0; i < childCount; i++) { 7325 PackageParser.Package childPkg = pkg.childPackages.get(i); 7326 scanPackageLI(childPkg, parseFlags, 7327 scanFlags, currentTime, user); 7328 } 7329 } finally { 7330 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7331 } 7332 7333 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 7334 return scanPackageTracedLI(pkg, parseFlags, scanFlags, currentTime, user); 7335 } 7336 7337 return scannedPkg; 7338 } 7339 7340 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags, 7341 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 7342 boolean success = false; 7343 try { 7344 final PackageParser.Package res = scanPackageDirtyLI(pkg, parseFlags, scanFlags, 7345 currentTime, user); 7346 success = true; 7347 return res; 7348 } finally { 7349 if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) { 7350 removeDataDirsLI(pkg.volumeUuid, pkg.packageName); 7351 } 7352 } 7353 } 7354 7355 private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags, 7356 int scanFlags, long currentTime, UserHandle user) 7357 throws PackageManagerException { 7358 final File scanFile = new File(pkg.codePath); 7359 if (pkg.applicationInfo.getCodePath() == null || 7360 pkg.applicationInfo.getResourcePath() == null) { 7361 // Bail out. The resource and code paths haven't been set. 7362 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 7363 "Code and resource paths haven't been set correctly"); 7364 } 7365 7366 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 7367 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; 7368 } else { 7369 // Only allow system apps to be flagged as core apps. 7370 pkg.coreApp = false; 7371 } 7372 7373 if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) { 7374 pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 7375 } 7376 7377 if (mCustomResolverComponentName != null && 7378 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) { 7379 setUpCustomResolverActivity(pkg); 7380 } 7381 7382 if (pkg.packageName.equals("android")) { 7383 synchronized (mPackages) { 7384 if (mAndroidApplication != null) { 7385 Slog.w(TAG, "*************************************************"); 7386 Slog.w(TAG, "Core android package being redefined. Skipping."); 7387 Slog.w(TAG, " file=" + scanFile); 7388 Slog.w(TAG, "*************************************************"); 7389 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 7390 "Core android package being redefined. Skipping."); 7391 } 7392 7393 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 7394 // Set up information for our fall-back user intent resolution activity. 7395 mPlatformPackage = pkg; 7396 pkg.mVersionCode = mSdkVersion; 7397 mAndroidApplication = pkg.applicationInfo; 7398 7399 if (!mResolverReplaced) { 7400 mResolveActivity.applicationInfo = mAndroidApplication; 7401 mResolveActivity.name = ResolverActivity.class.getName(); 7402 mResolveActivity.packageName = mAndroidApplication.packageName; 7403 mResolveActivity.processName = "system:ui"; 7404 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 7405 mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER; 7406 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS; 7407 mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert; 7408 mResolveActivity.exported = true; 7409 mResolveActivity.enabled = true; 7410 mResolveInfo.activityInfo = mResolveActivity; 7411 mResolveInfo.priority = 0; 7412 mResolveInfo.preferredOrder = 0; 7413 mResolveInfo.match = 0; 7414 mResolveComponentName = new ComponentName( 7415 mAndroidApplication.packageName, mResolveActivity.name); 7416 } 7417 } 7418 } 7419 } 7420 7421 if (DEBUG_PACKAGE_SCANNING) { 7422 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 7423 Log.d(TAG, "Scanning package " + pkg.packageName); 7424 } 7425 7426 synchronized (mPackages) { 7427 if (mPackages.containsKey(pkg.packageName) 7428 || mSharedLibraries.containsKey(pkg.packageName)) { 7429 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 7430 "Application package " + pkg.packageName 7431 + " already installed. Skipping duplicate."); 7432 } 7433 7434 // If we're only installing presumed-existing packages, require that the 7435 // scanned APK is both already known and at the path previously established 7436 // for it. Previously unknown packages we pick up normally, but if we have an 7437 // a priori expectation about this package's install presence, enforce it. 7438 // With a singular exception for new system packages. When an OTA contains 7439 // a new system package, we allow the codepath to change from a system location 7440 // to the user-installed location. If we don't allow this change, any newer, 7441 // user-installed version of the application will be ignored. 7442 if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) { 7443 if (mExpectingBetter.containsKey(pkg.packageName)) { 7444 logCriticalInfo(Log.WARN, 7445 "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName); 7446 } else { 7447 PackageSetting known = mSettings.peekPackageLPr(pkg.packageName); 7448 if (known != null) { 7449 if (DEBUG_PACKAGE_SCANNING) { 7450 Log.d(TAG, "Examining " + pkg.codePath 7451 + " and requiring known paths " + known.codePathString 7452 + " & " + known.resourcePathString); 7453 } 7454 if (!pkg.applicationInfo.getCodePath().equals(known.codePathString) 7455 || !pkg.applicationInfo.getResourcePath().equals( 7456 known.resourcePathString)) { 7457 throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED, 7458 "Application package " + pkg.packageName 7459 + " found at " + pkg.applicationInfo.getCodePath() 7460 + " but expected at " + known.codePathString 7461 + "; ignoring."); 7462 } 7463 } 7464 } 7465 } 7466 } 7467 7468 // Initialize package source and resource directories 7469 File destCodeFile = new File(pkg.applicationInfo.getCodePath()); 7470 File destResourceFile = new File(pkg.applicationInfo.getResourcePath()); 7471 7472 SharedUserSetting suid = null; 7473 PackageSetting pkgSetting = null; 7474 7475 if (!isSystemApp(pkg)) { 7476 // Only system apps can use these features. 7477 pkg.mOriginalPackages = null; 7478 pkg.mRealPackage = null; 7479 pkg.mAdoptPermissions = null; 7480 } 7481 7482 // Getting the package setting may have a side-effect, so if we 7483 // are only checking if scan would succeed, stash a copy of the 7484 // old setting to restore at the end. 7485 PackageSetting nonMutatedPs = null; 7486 7487 // writer 7488 synchronized (mPackages) { 7489 if (pkg.mSharedUserId != null) { 7490 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, true); 7491 if (suid == null) { 7492 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 7493 "Creating application package " + pkg.packageName 7494 + " for shared user failed"); 7495 } 7496 if (DEBUG_PACKAGE_SCANNING) { 7497 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 7498 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId 7499 + "): packages=" + suid.packages); 7500 } 7501 } 7502 7503 // Check if we are renaming from an original package name. 7504 PackageSetting origPackage = null; 7505 String realName = null; 7506 if (pkg.mOriginalPackages != null) { 7507 // This package may need to be renamed to a previously 7508 // installed name. Let's check on that... 7509 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage); 7510 if (pkg.mOriginalPackages.contains(renamed)) { 7511 // This package had originally been installed as the 7512 // original name, and we have already taken care of 7513 // transitioning to the new one. Just update the new 7514 // one to continue using the old name. 7515 realName = pkg.mRealPackage; 7516 if (!pkg.packageName.equals(renamed)) { 7517 // Callers into this function may have already taken 7518 // care of renaming the package; only do it here if 7519 // it is not already done. 7520 pkg.setPackageName(renamed); 7521 } 7522 7523 } else { 7524 for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) { 7525 if ((origPackage = mSettings.peekPackageLPr( 7526 pkg.mOriginalPackages.get(i))) != null) { 7527 // We do have the package already installed under its 7528 // original name... should we use it? 7529 if (!verifyPackageUpdateLPr(origPackage, pkg)) { 7530 // New package is not compatible with original. 7531 origPackage = null; 7532 continue; 7533 } else if (origPackage.sharedUser != null) { 7534 // Make sure uid is compatible between packages. 7535 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) { 7536 Slog.w(TAG, "Unable to migrate data from " + origPackage.name 7537 + " to " + pkg.packageName + ": old uid " 7538 + origPackage.sharedUser.name 7539 + " differs from " + pkg.mSharedUserId); 7540 origPackage = null; 7541 continue; 7542 } 7543 } else { 7544 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package " 7545 + pkg.packageName + " to old name " + origPackage.name); 7546 } 7547 break; 7548 } 7549 } 7550 } 7551 } 7552 7553 if (mTransferedPackages.contains(pkg.packageName)) { 7554 Slog.w(TAG, "Package " + pkg.packageName 7555 + " was transferred to another, but its .apk remains"); 7556 } 7557 7558 // See comments in nonMutatedPs declaration 7559 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 7560 PackageSetting foundPs = mSettings.peekPackageLPr(pkg.packageName); 7561 if (foundPs != null) { 7562 nonMutatedPs = new PackageSetting(foundPs); 7563 } 7564 } 7565 7566 // Just create the setting, don't add it yet. For already existing packages 7567 // the PkgSetting exists already and doesn't have to be created. 7568 pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile, 7569 destResourceFile, pkg.applicationInfo.nativeLibraryRootDir, 7570 pkg.applicationInfo.primaryCpuAbi, 7571 pkg.applicationInfo.secondaryCpuAbi, 7572 pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, 7573 user, false); 7574 if (pkgSetting == null) { 7575 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 7576 "Creating application package " + pkg.packageName + " failed"); 7577 } 7578 7579 if (pkgSetting.origPackage != null) { 7580 // If we are first transitioning from an original package, 7581 // fix up the new package's name now. We need to do this after 7582 // looking up the package under its new name, so getPackageLP 7583 // can take care of fiddling things correctly. 7584 pkg.setPackageName(origPackage.name); 7585 7586 // File a report about this. 7587 String msg = "New package " + pkgSetting.realName 7588 + " renamed to replace old package " + pkgSetting.name; 7589 reportSettingsProblem(Log.WARN, msg); 7590 7591 // Make a note of it. 7592 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 7593 mTransferedPackages.add(origPackage.name); 7594 } 7595 7596 // No longer need to retain this. 7597 pkgSetting.origPackage = null; 7598 } 7599 7600 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) { 7601 // Make a note of it. 7602 mTransferedPackages.add(pkg.packageName); 7603 } 7604 7605 if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) { 7606 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 7607 } 7608 7609 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 7610 // Check all shared libraries and map to their actual file path. 7611 // We only do this here for apps not on a system dir, because those 7612 // are the only ones that can fail an install due to this. We 7613 // will take care of the system apps by updating all of their 7614 // library paths after the scan is done. 7615 updateSharedLibrariesLPw(pkg, null); 7616 } 7617 7618 if (mFoundPolicyFile) { 7619 SELinuxMMAC.assignSeinfoValue(pkg); 7620 } 7621 7622 pkg.applicationInfo.uid = pkgSetting.appId; 7623 pkg.mExtras = pkgSetting; 7624 if (shouldCheckUpgradeKeySetLP(pkgSetting, scanFlags)) { 7625 if (checkUpgradeKeySetLP(pkgSetting, pkg)) { 7626 // We just determined the app is signed correctly, so bring 7627 // over the latest parsed certs. 7628 pkgSetting.signatures.mSignatures = pkg.mSignatures; 7629 } else { 7630 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 7631 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 7632 "Package " + pkg.packageName + " upgrade keys do not match the " 7633 + "previously installed version"); 7634 } else { 7635 pkgSetting.signatures.mSignatures = pkg.mSignatures; 7636 String msg = "System package " + pkg.packageName 7637 + " signature changed; retaining data."; 7638 reportSettingsProblem(Log.WARN, msg); 7639 } 7640 } 7641 } else { 7642 try { 7643 verifySignaturesLP(pkgSetting, pkg); 7644 // We just determined the app is signed correctly, so bring 7645 // over the latest parsed certs. 7646 pkgSetting.signatures.mSignatures = pkg.mSignatures; 7647 } catch (PackageManagerException e) { 7648 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 7649 throw e; 7650 } 7651 // The signature has changed, but this package is in the system 7652 // image... let's recover! 7653 pkgSetting.signatures.mSignatures = pkg.mSignatures; 7654 // However... if this package is part of a shared user, but it 7655 // doesn't match the signature of the shared user, let's fail. 7656 // What this means is that you can't change the signatures 7657 // associated with an overall shared user, which doesn't seem all 7658 // that unreasonable. 7659 if (pkgSetting.sharedUser != null) { 7660 if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 7661 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { 7662 throw new PackageManagerException( 7663 INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES, 7664 "Signature mismatch for shared user: " 7665 + pkgSetting.sharedUser); 7666 } 7667 } 7668 // File a report about this. 7669 String msg = "System package " + pkg.packageName 7670 + " signature changed; retaining data."; 7671 reportSettingsProblem(Log.WARN, msg); 7672 } 7673 } 7674 // Verify that this new package doesn't have any content providers 7675 // that conflict with existing packages. Only do this if the 7676 // package isn't already installed, since we don't want to break 7677 // things that are installed. 7678 if ((scanFlags & SCAN_NEW_INSTALL) != 0) { 7679 final int N = pkg.providers.size(); 7680 int i; 7681 for (i=0; i<N; i++) { 7682 PackageParser.Provider p = pkg.providers.get(i); 7683 if (p.info.authority != null) { 7684 String names[] = p.info.authority.split(";"); 7685 for (int j = 0; j < names.length; j++) { 7686 if (mProvidersByAuthority.containsKey(names[j])) { 7687 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 7688 final String otherPackageName = 7689 ((other != null && other.getComponentName() != null) ? 7690 other.getComponentName().getPackageName() : "?"); 7691 throw new PackageManagerException( 7692 INSTALL_FAILED_CONFLICTING_PROVIDER, 7693 "Can't install because provider name " + names[j] 7694 + " (in package " + pkg.applicationInfo.packageName 7695 + ") is already used by " + otherPackageName); 7696 } 7697 } 7698 } 7699 } 7700 } 7701 7702 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) { 7703 // This package wants to adopt ownership of permissions from 7704 // another package. 7705 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) { 7706 final String origName = pkg.mAdoptPermissions.get(i); 7707 final PackageSetting orig = mSettings.peekPackageLPr(origName); 7708 if (orig != null) { 7709 if (verifyPackageUpdateLPr(orig, pkg)) { 7710 Slog.i(TAG, "Adopting permissions from " + origName + " to " 7711 + pkg.packageName); 7712 mSettings.transferPermissionsLPw(origName, pkg.packageName); 7713 } 7714 } 7715 } 7716 } 7717 } 7718 7719 final String pkgName = pkg.packageName; 7720 7721 final long scanFileTime = scanFile.lastModified(); 7722 final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0; 7723 pkg.applicationInfo.processName = fixProcessName( 7724 pkg.applicationInfo.packageName, 7725 pkg.applicationInfo.processName, 7726 pkg.applicationInfo.uid); 7727 7728 if (pkg != mPlatformPackage) { 7729 // Get all of our default paths setup 7730 pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM); 7731 } 7732 7733 final String path = scanFile.getPath(); 7734 final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting); 7735 7736 if ((scanFlags & SCAN_NEW_INSTALL) == 0) { 7737 derivePackageAbi(pkg, scanFile, cpuAbiOverride, true /* extract libs */); 7738 7739 // Some system apps still use directory structure for native libraries 7740 // in which case we might end up not detecting abi solely based on apk 7741 // structure. Try to detect abi based on directory structure. 7742 if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() && 7743 pkg.applicationInfo.primaryCpuAbi == null) { 7744 setBundledAppAbisAndRoots(pkg, pkgSetting); 7745 setNativeLibraryPaths(pkg); 7746 } 7747 7748 } else { 7749 if ((scanFlags & SCAN_MOVE) != 0) { 7750 // We haven't run dex-opt for this move (since we've moved the compiled output too) 7751 // but we already have this packages package info in the PackageSetting. We just 7752 // use that and derive the native library path based on the new codepath. 7753 pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString; 7754 pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString; 7755 } 7756 7757 // Set native library paths again. For moves, the path will be updated based on the 7758 // ABIs we've determined above. For non-moves, the path will be updated based on the 7759 // ABIs we determined during compilation, but the path will depend on the final 7760 // package path (after the rename away from the stage path). 7761 setNativeLibraryPaths(pkg); 7762 } 7763 7764 // This is a special case for the "system" package, where the ABI is 7765 // dictated by the zygote configuration (and init.rc). We should keep track 7766 // of this ABI so that we can deal with "normal" applications that run under 7767 // the same UID correctly. 7768 if (mPlatformPackage == pkg) { 7769 pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ? 7770 Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]; 7771 } 7772 7773 // If there's a mismatch between the abi-override in the package setting 7774 // and the abiOverride specified for the install. Warn about this because we 7775 // would've already compiled the app without taking the package setting into 7776 // account. 7777 if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) { 7778 if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) { 7779 Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride + 7780 " for package " + pkg.packageName); 7781 } 7782 } 7783 7784 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 7785 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 7786 pkgSetting.cpuAbiOverrideString = cpuAbiOverride; 7787 7788 // Copy the derived override back to the parsed package, so that we can 7789 // update the package settings accordingly. 7790 pkg.cpuAbiOverride = cpuAbiOverride; 7791 7792 if (DEBUG_ABI_SELECTION) { 7793 Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName 7794 + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa=" 7795 + pkg.applicationInfo.nativeLibraryRootRequiresIsa); 7796 } 7797 7798 // Push the derived path down into PackageSettings so we know what to 7799 // clean up at uninstall time. 7800 pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir; 7801 7802 if (DEBUG_ABI_SELECTION) { 7803 Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" + 7804 " primary=" + pkg.applicationInfo.primaryCpuAbi + 7805 " secondary=" + pkg.applicationInfo.secondaryCpuAbi); 7806 } 7807 7808 if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) { 7809 // We don't do this here during boot because we can do it all 7810 // at once after scanning all existing packages. 7811 // 7812 // We also do this *before* we perform dexopt on this package, so that 7813 // we can avoid redundant dexopts, and also to make sure we've got the 7814 // code and package path correct. 7815 adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, 7816 pkg, true /* boot complete */); 7817 } 7818 7819 if (mFactoryTest && pkg.requestedPermissions.contains( 7820 android.Manifest.permission.FACTORY_TEST)) { 7821 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST; 7822 } 7823 7824 ArrayList<PackageParser.Package> clientLibPkgs = null; 7825 7826 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 7827 if (nonMutatedPs != null) { 7828 synchronized (mPackages) { 7829 mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs); 7830 } 7831 } 7832 return pkg; 7833 } 7834 7835 // Only privileged apps and updated privileged apps can add child packages. 7836 if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) { 7837 if ((parseFlags & PARSE_IS_PRIVILEGED) == 0) { 7838 throw new PackageManagerException("Only privileged apps and updated " 7839 + "privileged apps can add child packages. Ignoring package " 7840 + pkg.packageName); 7841 } 7842 final int childCount = pkg.childPackages.size(); 7843 for (int i = 0; i < childCount; i++) { 7844 PackageParser.Package childPkg = pkg.childPackages.get(i); 7845 if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName, 7846 childPkg.packageName)) { 7847 throw new PackageManagerException("Cannot override a child package of " 7848 + "another disabled system app. Ignoring package " + pkg.packageName); 7849 } 7850 } 7851 } 7852 7853 // writer 7854 synchronized (mPackages) { 7855 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 7856 // Only system apps can add new shared libraries. 7857 if (pkg.libraryNames != null) { 7858 for (int i=0; i<pkg.libraryNames.size(); i++) { 7859 String name = pkg.libraryNames.get(i); 7860 boolean allowed = false; 7861 if (pkg.isUpdatedSystemApp()) { 7862 // New library entries can only be added through the 7863 // system image. This is important to get rid of a lot 7864 // of nasty edge cases: for example if we allowed a non- 7865 // system update of the app to add a library, then uninstalling 7866 // the update would make the library go away, and assumptions 7867 // we made such as through app install filtering would now 7868 // have allowed apps on the device which aren't compatible 7869 // with it. Better to just have the restriction here, be 7870 // conservative, and create many fewer cases that can negatively 7871 // impact the user experience. 7872 final PackageSetting sysPs = mSettings 7873 .getDisabledSystemPkgLPr(pkg.packageName); 7874 if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) { 7875 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) { 7876 if (name.equals(sysPs.pkg.libraryNames.get(j))) { 7877 allowed = true; 7878 break; 7879 } 7880 } 7881 } 7882 } else { 7883 allowed = true; 7884 } 7885 if (allowed) { 7886 if (!mSharedLibraries.containsKey(name)) { 7887 mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName)); 7888 } else if (!name.equals(pkg.packageName)) { 7889 Slog.w(TAG, "Package " + pkg.packageName + " library " 7890 + name + " already exists; skipping"); 7891 } 7892 } else { 7893 Slog.w(TAG, "Package " + pkg.packageName + " declares lib " 7894 + name + " that is not declared on system image; skipping"); 7895 } 7896 } 7897 if ((scanFlags & SCAN_BOOTING) == 0) { 7898 // If we are not booting, we need to update any applications 7899 // that are clients of our shared library. If we are booting, 7900 // this will all be done once the scan is complete. 7901 clientLibPkgs = updateAllSharedLibrariesLPw(pkg); 7902 } 7903 } 7904 } 7905 } 7906 7907 // Request the ActivityManager to kill the process(only for existing packages) 7908 // so that we do not end up in a confused state while the user is still using the older 7909 // version of the application while the new one gets installed. 7910 final boolean isReplacing = (scanFlags & SCAN_REPLACING) != 0; 7911 final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0; 7912 if (killApp) { 7913 if (isReplacing) { 7914 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "killApplication"); 7915 7916 killApplication(pkg.applicationInfo.packageName, 7917 pkg.applicationInfo.uid, "replace pkg"); 7918 7919 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7920 } 7921 } 7922 7923 // Also need to kill any apps that are dependent on the library. 7924 if (clientLibPkgs != null) { 7925 for (int i=0; i<clientLibPkgs.size(); i++) { 7926 PackageParser.Package clientPkg = clientLibPkgs.get(i); 7927 killApplication(clientPkg.applicationInfo.packageName, 7928 clientPkg.applicationInfo.uid, "update lib"); 7929 } 7930 } 7931 7932 // Make sure we're not adding any bogus keyset info 7933 KeySetManagerService ksms = mSettings.mKeySetManagerService; 7934 ksms.assertScannedPackageValid(pkg); 7935 7936 // writer 7937 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 7938 7939 boolean createIdmapFailed = false; 7940 synchronized (mPackages) { 7941 // We don't expect installation to fail beyond this point 7942 7943 // Add the new setting to mSettings 7944 mSettings.insertPackageSettingLPw(pkgSetting, pkg); 7945 // Add the new setting to mPackages 7946 mPackages.put(pkg.applicationInfo.packageName, pkg); 7947 // Make sure we don't accidentally delete its data. 7948 final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator(); 7949 while (iter.hasNext()) { 7950 PackageCleanItem item = iter.next(); 7951 if (pkgName.equals(item.packageName)) { 7952 iter.remove(); 7953 } 7954 } 7955 7956 // Take care of first install / last update times. 7957 if (currentTime != 0) { 7958 if (pkgSetting.firstInstallTime == 0) { 7959 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime; 7960 } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) { 7961 pkgSetting.lastUpdateTime = currentTime; 7962 } 7963 } else if (pkgSetting.firstInstallTime == 0) { 7964 // We need *something*. Take time time stamp of the file. 7965 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime; 7966 } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) { 7967 if (scanFileTime != pkgSetting.timeStamp) { 7968 // A package on the system image has changed; consider this 7969 // to be an update. 7970 pkgSetting.lastUpdateTime = scanFileTime; 7971 } 7972 } 7973 7974 // Add the package's KeySets to the global KeySetManagerService 7975 ksms.addScannedPackageLPw(pkg); 7976 7977 int N = pkg.providers.size(); 7978 StringBuilder r = null; 7979 int i; 7980 for (i=0; i<N; i++) { 7981 PackageParser.Provider p = pkg.providers.get(i); 7982 p.info.processName = fixProcessName(pkg.applicationInfo.processName, 7983 p.info.processName, pkg.applicationInfo.uid); 7984 mProviders.addProvider(p); 7985 p.syncable = p.info.isSyncable; 7986 if (p.info.authority != null) { 7987 String names[] = p.info.authority.split(";"); 7988 p.info.authority = null; 7989 for (int j = 0; j < names.length; j++) { 7990 if (j == 1 && p.syncable) { 7991 // We only want the first authority for a provider to possibly be 7992 // syncable, so if we already added this provider using a different 7993 // authority clear the syncable flag. We copy the provider before 7994 // changing it because the mProviders object contains a reference 7995 // to a provider that we don't want to change. 7996 // Only do this for the second authority since the resulting provider 7997 // object can be the same for all future authorities for this provider. 7998 p = new PackageParser.Provider(p); 7999 p.syncable = false; 8000 } 8001 if (!mProvidersByAuthority.containsKey(names[j])) { 8002 mProvidersByAuthority.put(names[j], p); 8003 if (p.info.authority == null) { 8004 p.info.authority = names[j]; 8005 } else { 8006 p.info.authority = p.info.authority + ";" + names[j]; 8007 } 8008 if (DEBUG_PACKAGE_SCANNING) { 8009 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 8010 Log.d(TAG, "Registered content provider: " + names[j] 8011 + ", className = " + p.info.name + ", isSyncable = " 8012 + p.info.isSyncable); 8013 } 8014 } else { 8015 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 8016 Slog.w(TAG, "Skipping provider name " + names[j] + 8017 " (in package " + pkg.applicationInfo.packageName + 8018 "): name already used by " 8019 + ((other != null && other.getComponentName() != null) 8020 ? other.getComponentName().getPackageName() : "?")); 8021 } 8022 } 8023 } 8024 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8025 if (r == null) { 8026 r = new StringBuilder(256); 8027 } else { 8028 r.append(' '); 8029 } 8030 r.append(p.info.name); 8031 } 8032 } 8033 if (r != null) { 8034 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r); 8035 } 8036 8037 N = pkg.services.size(); 8038 r = null; 8039 for (i=0; i<N; i++) { 8040 PackageParser.Service s = pkg.services.get(i); 8041 s.info.processName = fixProcessName(pkg.applicationInfo.processName, 8042 s.info.processName, pkg.applicationInfo.uid); 8043 mServices.addService(s); 8044 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8045 if (r == null) { 8046 r = new StringBuilder(256); 8047 } else { 8048 r.append(' '); 8049 } 8050 r.append(s.info.name); 8051 } 8052 } 8053 if (r != null) { 8054 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r); 8055 } 8056 8057 N = pkg.receivers.size(); 8058 r = null; 8059 for (i=0; i<N; i++) { 8060 PackageParser.Activity a = pkg.receivers.get(i); 8061 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 8062 a.info.processName, pkg.applicationInfo.uid); 8063 mReceivers.addActivity(a, "receiver"); 8064 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8065 if (r == null) { 8066 r = new StringBuilder(256); 8067 } else { 8068 r.append(' '); 8069 } 8070 r.append(a.info.name); 8071 } 8072 } 8073 if (r != null) { 8074 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r); 8075 } 8076 8077 N = pkg.activities.size(); 8078 r = null; 8079 for (i=0; i<N; i++) { 8080 PackageParser.Activity a = pkg.activities.get(i); 8081 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 8082 a.info.processName, pkg.applicationInfo.uid); 8083 mActivities.addActivity(a, "activity"); 8084 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8085 if (r == null) { 8086 r = new StringBuilder(256); 8087 } else { 8088 r.append(' '); 8089 } 8090 r.append(a.info.name); 8091 } 8092 } 8093 if (r != null) { 8094 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r); 8095 } 8096 8097 N = pkg.permissionGroups.size(); 8098 r = null; 8099 for (i=0; i<N; i++) { 8100 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i); 8101 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name); 8102 if (cur == null) { 8103 mPermissionGroups.put(pg.info.name, pg); 8104 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8105 if (r == null) { 8106 r = new StringBuilder(256); 8107 } else { 8108 r.append(' '); 8109 } 8110 r.append(pg.info.name); 8111 } 8112 } else { 8113 Slog.w(TAG, "Permission group " + pg.info.name + " from package " 8114 + pg.info.packageName + " ignored: original from " 8115 + cur.info.packageName); 8116 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8117 if (r == null) { 8118 r = new StringBuilder(256); 8119 } else { 8120 r.append(' '); 8121 } 8122 r.append("DUP:"); 8123 r.append(pg.info.name); 8124 } 8125 } 8126 } 8127 if (r != null) { 8128 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permission Groups: " + r); 8129 } 8130 8131 N = pkg.permissions.size(); 8132 r = null; 8133 for (i=0; i<N; i++) { 8134 PackageParser.Permission p = pkg.permissions.get(i); 8135 8136 // Assume by default that we did not install this permission into the system. 8137 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED; 8138 8139 // Now that permission groups have a special meaning, we ignore permission 8140 // groups for legacy apps to prevent unexpected behavior. In particular, 8141 // permissions for one app being granted to someone just becase they happen 8142 // to be in a group defined by another app (before this had no implications). 8143 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) { 8144 p.group = mPermissionGroups.get(p.info.group); 8145 // Warn for a permission in an unknown group. 8146 if (p.info.group != null && p.group == null) { 8147 Slog.w(TAG, "Permission " + p.info.name + " from package " 8148 + p.info.packageName + " in an unknown group " + p.info.group); 8149 } 8150 } 8151 8152 ArrayMap<String, BasePermission> permissionMap = 8153 p.tree ? mSettings.mPermissionTrees 8154 : mSettings.mPermissions; 8155 BasePermission bp = permissionMap.get(p.info.name); 8156 8157 // Allow system apps to redefine non-system permissions 8158 if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) { 8159 final boolean currentOwnerIsSystem = (bp.perm != null 8160 && isSystemApp(bp.perm.owner)); 8161 if (isSystemApp(p.owner)) { 8162 if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) { 8163 // It's a built-in permission and no owner, take ownership now 8164 bp.packageSetting = pkgSetting; 8165 bp.perm = p; 8166 bp.uid = pkg.applicationInfo.uid; 8167 bp.sourcePackage = p.info.packageName; 8168 p.info.flags |= PermissionInfo.FLAG_INSTALLED; 8169 } else if (!currentOwnerIsSystem) { 8170 String msg = "New decl " + p.owner + " of permission " 8171 + p.info.name + " is system; overriding " + bp.sourcePackage; 8172 reportSettingsProblem(Log.WARN, msg); 8173 bp = null; 8174 } 8175 } 8176 } 8177 8178 if (bp == null) { 8179 bp = new BasePermission(p.info.name, p.info.packageName, 8180 BasePermission.TYPE_NORMAL); 8181 permissionMap.put(p.info.name, bp); 8182 } 8183 8184 if (bp.perm == null) { 8185 if (bp.sourcePackage == null 8186 || bp.sourcePackage.equals(p.info.packageName)) { 8187 BasePermission tree = findPermissionTreeLP(p.info.name); 8188 if (tree == null 8189 || tree.sourcePackage.equals(p.info.packageName)) { 8190 bp.packageSetting = pkgSetting; 8191 bp.perm = p; 8192 bp.uid = pkg.applicationInfo.uid; 8193 bp.sourcePackage = p.info.packageName; 8194 p.info.flags |= PermissionInfo.FLAG_INSTALLED; 8195 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8196 if (r == null) { 8197 r = new StringBuilder(256); 8198 } else { 8199 r.append(' '); 8200 } 8201 r.append(p.info.name); 8202 } 8203 } else { 8204 Slog.w(TAG, "Permission " + p.info.name + " from package " 8205 + p.info.packageName + " ignored: base tree " 8206 + tree.name + " is from package " 8207 + tree.sourcePackage); 8208 } 8209 } else { 8210 Slog.w(TAG, "Permission " + p.info.name + " from package " 8211 + p.info.packageName + " ignored: original from " 8212 + bp.sourcePackage); 8213 } 8214 } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8215 if (r == null) { 8216 r = new StringBuilder(256); 8217 } else { 8218 r.append(' '); 8219 } 8220 r.append("DUP:"); 8221 r.append(p.info.name); 8222 } 8223 if (bp.perm == p) { 8224 bp.protectionLevel = p.info.protectionLevel; 8225 } 8226 } 8227 8228 if (r != null) { 8229 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permissions: " + r); 8230 } 8231 8232 N = pkg.instrumentation.size(); 8233 r = null; 8234 for (i=0; i<N; i++) { 8235 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 8236 a.info.packageName = pkg.applicationInfo.packageName; 8237 a.info.sourceDir = pkg.applicationInfo.sourceDir; 8238 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir; 8239 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs; 8240 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs; 8241 a.info.dataDir = pkg.applicationInfo.dataDir; 8242 a.info.deviceEncryptedDataDir = pkg.applicationInfo.deviceEncryptedDataDir; 8243 a.info.credentialEncryptedDataDir = pkg.applicationInfo.credentialEncryptedDataDir; 8244 8245 // TODO: Update instrumentation.nativeLibraryDir as well ? Does it 8246 // need other information about the application, like the ABI and what not ? 8247 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir; 8248 mInstrumentation.put(a.getComponentName(), a); 8249 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8250 if (r == null) { 8251 r = new StringBuilder(256); 8252 } else { 8253 r.append(' '); 8254 } 8255 r.append(a.info.name); 8256 } 8257 } 8258 if (r != null) { 8259 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r); 8260 } 8261 8262 if (pkg.protectedBroadcasts != null) { 8263 N = pkg.protectedBroadcasts.size(); 8264 for (i=0; i<N; i++) { 8265 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i)); 8266 } 8267 } 8268 8269 pkgSetting.setTimeStamp(scanFileTime); 8270 8271 // Create idmap files for pairs of (packages, overlay packages). 8272 // Note: "android", ie framework-res.apk, is handled by native layers. 8273 if (pkg.mOverlayTarget != null) { 8274 // This is an overlay package. 8275 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) { 8276 if (!mOverlays.containsKey(pkg.mOverlayTarget)) { 8277 mOverlays.put(pkg.mOverlayTarget, 8278 new ArrayMap<String, PackageParser.Package>()); 8279 } 8280 ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget); 8281 map.put(pkg.packageName, pkg); 8282 PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget); 8283 if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) { 8284 createIdmapFailed = true; 8285 } 8286 } 8287 } else if (mOverlays.containsKey(pkg.packageName) && 8288 !pkg.packageName.equals("android")) { 8289 // This is a regular package, with one or more known overlay packages. 8290 createIdmapsForPackageLI(pkg); 8291 } 8292 } 8293 8294 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 8295 8296 if (createIdmapFailed) { 8297 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 8298 "scanPackageLI failed to createIdmap"); 8299 } 8300 return pkg; 8301 } 8302 8303 /** 8304 * Derive the ABI of a non-system package located at {@code scanFile}. This information 8305 * is derived purely on the basis of the contents of {@code scanFile} and 8306 * {@code cpuAbiOverride}. 8307 * 8308 * If {@code extractLibs} is true, native libraries are extracted from the app if required. 8309 */ 8310 private void derivePackageAbi(PackageParser.Package pkg, File scanFile, 8311 String cpuAbiOverride, boolean extractLibs) 8312 throws PackageManagerException { 8313 // TODO: We can probably be smarter about this stuff. For installed apps, 8314 // we can calculate this information at install time once and for all. For 8315 // system apps, we can probably assume that this information doesn't change 8316 // after the first boot scan. As things stand, we do lots of unnecessary work. 8317 8318 // Give ourselves some initial paths; we'll come back for another 8319 // pass once we've determined ABI below. 8320 setNativeLibraryPaths(pkg); 8321 8322 // We would never need to extract libs for forward-locked and external packages, 8323 // since the container service will do it for us. We shouldn't attempt to 8324 // extract libs from system app when it was not updated. 8325 if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() || 8326 (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) { 8327 extractLibs = false; 8328 } 8329 8330 final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir; 8331 final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa; 8332 8333 NativeLibraryHelper.Handle handle = null; 8334 try { 8335 handle = NativeLibraryHelper.Handle.create(pkg); 8336 // TODO(multiArch): This can be null for apps that didn't go through the 8337 // usual installation process. We can calculate it again, like we 8338 // do during install time. 8339 // 8340 // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally 8341 // unnecessary. 8342 final File nativeLibraryRoot = new File(nativeLibraryRootStr); 8343 8344 // Null out the abis so that they can be recalculated. 8345 pkg.applicationInfo.primaryCpuAbi = null; 8346 pkg.applicationInfo.secondaryCpuAbi = null; 8347 if (isMultiArch(pkg.applicationInfo)) { 8348 // Warn if we've set an abiOverride for multi-lib packages.. 8349 // By definition, we need to copy both 32 and 64 bit libraries for 8350 // such packages. 8351 if (pkg.cpuAbiOverride != null 8352 && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) { 8353 Slog.w(TAG, "Ignoring abiOverride for multi arch application."); 8354 } 8355 8356 int abi32 = PackageManager.NO_NATIVE_LIBRARIES; 8357 int abi64 = PackageManager.NO_NATIVE_LIBRARIES; 8358 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) { 8359 if (extractLibs) { 8360 abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 8361 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS, 8362 useIsaSpecificSubdirs); 8363 } else { 8364 abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS); 8365 } 8366 } 8367 8368 maybeThrowExceptionForMultiArchCopy( 8369 "Error unpackaging 32 bit native libs for multiarch app.", abi32); 8370 8371 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) { 8372 if (extractLibs) { 8373 abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 8374 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS, 8375 useIsaSpecificSubdirs); 8376 } else { 8377 abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS); 8378 } 8379 } 8380 8381 maybeThrowExceptionForMultiArchCopy( 8382 "Error unpackaging 64 bit native libs for multiarch app.", abi64); 8383 8384 if (abi64 >= 0) { 8385 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64]; 8386 } 8387 8388 if (abi32 >= 0) { 8389 final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32]; 8390 if (abi64 >= 0) { 8391 if (cpuAbiOverride == null && pkg.use32bitAbi) { 8392 pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi; 8393 pkg.applicationInfo.primaryCpuAbi = abi; 8394 } else { 8395 pkg.applicationInfo.secondaryCpuAbi = abi; 8396 } 8397 } else { 8398 pkg.applicationInfo.primaryCpuAbi = abi; 8399 } 8400 } 8401 8402 } else { 8403 String[] abiList = (cpuAbiOverride != null) ? 8404 new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS; 8405 8406 // Enable gross and lame hacks for apps that are built with old 8407 // SDK tools. We must scan their APKs for renderscript bitcode and 8408 // not launch them if it's present. Don't bother checking on devices 8409 // that don't have 64 bit support. 8410 boolean needsRenderScriptOverride = false; 8411 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null && 8412 NativeLibraryHelper.hasRenderscriptBitcode(handle)) { 8413 abiList = Build.SUPPORTED_32_BIT_ABIS; 8414 needsRenderScriptOverride = true; 8415 } 8416 8417 final int copyRet; 8418 if (extractLibs) { 8419 copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 8420 nativeLibraryRoot, abiList, useIsaSpecificSubdirs); 8421 } else { 8422 copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList); 8423 } 8424 8425 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { 8426 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, 8427 "Error unpackaging native libs for app, errorCode=" + copyRet); 8428 } 8429 8430 if (copyRet >= 0) { 8431 pkg.applicationInfo.primaryCpuAbi = abiList[copyRet]; 8432 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) { 8433 pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride; 8434 } else if (needsRenderScriptOverride) { 8435 pkg.applicationInfo.primaryCpuAbi = abiList[0]; 8436 } 8437 } 8438 } catch (IOException ioe) { 8439 Slog.e(TAG, "Unable to get canonical file " + ioe.toString()); 8440 } finally { 8441 IoUtils.closeQuietly(handle); 8442 } 8443 8444 // Now that we've calculated the ABIs and determined if it's an internal app, 8445 // we will go ahead and populate the nativeLibraryPath. 8446 setNativeLibraryPaths(pkg); 8447 } 8448 8449 /** 8450 * Adjusts ABIs for a set of packages belonging to a shared user so that they all match. 8451 * i.e, so that all packages can be run inside a single process if required. 8452 * 8453 * Optionally, callers can pass in a parsed package via {@code newPackage} in which case 8454 * this function will either try and make the ABI for all packages in {@code packagesForUser} 8455 * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match 8456 * the ABI selected for {@code packagesForUser}. This variant is used when installing or 8457 * updating a package that belongs to a shared user. 8458 * 8459 * NOTE: We currently only match for the primary CPU abi string. Matching the secondary 8460 * adds unnecessary complexity. 8461 */ 8462 private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser, 8463 PackageParser.Package scannedPackage, boolean bootComplete) { 8464 String requiredInstructionSet = null; 8465 if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) { 8466 requiredInstructionSet = VMRuntime.getInstructionSet( 8467 scannedPackage.applicationInfo.primaryCpuAbi); 8468 } 8469 8470 PackageSetting requirer = null; 8471 for (PackageSetting ps : packagesForUser) { 8472 // If packagesForUser contains scannedPackage, we skip it. This will happen 8473 // when scannedPackage is an update of an existing package. Without this check, 8474 // we will never be able to change the ABI of any package belonging to a shared 8475 // user, even if it's compatible with other packages. 8476 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 8477 if (ps.primaryCpuAbiString == null) { 8478 continue; 8479 } 8480 8481 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString); 8482 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) { 8483 // We have a mismatch between instruction sets (say arm vs arm64) warn about 8484 // this but there's not much we can do. 8485 String errorMessage = "Instruction set mismatch, " 8486 + ((requirer == null) ? "[caller]" : requirer) 8487 + " requires " + requiredInstructionSet + " whereas " + ps 8488 + " requires " + instructionSet; 8489 Slog.w(TAG, errorMessage); 8490 } 8491 8492 if (requiredInstructionSet == null) { 8493 requiredInstructionSet = instructionSet; 8494 requirer = ps; 8495 } 8496 } 8497 } 8498 8499 if (requiredInstructionSet != null) { 8500 String adjustedAbi; 8501 if (requirer != null) { 8502 // requirer != null implies that either scannedPackage was null or that scannedPackage 8503 // did not require an ABI, in which case we have to adjust scannedPackage to match 8504 // the ABI of the set (which is the same as requirer's ABI) 8505 adjustedAbi = requirer.primaryCpuAbiString; 8506 if (scannedPackage != null) { 8507 scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi; 8508 } 8509 } else { 8510 // requirer == null implies that we're updating all ABIs in the set to 8511 // match scannedPackage. 8512 adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi; 8513 } 8514 8515 for (PackageSetting ps : packagesForUser) { 8516 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 8517 if (ps.primaryCpuAbiString != null) { 8518 continue; 8519 } 8520 8521 ps.primaryCpuAbiString = adjustedAbi; 8522 if (ps.pkg != null && ps.pkg.applicationInfo != null && 8523 !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) { 8524 ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi; 8525 Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi 8526 + " (requirer=" 8527 + (requirer == null ? "null" : requirer.pkg.packageName) 8528 + ", scannedPackage=" 8529 + (scannedPackage != null ? scannedPackage.packageName : "null") 8530 + ")"); 8531 try { 8532 mInstaller.rmdex(ps.codePathString, 8533 getDexCodeInstructionSet(getPreferredInstructionSet())); 8534 } catch (InstallerException ignored) { 8535 } 8536 } 8537 } 8538 } 8539 } 8540 } 8541 8542 private void setUpCustomResolverActivity(PackageParser.Package pkg) { 8543 synchronized (mPackages) { 8544 mResolverReplaced = true; 8545 // Set up information for custom user intent resolution activity. 8546 mResolveActivity.applicationInfo = pkg.applicationInfo; 8547 mResolveActivity.name = mCustomResolverComponentName.getClassName(); 8548 mResolveActivity.packageName = pkg.applicationInfo.packageName; 8549 mResolveActivity.processName = pkg.applicationInfo.packageName; 8550 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 8551 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS | 8552 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 8553 mResolveActivity.theme = 0; 8554 mResolveActivity.exported = true; 8555 mResolveActivity.enabled = true; 8556 mResolveInfo.activityInfo = mResolveActivity; 8557 mResolveInfo.priority = 0; 8558 mResolveInfo.preferredOrder = 0; 8559 mResolveInfo.match = 0; 8560 mResolveComponentName = mCustomResolverComponentName; 8561 Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " + 8562 mResolveComponentName); 8563 } 8564 } 8565 8566 private void setUpEphemeralInstallerActivityLP(ComponentName installerComponent) { 8567 final PackageParser.Package pkg = mPackages.get(installerComponent.getPackageName()); 8568 8569 // Set up information for ephemeral installer activity 8570 mEphemeralInstallerActivity.applicationInfo = pkg.applicationInfo; 8571 mEphemeralInstallerActivity.name = mEphemeralInstallerComponent.getClassName(); 8572 mEphemeralInstallerActivity.packageName = pkg.applicationInfo.packageName; 8573 mEphemeralInstallerActivity.processName = pkg.applicationInfo.packageName; 8574 mEphemeralInstallerActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 8575 mEphemeralInstallerActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS | 8576 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 8577 mEphemeralInstallerActivity.theme = 0; 8578 mEphemeralInstallerActivity.exported = true; 8579 mEphemeralInstallerActivity.enabled = true; 8580 mEphemeralInstallerInfo.activityInfo = mEphemeralInstallerActivity; 8581 mEphemeralInstallerInfo.priority = 0; 8582 mEphemeralInstallerInfo.preferredOrder = 0; 8583 mEphemeralInstallerInfo.match = 0; 8584 8585 if (DEBUG_EPHEMERAL) { 8586 Slog.d(TAG, "Set ephemeral installer activity: " + mEphemeralInstallerComponent); 8587 } 8588 } 8589 8590 private static String calculateBundledApkRoot(final String codePathString) { 8591 final File codePath = new File(codePathString); 8592 final File codeRoot; 8593 if (FileUtils.contains(Environment.getRootDirectory(), codePath)) { 8594 codeRoot = Environment.getRootDirectory(); 8595 } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) { 8596 codeRoot = Environment.getOemDirectory(); 8597 } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) { 8598 codeRoot = Environment.getVendorDirectory(); 8599 } else { 8600 // Unrecognized code path; take its top real segment as the apk root: 8601 // e.g. /something/app/blah.apk => /something 8602 try { 8603 File f = codePath.getCanonicalFile(); 8604 File parent = f.getParentFile(); // non-null because codePath is a file 8605 File tmp; 8606 while ((tmp = parent.getParentFile()) != null) { 8607 f = parent; 8608 parent = tmp; 8609 } 8610 codeRoot = f; 8611 Slog.w(TAG, "Unrecognized code path " 8612 + codePath + " - using " + codeRoot); 8613 } catch (IOException e) { 8614 // Can't canonicalize the code path -- shenanigans? 8615 Slog.w(TAG, "Can't canonicalize code path " + codePath); 8616 return Environment.getRootDirectory().getPath(); 8617 } 8618 } 8619 return codeRoot.getPath(); 8620 } 8621 8622 /** 8623 * Derive and set the location of native libraries for the given package, 8624 * which varies depending on where and how the package was installed. 8625 */ 8626 private void setNativeLibraryPaths(PackageParser.Package pkg) { 8627 final ApplicationInfo info = pkg.applicationInfo; 8628 final String codePath = pkg.codePath; 8629 final File codeFile = new File(codePath); 8630 final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp(); 8631 final boolean asecApp = info.isForwardLocked() || info.isExternalAsec(); 8632 8633 info.nativeLibraryRootDir = null; 8634 info.nativeLibraryRootRequiresIsa = false; 8635 info.nativeLibraryDir = null; 8636 info.secondaryNativeLibraryDir = null; 8637 8638 if (isApkFile(codeFile)) { 8639 // Monolithic install 8640 if (bundledApp) { 8641 // If "/system/lib64/apkname" exists, assume that is the per-package 8642 // native library directory to use; otherwise use "/system/lib/apkname". 8643 final String apkRoot = calculateBundledApkRoot(info.sourceDir); 8644 final boolean is64Bit = VMRuntime.is64BitInstructionSet( 8645 getPrimaryInstructionSet(info)); 8646 8647 // This is a bundled system app so choose the path based on the ABI. 8648 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this 8649 // is just the default path. 8650 final String apkName = deriveCodePathName(codePath); 8651 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME; 8652 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir, 8653 apkName).getAbsolutePath(); 8654 8655 if (info.secondaryCpuAbi != null) { 8656 final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME; 8657 info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot), 8658 secondaryLibDir, apkName).getAbsolutePath(); 8659 } 8660 } else if (asecApp) { 8661 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME) 8662 .getAbsolutePath(); 8663 } else { 8664 final String apkName = deriveCodePathName(codePath); 8665 info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName) 8666 .getAbsolutePath(); 8667 } 8668 8669 info.nativeLibraryRootRequiresIsa = false; 8670 info.nativeLibraryDir = info.nativeLibraryRootDir; 8671 } else { 8672 // Cluster install 8673 info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath(); 8674 info.nativeLibraryRootRequiresIsa = true; 8675 8676 info.nativeLibraryDir = new File(info.nativeLibraryRootDir, 8677 getPrimaryInstructionSet(info)).getAbsolutePath(); 8678 8679 if (info.secondaryCpuAbi != null) { 8680 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir, 8681 VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath(); 8682 } 8683 } 8684 } 8685 8686 /** 8687 * Calculate the abis and roots for a bundled app. These can uniquely 8688 * be determined from the contents of the system partition, i.e whether 8689 * it contains 64 or 32 bit shared libraries etc. We do not validate any 8690 * of this information, and instead assume that the system was built 8691 * sensibly. 8692 */ 8693 private void setBundledAppAbisAndRoots(PackageParser.Package pkg, 8694 PackageSetting pkgSetting) { 8695 final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath()); 8696 8697 // If "/system/lib64/apkname" exists, assume that is the per-package 8698 // native library directory to use; otherwise use "/system/lib/apkname". 8699 final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir); 8700 setBundledAppAbi(pkg, apkRoot, apkName); 8701 // pkgSetting might be null during rescan following uninstall of updates 8702 // to a bundled app, so accommodate that possibility. The settings in 8703 // that case will be established later from the parsed package. 8704 // 8705 // If the settings aren't null, sync them up with what we've just derived. 8706 // note that apkRoot isn't stored in the package settings. 8707 if (pkgSetting != null) { 8708 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 8709 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 8710 } 8711 } 8712 8713 /** 8714 * Deduces the ABI of a bundled app and sets the relevant fields on the 8715 * parsed pkg object. 8716 * 8717 * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem} 8718 * under which system libraries are installed. 8719 * @param apkName the name of the installed package. 8720 */ 8721 private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) { 8722 final File codeFile = new File(pkg.codePath); 8723 8724 final boolean has64BitLibs; 8725 final boolean has32BitLibs; 8726 if (isApkFile(codeFile)) { 8727 // Monolithic install 8728 has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists(); 8729 has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists(); 8730 } else { 8731 // Cluster install 8732 final File rootDir = new File(codeFile, LIB_DIR_NAME); 8733 if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS) 8734 && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) { 8735 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]); 8736 has64BitLibs = (new File(rootDir, isa)).exists(); 8737 } else { 8738 has64BitLibs = false; 8739 } 8740 if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS) 8741 && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) { 8742 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]); 8743 has32BitLibs = (new File(rootDir, isa)).exists(); 8744 } else { 8745 has32BitLibs = false; 8746 } 8747 } 8748 8749 if (has64BitLibs && !has32BitLibs) { 8750 // The package has 64 bit libs, but not 32 bit libs. Its primary 8751 // ABI should be 64 bit. We can safely assume here that the bundled 8752 // native libraries correspond to the most preferred ABI in the list. 8753 8754 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 8755 pkg.applicationInfo.secondaryCpuAbi = null; 8756 } else if (has32BitLibs && !has64BitLibs) { 8757 // The package has 32 bit libs but not 64 bit libs. Its primary 8758 // ABI should be 32 bit. 8759 8760 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 8761 pkg.applicationInfo.secondaryCpuAbi = null; 8762 } else if (has32BitLibs && has64BitLibs) { 8763 // The application has both 64 and 32 bit bundled libraries. We check 8764 // here that the app declares multiArch support, and warn if it doesn't. 8765 // 8766 // We will be lenient here and record both ABIs. The primary will be the 8767 // ABI that's higher on the list, i.e, a device that's configured to prefer 8768 // 64 bit apps will see a 64 bit primary ABI, 8769 8770 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) { 8771 Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch."); 8772 } 8773 8774 if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) { 8775 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 8776 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 8777 } else { 8778 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 8779 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 8780 } 8781 } else { 8782 pkg.applicationInfo.primaryCpuAbi = null; 8783 pkg.applicationInfo.secondaryCpuAbi = null; 8784 } 8785 } 8786 8787 private void killPackage(PackageParser.Package pkg, String reason) { 8788 // Kill the parent package 8789 killApplication(pkg.packageName, pkg.applicationInfo.uid, reason); 8790 // Kill the child packages 8791 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8792 for (int i = 0; i < childCount; i++) { 8793 PackageParser.Package childPkg = pkg.childPackages.get(i); 8794 killApplication(childPkg.packageName, childPkg.applicationInfo.uid, reason); 8795 } 8796 } 8797 8798 private void killApplication(String pkgName, int appId, String reason) { 8799 // Request the ActivityManager to kill the process(only for existing packages) 8800 // so that we do not end up in a confused state while the user is still using the older 8801 // version of the application while the new one gets installed. 8802 IActivityManager am = ActivityManagerNative.getDefault(); 8803 if (am != null) { 8804 try { 8805 am.killApplicationWithAppId(pkgName, appId, reason); 8806 } catch (RemoteException e) { 8807 } 8808 } 8809 } 8810 8811 private void removePackageLI(PackageParser.Package pkg, boolean chatty) { 8812 // Remove the parent package setting 8813 PackageSetting ps = (PackageSetting) pkg.mExtras; 8814 if (ps != null) { 8815 removePackageLI(ps, chatty); 8816 } 8817 // Remove the child package setting 8818 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8819 for (int i = 0; i < childCount; i++) { 8820 PackageParser.Package childPkg = pkg.childPackages.get(i); 8821 ps = (PackageSetting) childPkg.mExtras; 8822 if (ps != null) { 8823 removePackageLI(ps, chatty); 8824 } 8825 } 8826 } 8827 8828 void removePackageLI(PackageSetting ps, boolean chatty) { 8829 if (DEBUG_INSTALL) { 8830 if (chatty) 8831 Log.d(TAG, "Removing package " + ps.name); 8832 } 8833 8834 // writer 8835 synchronized (mPackages) { 8836 mPackages.remove(ps.name); 8837 final PackageParser.Package pkg = ps.pkg; 8838 if (pkg != null) { 8839 cleanPackageDataStructuresLILPw(pkg, chatty); 8840 } 8841 } 8842 } 8843 8844 void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) { 8845 if (DEBUG_INSTALL) { 8846 if (chatty) 8847 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName); 8848 } 8849 8850 // writer 8851 synchronized (mPackages) { 8852 // Remove the parent package 8853 mPackages.remove(pkg.applicationInfo.packageName); 8854 cleanPackageDataStructuresLILPw(pkg, chatty); 8855 8856 // Remove the child packages 8857 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 8858 for (int i = 0; i < childCount; i++) { 8859 PackageParser.Package childPkg = pkg.childPackages.get(i); 8860 mPackages.remove(childPkg.applicationInfo.packageName); 8861 cleanPackageDataStructuresLILPw(childPkg, chatty); 8862 } 8863 } 8864 } 8865 8866 void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) { 8867 int N = pkg.providers.size(); 8868 StringBuilder r = null; 8869 int i; 8870 for (i=0; i<N; i++) { 8871 PackageParser.Provider p = pkg.providers.get(i); 8872 mProviders.removeProvider(p); 8873 if (p.info.authority == null) { 8874 8875 /* There was another ContentProvider with this authority when 8876 * this app was installed so this authority is null, 8877 * Ignore it as we don't have to unregister the provider. 8878 */ 8879 continue; 8880 } 8881 String names[] = p.info.authority.split(";"); 8882 for (int j = 0; j < names.length; j++) { 8883 if (mProvidersByAuthority.get(names[j]) == p) { 8884 mProvidersByAuthority.remove(names[j]); 8885 if (DEBUG_REMOVE) { 8886 if (chatty) 8887 Log.d(TAG, "Unregistered content provider: " + names[j] 8888 + ", className = " + p.info.name + ", isSyncable = " 8889 + p.info.isSyncable); 8890 } 8891 } 8892 } 8893 if (DEBUG_REMOVE && chatty) { 8894 if (r == null) { 8895 r = new StringBuilder(256); 8896 } else { 8897 r.append(' '); 8898 } 8899 r.append(p.info.name); 8900 } 8901 } 8902 if (r != null) { 8903 if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r); 8904 } 8905 8906 N = pkg.services.size(); 8907 r = null; 8908 for (i=0; i<N; i++) { 8909 PackageParser.Service s = pkg.services.get(i); 8910 mServices.removeService(s); 8911 if (chatty) { 8912 if (r == null) { 8913 r = new StringBuilder(256); 8914 } else { 8915 r.append(' '); 8916 } 8917 r.append(s.info.name); 8918 } 8919 } 8920 if (r != null) { 8921 if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r); 8922 } 8923 8924 N = pkg.receivers.size(); 8925 r = null; 8926 for (i=0; i<N; i++) { 8927 PackageParser.Activity a = pkg.receivers.get(i); 8928 mReceivers.removeActivity(a, "receiver"); 8929 if (DEBUG_REMOVE && chatty) { 8930 if (r == null) { 8931 r = new StringBuilder(256); 8932 } else { 8933 r.append(' '); 8934 } 8935 r.append(a.info.name); 8936 } 8937 } 8938 if (r != null) { 8939 if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r); 8940 } 8941 8942 N = pkg.activities.size(); 8943 r = null; 8944 for (i=0; i<N; i++) { 8945 PackageParser.Activity a = pkg.activities.get(i); 8946 mActivities.removeActivity(a, "activity"); 8947 if (DEBUG_REMOVE && chatty) { 8948 if (r == null) { 8949 r = new StringBuilder(256); 8950 } else { 8951 r.append(' '); 8952 } 8953 r.append(a.info.name); 8954 } 8955 } 8956 if (r != null) { 8957 if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r); 8958 } 8959 8960 N = pkg.permissions.size(); 8961 r = null; 8962 for (i=0; i<N; i++) { 8963 PackageParser.Permission p = pkg.permissions.get(i); 8964 BasePermission bp = mSettings.mPermissions.get(p.info.name); 8965 if (bp == null) { 8966 bp = mSettings.mPermissionTrees.get(p.info.name); 8967 } 8968 if (bp != null && bp.perm == p) { 8969 bp.perm = null; 8970 if (DEBUG_REMOVE && chatty) { 8971 if (r == null) { 8972 r = new StringBuilder(256); 8973 } else { 8974 r.append(' '); 8975 } 8976 r.append(p.info.name); 8977 } 8978 } 8979 if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 8980 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name); 8981 if (appOpPkgs != null) { 8982 appOpPkgs.remove(pkg.packageName); 8983 } 8984 } 8985 } 8986 if (r != null) { 8987 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 8988 } 8989 8990 N = pkg.requestedPermissions.size(); 8991 r = null; 8992 for (i=0; i<N; i++) { 8993 String perm = pkg.requestedPermissions.get(i); 8994 BasePermission bp = mSettings.mPermissions.get(perm); 8995 if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 8996 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm); 8997 if (appOpPkgs != null) { 8998 appOpPkgs.remove(pkg.packageName); 8999 if (appOpPkgs.isEmpty()) { 9000 mAppOpPermissionPackages.remove(perm); 9001 } 9002 } 9003 } 9004 } 9005 if (r != null) { 9006 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 9007 } 9008 9009 N = pkg.instrumentation.size(); 9010 r = null; 9011 for (i=0; i<N; i++) { 9012 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 9013 mInstrumentation.remove(a.getComponentName()); 9014 if (DEBUG_REMOVE && chatty) { 9015 if (r == null) { 9016 r = new StringBuilder(256); 9017 } else { 9018 r.append(' '); 9019 } 9020 r.append(a.info.name); 9021 } 9022 } 9023 if (r != null) { 9024 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r); 9025 } 9026 9027 r = null; 9028 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9029 // Only system apps can hold shared libraries. 9030 if (pkg.libraryNames != null) { 9031 for (i=0; i<pkg.libraryNames.size(); i++) { 9032 String name = pkg.libraryNames.get(i); 9033 SharedLibraryEntry cur = mSharedLibraries.get(name); 9034 if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) { 9035 mSharedLibraries.remove(name); 9036 if (DEBUG_REMOVE && chatty) { 9037 if (r == null) { 9038 r = new StringBuilder(256); 9039 } else { 9040 r.append(' '); 9041 } 9042 r.append(name); 9043 } 9044 } 9045 } 9046 } 9047 } 9048 if (r != null) { 9049 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r); 9050 } 9051 } 9052 9053 private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) { 9054 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) { 9055 if (pkgInfo.permissions.get(i).info.name.equals(perm)) { 9056 return true; 9057 } 9058 } 9059 return false; 9060 } 9061 9062 static final int UPDATE_PERMISSIONS_ALL = 1<<0; 9063 static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1; 9064 static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2; 9065 9066 private void updatePermissionsLPw(PackageParser.Package pkg, int flags) { 9067 // Update the parent permissions 9068 updatePermissionsLPw(pkg.packageName, pkg, flags); 9069 // Update the child permissions 9070 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 9071 for (int i = 0; i < childCount; i++) { 9072 PackageParser.Package childPkg = pkg.childPackages.get(i); 9073 updatePermissionsLPw(childPkg.packageName, childPkg, flags); 9074 } 9075 } 9076 9077 private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo, 9078 int flags) { 9079 final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null; 9080 updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags); 9081 } 9082 9083 private void updatePermissionsLPw(String changingPkg, 9084 PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) { 9085 // Make sure there are no dangling permission trees. 9086 Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator(); 9087 while (it.hasNext()) { 9088 final BasePermission bp = it.next(); 9089 if (bp.packageSetting == null) { 9090 // We may not yet have parsed the package, so just see if 9091 // we still know about its settings. 9092 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 9093 } 9094 if (bp.packageSetting == null) { 9095 Slog.w(TAG, "Removing dangling permission tree: " + bp.name 9096 + " from package " + bp.sourcePackage); 9097 it.remove(); 9098 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 9099 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 9100 Slog.i(TAG, "Removing old permission tree: " + bp.name 9101 + " from package " + bp.sourcePackage); 9102 flags |= UPDATE_PERMISSIONS_ALL; 9103 it.remove(); 9104 } 9105 } 9106 } 9107 9108 // Make sure all dynamic permissions have been assigned to a package, 9109 // and make sure there are no dangling permissions. 9110 it = mSettings.mPermissions.values().iterator(); 9111 while (it.hasNext()) { 9112 final BasePermission bp = it.next(); 9113 if (bp.type == BasePermission.TYPE_DYNAMIC) { 9114 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name=" 9115 + bp.name + " pkg=" + bp.sourcePackage 9116 + " info=" + bp.pendingInfo); 9117 if (bp.packageSetting == null && bp.pendingInfo != null) { 9118 final BasePermission tree = findPermissionTreeLP(bp.name); 9119 if (tree != null && tree.perm != null) { 9120 bp.packageSetting = tree.packageSetting; 9121 bp.perm = new PackageParser.Permission(tree.perm.owner, 9122 new PermissionInfo(bp.pendingInfo)); 9123 bp.perm.info.packageName = tree.perm.info.packageName; 9124 bp.perm.info.name = bp.name; 9125 bp.uid = tree.uid; 9126 } 9127 } 9128 } 9129 if (bp.packageSetting == null) { 9130 // We may not yet have parsed the package, so just see if 9131 // we still know about its settings. 9132 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 9133 } 9134 if (bp.packageSetting == null) { 9135 Slog.w(TAG, "Removing dangling permission: " + bp.name 9136 + " from package " + bp.sourcePackage); 9137 it.remove(); 9138 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 9139 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 9140 Slog.i(TAG, "Removing old permission: " + bp.name 9141 + " from package " + bp.sourcePackage); 9142 flags |= UPDATE_PERMISSIONS_ALL; 9143 it.remove(); 9144 } 9145 } 9146 } 9147 9148 // Now update the permissions for all packages, in particular 9149 // replace the granted permissions of the system packages. 9150 if ((flags&UPDATE_PERMISSIONS_ALL) != 0) { 9151 for (PackageParser.Package pkg : mPackages.values()) { 9152 if (pkg != pkgInfo) { 9153 // Only replace for packages on requested volume 9154 final String volumeUuid = getVolumeUuidForPackage(pkg); 9155 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0) 9156 && Objects.equals(replaceVolumeUuid, volumeUuid); 9157 grantPermissionsLPw(pkg, replace, changingPkg); 9158 } 9159 } 9160 } 9161 9162 if (pkgInfo != null) { 9163 // Only replace for packages on requested volume 9164 final String volumeUuid = getVolumeUuidForPackage(pkgInfo); 9165 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0) 9166 && Objects.equals(replaceVolumeUuid, volumeUuid); 9167 grantPermissionsLPw(pkgInfo, replace, changingPkg); 9168 } 9169 } 9170 9171 private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace, 9172 String packageOfInterest) { 9173 // IMPORTANT: There are two types of permissions: install and runtime. 9174 // Install time permissions are granted when the app is installed to 9175 // all device users and users added in the future. Runtime permissions 9176 // are granted at runtime explicitly to specific users. Normal and signature 9177 // protected permissions are install time permissions. Dangerous permissions 9178 // are install permissions if the app's target SDK is Lollipop MR1 or older, 9179 // otherwise they are runtime permissions. This function does not manage 9180 // runtime permissions except for the case an app targeting Lollipop MR1 9181 // being upgraded to target a newer SDK, in which case dangerous permissions 9182 // are transformed from install time to runtime ones. 9183 9184 final PackageSetting ps = (PackageSetting) pkg.mExtras; 9185 if (ps == null) { 9186 return; 9187 } 9188 9189 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions"); 9190 9191 PermissionsState permissionsState = ps.getPermissionsState(); 9192 PermissionsState origPermissions = permissionsState; 9193 9194 final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); 9195 9196 boolean runtimePermissionsRevoked = false; 9197 int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY; 9198 9199 boolean changedInstallPermission = false; 9200 9201 if (replace) { 9202 ps.installPermissionsFixed = false; 9203 if (!ps.isSharedUser()) { 9204 origPermissions = new PermissionsState(permissionsState); 9205 permissionsState.reset(); 9206 } else { 9207 // We need to know only about runtime permission changes since the 9208 // calling code always writes the install permissions state but 9209 // the runtime ones are written only if changed. The only cases of 9210 // changed runtime permissions here are promotion of an install to 9211 // runtime and revocation of a runtime from a shared user. 9212 changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw( 9213 ps.sharedUser, UserManagerService.getInstance().getUserIds()); 9214 if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) { 9215 runtimePermissionsRevoked = true; 9216 } 9217 } 9218 } 9219 9220 permissionsState.setGlobalGids(mGlobalGids); 9221 9222 final int N = pkg.requestedPermissions.size(); 9223 for (int i=0; i<N; i++) { 9224 final String name = pkg.requestedPermissions.get(i); 9225 final BasePermission bp = mSettings.mPermissions.get(name); 9226 9227 if (DEBUG_INSTALL) { 9228 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp); 9229 } 9230 9231 if (bp == null || bp.packageSetting == null) { 9232 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 9233 Slog.w(TAG, "Unknown permission " + name 9234 + " in package " + pkg.packageName); 9235 } 9236 continue; 9237 } 9238 9239 final String perm = bp.name; 9240 boolean allowedSig = false; 9241 int grant = GRANT_DENIED; 9242 9243 // Keep track of app op permissions. 9244 if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 9245 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name); 9246 if (pkgs == null) { 9247 pkgs = new ArraySet<>(); 9248 mAppOpPermissionPackages.put(bp.name, pkgs); 9249 } 9250 pkgs.add(pkg.packageName); 9251 } 9252 9253 final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; 9254 final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion 9255 >= Build.VERSION_CODES.M; 9256 switch (level) { 9257 case PermissionInfo.PROTECTION_NORMAL: { 9258 // For all apps normal permissions are install time ones. 9259 grant = GRANT_INSTALL; 9260 } break; 9261 9262 case PermissionInfo.PROTECTION_DANGEROUS: { 9263 // If a permission review is required for legacy apps we represent 9264 // their permissions as always granted runtime ones since we need 9265 // to keep the review required permission flag per user while an 9266 // install permission's state is shared across all users. 9267 if (!appSupportsRuntimePermissions && !Build.PERMISSIONS_REVIEW_REQUIRED) { 9268 // For legacy apps dangerous permissions are install time ones. 9269 grant = GRANT_INSTALL; 9270 } else if (origPermissions.hasInstallPermission(bp.name)) { 9271 // For legacy apps that became modern, install becomes runtime. 9272 grant = GRANT_UPGRADE; 9273 } else if (mPromoteSystemApps 9274 && isSystemApp(ps) 9275 && mExistingSystemPackages.contains(ps.name)) { 9276 // For legacy system apps, install becomes runtime. 9277 // We cannot check hasInstallPermission() for system apps since those 9278 // permissions were granted implicitly and not persisted pre-M. 9279 grant = GRANT_UPGRADE; 9280 } else { 9281 // For modern apps keep runtime permissions unchanged. 9282 grant = GRANT_RUNTIME; 9283 } 9284 } break; 9285 9286 case PermissionInfo.PROTECTION_SIGNATURE: { 9287 // For all apps signature permissions are install time ones. 9288 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions); 9289 if (allowedSig) { 9290 grant = GRANT_INSTALL; 9291 } 9292 } break; 9293 } 9294 9295 if (DEBUG_INSTALL) { 9296 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm); 9297 } 9298 9299 if (grant != GRANT_DENIED) { 9300 if (!isSystemApp(ps) && ps.installPermissionsFixed) { 9301 // If this is an existing, non-system package, then 9302 // we can't add any new permissions to it. 9303 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) { 9304 // Except... if this is a permission that was added 9305 // to the platform (note: need to only do this when 9306 // updating the platform). 9307 if (!isNewPlatformPermissionForPackage(perm, pkg)) { 9308 grant = GRANT_DENIED; 9309 } 9310 } 9311 } 9312 9313 switch (grant) { 9314 case GRANT_INSTALL: { 9315 // Revoke this as runtime permission to handle the case of 9316 // a runtime permission being downgraded to an install one. Also in permission review mode we keep dangerous permissions for legacy apps 9317 for (int userId : UserManagerService.getInstance().getUserIds()) { 9318 if (origPermissions.getRuntimePermissionState( 9319 bp.name, userId) != null) { 9320 // Revoke the runtime permission and clear the flags. 9321 origPermissions.revokeRuntimePermission(bp, userId); 9322 origPermissions.updatePermissionFlags(bp, userId, 9323 PackageManager.MASK_PERMISSION_FLAGS, 0); 9324 // If we revoked a permission permission, we have to write. 9325 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 9326 changedRuntimePermissionUserIds, userId); 9327 } 9328 } 9329 // Grant an install permission. 9330 if (permissionsState.grantInstallPermission(bp) != 9331 PermissionsState.PERMISSION_OPERATION_FAILURE) { 9332 changedInstallPermission = true; 9333 } 9334 } break; 9335 9336 case GRANT_RUNTIME: { 9337 // Grant previously granted runtime permissions. 9338 for (int userId : UserManagerService.getInstance().getUserIds()) { 9339 PermissionState permissionState = origPermissions 9340 .getRuntimePermissionState(bp.name, userId); 9341 int flags = permissionState != null 9342 ? permissionState.getFlags() : 0; 9343 if (origPermissions.hasRuntimePermission(bp.name, userId)) { 9344 if (permissionsState.grantRuntimePermission(bp, userId) == 9345 PermissionsState.PERMISSION_OPERATION_FAILURE) { 9346 // If we cannot put the permission as it was, we have to write. 9347 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 9348 changedRuntimePermissionUserIds, userId); 9349 } 9350 // If the app supports runtime permissions no need for a review. 9351 if (Build.PERMISSIONS_REVIEW_REQUIRED 9352 && appSupportsRuntimePermissions 9353 && (flags & PackageManager 9354 .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) { 9355 flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 9356 // Since we changed the flags, we have to write. 9357 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 9358 changedRuntimePermissionUserIds, userId); 9359 } 9360 } else if (Build.PERMISSIONS_REVIEW_REQUIRED 9361 && !appSupportsRuntimePermissions) { 9362 // For legacy apps that need a permission review, every new 9363 // runtime permission is granted but it is pending a review. 9364 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) { 9365 permissionsState.grantRuntimePermission(bp, userId); 9366 flags |= FLAG_PERMISSION_REVIEW_REQUIRED; 9367 // We changed the permission and flags, hence have to write. 9368 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 9369 changedRuntimePermissionUserIds, userId); 9370 } 9371 } 9372 // Propagate the permission flags. 9373 permissionsState.updatePermissionFlags(bp, userId, flags, flags); 9374 } 9375 } break; 9376 9377 case GRANT_UPGRADE: { 9378 // Grant runtime permissions for a previously held install permission. 9379 PermissionState permissionState = origPermissions 9380 .getInstallPermissionState(bp.name); 9381 final int flags = permissionState != null ? permissionState.getFlags() : 0; 9382 9383 if (origPermissions.revokeInstallPermission(bp) 9384 != PermissionsState.PERMISSION_OPERATION_FAILURE) { 9385 // We will be transferring the permission flags, so clear them. 9386 origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL, 9387 PackageManager.MASK_PERMISSION_FLAGS, 0); 9388 changedInstallPermission = true; 9389 } 9390 9391 // If the permission is not to be promoted to runtime we ignore it and 9392 // also its other flags as they are not applicable to install permissions. 9393 if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) { 9394 for (int userId : currentUserIds) { 9395 if (permissionsState.grantRuntimePermission(bp, userId) != 9396 PermissionsState.PERMISSION_OPERATION_FAILURE) { 9397 // Transfer the permission flags. 9398 permissionsState.updatePermissionFlags(bp, userId, 9399 flags, flags); 9400 // If we granted the permission, we have to write. 9401 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 9402 changedRuntimePermissionUserIds, userId); 9403 } 9404 } 9405 } 9406 } break; 9407 9408 default: { 9409 if (packageOfInterest == null 9410 || packageOfInterest.equals(pkg.packageName)) { 9411 Slog.w(TAG, "Not granting permission " + perm 9412 + " to package " + pkg.packageName 9413 + " because it was previously installed without"); 9414 } 9415 } break; 9416 } 9417 } else { 9418 if (permissionsState.revokeInstallPermission(bp) != 9419 PermissionsState.PERMISSION_OPERATION_FAILURE) { 9420 // Also drop the permission flags. 9421 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 9422 PackageManager.MASK_PERMISSION_FLAGS, 0); 9423 changedInstallPermission = true; 9424 Slog.i(TAG, "Un-granting permission " + perm 9425 + " from package " + pkg.packageName 9426 + " (protectionLevel=" + bp.protectionLevel 9427 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 9428 + ")"); 9429 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) { 9430 // Don't print warning for app op permissions, since it is fine for them 9431 // not to be granted, there is a UI for the user to decide. 9432 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 9433 Slog.w(TAG, "Not granting permission " + perm 9434 + " to package " + pkg.packageName 9435 + " (protectionLevel=" + bp.protectionLevel 9436 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 9437 + ")"); 9438 } 9439 } 9440 } 9441 } 9442 9443 if ((changedInstallPermission || replace) && !ps.installPermissionsFixed && 9444 !isSystemApp(ps) || isUpdatedSystemApp(ps)){ 9445 // This is the first that we have heard about this package, so the 9446 // permissions we have now selected are fixed until explicitly 9447 // changed. 9448 ps.installPermissionsFixed = true; 9449 } 9450 9451 // Persist the runtime permissions state for users with changes. If permissions 9452 // were revoked because no app in the shared user declares them we have to 9453 // write synchronously to avoid losing runtime permissions state. 9454 for (int userId : changedRuntimePermissionUserIds) { 9455 mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked); 9456 } 9457 9458 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 9459 } 9460 9461 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) { 9462 boolean allowed = false; 9463 final int NP = PackageParser.NEW_PERMISSIONS.length; 9464 for (int ip=0; ip<NP; ip++) { 9465 final PackageParser.NewPermissionInfo npi 9466 = PackageParser.NEW_PERMISSIONS[ip]; 9467 if (npi.name.equals(perm) 9468 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) { 9469 allowed = true; 9470 Log.i(TAG, "Auto-granting " + perm + " to old pkg " 9471 + pkg.packageName); 9472 break; 9473 } 9474 } 9475 return allowed; 9476 } 9477 9478 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg, 9479 BasePermission bp, PermissionsState origPermissions) { 9480 boolean allowed; 9481 allowed = (compareSignatures( 9482 bp.packageSetting.signatures.mSignatures, pkg.mSignatures) 9483 == PackageManager.SIGNATURE_MATCH) 9484 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures) 9485 == PackageManager.SIGNATURE_MATCH); 9486 if (!allowed && (bp.protectionLevel 9487 & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) { 9488 if (isSystemApp(pkg)) { 9489 // For updated system applications, a system permission 9490 // is granted only if it had been defined by the original application. 9491 if (pkg.isUpdatedSystemApp()) { 9492 final PackageSetting sysPs = mSettings 9493 .getDisabledSystemPkgLPr(pkg.packageName); 9494 if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) { 9495 // If the original was granted this permission, we take 9496 // that grant decision as read and propagate it to the 9497 // update. 9498 if (sysPs.isPrivileged()) { 9499 allowed = true; 9500 } 9501 } else { 9502 // The system apk may have been updated with an older 9503 // version of the one on the data partition, but which 9504 // granted a new system permission that it didn't have 9505 // before. In this case we do want to allow the app to 9506 // now get the new permission if the ancestral apk is 9507 // privileged to get it. 9508 if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) { 9509 for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) { 9510 if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) { 9511 allowed = true; 9512 break; 9513 } 9514 } 9515 } 9516 // Also if a privileged parent package on the system image or any of 9517 // its children requested a privileged permission, the updated child 9518 // packages can also get the permission. 9519 if (pkg.parentPackage != null) { 9520 final PackageSetting disabledSysParentPs = mSettings 9521 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName); 9522 if (disabledSysParentPs != null && disabledSysParentPs.pkg != null 9523 && disabledSysParentPs.isPrivileged()) { 9524 if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) { 9525 allowed = true; 9526 } else if (disabledSysParentPs.pkg.childPackages != null) { 9527 final int count = disabledSysParentPs.pkg.childPackages.size(); 9528 for (int i = 0; i < count; i++) { 9529 PackageParser.Package disabledSysChildPkg = 9530 disabledSysParentPs.pkg.childPackages.get(i); 9531 if (isPackageRequestingPermission(disabledSysChildPkg, 9532 perm)) { 9533 allowed = true; 9534 break; 9535 } 9536 } 9537 } 9538 } 9539 } 9540 } 9541 } else { 9542 allowed = isPrivilegedApp(pkg); 9543 } 9544 } 9545 } 9546 if (!allowed) { 9547 if (!allowed && (bp.protectionLevel 9548 & PermissionInfo.PROTECTION_FLAG_PRE23) != 0 9549 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 9550 // If this was a previously normal/dangerous permission that got moved 9551 // to a system permission as part of the runtime permission redesign, then 9552 // we still want to blindly grant it to old apps. 9553 allowed = true; 9554 } 9555 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0 9556 && pkg.packageName.equals(mRequiredInstallerPackage)) { 9557 // If this permission is to be granted to the system installer and 9558 // this app is an installer, then it gets the permission. 9559 allowed = true; 9560 } 9561 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0 9562 && pkg.packageName.equals(mRequiredVerifierPackage)) { 9563 // If this permission is to be granted to the system verifier and 9564 // this app is a verifier, then it gets the permission. 9565 allowed = true; 9566 } 9567 if (!allowed && (bp.protectionLevel 9568 & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0 9569 && isSystemApp(pkg)) { 9570 // Any pre-installed system app is allowed to get this permission. 9571 allowed = true; 9572 } 9573 if (!allowed && (bp.protectionLevel 9574 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) { 9575 // For development permissions, a development permission 9576 // is granted only if it was already granted. 9577 allowed = origPermissions.hasInstallPermission(perm); 9578 } 9579 } 9580 return allowed; 9581 } 9582 9583 private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) { 9584 final int permCount = pkg.requestedPermissions.size(); 9585 for (int j = 0; j < permCount; j++) { 9586 String requestedPermission = pkg.requestedPermissions.get(j); 9587 if (permission.equals(requestedPermission)) { 9588 return true; 9589 } 9590 } 9591 return false; 9592 } 9593 9594 final class ActivityIntentResolver 9595 extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> { 9596 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 9597 boolean defaultOnly, int userId) { 9598 if (!sUserManager.exists(userId)) return null; 9599 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 9600 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 9601 } 9602 9603 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 9604 int userId) { 9605 if (!sUserManager.exists(userId)) return null; 9606 mFlags = flags; 9607 return super.queryIntent(intent, resolvedType, 9608 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 9609 } 9610 9611 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 9612 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) { 9613 if (!sUserManager.exists(userId)) return null; 9614 if (packageActivities == null) { 9615 return null; 9616 } 9617 mFlags = flags; 9618 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 9619 final int N = packageActivities.size(); 9620 ArrayList<PackageParser.ActivityIntentInfo[]> listCut = 9621 new ArrayList<PackageParser.ActivityIntentInfo[]>(N); 9622 9623 ArrayList<PackageParser.ActivityIntentInfo> intentFilters; 9624 for (int i = 0; i < N; ++i) { 9625 intentFilters = packageActivities.get(i).intents; 9626 if (intentFilters != null && intentFilters.size() > 0) { 9627 PackageParser.ActivityIntentInfo[] array = 9628 new PackageParser.ActivityIntentInfo[intentFilters.size()]; 9629 intentFilters.toArray(array); 9630 listCut.add(array); 9631 } 9632 } 9633 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 9634 } 9635 9636 public final void addActivity(PackageParser.Activity a, String type) { 9637 final boolean systemApp = a.info.applicationInfo.isSystemApp(); 9638 mActivities.put(a.getComponentName(), a); 9639 if (DEBUG_SHOW_INFO) 9640 Log.v( 9641 TAG, " " + type + " " + 9642 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":"); 9643 if (DEBUG_SHOW_INFO) 9644 Log.v(TAG, " Class=" + a.info.name); 9645 final int NI = a.intents.size(); 9646 for (int j=0; j<NI; j++) { 9647 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 9648 if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) { 9649 intent.setPriority(0); 9650 Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity " 9651 + a.className + " with priority > 0, forcing to 0"); 9652 } 9653 if (DEBUG_SHOW_INFO) { 9654 Log.v(TAG, " IntentFilter:"); 9655 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 9656 } 9657 if (!intent.debugCheck()) { 9658 Log.w(TAG, "==> For Activity " + a.info.name); 9659 } 9660 addFilter(intent); 9661 } 9662 } 9663 9664 public final void removeActivity(PackageParser.Activity a, String type) { 9665 mActivities.remove(a.getComponentName()); 9666 if (DEBUG_SHOW_INFO) { 9667 Log.v(TAG, " " + type + " " 9668 + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel 9669 : a.info.name) + ":"); 9670 Log.v(TAG, " Class=" + a.info.name); 9671 } 9672 final int NI = a.intents.size(); 9673 for (int j=0; j<NI; j++) { 9674 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 9675 if (DEBUG_SHOW_INFO) { 9676 Log.v(TAG, " IntentFilter:"); 9677 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 9678 } 9679 removeFilter(intent); 9680 } 9681 } 9682 9683 @Override 9684 protected boolean allowFilterResult( 9685 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) { 9686 ActivityInfo filterAi = filter.activity.info; 9687 for (int i=dest.size()-1; i>=0; i--) { 9688 ActivityInfo destAi = dest.get(i).activityInfo; 9689 if (destAi.name == filterAi.name 9690 && destAi.packageName == filterAi.packageName) { 9691 return false; 9692 } 9693 } 9694 return true; 9695 } 9696 9697 @Override 9698 protected ActivityIntentInfo[] newArray(int size) { 9699 return new ActivityIntentInfo[size]; 9700 } 9701 9702 @Override 9703 protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) { 9704 if (!sUserManager.exists(userId)) return true; 9705 PackageParser.Package p = filter.activity.owner; 9706 if (p != null) { 9707 PackageSetting ps = (PackageSetting)p.mExtras; 9708 if (ps != null) { 9709 // System apps are never considered stopped for purposes of 9710 // filtering, because there may be no way for the user to 9711 // actually re-launch them. 9712 return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0 9713 && ps.getStopped(userId); 9714 } 9715 } 9716 return false; 9717 } 9718 9719 @Override 9720 protected boolean isPackageForFilter(String packageName, 9721 PackageParser.ActivityIntentInfo info) { 9722 return packageName.equals(info.activity.owner.packageName); 9723 } 9724 9725 @Override 9726 protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info, 9727 int match, int userId) { 9728 if (!sUserManager.exists(userId)) return null; 9729 if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) { 9730 return null; 9731 } 9732 final PackageParser.Activity activity = info.activity; 9733 PackageSetting ps = (PackageSetting) activity.owner.mExtras; 9734 if (ps == null) { 9735 return null; 9736 } 9737 ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags, 9738 ps.readUserState(userId), userId); 9739 if (ai == null) { 9740 return null; 9741 } 9742 final ResolveInfo res = new ResolveInfo(); 9743 res.activityInfo = ai; 9744 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 9745 res.filter = info; 9746 } 9747 if (info != null) { 9748 res.handleAllWebDataURI = info.handleAllWebDataURI(); 9749 } 9750 res.priority = info.getPriority(); 9751 res.preferredOrder = activity.owner.mPreferredOrder; 9752 //System.out.println("Result: " + res.activityInfo.className + 9753 // " = " + res.priority); 9754 res.match = match; 9755 res.isDefault = info.hasDefault; 9756 res.labelRes = info.labelRes; 9757 res.nonLocalizedLabel = info.nonLocalizedLabel; 9758 if (userNeedsBadging(userId)) { 9759 res.noResourceId = true; 9760 } else { 9761 res.icon = info.icon; 9762 } 9763 res.iconResourceId = info.icon; 9764 res.system = res.activityInfo.applicationInfo.isSystemApp(); 9765 return res; 9766 } 9767 9768 @Override 9769 protected void sortResults(List<ResolveInfo> results) { 9770 Collections.sort(results, mResolvePrioritySorter); 9771 } 9772 9773 @Override 9774 protected void dumpFilter(PrintWriter out, String prefix, 9775 PackageParser.ActivityIntentInfo filter) { 9776 out.print(prefix); out.print( 9777 Integer.toHexString(System.identityHashCode(filter.activity))); 9778 out.print(' '); 9779 filter.activity.printComponentShortName(out); 9780 out.print(" filter "); 9781 out.println(Integer.toHexString(System.identityHashCode(filter))); 9782 } 9783 9784 @Override 9785 protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) { 9786 return filter.activity; 9787 } 9788 9789 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 9790 PackageParser.Activity activity = (PackageParser.Activity)label; 9791 out.print(prefix); out.print( 9792 Integer.toHexString(System.identityHashCode(activity))); 9793 out.print(' '); 9794 activity.printComponentShortName(out); 9795 if (count > 1) { 9796 out.print(" ("); out.print(count); out.print(" filters)"); 9797 } 9798 out.println(); 9799 } 9800 9801// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 9802// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 9803// final List<ResolveInfo> retList = Lists.newArrayList(); 9804// while (i.hasNext()) { 9805// final ResolveInfo resolveInfo = i.next(); 9806// if (isEnabledLP(resolveInfo.activityInfo)) { 9807// retList.add(resolveInfo); 9808// } 9809// } 9810// return retList; 9811// } 9812 9813 // Keys are String (activity class name), values are Activity. 9814 private final ArrayMap<ComponentName, PackageParser.Activity> mActivities 9815 = new ArrayMap<ComponentName, PackageParser.Activity>(); 9816 private int mFlags; 9817 } 9818 9819 private final class ServiceIntentResolver 9820 extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> { 9821 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 9822 boolean defaultOnly, int userId) { 9823 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 9824 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 9825 } 9826 9827 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 9828 int userId) { 9829 if (!sUserManager.exists(userId)) return null; 9830 mFlags = flags; 9831 return super.queryIntent(intent, resolvedType, 9832 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 9833 } 9834 9835 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 9836 int flags, ArrayList<PackageParser.Service> packageServices, int userId) { 9837 if (!sUserManager.exists(userId)) return null; 9838 if (packageServices == null) { 9839 return null; 9840 } 9841 mFlags = flags; 9842 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 9843 final int N = packageServices.size(); 9844 ArrayList<PackageParser.ServiceIntentInfo[]> listCut = 9845 new ArrayList<PackageParser.ServiceIntentInfo[]>(N); 9846 9847 ArrayList<PackageParser.ServiceIntentInfo> intentFilters; 9848 for (int i = 0; i < N; ++i) { 9849 intentFilters = packageServices.get(i).intents; 9850 if (intentFilters != null && intentFilters.size() > 0) { 9851 PackageParser.ServiceIntentInfo[] array = 9852 new PackageParser.ServiceIntentInfo[intentFilters.size()]; 9853 intentFilters.toArray(array); 9854 listCut.add(array); 9855 } 9856 } 9857 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 9858 } 9859 9860 public final void addService(PackageParser.Service s) { 9861 mServices.put(s.getComponentName(), s); 9862 if (DEBUG_SHOW_INFO) { 9863 Log.v(TAG, " " 9864 + (s.info.nonLocalizedLabel != null 9865 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 9866 Log.v(TAG, " Class=" + s.info.name); 9867 } 9868 final int NI = s.intents.size(); 9869 int j; 9870 for (j=0; j<NI; j++) { 9871 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 9872 if (DEBUG_SHOW_INFO) { 9873 Log.v(TAG, " IntentFilter:"); 9874 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 9875 } 9876 if (!intent.debugCheck()) { 9877 Log.w(TAG, "==> For Service " + s.info.name); 9878 } 9879 addFilter(intent); 9880 } 9881 } 9882 9883 public final void removeService(PackageParser.Service s) { 9884 mServices.remove(s.getComponentName()); 9885 if (DEBUG_SHOW_INFO) { 9886 Log.v(TAG, " " + (s.info.nonLocalizedLabel != null 9887 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 9888 Log.v(TAG, " Class=" + s.info.name); 9889 } 9890 final int NI = s.intents.size(); 9891 int j; 9892 for (j=0; j<NI; j++) { 9893 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 9894 if (DEBUG_SHOW_INFO) { 9895 Log.v(TAG, " IntentFilter:"); 9896 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 9897 } 9898 removeFilter(intent); 9899 } 9900 } 9901 9902 @Override 9903 protected boolean allowFilterResult( 9904 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) { 9905 ServiceInfo filterSi = filter.service.info; 9906 for (int i=dest.size()-1; i>=0; i--) { 9907 ServiceInfo destAi = dest.get(i).serviceInfo; 9908 if (destAi.name == filterSi.name 9909 && destAi.packageName == filterSi.packageName) { 9910 return false; 9911 } 9912 } 9913 return true; 9914 } 9915 9916 @Override 9917 protected PackageParser.ServiceIntentInfo[] newArray(int size) { 9918 return new PackageParser.ServiceIntentInfo[size]; 9919 } 9920 9921 @Override 9922 protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) { 9923 if (!sUserManager.exists(userId)) return true; 9924 PackageParser.Package p = filter.service.owner; 9925 if (p != null) { 9926 PackageSetting ps = (PackageSetting)p.mExtras; 9927 if (ps != null) { 9928 // System apps are never considered stopped for purposes of 9929 // filtering, because there may be no way for the user to 9930 // actually re-launch them. 9931 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 9932 && ps.getStopped(userId); 9933 } 9934 } 9935 return false; 9936 } 9937 9938 @Override 9939 protected boolean isPackageForFilter(String packageName, 9940 PackageParser.ServiceIntentInfo info) { 9941 return packageName.equals(info.service.owner.packageName); 9942 } 9943 9944 @Override 9945 protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter, 9946 int match, int userId) { 9947 if (!sUserManager.exists(userId)) return null; 9948 final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter; 9949 if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) { 9950 return null; 9951 } 9952 final PackageParser.Service service = info.service; 9953 PackageSetting ps = (PackageSetting) service.owner.mExtras; 9954 if (ps == null) { 9955 return null; 9956 } 9957 ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags, 9958 ps.readUserState(userId), userId); 9959 if (si == null) { 9960 return null; 9961 } 9962 final ResolveInfo res = new ResolveInfo(); 9963 res.serviceInfo = si; 9964 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 9965 res.filter = filter; 9966 } 9967 res.priority = info.getPriority(); 9968 res.preferredOrder = service.owner.mPreferredOrder; 9969 res.match = match; 9970 res.isDefault = info.hasDefault; 9971 res.labelRes = info.labelRes; 9972 res.nonLocalizedLabel = info.nonLocalizedLabel; 9973 res.icon = info.icon; 9974 res.system = res.serviceInfo.applicationInfo.isSystemApp(); 9975 return res; 9976 } 9977 9978 @Override 9979 protected void sortResults(List<ResolveInfo> results) { 9980 Collections.sort(results, mResolvePrioritySorter); 9981 } 9982 9983 @Override 9984 protected void dumpFilter(PrintWriter out, String prefix, 9985 PackageParser.ServiceIntentInfo filter) { 9986 out.print(prefix); out.print( 9987 Integer.toHexString(System.identityHashCode(filter.service))); 9988 out.print(' '); 9989 filter.service.printComponentShortName(out); 9990 out.print(" filter "); 9991 out.println(Integer.toHexString(System.identityHashCode(filter))); 9992 } 9993 9994 @Override 9995 protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) { 9996 return filter.service; 9997 } 9998 9999 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 10000 PackageParser.Service service = (PackageParser.Service)label; 10001 out.print(prefix); out.print( 10002 Integer.toHexString(System.identityHashCode(service))); 10003 out.print(' '); 10004 service.printComponentShortName(out); 10005 if (count > 1) { 10006 out.print(" ("); out.print(count); out.print(" filters)"); 10007 } 10008 out.println(); 10009 } 10010 10011// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 10012// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 10013// final List<ResolveInfo> retList = Lists.newArrayList(); 10014// while (i.hasNext()) { 10015// final ResolveInfo resolveInfo = (ResolveInfo) i; 10016// if (isEnabledLP(resolveInfo.serviceInfo)) { 10017// retList.add(resolveInfo); 10018// } 10019// } 10020// return retList; 10021// } 10022 10023 // Keys are String (activity class name), values are Activity. 10024 private final ArrayMap<ComponentName, PackageParser.Service> mServices 10025 = new ArrayMap<ComponentName, PackageParser.Service>(); 10026 private int mFlags; 10027 }; 10028 10029 private final class ProviderIntentResolver 10030 extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> { 10031 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 10032 boolean defaultOnly, int userId) { 10033 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 10034 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 10035 } 10036 10037 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 10038 int userId) { 10039 if (!sUserManager.exists(userId)) 10040 return null; 10041 mFlags = flags; 10042 return super.queryIntent(intent, resolvedType, 10043 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 10044 } 10045 10046 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 10047 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) { 10048 if (!sUserManager.exists(userId)) 10049 return null; 10050 if (packageProviders == null) { 10051 return null; 10052 } 10053 mFlags = flags; 10054 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; 10055 final int N = packageProviders.size(); 10056 ArrayList<PackageParser.ProviderIntentInfo[]> listCut = 10057 new ArrayList<PackageParser.ProviderIntentInfo[]>(N); 10058 10059 ArrayList<PackageParser.ProviderIntentInfo> intentFilters; 10060 for (int i = 0; i < N; ++i) { 10061 intentFilters = packageProviders.get(i).intents; 10062 if (intentFilters != null && intentFilters.size() > 0) { 10063 PackageParser.ProviderIntentInfo[] array = 10064 new PackageParser.ProviderIntentInfo[intentFilters.size()]; 10065 intentFilters.toArray(array); 10066 listCut.add(array); 10067 } 10068 } 10069 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 10070 } 10071 10072 public final void addProvider(PackageParser.Provider p) { 10073 if (mProviders.containsKey(p.getComponentName())) { 10074 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring"); 10075 return; 10076 } 10077 10078 mProviders.put(p.getComponentName(), p); 10079 if (DEBUG_SHOW_INFO) { 10080 Log.v(TAG, " " 10081 + (p.info.nonLocalizedLabel != null 10082 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 10083 Log.v(TAG, " Class=" + p.info.name); 10084 } 10085 final int NI = p.intents.size(); 10086 int j; 10087 for (j = 0; j < NI; j++) { 10088 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 10089 if (DEBUG_SHOW_INFO) { 10090 Log.v(TAG, " IntentFilter:"); 10091 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10092 } 10093 if (!intent.debugCheck()) { 10094 Log.w(TAG, "==> For Provider " + p.info.name); 10095 } 10096 addFilter(intent); 10097 } 10098 } 10099 10100 public final void removeProvider(PackageParser.Provider p) { 10101 mProviders.remove(p.getComponentName()); 10102 if (DEBUG_SHOW_INFO) { 10103 Log.v(TAG, " " + (p.info.nonLocalizedLabel != null 10104 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 10105 Log.v(TAG, " Class=" + p.info.name); 10106 } 10107 final int NI = p.intents.size(); 10108 int j; 10109 for (j = 0; j < NI; j++) { 10110 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 10111 if (DEBUG_SHOW_INFO) { 10112 Log.v(TAG, " IntentFilter:"); 10113 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10114 } 10115 removeFilter(intent); 10116 } 10117 } 10118 10119 @Override 10120 protected boolean allowFilterResult( 10121 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) { 10122 ProviderInfo filterPi = filter.provider.info; 10123 for (int i = dest.size() - 1; i >= 0; i--) { 10124 ProviderInfo destPi = dest.get(i).providerInfo; 10125 if (destPi.name == filterPi.name 10126 && destPi.packageName == filterPi.packageName) { 10127 return false; 10128 } 10129 } 10130 return true; 10131 } 10132 10133 @Override 10134 protected PackageParser.ProviderIntentInfo[] newArray(int size) { 10135 return new PackageParser.ProviderIntentInfo[size]; 10136 } 10137 10138 @Override 10139 protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) { 10140 if (!sUserManager.exists(userId)) 10141 return true; 10142 PackageParser.Package p = filter.provider.owner; 10143 if (p != null) { 10144 PackageSetting ps = (PackageSetting) p.mExtras; 10145 if (ps != null) { 10146 // System apps are never considered stopped for purposes of 10147 // filtering, because there may be no way for the user to 10148 // actually re-launch them. 10149 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 10150 && ps.getStopped(userId); 10151 } 10152 } 10153 return false; 10154 } 10155 10156 @Override 10157 protected boolean isPackageForFilter(String packageName, 10158 PackageParser.ProviderIntentInfo info) { 10159 return packageName.equals(info.provider.owner.packageName); 10160 } 10161 10162 @Override 10163 protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter, 10164 int match, int userId) { 10165 if (!sUserManager.exists(userId)) 10166 return null; 10167 final PackageParser.ProviderIntentInfo info = filter; 10168 if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) { 10169 return null; 10170 } 10171 final PackageParser.Provider provider = info.provider; 10172 PackageSetting ps = (PackageSetting) provider.owner.mExtras; 10173 if (ps == null) { 10174 return null; 10175 } 10176 ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags, 10177 ps.readUserState(userId), userId); 10178 if (pi == null) { 10179 return null; 10180 } 10181 final ResolveInfo res = new ResolveInfo(); 10182 res.providerInfo = pi; 10183 if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) { 10184 res.filter = filter; 10185 } 10186 res.priority = info.getPriority(); 10187 res.preferredOrder = provider.owner.mPreferredOrder; 10188 res.match = match; 10189 res.isDefault = info.hasDefault; 10190 res.labelRes = info.labelRes; 10191 res.nonLocalizedLabel = info.nonLocalizedLabel; 10192 res.icon = info.icon; 10193 res.system = res.providerInfo.applicationInfo.isSystemApp(); 10194 return res; 10195 } 10196 10197 @Override 10198 protected void sortResults(List<ResolveInfo> results) { 10199 Collections.sort(results, mResolvePrioritySorter); 10200 } 10201 10202 @Override 10203 protected void dumpFilter(PrintWriter out, String prefix, 10204 PackageParser.ProviderIntentInfo filter) { 10205 out.print(prefix); 10206 out.print( 10207 Integer.toHexString(System.identityHashCode(filter.provider))); 10208 out.print(' '); 10209 filter.provider.printComponentShortName(out); 10210 out.print(" filter "); 10211 out.println(Integer.toHexString(System.identityHashCode(filter))); 10212 } 10213 10214 @Override 10215 protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) { 10216 return filter.provider; 10217 } 10218 10219 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 10220 PackageParser.Provider provider = (PackageParser.Provider)label; 10221 out.print(prefix); out.print( 10222 Integer.toHexString(System.identityHashCode(provider))); 10223 out.print(' '); 10224 provider.printComponentShortName(out); 10225 if (count > 1) { 10226 out.print(" ("); out.print(count); out.print(" filters)"); 10227 } 10228 out.println(); 10229 } 10230 10231 private final ArrayMap<ComponentName, PackageParser.Provider> mProviders 10232 = new ArrayMap<ComponentName, PackageParser.Provider>(); 10233 private int mFlags; 10234 } 10235 10236 private static final class EphemeralIntentResolver 10237 extends IntentResolver<EphemeralResolveIntentInfo, EphemeralResolveInfo> { 10238 @Override 10239 protected EphemeralResolveIntentInfo[] newArray(int size) { 10240 return new EphemeralResolveIntentInfo[size]; 10241 } 10242 10243 @Override 10244 protected boolean isPackageForFilter(String packageName, EphemeralResolveIntentInfo info) { 10245 return true; 10246 } 10247 10248 @Override 10249 protected EphemeralResolveInfo newResult(EphemeralResolveIntentInfo info, int match, 10250 int userId) { 10251 if (!sUserManager.exists(userId)) { 10252 return null; 10253 } 10254 return info.getEphemeralResolveInfo(); 10255 } 10256 } 10257 10258 private static final Comparator<ResolveInfo> mResolvePrioritySorter = 10259 new Comparator<ResolveInfo>() { 10260 public int compare(ResolveInfo r1, ResolveInfo r2) { 10261 int v1 = r1.priority; 10262 int v2 = r2.priority; 10263 //System.out.println("Comparing: q1=" + q1 + " q2=" + q2); 10264 if (v1 != v2) { 10265 return (v1 > v2) ? -1 : 1; 10266 } 10267 v1 = r1.preferredOrder; 10268 v2 = r2.preferredOrder; 10269 if (v1 != v2) { 10270 return (v1 > v2) ? -1 : 1; 10271 } 10272 if (r1.isDefault != r2.isDefault) { 10273 return r1.isDefault ? -1 : 1; 10274 } 10275 v1 = r1.match; 10276 v2 = r2.match; 10277 //System.out.println("Comparing: m1=" + m1 + " m2=" + m2); 10278 if (v1 != v2) { 10279 return (v1 > v2) ? -1 : 1; 10280 } 10281 if (r1.system != r2.system) { 10282 return r1.system ? -1 : 1; 10283 } 10284 if (r1.activityInfo != null) { 10285 return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName); 10286 } 10287 if (r1.serviceInfo != null) { 10288 return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName); 10289 } 10290 if (r1.providerInfo != null) { 10291 return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName); 10292 } 10293 return 0; 10294 } 10295 }; 10296 10297 private static final Comparator<ProviderInfo> mProviderInitOrderSorter = 10298 new Comparator<ProviderInfo>() { 10299 public int compare(ProviderInfo p1, ProviderInfo p2) { 10300 final int v1 = p1.initOrder; 10301 final int v2 = p2.initOrder; 10302 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0); 10303 } 10304 }; 10305 10306 final void sendPackageBroadcast(final String action, final String pkg, final Bundle extras, 10307 final int flags, final String targetPkg, final IIntentReceiver finishedReceiver, 10308 final int[] userIds) { 10309 mHandler.post(new Runnable() { 10310 @Override 10311 public void run() { 10312 try { 10313 final IActivityManager am = ActivityManagerNative.getDefault(); 10314 if (am == null) return; 10315 final int[] resolvedUserIds; 10316 if (userIds == null) { 10317 resolvedUserIds = am.getRunningUserIds(); 10318 } else { 10319 resolvedUserIds = userIds; 10320 } 10321 for (int id : resolvedUserIds) { 10322 final Intent intent = new Intent(action, 10323 pkg != null ? Uri.fromParts("package", pkg, null) : null); 10324 if (extras != null) { 10325 intent.putExtras(extras); 10326 } 10327 if (targetPkg != null) { 10328 intent.setPackage(targetPkg); 10329 } 10330 // Modify the UID when posting to other users 10331 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); 10332 if (uid > 0 && UserHandle.getUserId(uid) != id) { 10333 uid = UserHandle.getUid(id, UserHandle.getAppId(uid)); 10334 intent.putExtra(Intent.EXTRA_UID, uid); 10335 } 10336 intent.putExtra(Intent.EXTRA_USER_HANDLE, id); 10337 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags); 10338 if (DEBUG_BROADCASTS) { 10339 RuntimeException here = new RuntimeException("here"); 10340 here.fillInStackTrace(); 10341 Slog.d(TAG, "Sending to user " + id + ": " 10342 + intent.toShortString(false, true, false, false) 10343 + " " + intent.getExtras(), here); 10344 } 10345 am.broadcastIntent(null, intent, null, finishedReceiver, 10346 0, null, null, null, android.app.AppOpsManager.OP_NONE, 10347 null, finishedReceiver != null, false, id); 10348 } 10349 } catch (RemoteException ex) { 10350 } 10351 } 10352 }); 10353 } 10354 10355 /** 10356 * Check if the external storage media is available. This is true if there 10357 * is a mounted external storage medium or if the external storage is 10358 * emulated. 10359 */ 10360 private boolean isExternalMediaAvailable() { 10361 return mMediaMounted || Environment.isExternalStorageEmulated(); 10362 } 10363 10364 @Override 10365 public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) { 10366 // writer 10367 synchronized (mPackages) { 10368 if (!isExternalMediaAvailable()) { 10369 // If the external storage is no longer mounted at this point, 10370 // the caller may not have been able to delete all of this 10371 // packages files and can not delete any more. Bail. 10372 return null; 10373 } 10374 final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned; 10375 if (lastPackage != null) { 10376 pkgs.remove(lastPackage); 10377 } 10378 if (pkgs.size() > 0) { 10379 return pkgs.get(0); 10380 } 10381 } 10382 return null; 10383 } 10384 10385 void schedulePackageCleaning(String packageName, int userId, boolean andCode) { 10386 final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE, 10387 userId, andCode ? 1 : 0, packageName); 10388 if (mSystemReady) { 10389 msg.sendToTarget(); 10390 } else { 10391 if (mPostSystemReadyMessages == null) { 10392 mPostSystemReadyMessages = new ArrayList<>(); 10393 } 10394 mPostSystemReadyMessages.add(msg); 10395 } 10396 } 10397 10398 void startCleaningPackages() { 10399 // reader 10400 synchronized (mPackages) { 10401 if (!isExternalMediaAvailable()) { 10402 return; 10403 } 10404 if (mSettings.mPackagesToBeCleaned.isEmpty()) { 10405 return; 10406 } 10407 } 10408 Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE); 10409 intent.setComponent(DEFAULT_CONTAINER_COMPONENT); 10410 IActivityManager am = ActivityManagerNative.getDefault(); 10411 if (am != null) { 10412 try { 10413 am.startService(null, intent, null, mContext.getOpPackageName(), 10414 UserHandle.USER_SYSTEM); 10415 } catch (RemoteException e) { 10416 } 10417 } 10418 } 10419 10420 @Override 10421 public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer, 10422 int installFlags, String installerPackageName, int userId) { 10423 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null); 10424 10425 final int callingUid = Binder.getCallingUid(); 10426 enforceCrossUserPermission(callingUid, userId, 10427 true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser"); 10428 10429 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 10430 try { 10431 if (observer != null) { 10432 observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null); 10433 } 10434 } catch (RemoteException re) { 10435 } 10436 return; 10437 } 10438 10439 if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) { 10440 installFlags |= PackageManager.INSTALL_FROM_ADB; 10441 10442 } else { 10443 // Caller holds INSTALL_PACKAGES permission, so we're less strict 10444 // about installerPackageName. 10445 10446 installFlags &= ~PackageManager.INSTALL_FROM_ADB; 10447 installFlags &= ~PackageManager.INSTALL_ALL_USERS; 10448 } 10449 10450 UserHandle user; 10451 if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) { 10452 user = UserHandle.ALL; 10453 } else { 10454 user = new UserHandle(userId); 10455 } 10456 10457 // Only system components can circumvent runtime permissions when installing. 10458 if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0 10459 && mContext.checkCallingOrSelfPermission(Manifest.permission 10460 .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) { 10461 throw new SecurityException("You need the " 10462 + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission " 10463 + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag"); 10464 } 10465 10466 final File originFile = new File(originPath); 10467 final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile); 10468 10469 final Message msg = mHandler.obtainMessage(INIT_COPY); 10470 final VerificationInfo verificationInfo = new VerificationInfo( 10471 null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid); 10472 final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer, 10473 installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user, 10474 null /*packageAbiOverride*/, null /*grantedPermissions*/); 10475 params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params)); 10476 msg.obj = params; 10477 10478 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser", 10479 System.identityHashCode(msg.obj)); 10480 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 10481 System.identityHashCode(msg.obj)); 10482 10483 mHandler.sendMessage(msg); 10484 } 10485 10486 void installStage(String packageName, File stagedDir, String stagedCid, 10487 IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams, 10488 String installerPackageName, int installerUid, UserHandle user) { 10489 if (DEBUG_EPHEMERAL) { 10490 if ((sessionParams.installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) { 10491 Slog.d(TAG, "Ephemeral install of " + packageName); 10492 } 10493 } 10494 final VerificationInfo verificationInfo = new VerificationInfo( 10495 sessionParams.originatingUri, sessionParams.referrerUri, 10496 sessionParams.originatingUid, installerUid); 10497 10498 final OriginInfo origin; 10499 if (stagedDir != null) { 10500 origin = OriginInfo.fromStagedFile(stagedDir); 10501 } else { 10502 origin = OriginInfo.fromStagedContainer(stagedCid); 10503 } 10504 10505 final Message msg = mHandler.obtainMessage(INIT_COPY); 10506 final InstallParams params = new InstallParams(origin, null, observer, 10507 sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid, 10508 verificationInfo, user, sessionParams.abiOverride, 10509 sessionParams.grantedRuntimePermissions); 10510 params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params)); 10511 msg.obj = params; 10512 10513 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage", 10514 System.identityHashCode(msg.obj)); 10515 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 10516 System.identityHashCode(msg.obj)); 10517 10518 mHandler.sendMessage(msg); 10519 } 10520 10521 private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, 10522 int userId) { 10523 final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting); 10524 sendPackageAddedForUser(packageName, isSystem, pkgSetting.appId, userId); 10525 } 10526 10527 private void sendPackageAddedForUser(String packageName, boolean isSystem, 10528 int appId, int userId) { 10529 Bundle extras = new Bundle(1); 10530 extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, appId)); 10531 10532 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 10533 packageName, extras, 0, null, null, new int[] {userId}); 10534 try { 10535 IActivityManager am = ActivityManagerNative.getDefault(); 10536 if (isSystem && am.isUserRunning(userId, 0)) { 10537 // The just-installed/enabled app is bundled on the system, so presumed 10538 // to be able to run automatically without needing an explicit launch. 10539 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one. 10540 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED) 10541 .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES) 10542 .setPackage(packageName); 10543 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null, 10544 android.app.AppOpsManager.OP_NONE, null, false, false, userId); 10545 } 10546 } catch (RemoteException e) { 10547 // shouldn't happen 10548 Slog.w(TAG, "Unable to bootstrap installed package", e); 10549 } 10550 } 10551 10552 @Override 10553 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, 10554 int userId) { 10555 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 10556 PackageSetting pkgSetting; 10557 final int uid = Binder.getCallingUid(); 10558 enforceCrossUserPermission(uid, userId, 10559 true /* requireFullPermission */, true /* checkShell */, 10560 "setApplicationHiddenSetting for user " + userId); 10561 10562 if (hidden && isPackageDeviceAdmin(packageName, userId)) { 10563 Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin"); 10564 return false; 10565 } 10566 10567 long callingId = Binder.clearCallingIdentity(); 10568 try { 10569 boolean sendAdded = false; 10570 boolean sendRemoved = false; 10571 // writer 10572 synchronized (mPackages) { 10573 pkgSetting = mSettings.mPackages.get(packageName); 10574 if (pkgSetting == null) { 10575 return false; 10576 } 10577 if (pkgSetting.getHidden(userId) != hidden) { 10578 pkgSetting.setHidden(hidden, userId); 10579 mSettings.writePackageRestrictionsLPr(userId); 10580 if (hidden) { 10581 sendRemoved = true; 10582 } else { 10583 sendAdded = true; 10584 } 10585 } 10586 } 10587 if (sendAdded) { 10588 sendPackageAddedForUser(packageName, pkgSetting, userId); 10589 return true; 10590 } 10591 if (sendRemoved) { 10592 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId), 10593 "hiding pkg"); 10594 sendApplicationHiddenForUser(packageName, pkgSetting, userId); 10595 return true; 10596 } 10597 } finally { 10598 Binder.restoreCallingIdentity(callingId); 10599 } 10600 return false; 10601 } 10602 10603 private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting, 10604 int userId) { 10605 final PackageRemovedInfo info = new PackageRemovedInfo(); 10606 info.removedPackage = packageName; 10607 info.removedUsers = new int[] {userId}; 10608 info.uid = UserHandle.getUid(userId, pkgSetting.appId); 10609 info.sendPackageRemovedBroadcasts(true /*killApp*/); 10610 } 10611 10612 private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) { 10613 if (pkgList.length > 0) { 10614 Bundle extras = new Bundle(1); 10615 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 10616 10617 sendPackageBroadcast( 10618 suspended ? Intent.ACTION_PACKAGES_SUSPENDED 10619 : Intent.ACTION_PACKAGES_UNSUSPENDED, 10620 null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null, 10621 new int[] {userId}); 10622 } 10623 } 10624 10625 /** 10626 * Returns true if application is not found or there was an error. Otherwise it returns 10627 * the hidden state of the package for the given user. 10628 */ 10629 @Override 10630 public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) { 10631 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 10632 enforceCrossUserPermission(Binder.getCallingUid(), userId, 10633 true /* requireFullPermission */, false /* checkShell */, 10634 "getApplicationHidden for user " + userId); 10635 PackageSetting pkgSetting; 10636 long callingId = Binder.clearCallingIdentity(); 10637 try { 10638 // writer 10639 synchronized (mPackages) { 10640 pkgSetting = mSettings.mPackages.get(packageName); 10641 if (pkgSetting == null) { 10642 return true; 10643 } 10644 return pkgSetting.getHidden(userId); 10645 } 10646 } finally { 10647 Binder.restoreCallingIdentity(callingId); 10648 } 10649 } 10650 10651 /** 10652 * @hide 10653 */ 10654 @Override 10655 public int installExistingPackageAsUser(String packageName, int userId) { 10656 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, 10657 null); 10658 PackageSetting pkgSetting; 10659 final int uid = Binder.getCallingUid(); 10660 enforceCrossUserPermission(uid, userId, 10661 true /* requireFullPermission */, true /* checkShell */, 10662 "installExistingPackage for user " + userId); 10663 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 10664 return PackageManager.INSTALL_FAILED_USER_RESTRICTED; 10665 } 10666 10667 long callingId = Binder.clearCallingIdentity(); 10668 try { 10669 boolean installed = false; 10670 10671 // writer 10672 synchronized (mPackages) { 10673 pkgSetting = mSettings.mPackages.get(packageName); 10674 if (pkgSetting == null) { 10675 return PackageManager.INSTALL_FAILED_INVALID_URI; 10676 } 10677 if (!pkgSetting.getInstalled(userId)) { 10678 pkgSetting.setInstalled(true, userId); 10679 pkgSetting.setHidden(false, userId); 10680 mSettings.writePackageRestrictionsLPr(userId); 10681 installed = true; 10682 } 10683 } 10684 10685 if (installed) { 10686 if (pkgSetting.pkg != null) { 10687 prepareAppDataAfterInstall(pkgSetting.pkg); 10688 } 10689 sendPackageAddedForUser(packageName, pkgSetting, userId); 10690 } 10691 } finally { 10692 Binder.restoreCallingIdentity(callingId); 10693 } 10694 10695 return PackageManager.INSTALL_SUCCEEDED; 10696 } 10697 10698 boolean isUserRestricted(int userId, String restrictionKey) { 10699 Bundle restrictions = sUserManager.getUserRestrictions(userId); 10700 if (restrictions.getBoolean(restrictionKey, false)) { 10701 Log.w(TAG, "User is restricted: " + restrictionKey); 10702 return true; 10703 } 10704 return false; 10705 } 10706 10707 @Override 10708 public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended, 10709 int userId) { 10710 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 10711 enforceCrossUserPermission(Binder.getCallingUid(), userId, 10712 true /* requireFullPermission */, true /* checkShell */, 10713 "setPackagesSuspended for user " + userId); 10714 10715 if (ArrayUtils.isEmpty(packageNames)) { 10716 return packageNames; 10717 } 10718 10719 // List of package names for whom the suspended state has changed. 10720 List<String> changedPackages = new ArrayList<>(packageNames.length); 10721 // List of package names for whom the suspended state is not set as requested in this 10722 // method. 10723 List<String> unactionedPackages = new ArrayList<>(packageNames.length); 10724 for (int i = 0; i < packageNames.length; i++) { 10725 String packageName = packageNames[i]; 10726 long callingId = Binder.clearCallingIdentity(); 10727 try { 10728 boolean changed = false; 10729 final int appId; 10730 synchronized (mPackages) { 10731 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName); 10732 if (pkgSetting == null) { 10733 Slog.w(TAG, "Could not find package setting for package \"" + packageName 10734 + "\". Skipping suspending/un-suspending."); 10735 unactionedPackages.add(packageName); 10736 continue; 10737 } 10738 appId = pkgSetting.appId; 10739 if (pkgSetting.getSuspended(userId) != suspended) { 10740 if (!canSuspendPackageForUserLocked(packageName, userId)) { 10741 unactionedPackages.add(packageName); 10742 continue; 10743 } 10744 pkgSetting.setSuspended(suspended, userId); 10745 mSettings.writePackageRestrictionsLPr(userId); 10746 changed = true; 10747 changedPackages.add(packageName); 10748 } 10749 } 10750 10751 if (changed && suspended) { 10752 killApplication(packageName, UserHandle.getUid(userId, appId), 10753 "suspending package"); 10754 } 10755 } finally { 10756 Binder.restoreCallingIdentity(callingId); 10757 } 10758 } 10759 10760 if (!changedPackages.isEmpty()) { 10761 sendPackagesSuspendedForUser(changedPackages.toArray( 10762 new String[changedPackages.size()]), userId, suspended); 10763 } 10764 10765 return unactionedPackages.toArray(new String[unactionedPackages.size()]); 10766 } 10767 10768 @Override 10769 public boolean isPackageSuspendedForUser(String packageName, int userId) { 10770 enforceCrossUserPermission(Binder.getCallingUid(), userId, 10771 true /* requireFullPermission */, false /* checkShell */, 10772 "isPackageSuspendedForUser for user " + userId); 10773 synchronized (mPackages) { 10774 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName); 10775 return pkgSetting != null && pkgSetting.getSuspended(userId); 10776 } 10777 } 10778 10779 // TODO: investigate and add more restrictions for suspending crucial packages. 10780 private boolean canSuspendPackageForUserLocked(String packageName, int userId) { 10781 if (isPackageDeviceAdmin(packageName, userId)) { 10782 Slog.w(TAG, "Not suspending/un-suspending package \"" + packageName 10783 + "\": has active device admin"); 10784 return false; 10785 } 10786 10787 String activeLauncherPackageName = getActiveLauncherPackageName(userId); 10788 if (packageName.equals(activeLauncherPackageName)) { 10789 Slog.w(TAG, "Not suspending/un-suspending package \"" + packageName 10790 + "\" because it is set as the active launcher"); 10791 return false; 10792 } 10793 10794 final PackageParser.Package pkg = mPackages.get(packageName); 10795 if (pkg != null && isPrivilegedApp(pkg)) { 10796 Slog.w(TAG, "Not suspending/un-suspending package \"" + packageName 10797 + "\" because it is a privileged app"); 10798 return false; 10799 } 10800 10801 return true; 10802 } 10803 10804 private String getActiveLauncherPackageName(int userId) { 10805 Intent intent = new Intent(Intent.ACTION_MAIN); 10806 intent.addCategory(Intent.CATEGORY_HOME); 10807 ResolveInfo resolveInfo = resolveIntent( 10808 intent, 10809 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 10810 PackageManager.MATCH_DEFAULT_ONLY, 10811 userId); 10812 10813 return resolveInfo == null ? null : resolveInfo.activityInfo.packageName; 10814 } 10815 10816 @Override 10817 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException { 10818 mContext.enforceCallingOrSelfPermission( 10819 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 10820 "Only package verification agents can verify applications"); 10821 10822 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 10823 final PackageVerificationResponse response = new PackageVerificationResponse( 10824 verificationCode, Binder.getCallingUid()); 10825 msg.arg1 = id; 10826 msg.obj = response; 10827 mHandler.sendMessage(msg); 10828 } 10829 10830 @Override 10831 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, 10832 long millisecondsToDelay) { 10833 mContext.enforceCallingOrSelfPermission( 10834 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 10835 "Only package verification agents can extend verification timeouts"); 10836 10837 final PackageVerificationState state = mPendingVerification.get(id); 10838 final PackageVerificationResponse response = new PackageVerificationResponse( 10839 verificationCodeAtTimeout, Binder.getCallingUid()); 10840 10841 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) { 10842 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT; 10843 } 10844 if (millisecondsToDelay < 0) { 10845 millisecondsToDelay = 0; 10846 } 10847 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW) 10848 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) { 10849 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT; 10850 } 10851 10852 if ((state != null) && !state.timeoutExtended()) { 10853 state.extendTimeout(); 10854 10855 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 10856 msg.arg1 = id; 10857 msg.obj = response; 10858 mHandler.sendMessageDelayed(msg, millisecondsToDelay); 10859 } 10860 } 10861 10862 private void broadcastPackageVerified(int verificationId, Uri packageUri, 10863 int verificationCode, UserHandle user) { 10864 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED); 10865 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE); 10866 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 10867 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 10868 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode); 10869 10870 mContext.sendBroadcastAsUser(intent, user, 10871 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT); 10872 } 10873 10874 private ComponentName matchComponentForVerifier(String packageName, 10875 List<ResolveInfo> receivers) { 10876 ActivityInfo targetReceiver = null; 10877 10878 final int NR = receivers.size(); 10879 for (int i = 0; i < NR; i++) { 10880 final ResolveInfo info = receivers.get(i); 10881 if (info.activityInfo == null) { 10882 continue; 10883 } 10884 10885 if (packageName.equals(info.activityInfo.packageName)) { 10886 targetReceiver = info.activityInfo; 10887 break; 10888 } 10889 } 10890 10891 if (targetReceiver == null) { 10892 return null; 10893 } 10894 10895 return new ComponentName(targetReceiver.packageName, targetReceiver.name); 10896 } 10897 10898 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo, 10899 List<ResolveInfo> receivers, final PackageVerificationState verificationState) { 10900 if (pkgInfo.verifiers.length == 0) { 10901 return null; 10902 } 10903 10904 final int N = pkgInfo.verifiers.length; 10905 final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1); 10906 for (int i = 0; i < N; i++) { 10907 final VerifierInfo verifierInfo = pkgInfo.verifiers[i]; 10908 10909 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName, 10910 receivers); 10911 if (comp == null) { 10912 continue; 10913 } 10914 10915 final int verifierUid = getUidForVerifier(verifierInfo); 10916 if (verifierUid == -1) { 10917 continue; 10918 } 10919 10920 if (DEBUG_VERIFY) { 10921 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName 10922 + " with the correct signature"); 10923 } 10924 sufficientVerifiers.add(comp); 10925 verificationState.addSufficientVerifier(verifierUid); 10926 } 10927 10928 return sufficientVerifiers; 10929 } 10930 10931 private int getUidForVerifier(VerifierInfo verifierInfo) { 10932 synchronized (mPackages) { 10933 final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName); 10934 if (pkg == null) { 10935 return -1; 10936 } else if (pkg.mSignatures.length != 1) { 10937 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 10938 + " has more than one signature; ignoring"); 10939 return -1; 10940 } 10941 10942 /* 10943 * If the public key of the package's signature does not match 10944 * our expected public key, then this is a different package and 10945 * we should skip. 10946 */ 10947 10948 final byte[] expectedPublicKey; 10949 try { 10950 final Signature verifierSig = pkg.mSignatures[0]; 10951 final PublicKey publicKey = verifierSig.getPublicKey(); 10952 expectedPublicKey = publicKey.getEncoded(); 10953 } catch (CertificateException e) { 10954 return -1; 10955 } 10956 10957 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded(); 10958 10959 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) { 10960 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 10961 + " does not have the expected public key; ignoring"); 10962 return -1; 10963 } 10964 10965 return pkg.applicationInfo.uid; 10966 } 10967 } 10968 10969 @Override 10970 public void finishPackageInstall(int token) { 10971 enforceSystemOrRoot("Only the system is allowed to finish installs"); 10972 10973 if (DEBUG_INSTALL) { 10974 Slog.v(TAG, "BM finishing package install for " + token); 10975 } 10976 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token); 10977 10978 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 10979 mHandler.sendMessage(msg); 10980 } 10981 10982 /** 10983 * Get the verification agent timeout. 10984 * 10985 * @return verification timeout in milliseconds 10986 */ 10987 private long getVerificationTimeout() { 10988 return android.provider.Settings.Global.getLong(mContext.getContentResolver(), 10989 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT, 10990 DEFAULT_VERIFICATION_TIMEOUT); 10991 } 10992 10993 /** 10994 * Get the default verification agent response code. 10995 * 10996 * @return default verification response code 10997 */ 10998 private int getDefaultVerificationResponse() { 10999 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 11000 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE, 11001 DEFAULT_VERIFICATION_RESPONSE); 11002 } 11003 11004 /** 11005 * Check whether or not package verification has been enabled. 11006 * 11007 * @return true if verification should be performed 11008 */ 11009 private boolean isVerificationEnabled(int userId, int installFlags) { 11010 if (!DEFAULT_VERIFY_ENABLE) { 11011 return false; 11012 } 11013 // Ephemeral apps don't get the full verification treatment 11014 if ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) { 11015 if (DEBUG_EPHEMERAL) { 11016 Slog.d(TAG, "INSTALL_EPHEMERAL so skipping verification"); 11017 } 11018 return false; 11019 } 11020 11021 boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS); 11022 11023 // Check if installing from ADB 11024 if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) { 11025 // Do not run verification in a test harness environment 11026 if (ActivityManager.isRunningInTestHarness()) { 11027 return false; 11028 } 11029 if (ensureVerifyAppsEnabled) { 11030 return true; 11031 } 11032 // Check if the developer does not want package verification for ADB installs 11033 if (android.provider.Settings.Global.getInt(mContext.getContentResolver(), 11034 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) { 11035 return false; 11036 } 11037 } 11038 11039 if (ensureVerifyAppsEnabled) { 11040 return true; 11041 } 11042 11043 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 11044 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1; 11045 } 11046 11047 @Override 11048 public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains) 11049 throws RemoteException { 11050 mContext.enforceCallingOrSelfPermission( 11051 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 11052 "Only intentfilter verification agents can verify applications"); 11053 11054 final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED); 11055 final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse( 11056 Binder.getCallingUid(), verificationCode, failedDomains); 11057 msg.arg1 = id; 11058 msg.obj = response; 11059 mHandler.sendMessage(msg); 11060 } 11061 11062 @Override 11063 public int getIntentVerificationStatus(String packageName, int userId) { 11064 synchronized (mPackages) { 11065 return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 11066 } 11067 } 11068 11069 @Override 11070 public boolean updateIntentVerificationStatus(String packageName, int status, int userId) { 11071 mContext.enforceCallingOrSelfPermission( 11072 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 11073 11074 boolean result = false; 11075 synchronized (mPackages) { 11076 result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId); 11077 } 11078 if (result) { 11079 scheduleWritePackageRestrictionsLocked(userId); 11080 } 11081 return result; 11082 } 11083 11084 @Override 11085 public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) { 11086 synchronized (mPackages) { 11087 return mSettings.getIntentFilterVerificationsLPr(packageName); 11088 } 11089 } 11090 11091 @Override 11092 public List<IntentFilter> getAllIntentFilters(String packageName) { 11093 if (TextUtils.isEmpty(packageName)) { 11094 return Collections.<IntentFilter>emptyList(); 11095 } 11096 synchronized (mPackages) { 11097 PackageParser.Package pkg = mPackages.get(packageName); 11098 if (pkg == null || pkg.activities == null) { 11099 return Collections.<IntentFilter>emptyList(); 11100 } 11101 final int count = pkg.activities.size(); 11102 ArrayList<IntentFilter> result = new ArrayList<>(); 11103 for (int n=0; n<count; n++) { 11104 PackageParser.Activity activity = pkg.activities.get(n); 11105 if (activity.intents != null && activity.intents.size() > 0) { 11106 result.addAll(activity.intents); 11107 } 11108 } 11109 return result; 11110 } 11111 } 11112 11113 @Override 11114 public boolean setDefaultBrowserPackageName(String packageName, int userId) { 11115 mContext.enforceCallingOrSelfPermission( 11116 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 11117 11118 synchronized (mPackages) { 11119 boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId); 11120 if (packageName != null) { 11121 result |= updateIntentVerificationStatus(packageName, 11122 PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, 11123 userId); 11124 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr( 11125 packageName, userId); 11126 } 11127 return result; 11128 } 11129 } 11130 11131 @Override 11132 public String getDefaultBrowserPackageName(int userId) { 11133 synchronized (mPackages) { 11134 return mSettings.getDefaultBrowserPackageNameLPw(userId); 11135 } 11136 } 11137 11138 /** 11139 * Get the "allow unknown sources" setting. 11140 * 11141 * @return the current "allow unknown sources" setting 11142 */ 11143 private int getUnknownSourcesSettings() { 11144 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 11145 android.provider.Settings.Global.INSTALL_NON_MARKET_APPS, 11146 -1); 11147 } 11148 11149 @Override 11150 public void setInstallerPackageName(String targetPackage, String installerPackageName) { 11151 final int uid = Binder.getCallingUid(); 11152 // writer 11153 synchronized (mPackages) { 11154 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage); 11155 if (targetPackageSetting == null) { 11156 throw new IllegalArgumentException("Unknown target package: " + targetPackage); 11157 } 11158 11159 PackageSetting installerPackageSetting; 11160 if (installerPackageName != null) { 11161 installerPackageSetting = mSettings.mPackages.get(installerPackageName); 11162 if (installerPackageSetting == null) { 11163 throw new IllegalArgumentException("Unknown installer package: " 11164 + installerPackageName); 11165 } 11166 } else { 11167 installerPackageSetting = null; 11168 } 11169 11170 Signature[] callerSignature; 11171 Object obj = mSettings.getUserIdLPr(uid); 11172 if (obj != null) { 11173 if (obj instanceof SharedUserSetting) { 11174 callerSignature = ((SharedUserSetting)obj).signatures.mSignatures; 11175 } else if (obj instanceof PackageSetting) { 11176 callerSignature = ((PackageSetting)obj).signatures.mSignatures; 11177 } else { 11178 throw new SecurityException("Bad object " + obj + " for uid " + uid); 11179 } 11180 } else { 11181 throw new SecurityException("Unknown calling UID: " + uid); 11182 } 11183 11184 // Verify: can't set installerPackageName to a package that is 11185 // not signed with the same cert as the caller. 11186 if (installerPackageSetting != null) { 11187 if (compareSignatures(callerSignature, 11188 installerPackageSetting.signatures.mSignatures) 11189 != PackageManager.SIGNATURE_MATCH) { 11190 throw new SecurityException( 11191 "Caller does not have same cert as new installer package " 11192 + installerPackageName); 11193 } 11194 } 11195 11196 // Verify: if target already has an installer package, it must 11197 // be signed with the same cert as the caller. 11198 if (targetPackageSetting.installerPackageName != null) { 11199 PackageSetting setting = mSettings.mPackages.get( 11200 targetPackageSetting.installerPackageName); 11201 // If the currently set package isn't valid, then it's always 11202 // okay to change it. 11203 if (setting != null) { 11204 if (compareSignatures(callerSignature, 11205 setting.signatures.mSignatures) 11206 != PackageManager.SIGNATURE_MATCH) { 11207 throw new SecurityException( 11208 "Caller does not have same cert as old installer package " 11209 + targetPackageSetting.installerPackageName); 11210 } 11211 } 11212 } 11213 11214 // Okay! 11215 targetPackageSetting.installerPackageName = installerPackageName; 11216 scheduleWriteSettingsLocked(); 11217 } 11218 } 11219 11220 private void processPendingInstall(final InstallArgs args, final int currentStatus) { 11221 // Queue up an async operation since the package installation may take a little while. 11222 mHandler.post(new Runnable() { 11223 public void run() { 11224 mHandler.removeCallbacks(this); 11225 // Result object to be returned 11226 PackageInstalledInfo res = new PackageInstalledInfo(); 11227 res.setReturnCode(currentStatus); 11228 res.uid = -1; 11229 res.pkg = null; 11230 res.removedInfo = null; 11231 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 11232 args.doPreInstall(res.returnCode); 11233 synchronized (mInstallLock) { 11234 installPackageTracedLI(args, res); 11235 } 11236 args.doPostInstall(res.returnCode, res.uid); 11237 } 11238 11239 // A restore should be performed at this point if (a) the install 11240 // succeeded, (b) the operation is not an update, and (c) the new 11241 // package has not opted out of backup participation. 11242 final boolean update = res.removedInfo != null 11243 && res.removedInfo.removedPackage != null; 11244 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags; 11245 boolean doRestore = !update 11246 && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0); 11247 11248 // Set up the post-install work request bookkeeping. This will be used 11249 // and cleaned up by the post-install event handling regardless of whether 11250 // there's a restore pass performed. Token values are >= 1. 11251 int token; 11252 if (mNextInstallToken < 0) mNextInstallToken = 1; 11253 token = mNextInstallToken++; 11254 11255 PostInstallData data = new PostInstallData(args, res); 11256 mRunningInstalls.put(token, data); 11257 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token); 11258 11259 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) { 11260 // Pass responsibility to the Backup Manager. It will perform a 11261 // restore if appropriate, then pass responsibility back to the 11262 // Package Manager to run the post-install observer callbacks 11263 // and broadcasts. 11264 IBackupManager bm = IBackupManager.Stub.asInterface( 11265 ServiceManager.getService(Context.BACKUP_SERVICE)); 11266 if (bm != null) { 11267 if (DEBUG_INSTALL) Log.v(TAG, "token " + token 11268 + " to BM for possible restore"); 11269 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token); 11270 try { 11271 // TODO: http://b/22388012 11272 if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) { 11273 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token); 11274 } else { 11275 doRestore = false; 11276 } 11277 } catch (RemoteException e) { 11278 // can't happen; the backup manager is local 11279 } catch (Exception e) { 11280 Slog.e(TAG, "Exception trying to enqueue restore", e); 11281 doRestore = false; 11282 } 11283 } else { 11284 Slog.e(TAG, "Backup Manager not found!"); 11285 doRestore = false; 11286 } 11287 } 11288 11289 if (!doRestore) { 11290 // No restore possible, or the Backup Manager was mysteriously not 11291 // available -- just fire the post-install work request directly. 11292 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token); 11293 11294 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token); 11295 11296 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 11297 mHandler.sendMessage(msg); 11298 } 11299 } 11300 }); 11301 } 11302 11303 private abstract class HandlerParams { 11304 private static final int MAX_RETRIES = 4; 11305 11306 /** 11307 * Number of times startCopy() has been attempted and had a non-fatal 11308 * error. 11309 */ 11310 private int mRetries = 0; 11311 11312 /** User handle for the user requesting the information or installation. */ 11313 private final UserHandle mUser; 11314 String traceMethod; 11315 int traceCookie; 11316 11317 HandlerParams(UserHandle user) { 11318 mUser = user; 11319 } 11320 11321 UserHandle getUser() { 11322 return mUser; 11323 } 11324 11325 HandlerParams setTraceMethod(String traceMethod) { 11326 this.traceMethod = traceMethod; 11327 return this; 11328 } 11329 11330 HandlerParams setTraceCookie(int traceCookie) { 11331 this.traceCookie = traceCookie; 11332 return this; 11333 } 11334 11335 final boolean startCopy() { 11336 boolean res; 11337 try { 11338 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this); 11339 11340 if (++mRetries > MAX_RETRIES) { 11341 Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up"); 11342 mHandler.sendEmptyMessage(MCS_GIVE_UP); 11343 handleServiceError(); 11344 return false; 11345 } else { 11346 handleStartCopy(); 11347 res = true; 11348 } 11349 } catch (RemoteException e) { 11350 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT"); 11351 mHandler.sendEmptyMessage(MCS_RECONNECT); 11352 res = false; 11353 } 11354 handleReturnCode(); 11355 return res; 11356 } 11357 11358 final void serviceError() { 11359 if (DEBUG_INSTALL) Slog.i(TAG, "serviceError"); 11360 handleServiceError(); 11361 handleReturnCode(); 11362 } 11363 11364 abstract void handleStartCopy() throws RemoteException; 11365 abstract void handleServiceError(); 11366 abstract void handleReturnCode(); 11367 } 11368 11369 class MeasureParams extends HandlerParams { 11370 private final PackageStats mStats; 11371 private boolean mSuccess; 11372 11373 private final IPackageStatsObserver mObserver; 11374 11375 public MeasureParams(PackageStats stats, IPackageStatsObserver observer) { 11376 super(new UserHandle(stats.userHandle)); 11377 mObserver = observer; 11378 mStats = stats; 11379 } 11380 11381 @Override 11382 public String toString() { 11383 return "MeasureParams{" 11384 + Integer.toHexString(System.identityHashCode(this)) 11385 + " " + mStats.packageName + "}"; 11386 } 11387 11388 @Override 11389 void handleStartCopy() throws RemoteException { 11390 synchronized (mInstallLock) { 11391 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats); 11392 } 11393 11394 if (mSuccess) { 11395 final boolean mounted; 11396 if (Environment.isExternalStorageEmulated()) { 11397 mounted = true; 11398 } else { 11399 final String status = Environment.getExternalStorageState(); 11400 mounted = (Environment.MEDIA_MOUNTED.equals(status) 11401 || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status)); 11402 } 11403 11404 if (mounted) { 11405 final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle); 11406 11407 mStats.externalCacheSize = calculateDirectorySize(mContainerService, 11408 userEnv.buildExternalStorageAppCacheDirs(mStats.packageName)); 11409 11410 mStats.externalDataSize = calculateDirectorySize(mContainerService, 11411 userEnv.buildExternalStorageAppDataDirs(mStats.packageName)); 11412 11413 // Always subtract cache size, since it's a subdirectory 11414 mStats.externalDataSize -= mStats.externalCacheSize; 11415 11416 mStats.externalMediaSize = calculateDirectorySize(mContainerService, 11417 userEnv.buildExternalStorageAppMediaDirs(mStats.packageName)); 11418 11419 mStats.externalObbSize = calculateDirectorySize(mContainerService, 11420 userEnv.buildExternalStorageAppObbDirs(mStats.packageName)); 11421 } 11422 } 11423 } 11424 11425 @Override 11426 void handleReturnCode() { 11427 if (mObserver != null) { 11428 try { 11429 mObserver.onGetStatsCompleted(mStats, mSuccess); 11430 } catch (RemoteException e) { 11431 Slog.i(TAG, "Observer no longer exists."); 11432 } 11433 } 11434 } 11435 11436 @Override 11437 void handleServiceError() { 11438 Slog.e(TAG, "Could not measure application " + mStats.packageName 11439 + " external storage"); 11440 } 11441 } 11442 11443 private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths) 11444 throws RemoteException { 11445 long result = 0; 11446 for (File path : paths) { 11447 result += mcs.calculateDirectorySize(path.getAbsolutePath()); 11448 } 11449 return result; 11450 } 11451 11452 private static void clearDirectory(IMediaContainerService mcs, File[] paths) { 11453 for (File path : paths) { 11454 try { 11455 mcs.clearDirectory(path.getAbsolutePath()); 11456 } catch (RemoteException e) { 11457 } 11458 } 11459 } 11460 11461 static class OriginInfo { 11462 /** 11463 * Location where install is coming from, before it has been 11464 * copied/renamed into place. This could be a single monolithic APK 11465 * file, or a cluster directory. This location may be untrusted. 11466 */ 11467 final File file; 11468 final String cid; 11469 11470 /** 11471 * Flag indicating that {@link #file} or {@link #cid} has already been 11472 * staged, meaning downstream users don't need to defensively copy the 11473 * contents. 11474 */ 11475 final boolean staged; 11476 11477 /** 11478 * Flag indicating that {@link #file} or {@link #cid} is an already 11479 * installed app that is being moved. 11480 */ 11481 final boolean existing; 11482 11483 final String resolvedPath; 11484 final File resolvedFile; 11485 11486 static OriginInfo fromNothing() { 11487 return new OriginInfo(null, null, false, false); 11488 } 11489 11490 static OriginInfo fromUntrustedFile(File file) { 11491 return new OriginInfo(file, null, false, false); 11492 } 11493 11494 static OriginInfo fromExistingFile(File file) { 11495 return new OriginInfo(file, null, false, true); 11496 } 11497 11498 static OriginInfo fromStagedFile(File file) { 11499 return new OriginInfo(file, null, true, false); 11500 } 11501 11502 static OriginInfo fromStagedContainer(String cid) { 11503 return new OriginInfo(null, cid, true, false); 11504 } 11505 11506 private OriginInfo(File file, String cid, boolean staged, boolean existing) { 11507 this.file = file; 11508 this.cid = cid; 11509 this.staged = staged; 11510 this.existing = existing; 11511 11512 if (cid != null) { 11513 resolvedPath = PackageHelper.getSdDir(cid); 11514 resolvedFile = new File(resolvedPath); 11515 } else if (file != null) { 11516 resolvedPath = file.getAbsolutePath(); 11517 resolvedFile = file; 11518 } else { 11519 resolvedPath = null; 11520 resolvedFile = null; 11521 } 11522 } 11523 } 11524 11525 static class MoveInfo { 11526 final int moveId; 11527 final String fromUuid; 11528 final String toUuid; 11529 final String packageName; 11530 final String dataAppName; 11531 final int appId; 11532 final String seinfo; 11533 final int targetSdkVersion; 11534 11535 public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName, 11536 String dataAppName, int appId, String seinfo, int targetSdkVersion) { 11537 this.moveId = moveId; 11538 this.fromUuid = fromUuid; 11539 this.toUuid = toUuid; 11540 this.packageName = packageName; 11541 this.dataAppName = dataAppName; 11542 this.appId = appId; 11543 this.seinfo = seinfo; 11544 this.targetSdkVersion = targetSdkVersion; 11545 } 11546 } 11547 11548 static class VerificationInfo { 11549 /** A constant used to indicate that a uid value is not present. */ 11550 public static final int NO_UID = -1; 11551 11552 /** URI referencing where the package was downloaded from. */ 11553 final Uri originatingUri; 11554 11555 /** HTTP referrer URI associated with the originatingURI. */ 11556 final Uri referrer; 11557 11558 /** UID of the application that the install request originated from. */ 11559 final int originatingUid; 11560 11561 /** UID of application requesting the install */ 11562 final int installerUid; 11563 11564 VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) { 11565 this.originatingUri = originatingUri; 11566 this.referrer = referrer; 11567 this.originatingUid = originatingUid; 11568 this.installerUid = installerUid; 11569 } 11570 } 11571 11572 class InstallParams extends HandlerParams { 11573 final OriginInfo origin; 11574 final MoveInfo move; 11575 final IPackageInstallObserver2 observer; 11576 int installFlags; 11577 final String installerPackageName; 11578 final String volumeUuid; 11579 private InstallArgs mArgs; 11580 private int mRet; 11581 final String packageAbiOverride; 11582 final String[] grantedRuntimePermissions; 11583 final VerificationInfo verificationInfo; 11584 11585 InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 11586 int installFlags, String installerPackageName, String volumeUuid, 11587 VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride, 11588 String[] grantedPermissions) { 11589 super(user); 11590 this.origin = origin; 11591 this.move = move; 11592 this.observer = observer; 11593 this.installFlags = installFlags; 11594 this.installerPackageName = installerPackageName; 11595 this.volumeUuid = volumeUuid; 11596 this.verificationInfo = verificationInfo; 11597 this.packageAbiOverride = packageAbiOverride; 11598 this.grantedRuntimePermissions = grantedPermissions; 11599 } 11600 11601 @Override 11602 public String toString() { 11603 return "InstallParams{" + Integer.toHexString(System.identityHashCode(this)) 11604 + " file=" + origin.file + " cid=" + origin.cid + "}"; 11605 } 11606 11607 private int installLocationPolicy(PackageInfoLite pkgLite) { 11608 String packageName = pkgLite.packageName; 11609 int installLocation = pkgLite.installLocation; 11610 boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 11611 // reader 11612 synchronized (mPackages) { 11613 // Currently installed package which the new package is attempting to replace or 11614 // null if no such package is installed. 11615 PackageParser.Package installedPkg = mPackages.get(packageName); 11616 // Package which currently owns the data which the new package will own if installed. 11617 // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg 11618 // will be null whereas dataOwnerPkg will contain information about the package 11619 // which was uninstalled while keeping its data. 11620 PackageParser.Package dataOwnerPkg = installedPkg; 11621 if (dataOwnerPkg == null) { 11622 PackageSetting ps = mSettings.mPackages.get(packageName); 11623 if (ps != null) { 11624 dataOwnerPkg = ps.pkg; 11625 } 11626 } 11627 11628 if (dataOwnerPkg != null) { 11629 // If installed, the package will get access to data left on the device by its 11630 // predecessor. As a security measure, this is permited only if this is not a 11631 // version downgrade or if the predecessor package is marked as debuggable and 11632 // a downgrade is explicitly requested. 11633 if (((dataOwnerPkg.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) 11634 || ((installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) == 0)) { 11635 try { 11636 checkDowngrade(dataOwnerPkg, pkgLite); 11637 } catch (PackageManagerException e) { 11638 Slog.w(TAG, "Downgrade detected: " + e.getMessage()); 11639 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE; 11640 } 11641 } 11642 } 11643 11644 if (installedPkg != null) { 11645 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 11646 // Check for updated system application. 11647 if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11648 if (onSd) { 11649 Slog.w(TAG, "Cannot install update to system app on sdcard"); 11650 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION; 11651 } 11652 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 11653 } else { 11654 if (onSd) { 11655 // Install flag overrides everything. 11656 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 11657 } 11658 // If current upgrade specifies particular preference 11659 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) { 11660 // Application explicitly specified internal. 11661 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 11662 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) { 11663 // App explictly prefers external. Let policy decide 11664 } else { 11665 // Prefer previous location 11666 if (isExternal(installedPkg)) { 11667 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 11668 } 11669 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 11670 } 11671 } 11672 } else { 11673 // Invalid install. Return error code 11674 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS; 11675 } 11676 } 11677 } 11678 // All the special cases have been taken care of. 11679 // Return result based on recommended install location. 11680 if (onSd) { 11681 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 11682 } 11683 return pkgLite.recommendedInstallLocation; 11684 } 11685 11686 /* 11687 * Invoke remote method to get package information and install 11688 * location values. Override install location based on default 11689 * policy if needed and then create install arguments based 11690 * on the install location. 11691 */ 11692 public void handleStartCopy() throws RemoteException { 11693 int ret = PackageManager.INSTALL_SUCCEEDED; 11694 11695 // If we're already staged, we've firmly committed to an install location 11696 if (origin.staged) { 11697 if (origin.file != null) { 11698 installFlags |= PackageManager.INSTALL_INTERNAL; 11699 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 11700 } else if (origin.cid != null) { 11701 installFlags |= PackageManager.INSTALL_EXTERNAL; 11702 installFlags &= ~PackageManager.INSTALL_INTERNAL; 11703 } else { 11704 throw new IllegalStateException("Invalid stage location"); 11705 } 11706 } 11707 11708 final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 11709 final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0; 11710 final boolean ephemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; 11711 PackageInfoLite pkgLite = null; 11712 11713 if (onInt && onSd) { 11714 // Check if both bits are set. 11715 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external"); 11716 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 11717 } else if (onSd && ephemeral) { 11718 Slog.w(TAG, "Conflicting flags specified for installing ephemeral on external"); 11719 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 11720 } else { 11721 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags, 11722 packageAbiOverride); 11723 11724 if (DEBUG_EPHEMERAL && ephemeral) { 11725 Slog.v(TAG, "pkgLite for install: " + pkgLite); 11726 } 11727 11728 /* 11729 * If we have too little free space, try to free cache 11730 * before giving up. 11731 */ 11732 if (!origin.staged && pkgLite.recommendedInstallLocation 11733 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 11734 // TODO: focus freeing disk space on the target device 11735 final StorageManager storage = StorageManager.from(mContext); 11736 final long lowThreshold = storage.getStorageLowBytes( 11737 Environment.getDataDirectory()); 11738 11739 final long sizeBytes = mContainerService.calculateInstalledSize( 11740 origin.resolvedPath, isForwardLocked(), packageAbiOverride); 11741 11742 try { 11743 mInstaller.freeCache(null, sizeBytes + lowThreshold); 11744 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, 11745 installFlags, packageAbiOverride); 11746 } catch (InstallerException e) { 11747 Slog.w(TAG, "Failed to free cache", e); 11748 } 11749 11750 /* 11751 * The cache free must have deleted the file we 11752 * downloaded to install. 11753 * 11754 * TODO: fix the "freeCache" call to not delete 11755 * the file we care about. 11756 */ 11757 if (pkgLite.recommendedInstallLocation 11758 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 11759 pkgLite.recommendedInstallLocation 11760 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE; 11761 } 11762 } 11763 } 11764 11765 if (ret == PackageManager.INSTALL_SUCCEEDED) { 11766 int loc = pkgLite.recommendedInstallLocation; 11767 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) { 11768 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 11769 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) { 11770 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 11771 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 11772 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 11773 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) { 11774 ret = PackageManager.INSTALL_FAILED_INVALID_APK; 11775 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 11776 ret = PackageManager.INSTALL_FAILED_INVALID_URI; 11777 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) { 11778 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE; 11779 } else { 11780 // Override with defaults if needed. 11781 loc = installLocationPolicy(pkgLite); 11782 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) { 11783 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 11784 } else if (!onSd && !onInt) { 11785 // Override install location with flags 11786 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) { 11787 // Set the flag to install on external media. 11788 installFlags |= PackageManager.INSTALL_EXTERNAL; 11789 installFlags &= ~PackageManager.INSTALL_INTERNAL; 11790 } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) { 11791 if (DEBUG_EPHEMERAL) { 11792 Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag"); 11793 } 11794 installFlags |= PackageManager.INSTALL_EPHEMERAL; 11795 installFlags &= ~(PackageManager.INSTALL_EXTERNAL 11796 |PackageManager.INSTALL_INTERNAL); 11797 } else { 11798 // Make sure the flag for installing on external 11799 // media is unset 11800 installFlags |= PackageManager.INSTALL_INTERNAL; 11801 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 11802 } 11803 } 11804 } 11805 } 11806 11807 final InstallArgs args = createInstallArgs(this); 11808 mArgs = args; 11809 11810 if (ret == PackageManager.INSTALL_SUCCEEDED) { 11811 // TODO: http://b/22976637 11812 // Apps installed for "all" users use the device owner to verify the app 11813 UserHandle verifierUser = getUser(); 11814 if (verifierUser == UserHandle.ALL) { 11815 verifierUser = UserHandle.SYSTEM; 11816 } 11817 11818 /* 11819 * Determine if we have any installed package verifiers. If we 11820 * do, then we'll defer to them to verify the packages. 11821 */ 11822 final int requiredUid = mRequiredVerifierPackage == null ? -1 11823 : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 11824 verifierUser.getIdentifier()); 11825 if (!origin.existing && requiredUid != -1 11826 && isVerificationEnabled(verifierUser.getIdentifier(), installFlags)) { 11827 final Intent verification = new Intent( 11828 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 11829 verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 11830 verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)), 11831 PACKAGE_MIME_TYPE); 11832 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 11833 11834 // Query all live verifiers based on current user state 11835 final List<ResolveInfo> receivers = queryIntentReceivers(verification, 11836 PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier()); 11837 11838 if (DEBUG_VERIFY) { 11839 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent " 11840 + verification.toString() + " with " + pkgLite.verifiers.length 11841 + " optional verifiers"); 11842 } 11843 11844 final int verificationId = mPendingVerificationToken++; 11845 11846 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 11847 11848 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE, 11849 installerPackageName); 11850 11851 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, 11852 installFlags); 11853 11854 verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME, 11855 pkgLite.packageName); 11856 11857 verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE, 11858 pkgLite.versionCode); 11859 11860 if (verificationInfo != null) { 11861 if (verificationInfo.originatingUri != null) { 11862 verification.putExtra(Intent.EXTRA_ORIGINATING_URI, 11863 verificationInfo.originatingUri); 11864 } 11865 if (verificationInfo.referrer != null) { 11866 verification.putExtra(Intent.EXTRA_REFERRER, 11867 verificationInfo.referrer); 11868 } 11869 if (verificationInfo.originatingUid >= 0) { 11870 verification.putExtra(Intent.EXTRA_ORIGINATING_UID, 11871 verificationInfo.originatingUid); 11872 } 11873 if (verificationInfo.installerUid >= 0) { 11874 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID, 11875 verificationInfo.installerUid); 11876 } 11877 } 11878 11879 final PackageVerificationState verificationState = new PackageVerificationState( 11880 requiredUid, args); 11881 11882 mPendingVerification.append(verificationId, verificationState); 11883 11884 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite, 11885 receivers, verificationState); 11886 11887 /* 11888 * If any sufficient verifiers were listed in the package 11889 * manifest, attempt to ask them. 11890 */ 11891 if (sufficientVerifiers != null) { 11892 final int N = sufficientVerifiers.size(); 11893 if (N == 0) { 11894 Slog.i(TAG, "Additional verifiers required, but none installed."); 11895 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 11896 } else { 11897 for (int i = 0; i < N; i++) { 11898 final ComponentName verifierComponent = sufficientVerifiers.get(i); 11899 11900 final Intent sufficientIntent = new Intent(verification); 11901 sufficientIntent.setComponent(verifierComponent); 11902 mContext.sendBroadcastAsUser(sufficientIntent, verifierUser); 11903 } 11904 } 11905 } 11906 11907 final ComponentName requiredVerifierComponent = matchComponentForVerifier( 11908 mRequiredVerifierPackage, receivers); 11909 if (ret == PackageManager.INSTALL_SUCCEEDED 11910 && mRequiredVerifierPackage != null) { 11911 Trace.asyncTraceBegin( 11912 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 11913 /* 11914 * Send the intent to the required verification agent, 11915 * but only start the verification timeout after the 11916 * target BroadcastReceivers have run. 11917 */ 11918 verification.setComponent(requiredVerifierComponent); 11919 mContext.sendOrderedBroadcastAsUser(verification, verifierUser, 11920 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 11921 new BroadcastReceiver() { 11922 @Override 11923 public void onReceive(Context context, Intent intent) { 11924 final Message msg = mHandler 11925 .obtainMessage(CHECK_PENDING_VERIFICATION); 11926 msg.arg1 = verificationId; 11927 mHandler.sendMessageDelayed(msg, getVerificationTimeout()); 11928 } 11929 }, null, 0, null, null); 11930 11931 /* 11932 * We don't want the copy to proceed until verification 11933 * succeeds, so null out this field. 11934 */ 11935 mArgs = null; 11936 } 11937 } else { 11938 /* 11939 * No package verification is enabled, so immediately start 11940 * the remote call to initiate copy using temporary file. 11941 */ 11942 ret = args.copyApk(mContainerService, true); 11943 } 11944 } 11945 11946 mRet = ret; 11947 } 11948 11949 @Override 11950 void handleReturnCode() { 11951 // If mArgs is null, then MCS couldn't be reached. When it 11952 // reconnects, it will try again to install. At that point, this 11953 // will succeed. 11954 if (mArgs != null) { 11955 processPendingInstall(mArgs, mRet); 11956 } 11957 } 11958 11959 @Override 11960 void handleServiceError() { 11961 mArgs = createInstallArgs(this); 11962 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 11963 } 11964 11965 public boolean isForwardLocked() { 11966 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 11967 } 11968 } 11969 11970 /** 11971 * Used during creation of InstallArgs 11972 * 11973 * @param installFlags package installation flags 11974 * @return true if should be installed on external storage 11975 */ 11976 private static boolean installOnExternalAsec(int installFlags) { 11977 if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) { 11978 return false; 11979 } 11980 if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) { 11981 return true; 11982 } 11983 return false; 11984 } 11985 11986 /** 11987 * Used during creation of InstallArgs 11988 * 11989 * @param installFlags package installation flags 11990 * @return true if should be installed as forward locked 11991 */ 11992 private static boolean installForwardLocked(int installFlags) { 11993 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 11994 } 11995 11996 private InstallArgs createInstallArgs(InstallParams params) { 11997 if (params.move != null) { 11998 return new MoveInstallArgs(params); 11999 } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) { 12000 return new AsecInstallArgs(params); 12001 } else { 12002 return new FileInstallArgs(params); 12003 } 12004 } 12005 12006 /** 12007 * Create args that describe an existing installed package. Typically used 12008 * when cleaning up old installs, or used as a move source. 12009 */ 12010 private InstallArgs createInstallArgsForExisting(int installFlags, String codePath, 12011 String resourcePath, String[] instructionSets) { 12012 final boolean isInAsec; 12013 if (installOnExternalAsec(installFlags)) { 12014 /* Apps on SD card are always in ASEC containers. */ 12015 isInAsec = true; 12016 } else if (installForwardLocked(installFlags) 12017 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) { 12018 /* 12019 * Forward-locked apps are only in ASEC containers if they're the 12020 * new style 12021 */ 12022 isInAsec = true; 12023 } else { 12024 isInAsec = false; 12025 } 12026 12027 if (isInAsec) { 12028 return new AsecInstallArgs(codePath, instructionSets, 12029 installOnExternalAsec(installFlags), installForwardLocked(installFlags)); 12030 } else { 12031 return new FileInstallArgs(codePath, resourcePath, instructionSets); 12032 } 12033 } 12034 12035 static abstract class InstallArgs { 12036 /** @see InstallParams#origin */ 12037 final OriginInfo origin; 12038 /** @see InstallParams#move */ 12039 final MoveInfo move; 12040 12041 final IPackageInstallObserver2 observer; 12042 // Always refers to PackageManager flags only 12043 final int installFlags; 12044 final String installerPackageName; 12045 final String volumeUuid; 12046 final UserHandle user; 12047 final String abiOverride; 12048 final String[] installGrantPermissions; 12049 /** If non-null, drop an async trace when the install completes */ 12050 final String traceMethod; 12051 final int traceCookie; 12052 12053 // The list of instruction sets supported by this app. This is currently 12054 // only used during the rmdex() phase to clean up resources. We can get rid of this 12055 // if we move dex files under the common app path. 12056 /* nullable */ String[] instructionSets; 12057 12058 InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 12059 int installFlags, String installerPackageName, String volumeUuid, 12060 UserHandle user, String[] instructionSets, 12061 String abiOverride, String[] installGrantPermissions, 12062 String traceMethod, int traceCookie) { 12063 this.origin = origin; 12064 this.move = move; 12065 this.installFlags = installFlags; 12066 this.observer = observer; 12067 this.installerPackageName = installerPackageName; 12068 this.volumeUuid = volumeUuid; 12069 this.user = user; 12070 this.instructionSets = instructionSets; 12071 this.abiOverride = abiOverride; 12072 this.installGrantPermissions = installGrantPermissions; 12073 this.traceMethod = traceMethod; 12074 this.traceCookie = traceCookie; 12075 } 12076 12077 abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException; 12078 abstract int doPreInstall(int status); 12079 12080 /** 12081 * Rename package into final resting place. All paths on the given 12082 * scanned package should be updated to reflect the rename. 12083 */ 12084 abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath); 12085 abstract int doPostInstall(int status, int uid); 12086 12087 /** @see PackageSettingBase#codePathString */ 12088 abstract String getCodePath(); 12089 /** @see PackageSettingBase#resourcePathString */ 12090 abstract String getResourcePath(); 12091 12092 // Need installer lock especially for dex file removal. 12093 abstract void cleanUpResourcesLI(); 12094 abstract boolean doPostDeleteLI(boolean delete); 12095 12096 /** 12097 * Called before the source arguments are copied. This is used mostly 12098 * for MoveParams when it needs to read the source file to put it in the 12099 * destination. 12100 */ 12101 int doPreCopy() { 12102 return PackageManager.INSTALL_SUCCEEDED; 12103 } 12104 12105 /** 12106 * Called after the source arguments are copied. This is used mostly for 12107 * MoveParams when it needs to read the source file to put it in the 12108 * destination. 12109 * 12110 * @return 12111 */ 12112 int doPostCopy(int uid) { 12113 return PackageManager.INSTALL_SUCCEEDED; 12114 } 12115 12116 protected boolean isFwdLocked() { 12117 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 12118 } 12119 12120 protected boolean isExternalAsec() { 12121 return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 12122 } 12123 12124 protected boolean isEphemeral() { 12125 return (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; 12126 } 12127 12128 UserHandle getUser() { 12129 return user; 12130 } 12131 } 12132 12133 private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) { 12134 if (!allCodePaths.isEmpty()) { 12135 if (instructionSets == null) { 12136 throw new IllegalStateException("instructionSet == null"); 12137 } 12138 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); 12139 for (String codePath : allCodePaths) { 12140 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 12141 try { 12142 mInstaller.rmdex(codePath, dexCodeInstructionSet); 12143 } catch (InstallerException ignored) { 12144 } 12145 } 12146 } 12147 } 12148 } 12149 12150 /** 12151 * Logic to handle installation of non-ASEC applications, including copying 12152 * and renaming logic. 12153 */ 12154 class FileInstallArgs extends InstallArgs { 12155 private File codeFile; 12156 private File resourceFile; 12157 12158 // Example topology: 12159 // /data/app/com.example/base.apk 12160 // /data/app/com.example/split_foo.apk 12161 // /data/app/com.example/lib/arm/libfoo.so 12162 // /data/app/com.example/lib/arm64/libfoo.so 12163 // /data/app/com.example/dalvik/arm/base.apk@classes.dex 12164 12165 /** New install */ 12166 FileInstallArgs(InstallParams params) { 12167 super(params.origin, params.move, params.observer, params.installFlags, 12168 params.installerPackageName, params.volumeUuid, 12169 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 12170 params.grantedRuntimePermissions, 12171 params.traceMethod, params.traceCookie); 12172 if (isFwdLocked()) { 12173 throw new IllegalArgumentException("Forward locking only supported in ASEC"); 12174 } 12175 } 12176 12177 /** Existing install */ 12178 FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) { 12179 super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets, 12180 null, null, null, 0); 12181 this.codeFile = (codePath != null) ? new File(codePath) : null; 12182 this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null; 12183 } 12184 12185 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 12186 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk"); 12187 try { 12188 return doCopyApk(imcs, temp); 12189 } finally { 12190 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 12191 } 12192 } 12193 12194 private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 12195 if (origin.staged) { 12196 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy"); 12197 codeFile = origin.file; 12198 resourceFile = origin.file; 12199 return PackageManager.INSTALL_SUCCEEDED; 12200 } 12201 12202 try { 12203 final boolean isEphemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; 12204 final File tempDir = 12205 mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral); 12206 codeFile = tempDir; 12207 resourceFile = tempDir; 12208 } catch (IOException e) { 12209 Slog.w(TAG, "Failed to create copy file: " + e); 12210 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 12211 } 12212 12213 final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() { 12214 @Override 12215 public ParcelFileDescriptor open(String name, int mode) throws RemoteException { 12216 if (!FileUtils.isValidExtFilename(name)) { 12217 throw new IllegalArgumentException("Invalid filename: " + name); 12218 } 12219 try { 12220 final File file = new File(codeFile, name); 12221 final FileDescriptor fd = Os.open(file.getAbsolutePath(), 12222 O_RDWR | O_CREAT, 0644); 12223 Os.chmod(file.getAbsolutePath(), 0644); 12224 return new ParcelFileDescriptor(fd); 12225 } catch (ErrnoException e) { 12226 throw new RemoteException("Failed to open: " + e.getMessage()); 12227 } 12228 } 12229 }; 12230 12231 int ret = PackageManager.INSTALL_SUCCEEDED; 12232 ret = imcs.copyPackage(origin.file.getAbsolutePath(), target); 12233 if (ret != PackageManager.INSTALL_SUCCEEDED) { 12234 Slog.e(TAG, "Failed to copy package"); 12235 return ret; 12236 } 12237 12238 final File libraryRoot = new File(codeFile, LIB_DIR_NAME); 12239 NativeLibraryHelper.Handle handle = null; 12240 try { 12241 handle = NativeLibraryHelper.Handle.create(codeFile); 12242 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot, 12243 abiOverride); 12244 } catch (IOException e) { 12245 Slog.e(TAG, "Copying native libraries failed", e); 12246 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 12247 } finally { 12248 IoUtils.closeQuietly(handle); 12249 } 12250 12251 return ret; 12252 } 12253 12254 int doPreInstall(int status) { 12255 if (status != PackageManager.INSTALL_SUCCEEDED) { 12256 cleanUp(); 12257 } 12258 return status; 12259 } 12260 12261 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 12262 if (status != PackageManager.INSTALL_SUCCEEDED) { 12263 cleanUp(); 12264 return false; 12265 } 12266 12267 final File targetDir = codeFile.getParentFile(); 12268 final File beforeCodeFile = codeFile; 12269 final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName); 12270 12271 if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile); 12272 try { 12273 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath()); 12274 } catch (ErrnoException e) { 12275 Slog.w(TAG, "Failed to rename", e); 12276 return false; 12277 } 12278 12279 if (!SELinux.restoreconRecursive(afterCodeFile)) { 12280 Slog.w(TAG, "Failed to restorecon"); 12281 return false; 12282 } 12283 12284 // Reflect the rename internally 12285 codeFile = afterCodeFile; 12286 resourceFile = afterCodeFile; 12287 12288 // Reflect the rename in scanned details 12289 pkg.setCodePath(afterCodeFile.getAbsolutePath()); 12290 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile, 12291 afterCodeFile, pkg.baseCodePath)); 12292 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile, 12293 afterCodeFile, pkg.splitCodePaths)); 12294 12295 // Reflect the rename in app info 12296 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 12297 pkg.setApplicationInfoCodePath(pkg.codePath); 12298 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 12299 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 12300 pkg.setApplicationInfoResourcePath(pkg.codePath); 12301 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 12302 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 12303 12304 return true; 12305 } 12306 12307 int doPostInstall(int status, int uid) { 12308 if (status != PackageManager.INSTALL_SUCCEEDED) { 12309 cleanUp(); 12310 } 12311 return status; 12312 } 12313 12314 @Override 12315 String getCodePath() { 12316 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 12317 } 12318 12319 @Override 12320 String getResourcePath() { 12321 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 12322 } 12323 12324 private boolean cleanUp() { 12325 if (codeFile == null || !codeFile.exists()) { 12326 return false; 12327 } 12328 12329 removeCodePathLI(codeFile); 12330 12331 if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) { 12332 resourceFile.delete(); 12333 } 12334 12335 return true; 12336 } 12337 12338 void cleanUpResourcesLI() { 12339 // Try enumerating all code paths before deleting 12340 List<String> allCodePaths = Collections.EMPTY_LIST; 12341 if (codeFile != null && codeFile.exists()) { 12342 try { 12343 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 12344 allCodePaths = pkg.getAllCodePaths(); 12345 } catch (PackageParserException e) { 12346 // Ignored; we tried our best 12347 } 12348 } 12349 12350 cleanUp(); 12351 removeDexFiles(allCodePaths, instructionSets); 12352 } 12353 12354 boolean doPostDeleteLI(boolean delete) { 12355 // XXX err, shouldn't we respect the delete flag? 12356 cleanUpResourcesLI(); 12357 return true; 12358 } 12359 } 12360 12361 private boolean isAsecExternal(String cid) { 12362 final String asecPath = PackageHelper.getSdFilesystem(cid); 12363 return !asecPath.startsWith(mAsecInternalPath); 12364 } 12365 12366 private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws 12367 PackageManagerException { 12368 if (copyRet < 0) { 12369 if (copyRet != PackageManager.NO_NATIVE_LIBRARIES && 12370 copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) { 12371 throw new PackageManagerException(copyRet, message); 12372 } 12373 } 12374 } 12375 12376 /** 12377 * Extract the MountService "container ID" from the full code path of an 12378 * .apk. 12379 */ 12380 static String cidFromCodePath(String fullCodePath) { 12381 int eidx = fullCodePath.lastIndexOf("/"); 12382 String subStr1 = fullCodePath.substring(0, eidx); 12383 int sidx = subStr1.lastIndexOf("/"); 12384 return subStr1.substring(sidx+1, eidx); 12385 } 12386 12387 /** 12388 * Logic to handle installation of ASEC applications, including copying and 12389 * renaming logic. 12390 */ 12391 class AsecInstallArgs extends InstallArgs { 12392 static final String RES_FILE_NAME = "pkg.apk"; 12393 static final String PUBLIC_RES_FILE_NAME = "res.zip"; 12394 12395 String cid; 12396 String packagePath; 12397 String resourcePath; 12398 12399 /** New install */ 12400 AsecInstallArgs(InstallParams params) { 12401 super(params.origin, params.move, params.observer, params.installFlags, 12402 params.installerPackageName, params.volumeUuid, 12403 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 12404 params.grantedRuntimePermissions, 12405 params.traceMethod, params.traceCookie); 12406 } 12407 12408 /** Existing install */ 12409 AsecInstallArgs(String fullCodePath, String[] instructionSets, 12410 boolean isExternal, boolean isForwardLocked) { 12411 super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0) 12412 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, 12413 instructionSets, null, null, null, 0); 12414 // Hackily pretend we're still looking at a full code path 12415 if (!fullCodePath.endsWith(RES_FILE_NAME)) { 12416 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath(); 12417 } 12418 12419 // Extract cid from fullCodePath 12420 int eidx = fullCodePath.lastIndexOf("/"); 12421 String subStr1 = fullCodePath.substring(0, eidx); 12422 int sidx = subStr1.lastIndexOf("/"); 12423 cid = subStr1.substring(sidx+1, eidx); 12424 setMountPath(subStr1); 12425 } 12426 12427 AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) { 12428 super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0) 12429 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, 12430 instructionSets, null, null, null, 0); 12431 this.cid = cid; 12432 setMountPath(PackageHelper.getSdDir(cid)); 12433 } 12434 12435 void createCopyFile() { 12436 cid = mInstallerService.allocateExternalStageCidLegacy(); 12437 } 12438 12439 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 12440 if (origin.staged && origin.cid != null) { 12441 if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy"); 12442 cid = origin.cid; 12443 setMountPath(PackageHelper.getSdDir(cid)); 12444 return PackageManager.INSTALL_SUCCEEDED; 12445 } 12446 12447 if (temp) { 12448 createCopyFile(); 12449 } else { 12450 /* 12451 * Pre-emptively destroy the container since it's destroyed if 12452 * copying fails due to it existing anyway. 12453 */ 12454 PackageHelper.destroySdDir(cid); 12455 } 12456 12457 final String newMountPath = imcs.copyPackageToContainer( 12458 origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(), 12459 isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */)); 12460 12461 if (newMountPath != null) { 12462 setMountPath(newMountPath); 12463 return PackageManager.INSTALL_SUCCEEDED; 12464 } else { 12465 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 12466 } 12467 } 12468 12469 @Override 12470 String getCodePath() { 12471 return packagePath; 12472 } 12473 12474 @Override 12475 String getResourcePath() { 12476 return resourcePath; 12477 } 12478 12479 int doPreInstall(int status) { 12480 if (status != PackageManager.INSTALL_SUCCEEDED) { 12481 // Destroy container 12482 PackageHelper.destroySdDir(cid); 12483 } else { 12484 boolean mounted = PackageHelper.isContainerMounted(cid); 12485 if (!mounted) { 12486 String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(), 12487 Process.SYSTEM_UID); 12488 if (newMountPath != null) { 12489 setMountPath(newMountPath); 12490 } else { 12491 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 12492 } 12493 } 12494 } 12495 return status; 12496 } 12497 12498 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 12499 String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME); 12500 String newMountPath = null; 12501 if (PackageHelper.isContainerMounted(cid)) { 12502 // Unmount the container 12503 if (!PackageHelper.unMountSdDir(cid)) { 12504 Slog.i(TAG, "Failed to unmount " + cid + " before renaming"); 12505 return false; 12506 } 12507 } 12508 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 12509 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId + 12510 " which might be stale. Will try to clean up."); 12511 // Clean up the stale container and proceed to recreate. 12512 if (!PackageHelper.destroySdDir(newCacheId)) { 12513 Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId); 12514 return false; 12515 } 12516 // Successfully cleaned up stale container. Try to rename again. 12517 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 12518 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId 12519 + " inspite of cleaning it up."); 12520 return false; 12521 } 12522 } 12523 if (!PackageHelper.isContainerMounted(newCacheId)) { 12524 Slog.w(TAG, "Mounting container " + newCacheId); 12525 newMountPath = PackageHelper.mountSdDir(newCacheId, 12526 getEncryptKey(), Process.SYSTEM_UID); 12527 } else { 12528 newMountPath = PackageHelper.getSdDir(newCacheId); 12529 } 12530 if (newMountPath == null) { 12531 Slog.w(TAG, "Failed to get cache path for " + newCacheId); 12532 return false; 12533 } 12534 Log.i(TAG, "Succesfully renamed " + cid + 12535 " to " + newCacheId + 12536 " at new path: " + newMountPath); 12537 cid = newCacheId; 12538 12539 final File beforeCodeFile = new File(packagePath); 12540 setMountPath(newMountPath); 12541 final File afterCodeFile = new File(packagePath); 12542 12543 // Reflect the rename in scanned details 12544 pkg.setCodePath(afterCodeFile.getAbsolutePath()); 12545 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile, 12546 afterCodeFile, pkg.baseCodePath)); 12547 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile, 12548 afterCodeFile, pkg.splitCodePaths)); 12549 12550 // Reflect the rename in app info 12551 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 12552 pkg.setApplicationInfoCodePath(pkg.codePath); 12553 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 12554 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 12555 pkg.setApplicationInfoResourcePath(pkg.codePath); 12556 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 12557 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 12558 12559 return true; 12560 } 12561 12562 private void setMountPath(String mountPath) { 12563 final File mountFile = new File(mountPath); 12564 12565 final File monolithicFile = new File(mountFile, RES_FILE_NAME); 12566 if (monolithicFile.exists()) { 12567 packagePath = monolithicFile.getAbsolutePath(); 12568 if (isFwdLocked()) { 12569 resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath(); 12570 } else { 12571 resourcePath = packagePath; 12572 } 12573 } else { 12574 packagePath = mountFile.getAbsolutePath(); 12575 resourcePath = packagePath; 12576 } 12577 } 12578 12579 int doPostInstall(int status, int uid) { 12580 if (status != PackageManager.INSTALL_SUCCEEDED) { 12581 cleanUp(); 12582 } else { 12583 final int groupOwner; 12584 final String protectedFile; 12585 if (isFwdLocked()) { 12586 groupOwner = UserHandle.getSharedAppGid(uid); 12587 protectedFile = RES_FILE_NAME; 12588 } else { 12589 groupOwner = -1; 12590 protectedFile = null; 12591 } 12592 12593 if (uid < Process.FIRST_APPLICATION_UID 12594 || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) { 12595 Slog.e(TAG, "Failed to finalize " + cid); 12596 PackageHelper.destroySdDir(cid); 12597 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 12598 } 12599 12600 boolean mounted = PackageHelper.isContainerMounted(cid); 12601 if (!mounted) { 12602 PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid()); 12603 } 12604 } 12605 return status; 12606 } 12607 12608 private void cleanUp() { 12609 if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp"); 12610 12611 // Destroy secure container 12612 PackageHelper.destroySdDir(cid); 12613 } 12614 12615 private List<String> getAllCodePaths() { 12616 final File codeFile = new File(getCodePath()); 12617 if (codeFile != null && codeFile.exists()) { 12618 try { 12619 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 12620 return pkg.getAllCodePaths(); 12621 } catch (PackageParserException e) { 12622 // Ignored; we tried our best 12623 } 12624 } 12625 return Collections.EMPTY_LIST; 12626 } 12627 12628 void cleanUpResourcesLI() { 12629 // Enumerate all code paths before deleting 12630 cleanUpResourcesLI(getAllCodePaths()); 12631 } 12632 12633 private void cleanUpResourcesLI(List<String> allCodePaths) { 12634 cleanUp(); 12635 removeDexFiles(allCodePaths, instructionSets); 12636 } 12637 12638 String getPackageName() { 12639 return getAsecPackageName(cid); 12640 } 12641 12642 boolean doPostDeleteLI(boolean delete) { 12643 if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete); 12644 final List<String> allCodePaths = getAllCodePaths(); 12645 boolean mounted = PackageHelper.isContainerMounted(cid); 12646 if (mounted) { 12647 // Unmount first 12648 if (PackageHelper.unMountSdDir(cid)) { 12649 mounted = false; 12650 } 12651 } 12652 if (!mounted && delete) { 12653 cleanUpResourcesLI(allCodePaths); 12654 } 12655 return !mounted; 12656 } 12657 12658 @Override 12659 int doPreCopy() { 12660 if (isFwdLocked()) { 12661 if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE, 12662 MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) { 12663 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 12664 } 12665 } 12666 12667 return PackageManager.INSTALL_SUCCEEDED; 12668 } 12669 12670 @Override 12671 int doPostCopy(int uid) { 12672 if (isFwdLocked()) { 12673 if (uid < Process.FIRST_APPLICATION_UID 12674 || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid), 12675 RES_FILE_NAME)) { 12676 Slog.e(TAG, "Failed to finalize " + cid); 12677 PackageHelper.destroySdDir(cid); 12678 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 12679 } 12680 } 12681 12682 return PackageManager.INSTALL_SUCCEEDED; 12683 } 12684 } 12685 12686 /** 12687 * Logic to handle movement of existing installed applications. 12688 */ 12689 class MoveInstallArgs extends InstallArgs { 12690 private File codeFile; 12691 private File resourceFile; 12692 12693 /** New install */ 12694 MoveInstallArgs(InstallParams params) { 12695 super(params.origin, params.move, params.observer, params.installFlags, 12696 params.installerPackageName, params.volumeUuid, 12697 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 12698 params.grantedRuntimePermissions, 12699 params.traceMethod, params.traceCookie); 12700 } 12701 12702 int copyApk(IMediaContainerService imcs, boolean temp) { 12703 if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from " 12704 + move.fromUuid + " to " + move.toUuid); 12705 synchronized (mInstaller) { 12706 try { 12707 mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName, 12708 move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion); 12709 } catch (InstallerException e) { 12710 Slog.w(TAG, "Failed to move app", e); 12711 return PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 12712 } 12713 } 12714 12715 codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName); 12716 resourceFile = codeFile; 12717 if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile); 12718 12719 return PackageManager.INSTALL_SUCCEEDED; 12720 } 12721 12722 int doPreInstall(int status) { 12723 if (status != PackageManager.INSTALL_SUCCEEDED) { 12724 cleanUp(move.toUuid); 12725 } 12726 return status; 12727 } 12728 12729 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 12730 if (status != PackageManager.INSTALL_SUCCEEDED) { 12731 cleanUp(move.toUuid); 12732 return false; 12733 } 12734 12735 // Reflect the move in app info 12736 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 12737 pkg.setApplicationInfoCodePath(pkg.codePath); 12738 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 12739 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 12740 pkg.setApplicationInfoResourcePath(pkg.codePath); 12741 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 12742 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 12743 12744 return true; 12745 } 12746 12747 int doPostInstall(int status, int uid) { 12748 if (status == PackageManager.INSTALL_SUCCEEDED) { 12749 cleanUp(move.fromUuid); 12750 } else { 12751 cleanUp(move.toUuid); 12752 } 12753 return status; 12754 } 12755 12756 @Override 12757 String getCodePath() { 12758 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 12759 } 12760 12761 @Override 12762 String getResourcePath() { 12763 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 12764 } 12765 12766 private boolean cleanUp(String volumeUuid) { 12767 final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid), 12768 move.dataAppName); 12769 Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid); 12770 synchronized (mInstallLock) { 12771 // Clean up both app data and code 12772 removeDataDirsLI(volumeUuid, move.packageName); 12773 removeCodePathLI(codeFile); 12774 } 12775 return true; 12776 } 12777 12778 void cleanUpResourcesLI() { 12779 throw new UnsupportedOperationException(); 12780 } 12781 12782 boolean doPostDeleteLI(boolean delete) { 12783 throw new UnsupportedOperationException(); 12784 } 12785 } 12786 12787 static String getAsecPackageName(String packageCid) { 12788 int idx = packageCid.lastIndexOf("-"); 12789 if (idx == -1) { 12790 return packageCid; 12791 } 12792 return packageCid.substring(0, idx); 12793 } 12794 12795 // Utility method used to create code paths based on package name and available index. 12796 private static String getNextCodePath(String oldCodePath, String prefix, String suffix) { 12797 String idxStr = ""; 12798 int idx = 1; 12799 // Fall back to default value of idx=1 if prefix is not 12800 // part of oldCodePath 12801 if (oldCodePath != null) { 12802 String subStr = oldCodePath; 12803 // Drop the suffix right away 12804 if (suffix != null && subStr.endsWith(suffix)) { 12805 subStr = subStr.substring(0, subStr.length() - suffix.length()); 12806 } 12807 // If oldCodePath already contains prefix find out the 12808 // ending index to either increment or decrement. 12809 int sidx = subStr.lastIndexOf(prefix); 12810 if (sidx != -1) { 12811 subStr = subStr.substring(sidx + prefix.length()); 12812 if (subStr != null) { 12813 if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) { 12814 subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length()); 12815 } 12816 try { 12817 idx = Integer.parseInt(subStr); 12818 if (idx <= 1) { 12819 idx++; 12820 } else { 12821 idx--; 12822 } 12823 } catch(NumberFormatException e) { 12824 } 12825 } 12826 } 12827 } 12828 idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx); 12829 return prefix + idxStr; 12830 } 12831 12832 private File getNextCodePath(File targetDir, String packageName) { 12833 int suffix = 1; 12834 File result; 12835 do { 12836 result = new File(targetDir, packageName + "-" + suffix); 12837 suffix++; 12838 } while (result.exists()); 12839 return result; 12840 } 12841 12842 // Utility method that returns the relative package path with respect 12843 // to the installation directory. Like say for /data/data/com.test-1.apk 12844 // string com.test-1 is returned. 12845 static String deriveCodePathName(String codePath) { 12846 if (codePath == null) { 12847 return null; 12848 } 12849 final File codeFile = new File(codePath); 12850 final String name = codeFile.getName(); 12851 if (codeFile.isDirectory()) { 12852 return name; 12853 } else if (name.endsWith(".apk") || name.endsWith(".tmp")) { 12854 final int lastDot = name.lastIndexOf('.'); 12855 return name.substring(0, lastDot); 12856 } else { 12857 Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK"); 12858 return null; 12859 } 12860 } 12861 12862 static class PackageInstalledInfo { 12863 String name; 12864 int uid; 12865 // The set of users that originally had this package installed. 12866 int[] origUsers; 12867 // The set of users that now have this package installed. 12868 int[] newUsers; 12869 PackageParser.Package pkg; 12870 int returnCode; 12871 String returnMsg; 12872 PackageRemovedInfo removedInfo; 12873 ArrayMap<String, PackageInstalledInfo> addedChildPackages; 12874 12875 public void setError(int code, String msg) { 12876 setReturnCode(code); 12877 setReturnMessage(msg); 12878 Slog.w(TAG, msg); 12879 } 12880 12881 public void setError(String msg, PackageParserException e) { 12882 setReturnCode(e.error); 12883 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e)); 12884 Slog.w(TAG, msg, e); 12885 } 12886 12887 public void setError(String msg, PackageManagerException e) { 12888 returnCode = e.error; 12889 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e)); 12890 Slog.w(TAG, msg, e); 12891 } 12892 12893 public void setReturnCode(int returnCode) { 12894 this.returnCode = returnCode; 12895 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0; 12896 for (int i = 0; i < childCount; i++) { 12897 addedChildPackages.valueAt(i).returnCode = returnCode; 12898 } 12899 } 12900 12901 private void setReturnMessage(String returnMsg) { 12902 this.returnMsg = returnMsg; 12903 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0; 12904 for (int i = 0; i < childCount; i++) { 12905 addedChildPackages.valueAt(i).returnMsg = returnMsg; 12906 } 12907 } 12908 12909 // In some error cases we want to convey more info back to the observer 12910 String origPackage; 12911 String origPermission; 12912 } 12913 12914 /* 12915 * Install a non-existing package. 12916 */ 12917 private void installNewPackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, 12918 UserHandle user, String installerPackageName, String volumeUuid, 12919 PackageInstalledInfo res) { 12920 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage"); 12921 12922 // Remember this for later, in case we need to rollback this install 12923 String pkgName = pkg.packageName; 12924 12925 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg); 12926 12927 synchronized(mPackages) { 12928 if (mSettings.mRenamedPackages.containsKey(pkgName)) { 12929 // A package with the same name is already installed, though 12930 // it has been renamed to an older name. The package we 12931 // are trying to install should be installed as an update to 12932 // the existing one, but that has not been requested, so bail. 12933 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 12934 + " without first uninstalling package running as " 12935 + mSettings.mRenamedPackages.get(pkgName)); 12936 return; 12937 } 12938 if (mPackages.containsKey(pkgName)) { 12939 // Don't allow installation over an existing package with the same name. 12940 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 12941 + " without first uninstalling."); 12942 return; 12943 } 12944 } 12945 12946 try { 12947 PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags, 12948 System.currentTimeMillis(), user); 12949 12950 updateSettingsLI(newPackage, installerPackageName, null, res, user); 12951 12952 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 12953 prepareAppDataAfterInstall(newPackage); 12954 12955 } else { 12956 // Remove package from internal structures, but keep around any 12957 // data that might have already existed 12958 deletePackageLI(pkgName, UserHandle.ALL, false, null, 12959 PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null); 12960 } 12961 } catch (PackageManagerException e) { 12962 res.setError("Package couldn't be installed in " + pkg.codePath, e); 12963 } 12964 12965 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 12966 } 12967 12968 private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) { 12969 // Can't rotate keys during boot or if sharedUser. 12970 if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null 12971 || !oldPs.keySetData.isUsingUpgradeKeySets()) { 12972 return false; 12973 } 12974 // app is using upgradeKeySets; make sure all are valid 12975 KeySetManagerService ksms = mSettings.mKeySetManagerService; 12976 long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets(); 12977 for (int i = 0; i < upgradeKeySets.length; i++) { 12978 if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) { 12979 Slog.wtf(TAG, "Package " 12980 + (oldPs.name != null ? oldPs.name : "<null>") 12981 + " contains upgrade-key-set reference to unknown key-set: " 12982 + upgradeKeySets[i] 12983 + " reverting to signatures check."); 12984 return false; 12985 } 12986 } 12987 return true; 12988 } 12989 12990 private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) { 12991 // Upgrade keysets are being used. Determine if new package has a superset of the 12992 // required keys. 12993 long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets(); 12994 KeySetManagerService ksms = mSettings.mKeySetManagerService; 12995 for (int i = 0; i < upgradeKeySets.length; i++) { 12996 Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]); 12997 if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) { 12998 return true; 12999 } 13000 } 13001 return false; 13002 } 13003 13004 private void replacePackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, 13005 UserHandle user, String installerPackageName, PackageInstalledInfo res) { 13006 final boolean isEphemeral = (parseFlags & PackageParser.PARSE_IS_EPHEMERAL) != 0; 13007 13008 final PackageParser.Package oldPackage; 13009 final String pkgName = pkg.packageName; 13010 final int[] allUsers; 13011 13012 // First find the old package info and check signatures 13013 synchronized(mPackages) { 13014 oldPackage = mPackages.get(pkgName); 13015 final boolean oldIsEphemeral = oldPackage.applicationInfo.isEphemeralApp(); 13016 if (isEphemeral && !oldIsEphemeral) { 13017 // can't downgrade from full to ephemeral 13018 Slog.w(TAG, "Can't replace app with ephemeral: " + pkgName); 13019 res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID); 13020 return; 13021 } 13022 if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage); 13023 final PackageSetting ps = mSettings.mPackages.get(pkgName); 13024 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { 13025 if (!checkUpgradeKeySetLP(ps, pkg)) { 13026 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 13027 "New package not signed by keys specified by upgrade-keysets: " 13028 + pkgName); 13029 return; 13030 } 13031 } else { 13032 // default to original signature matching 13033 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures) 13034 != PackageManager.SIGNATURE_MATCH) { 13035 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 13036 "New package has a different signature: " + pkgName); 13037 return; 13038 } 13039 } 13040 13041 // In case of rollback, remember per-user/profile install state 13042 allUsers = sUserManager.getUserIds(); 13043 } 13044 13045 // Update what is removed 13046 res.removedInfo = new PackageRemovedInfo(); 13047 res.removedInfo.uid = oldPackage.applicationInfo.uid; 13048 res.removedInfo.removedPackage = oldPackage.packageName; 13049 res.removedInfo.isUpdate = true; 13050 final int childCount = (oldPackage.childPackages != null) 13051 ? oldPackage.childPackages.size() : 0; 13052 for (int i = 0; i < childCount; i++) { 13053 boolean childPackageUpdated = false; 13054 PackageParser.Package childPkg = oldPackage.childPackages.get(i); 13055 if (res.addedChildPackages != null) { 13056 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName); 13057 if (childRes != null) { 13058 childRes.removedInfo.uid = childPkg.applicationInfo.uid; 13059 childRes.removedInfo.removedPackage = childPkg.packageName; 13060 childRes.removedInfo.isUpdate = true; 13061 childPackageUpdated = true; 13062 } 13063 } 13064 if (!childPackageUpdated) { 13065 PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(); 13066 childRemovedRes.removedPackage = childPkg.packageName; 13067 childRemovedRes.isUpdate = false; 13068 childRemovedRes.dataRemoved = true; 13069 synchronized (mPackages) { 13070 PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName); 13071 if (childPs != null) { 13072 childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true); 13073 } 13074 } 13075 if (res.removedInfo.removedChildPackages == null) { 13076 res.removedInfo.removedChildPackages = new ArrayMap<>(); 13077 } 13078 res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes); 13079 } 13080 } 13081 13082 boolean sysPkg = (isSystemApp(oldPackage)); 13083 if (sysPkg) { 13084 replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags, 13085 user, allUsers, installerPackageName, res); 13086 } else { 13087 replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags, 13088 user, allUsers, installerPackageName, res); 13089 } 13090 } 13091 13092 public List<String> getPreviousCodePaths(String packageName) { 13093 final PackageSetting ps = mSettings.mPackages.get(packageName); 13094 final List<String> result = new ArrayList<String>(); 13095 if (ps != null && ps.oldCodePaths != null) { 13096 result.addAll(ps.oldCodePaths); 13097 } 13098 return result; 13099 } 13100 13101 private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage, 13102 PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, 13103 int[] allUsers, String installerPackageName, PackageInstalledInfo res) { 13104 if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old=" 13105 + deletedPackage); 13106 13107 String pkgName = deletedPackage.packageName; 13108 boolean deletedPkg = true; 13109 boolean addedPkg = false; 13110 boolean updatedSettings = false; 13111 final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0; 13112 final int deleteFlags = PackageManager.DELETE_KEEP_DATA 13113 | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP); 13114 13115 final long origUpdateTime = (pkg.mExtras != null) 13116 ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0; 13117 13118 // First delete the existing package while retaining the data directory 13119 if (!deletePackageLI(pkgName, null, true, allUsers, deleteFlags, 13120 res.removedInfo, true, pkg)) { 13121 // If the existing package wasn't successfully deleted 13122 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI"); 13123 deletedPkg = false; 13124 } else { 13125 // Successfully deleted the old package; proceed with replace. 13126 13127 // If deleted package lived in a container, give users a chance to 13128 // relinquish resources before killing. 13129 if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) { 13130 if (DEBUG_INSTALL) { 13131 Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE"); 13132 } 13133 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid }; 13134 final ArrayList<String> pkgList = new ArrayList<String>(1); 13135 pkgList.add(deletedPackage.applicationInfo.packageName); 13136 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null); 13137 } 13138 13139 deleteCodeCacheDirsLI(pkg); 13140 13141 try { 13142 final PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags, 13143 scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user); 13144 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user); 13145 13146 // Update the in-memory copy of the previous code paths. 13147 PackageSetting ps = mSettings.mPackages.get(pkgName); 13148 if (!killApp) { 13149 if (ps.oldCodePaths == null) { 13150 ps.oldCodePaths = new ArraySet<>(); 13151 } 13152 Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath); 13153 if (deletedPackage.splitCodePaths != null) { 13154 Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths); 13155 } 13156 } else { 13157 ps.oldCodePaths = null; 13158 } 13159 if (ps.childPackageNames != null) { 13160 for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) { 13161 final String childPkgName = ps.childPackageNames.get(i); 13162 final PackageSetting childPs = mSettings.mPackages.get(childPkgName); 13163 childPs.oldCodePaths = ps.oldCodePaths; 13164 } 13165 } 13166 prepareAppDataAfterInstall(newPackage); 13167 addedPkg = true; 13168 } catch (PackageManagerException e) { 13169 res.setError("Package couldn't be installed in " + pkg.codePath, e); 13170 } 13171 } 13172 13173 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 13174 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName); 13175 13176 // Revert all internal state mutations and added folders for the failed install 13177 if (addedPkg) { 13178 deletePackageLI(pkgName, null, true, allUsers, deleteFlags, 13179 res.removedInfo, true, null); 13180 } 13181 13182 // Restore the old package 13183 if (deletedPkg) { 13184 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage); 13185 File restoreFile = new File(deletedPackage.codePath); 13186 // Parse old package 13187 boolean oldExternal = isExternal(deletedPackage); 13188 int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY | 13189 (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) | 13190 (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0); 13191 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME; 13192 try { 13193 scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, 13194 null); 13195 } catch (PackageManagerException e) { 13196 Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: " 13197 + e.getMessage()); 13198 return; 13199 } 13200 13201 synchronized (mPackages) { 13202 // Ensure the installer package name up to date 13203 setInstallerPackageNameLPw(deletedPackage, installerPackageName); 13204 13205 // Update permissions for restored package 13206 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL); 13207 13208 mSettings.writeLPr(); 13209 } 13210 13211 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade"); 13212 } 13213 } else { 13214 synchronized (mPackages) { 13215 PackageSetting ps = mSettings.peekPackageLPr(pkg.packageName); 13216 if (ps != null) { 13217 res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null; 13218 if (res.removedInfo.removedChildPackages != null) { 13219 final int childCount = res.removedInfo.removedChildPackages.size(); 13220 // Iterate in reverse as we may modify the collection 13221 for (int i = childCount - 1; i >= 0; i--) { 13222 String childPackageName = res.removedInfo.removedChildPackages.keyAt(i); 13223 if (res.addedChildPackages.containsKey(childPackageName)) { 13224 res.removedInfo.removedChildPackages.removeAt(i); 13225 } else { 13226 PackageRemovedInfo childInfo = res.removedInfo 13227 .removedChildPackages.valueAt(i); 13228 childInfo.removedForAllUsers = mPackages.get( 13229 childInfo.removedPackage) == null; 13230 } 13231 } 13232 } 13233 } 13234 } 13235 } 13236 } 13237 13238 private void replaceSystemPackageLI(PackageParser.Package deletedPackage, 13239 PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, 13240 int[] allUsers, String installerPackageName, PackageInstalledInfo res) { 13241 if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg 13242 + ", old=" + deletedPackage); 13243 13244 final boolean disabledSystem; 13245 13246 // Set the system/privileged flags as needed 13247 parseFlags |= PackageParser.PARSE_IS_SYSTEM; 13248 if ((deletedPackage.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) 13249 != 0) { 13250 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 13251 } 13252 13253 // Kill package processes including services, providers, etc. 13254 killPackage(deletedPackage, "replace sys pkg"); 13255 13256 // Remove existing system package 13257 removePackageLI(deletedPackage, true); 13258 13259 disabledSystem = disableSystemPackageLPw(deletedPackage, pkg); 13260 if (!disabledSystem) { 13261 // We didn't need to disable the .apk as a current system package, 13262 // which means we are replacing another update that is already 13263 // installed. We need to make sure to delete the older one's .apk. 13264 res.removedInfo.args = createInstallArgsForExisting(0, 13265 deletedPackage.applicationInfo.getCodePath(), 13266 deletedPackage.applicationInfo.getResourcePath(), 13267 getAppDexInstructionSets(deletedPackage.applicationInfo)); 13268 } else { 13269 res.removedInfo.args = null; 13270 } 13271 13272 // Successfully disabled the old package. Now proceed with re-installation 13273 deleteCodeCacheDirsLI(pkg); 13274 13275 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 13276 pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP, 13277 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP); 13278 13279 PackageParser.Package newPackage = null; 13280 try { 13281 // Add the package to the internal data structures 13282 newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags, 0, user); 13283 13284 // Set the update and install times 13285 PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras; 13286 setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime, 13287 System.currentTimeMillis()); 13288 13289 // Check for shared user id changes 13290 String invalidPackageName = getParentOrChildPackageChangedSharedUser( 13291 deletedPackage, newPackage); 13292 if (invalidPackageName != null) { 13293 res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 13294 "Forbidding shared user change from " + deletedPkgSetting.sharedUser 13295 + " to " + invalidPackageName); 13296 } 13297 13298 // Update the package dynamic state if succeeded 13299 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 13300 // Now that the install succeeded make sure we remove data 13301 // directories for any child package the update removed. 13302 final int deletedChildCount = (deletedPackage.childPackages != null) 13303 ? deletedPackage.childPackages.size() : 0; 13304 final int newChildCount = (newPackage.childPackages != null) 13305 ? newPackage.childPackages.size() : 0; 13306 for (int i = 0; i < deletedChildCount; i++) { 13307 PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i); 13308 boolean childPackageDeleted = true; 13309 for (int j = 0; j < newChildCount; j++) { 13310 PackageParser.Package newChildPkg = newPackage.childPackages.get(j); 13311 if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) { 13312 childPackageDeleted = false; 13313 break; 13314 } 13315 } 13316 if (childPackageDeleted) { 13317 PackageSetting ps = mSettings.getDisabledSystemPkgLPr( 13318 deletedChildPkg.packageName); 13319 if (ps != null && res.removedInfo.removedChildPackages != null) { 13320 PackageRemovedInfo removedChildRes = res.removedInfo 13321 .removedChildPackages.get(deletedChildPkg.packageName); 13322 removePackageDataLI(ps, allUsers, removedChildRes, 0, false); 13323 removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null; 13324 } 13325 } 13326 } 13327 13328 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user); 13329 prepareAppDataAfterInstall(newPackage); 13330 } 13331 } catch (PackageManagerException e) { 13332 res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR); 13333 res.setError("Package couldn't be installed in " + pkg.codePath, e); 13334 } 13335 13336 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 13337 // Re installation failed. Restore old information 13338 // Remove new pkg information 13339 if (newPackage != null) { 13340 removeInstalledPackageLI(newPackage, true); 13341 } 13342 // Add back the old system package 13343 try { 13344 scanPackageTracedLI(deletedPackage, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user); 13345 } catch (PackageManagerException e) { 13346 Slog.e(TAG, "Failed to restore original package: " + e.getMessage()); 13347 } 13348 13349 synchronized (mPackages) { 13350 if (disabledSystem) { 13351 enableSystemPackageLPw(deletedPackage); 13352 } 13353 13354 // Ensure the installer package name up to date 13355 setInstallerPackageNameLPw(deletedPackage, installerPackageName); 13356 13357 // Update permissions for restored package 13358 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL); 13359 13360 mSettings.writeLPr(); 13361 } 13362 13363 Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName 13364 + " after failed upgrade"); 13365 } 13366 } 13367 13368 /** 13369 * Checks whether the parent or any of the child packages have a change shared 13370 * user. For a package to be a valid update the shred users of the parent and 13371 * the children should match. We may later support changing child shared users. 13372 * @param oldPkg The updated package. 13373 * @param newPkg The update package. 13374 * @return The shared user that change between the versions. 13375 */ 13376 private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg, 13377 PackageParser.Package newPkg) { 13378 // Check parent shared user 13379 if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) { 13380 return newPkg.packageName; 13381 } 13382 // Check child shared users 13383 final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0; 13384 final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0; 13385 for (int i = 0; i < newChildCount; i++) { 13386 PackageParser.Package newChildPkg = newPkg.childPackages.get(i); 13387 // If this child was present, did it have the same shared user? 13388 for (int j = 0; j < oldChildCount; j++) { 13389 PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j); 13390 if (newChildPkg.packageName.equals(oldChildPkg.packageName) 13391 && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) { 13392 return newChildPkg.packageName; 13393 } 13394 } 13395 } 13396 return null; 13397 } 13398 13399 private void removeNativeBinariesLI(PackageSetting ps) { 13400 // Remove the lib path for the parent package 13401 if (ps != null) { 13402 NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString); 13403 // Remove the lib path for the child packages 13404 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0; 13405 for (int i = 0; i < childCount; i++) { 13406 PackageSetting childPs = null; 13407 synchronized (mPackages) { 13408 childPs = mSettings.peekPackageLPr(ps.childPackageNames.get(i)); 13409 } 13410 if (childPs != null) { 13411 NativeLibraryHelper.removeNativeBinariesLI(childPs 13412 .legacyNativeLibraryPathString); 13413 } 13414 } 13415 } 13416 } 13417 13418 private void enableSystemPackageLPw(PackageParser.Package pkg) { 13419 // Enable the parent package 13420 mSettings.enableSystemPackageLPw(pkg.packageName); 13421 // Enable the child packages 13422 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 13423 for (int i = 0; i < childCount; i++) { 13424 PackageParser.Package childPkg = pkg.childPackages.get(i); 13425 mSettings.enableSystemPackageLPw(childPkg.packageName); 13426 } 13427 } 13428 13429 private boolean disableSystemPackageLPw(PackageParser.Package oldPkg, 13430 PackageParser.Package newPkg) { 13431 // Disable the parent package (parent always replaced) 13432 boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true); 13433 // Disable the child packages 13434 final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0; 13435 for (int i = 0; i < childCount; i++) { 13436 PackageParser.Package childPkg = oldPkg.childPackages.get(i); 13437 final boolean replace = newPkg.hasChildPackage(childPkg.packageName); 13438 disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace); 13439 } 13440 return disabled; 13441 } 13442 13443 private void setInstallerPackageNameLPw(PackageParser.Package pkg, 13444 String installerPackageName) { 13445 // Enable the parent package 13446 mSettings.setInstallerPackageName(pkg.packageName, installerPackageName); 13447 // Enable the child packages 13448 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 13449 for (int i = 0; i < childCount; i++) { 13450 PackageParser.Package childPkg = pkg.childPackages.get(i); 13451 mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName); 13452 } 13453 } 13454 13455 private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) { 13456 // Collect all used permissions in the UID 13457 ArraySet<String> usedPermissions = new ArraySet<>(); 13458 final int packageCount = su.packages.size(); 13459 for (int i = 0; i < packageCount; i++) { 13460 PackageSetting ps = su.packages.valueAt(i); 13461 if (ps.pkg == null) { 13462 continue; 13463 } 13464 final int requestedPermCount = ps.pkg.requestedPermissions.size(); 13465 for (int j = 0; j < requestedPermCount; j++) { 13466 String permission = ps.pkg.requestedPermissions.get(j); 13467 BasePermission bp = mSettings.mPermissions.get(permission); 13468 if (bp != null) { 13469 usedPermissions.add(permission); 13470 } 13471 } 13472 } 13473 13474 PermissionsState permissionsState = su.getPermissionsState(); 13475 // Prune install permissions 13476 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates(); 13477 final int installPermCount = installPermStates.size(); 13478 for (int i = installPermCount - 1; i >= 0; i--) { 13479 PermissionState permissionState = installPermStates.get(i); 13480 if (!usedPermissions.contains(permissionState.getName())) { 13481 BasePermission bp = mSettings.mPermissions.get(permissionState.getName()); 13482 if (bp != null) { 13483 permissionsState.revokeInstallPermission(bp); 13484 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 13485 PackageManager.MASK_PERMISSION_FLAGS, 0); 13486 } 13487 } 13488 } 13489 13490 int[] runtimePermissionChangedUserIds = EmptyArray.INT; 13491 13492 // Prune runtime permissions 13493 for (int userId : allUserIds) { 13494 List<PermissionState> runtimePermStates = permissionsState 13495 .getRuntimePermissionStates(userId); 13496 final int runtimePermCount = runtimePermStates.size(); 13497 for (int i = runtimePermCount - 1; i >= 0; i--) { 13498 PermissionState permissionState = runtimePermStates.get(i); 13499 if (!usedPermissions.contains(permissionState.getName())) { 13500 BasePermission bp = mSettings.mPermissions.get(permissionState.getName()); 13501 if (bp != null) { 13502 permissionsState.revokeRuntimePermission(bp, userId); 13503 permissionsState.updatePermissionFlags(bp, userId, 13504 PackageManager.MASK_PERMISSION_FLAGS, 0); 13505 runtimePermissionChangedUserIds = ArrayUtils.appendInt( 13506 runtimePermissionChangedUserIds, userId); 13507 } 13508 } 13509 } 13510 } 13511 13512 return runtimePermissionChangedUserIds; 13513 } 13514 13515 private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, 13516 int[] allUsers, PackageInstalledInfo res, UserHandle user) { 13517 // Update the parent package setting 13518 updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers, 13519 res, user); 13520 // Update the child packages setting 13521 final int childCount = (newPackage.childPackages != null) 13522 ? newPackage.childPackages.size() : 0; 13523 for (int i = 0; i < childCount; i++) { 13524 PackageParser.Package childPackage = newPackage.childPackages.get(i); 13525 PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName); 13526 updateSettingsInternalLI(childPackage, installerPackageName, allUsers, 13527 childRes.origUsers, childRes, user); 13528 } 13529 } 13530 13531 private void updateSettingsInternalLI(PackageParser.Package newPackage, 13532 String installerPackageName, int[] allUsers, int[] installedForUsers, 13533 PackageInstalledInfo res, UserHandle user) { 13534 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 13535 13536 String pkgName = newPackage.packageName; 13537 synchronized (mPackages) { 13538 //write settings. the installStatus will be incomplete at this stage. 13539 //note that the new package setting would have already been 13540 //added to mPackages. It hasn't been persisted yet. 13541 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE); 13542 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings"); 13543 mSettings.writeLPr(); 13544 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13545 } 13546 13547 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath); 13548 synchronized (mPackages) { 13549 updatePermissionsLPw(newPackage.packageName, newPackage, 13550 UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0 13551 ? UPDATE_PERMISSIONS_ALL : 0)); 13552 // For system-bundled packages, we assume that installing an upgraded version 13553 // of the package implies that the user actually wants to run that new code, 13554 // so we enable the package. 13555 PackageSetting ps = mSettings.mPackages.get(pkgName); 13556 final int userId = user.getIdentifier(); 13557 if (ps != null) { 13558 if (isSystemApp(newPackage)) { 13559 if (DEBUG_INSTALL) { 13560 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName); 13561 } 13562 // Enable system package for requested users 13563 if (res.origUsers != null) { 13564 for (int origUserId : res.origUsers) { 13565 if (userId == UserHandle.USER_ALL || userId == origUserId) { 13566 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 13567 origUserId, installerPackageName); 13568 } 13569 } 13570 } 13571 // Also convey the prior install/uninstall state 13572 if (allUsers != null && installedForUsers != null) { 13573 for (int currentUserId : allUsers) { 13574 final boolean installed = ArrayUtils.contains( 13575 installedForUsers, currentUserId); 13576 if (DEBUG_INSTALL) { 13577 Slog.d(TAG, " user " + currentUserId + " => " + installed); 13578 } 13579 ps.setInstalled(installed, currentUserId); 13580 } 13581 // these install state changes will be persisted in the 13582 // upcoming call to mSettings.writeLPr(). 13583 } 13584 } 13585 // It's implied that when a user requests installation, they want the app to be 13586 // installed and enabled. 13587 if (userId != UserHandle.USER_ALL) { 13588 ps.setInstalled(true, userId); 13589 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName); 13590 } 13591 } 13592 res.name = pkgName; 13593 res.uid = newPackage.applicationInfo.uid; 13594 res.pkg = newPackage; 13595 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE); 13596 mSettings.setInstallerPackageName(pkgName, installerPackageName); 13597 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 13598 //to update install status 13599 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings"); 13600 mSettings.writeLPr(); 13601 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13602 } 13603 13604 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13605 } 13606 13607 private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) { 13608 try { 13609 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage"); 13610 installPackageLI(args, res); 13611 } finally { 13612 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13613 } 13614 } 13615 13616 private void installPackageLI(InstallArgs args, PackageInstalledInfo res) { 13617 final int installFlags = args.installFlags; 13618 final String installerPackageName = args.installerPackageName; 13619 final String volumeUuid = args.volumeUuid; 13620 final File tmpPackageFile = new File(args.getCodePath()); 13621 final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0); 13622 final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) 13623 || (args.volumeUuid != null)); 13624 final boolean ephemeral = ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0); 13625 boolean replace = false; 13626 int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE; 13627 if (args.move != null) { 13628 // moving a complete application; perform an initial scan on the new install location 13629 scanFlags |= SCAN_INITIAL; 13630 } 13631 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) { 13632 scanFlags |= SCAN_DONT_KILL_APP; 13633 } 13634 13635 // Result object to be returned 13636 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 13637 13638 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile); 13639 13640 // Sanity check 13641 if (ephemeral && (forwardLocked || onExternal)) { 13642 Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked 13643 + " external=" + onExternal); 13644 res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID); 13645 return; 13646 } 13647 13648 // Retrieve PackageSettings and parse package 13649 final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY 13650 | PackageParser.PARSE_ENFORCE_CODE 13651 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) 13652 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0) 13653 | (ephemeral ? PackageParser.PARSE_IS_EPHEMERAL : 0); 13654 PackageParser pp = new PackageParser(); 13655 pp.setSeparateProcesses(mSeparateProcesses); 13656 pp.setDisplayMetrics(mMetrics); 13657 13658 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage"); 13659 final PackageParser.Package pkg; 13660 try { 13661 pkg = pp.parsePackage(tmpPackageFile, parseFlags); 13662 } catch (PackageParserException e) { 13663 res.setError("Failed parse during installPackageLI", e); 13664 return; 13665 } finally { 13666 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13667 } 13668 13669 // If we are installing a clustered package add results for the children 13670 if (pkg.childPackages != null) { 13671 synchronized (mPackages) { 13672 final int childCount = pkg.childPackages.size(); 13673 for (int i = 0; i < childCount; i++) { 13674 PackageParser.Package childPkg = pkg.childPackages.get(i); 13675 PackageInstalledInfo childRes = new PackageInstalledInfo(); 13676 childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 13677 childRes.pkg = childPkg; 13678 childRes.name = childPkg.packageName; 13679 PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName); 13680 if (childPs != null) { 13681 childRes.origUsers = childPs.queryInstalledUsers( 13682 sUserManager.getUserIds(), true); 13683 } 13684 if ((mPackages.containsKey(childPkg.packageName))) { 13685 childRes.removedInfo = new PackageRemovedInfo(); 13686 childRes.removedInfo.removedPackage = childPkg.packageName; 13687 } 13688 if (res.addedChildPackages == null) { 13689 res.addedChildPackages = new ArrayMap<>(); 13690 } 13691 res.addedChildPackages.put(childPkg.packageName, childRes); 13692 } 13693 } 13694 } 13695 13696 // If package doesn't declare API override, mark that we have an install 13697 // time CPU ABI override. 13698 if (TextUtils.isEmpty(pkg.cpuAbiOverride)) { 13699 pkg.cpuAbiOverride = args.abiOverride; 13700 } 13701 13702 String pkgName = res.name = pkg.packageName; 13703 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) { 13704 if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) { 13705 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI"); 13706 return; 13707 } 13708 } 13709 13710 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates"); 13711 try { 13712 PackageParser.collectCertificates(pkg, parseFlags); 13713 } catch (PackageParserException e) { 13714 res.setError("Failed collect during installPackageLI", e); 13715 return; 13716 } finally { 13717 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13718 } 13719 13720 // Get rid of all references to package scan path via parser. 13721 pp = null; 13722 String oldCodePath = null; 13723 boolean systemApp = false; 13724 synchronized (mPackages) { 13725 // Check if installing already existing package 13726 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 13727 String oldName = mSettings.mRenamedPackages.get(pkgName); 13728 if (pkg.mOriginalPackages != null 13729 && pkg.mOriginalPackages.contains(oldName) 13730 && mPackages.containsKey(oldName)) { 13731 // This package is derived from an original package, 13732 // and this device has been updating from that original 13733 // name. We must continue using the original name, so 13734 // rename the new package here. 13735 pkg.setPackageName(oldName); 13736 pkgName = pkg.packageName; 13737 replace = true; 13738 if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName=" 13739 + oldName + " pkgName=" + pkgName); 13740 } else if (mPackages.containsKey(pkgName)) { 13741 // This package, under its official name, already exists 13742 // on the device; we should replace it. 13743 replace = true; 13744 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName); 13745 } 13746 13747 // Child packages are installed through the parent package 13748 if (pkg.parentPackage != null) { 13749 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME, 13750 "Package " + pkg.packageName + " is child of package " 13751 + pkg.parentPackage.parentPackage + ". Child packages " 13752 + "can be updated only through the parent package."); 13753 return; 13754 } 13755 13756 if (replace) { 13757 // Prevent apps opting out from runtime permissions 13758 PackageParser.Package oldPackage = mPackages.get(pkgName); 13759 final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion; 13760 final int newTargetSdk = pkg.applicationInfo.targetSdkVersion; 13761 if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1 13762 && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) { 13763 res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE, 13764 "Package " + pkg.packageName + " new target SDK " + newTargetSdk 13765 + " doesn't support runtime permissions but the old" 13766 + " target SDK " + oldTargetSdk + " does."); 13767 return; 13768 } 13769 13770 // Prevent installing of child packages 13771 if (oldPackage.parentPackage != null) { 13772 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME, 13773 "Package " + pkg.packageName + " is child of package " 13774 + oldPackage.parentPackage + ". Child packages " 13775 + "can be updated only through the parent package."); 13776 return; 13777 } 13778 } 13779 } 13780 13781 PackageSetting ps = mSettings.mPackages.get(pkgName); 13782 if (ps != null) { 13783 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps); 13784 13785 // Quick sanity check that we're signed correctly if updating; 13786 // we'll check this again later when scanning, but we want to 13787 // bail early here before tripping over redefined permissions. 13788 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { 13789 if (!checkUpgradeKeySetLP(ps, pkg)) { 13790 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 13791 + pkg.packageName + " upgrade keys do not match the " 13792 + "previously installed version"); 13793 return; 13794 } 13795 } else { 13796 try { 13797 verifySignaturesLP(ps, pkg); 13798 } catch (PackageManagerException e) { 13799 res.setError(e.error, e.getMessage()); 13800 return; 13801 } 13802 } 13803 13804 oldCodePath = mSettings.mPackages.get(pkgName).codePathString; 13805 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 13806 systemApp = (ps.pkg.applicationInfo.flags & 13807 ApplicationInfo.FLAG_SYSTEM) != 0; 13808 } 13809 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 13810 } 13811 13812 // Check whether the newly-scanned package wants to define an already-defined perm 13813 int N = pkg.permissions.size(); 13814 for (int i = N-1; i >= 0; i--) { 13815 PackageParser.Permission perm = pkg.permissions.get(i); 13816 BasePermission bp = mSettings.mPermissions.get(perm.info.name); 13817 if (bp != null) { 13818 // If the defining package is signed with our cert, it's okay. This 13819 // also includes the "updating the same package" case, of course. 13820 // "updating same package" could also involve key-rotation. 13821 final boolean sigsOk; 13822 if (bp.sourcePackage.equals(pkg.packageName) 13823 && (bp.packageSetting instanceof PackageSetting) 13824 && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting, 13825 scanFlags))) { 13826 sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg); 13827 } else { 13828 sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures, 13829 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 13830 } 13831 if (!sigsOk) { 13832 // If the owning package is the system itself, we log but allow 13833 // install to proceed; we fail the install on all other permission 13834 // redefinitions. 13835 if (!bp.sourcePackage.equals("android")) { 13836 res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package " 13837 + pkg.packageName + " attempting to redeclare permission " 13838 + perm.info.name + " already owned by " + bp.sourcePackage); 13839 res.origPermission = perm.info.name; 13840 res.origPackage = bp.sourcePackage; 13841 return; 13842 } else { 13843 Slog.w(TAG, "Package " + pkg.packageName 13844 + " attempting to redeclare system permission " 13845 + perm.info.name + "; ignoring new declaration"); 13846 pkg.permissions.remove(i); 13847 } 13848 } 13849 } 13850 } 13851 } 13852 13853 if (systemApp) { 13854 if (onExternal) { 13855 // Abort update; system app can't be replaced with app on sdcard 13856 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION, 13857 "Cannot install updates to system apps on sdcard"); 13858 return; 13859 } else if (ephemeral) { 13860 // Abort update; system app can't be replaced with an ephemeral app 13861 res.setError(INSTALL_FAILED_EPHEMERAL_INVALID, 13862 "Cannot update a system app with an ephemeral app"); 13863 return; 13864 } 13865 } 13866 13867 if (args.move != null) { 13868 // We did an in-place move, so dex is ready to roll 13869 scanFlags |= SCAN_NO_DEX; 13870 scanFlags |= SCAN_MOVE; 13871 13872 synchronized (mPackages) { 13873 final PackageSetting ps = mSettings.mPackages.get(pkgName); 13874 if (ps == null) { 13875 res.setError(INSTALL_FAILED_INTERNAL_ERROR, 13876 "Missing settings for moved package " + pkgName); 13877 } 13878 13879 // We moved the entire application as-is, so bring over the 13880 // previously derived ABI information. 13881 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString; 13882 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString; 13883 } 13884 13885 } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) { 13886 // Enable SCAN_NO_DEX flag to skip dexopt at a later stage 13887 scanFlags |= SCAN_NO_DEX; 13888 13889 try { 13890 String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ? 13891 args.abiOverride : pkg.cpuAbiOverride); 13892 derivePackageAbi(pkg, new File(pkg.codePath), abiOverride, 13893 true /* extract libs */); 13894 } catch (PackageManagerException pme) { 13895 Slog.e(TAG, "Error deriving application ABI", pme); 13896 res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI"); 13897 return; 13898 } 13899 13900 13901 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 13902 // Do not run PackageDexOptimizer through the local performDexOpt 13903 // method because `pkg` is not in `mPackages` yet. 13904 int result = mPackageDexOptimizer.performDexOpt(pkg, null /* instructionSets */, 13905 false /* useProfiles */, true /* extractOnly */); 13906 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13907 if (result == PackageDexOptimizer.DEX_OPT_FAILED) { 13908 String msg = "Extracking package failed for " + pkgName; 13909 res.setError(INSTALL_FAILED_DEXOPT, msg); 13910 return; 13911 } 13912 } 13913 13914 if (!args.doRename(res.returnCode, pkg, oldCodePath)) { 13915 res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename"); 13916 return; 13917 } 13918 13919 startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg); 13920 13921 if (replace) { 13922 replacePackageLI(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user, 13923 installerPackageName, res); 13924 } else { 13925 installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES, 13926 args.user, installerPackageName, volumeUuid, res); 13927 } 13928 synchronized (mPackages) { 13929 final PackageSetting ps = mSettings.mPackages.get(pkgName); 13930 if (ps != null) { 13931 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 13932 } 13933 13934 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 13935 for (int i = 0; i < childCount; i++) { 13936 PackageParser.Package childPkg = pkg.childPackages.get(i); 13937 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName); 13938 PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName); 13939 if (childPs != null) { 13940 childRes.newUsers = childPs.queryInstalledUsers( 13941 sUserManager.getUserIds(), true); 13942 } 13943 } 13944 } 13945 } 13946 13947 private void startIntentFilterVerifications(int userId, boolean replacing, 13948 PackageParser.Package pkg) { 13949 if (mIntentFilterVerifierComponent == null) { 13950 Slog.w(TAG, "No IntentFilter verification will not be done as " 13951 + "there is no IntentFilterVerifier available!"); 13952 return; 13953 } 13954 13955 final int verifierUid = getPackageUid( 13956 mIntentFilterVerifierComponent.getPackageName(), 13957 MATCH_DEBUG_TRIAGED_MISSING, 13958 (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId); 13959 13960 Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 13961 msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid); 13962 mHandler.sendMessage(msg); 13963 13964 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 13965 for (int i = 0; i < childCount; i++) { 13966 PackageParser.Package childPkg = pkg.childPackages.get(i); 13967 msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 13968 msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid); 13969 mHandler.sendMessage(msg); 13970 } 13971 } 13972 13973 private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing, 13974 PackageParser.Package pkg) { 13975 int size = pkg.activities.size(); 13976 if (size == 0) { 13977 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 13978 "No activity, so no need to verify any IntentFilter!"); 13979 return; 13980 } 13981 13982 final boolean hasDomainURLs = hasDomainURLs(pkg); 13983 if (!hasDomainURLs) { 13984 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 13985 "No domain URLs, so no need to verify any IntentFilter!"); 13986 return; 13987 } 13988 13989 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId 13990 + " if any IntentFilter from the " + size 13991 + " Activities needs verification ..."); 13992 13993 int count = 0; 13994 final String packageName = pkg.packageName; 13995 13996 synchronized (mPackages) { 13997 // If this is a new install and we see that we've already run verification for this 13998 // package, we have nothing to do: it means the state was restored from backup. 13999 if (!replacing) { 14000 IntentFilterVerificationInfo ivi = 14001 mSettings.getIntentFilterVerificationLPr(packageName); 14002 if (ivi != null) { 14003 if (DEBUG_DOMAIN_VERIFICATION) { 14004 Slog.i(TAG, "Package " + packageName+ " already verified: status=" 14005 + ivi.getStatusString()); 14006 } 14007 return; 14008 } 14009 } 14010 14011 // If any filters need to be verified, then all need to be. 14012 boolean needToVerify = false; 14013 for (PackageParser.Activity a : pkg.activities) { 14014 for (ActivityIntentInfo filter : a.intents) { 14015 if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) { 14016 if (DEBUG_DOMAIN_VERIFICATION) { 14017 Slog.d(TAG, "Intent filter needs verification, so processing all filters"); 14018 } 14019 needToVerify = true; 14020 break; 14021 } 14022 } 14023 } 14024 14025 if (needToVerify) { 14026 final int verificationId = mIntentFilterVerificationToken++; 14027 for (PackageParser.Activity a : pkg.activities) { 14028 for (ActivityIntentInfo filter : a.intents) { 14029 if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) { 14030 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 14031 "Verification needed for IntentFilter:" + filter.toString()); 14032 mIntentFilterVerifier.addOneIntentFilterVerification( 14033 verifierUid, userId, verificationId, filter, packageName); 14034 count++; 14035 } 14036 } 14037 } 14038 } 14039 } 14040 14041 if (count > 0) { 14042 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count 14043 + " IntentFilter verification" + (count > 1 ? "s" : "") 14044 + " for userId:" + userId); 14045 mIntentFilterVerifier.startVerifications(userId); 14046 } else { 14047 if (DEBUG_DOMAIN_VERIFICATION) { 14048 Slog.d(TAG, "No filters or not all autoVerify for " + packageName); 14049 } 14050 } 14051 } 14052 14053 private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) { 14054 final ComponentName cn = filter.activity.getComponentName(); 14055 final String packageName = cn.getPackageName(); 14056 14057 IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr( 14058 packageName); 14059 if (ivi == null) { 14060 return true; 14061 } 14062 int status = ivi.getStatus(); 14063 switch (status) { 14064 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 14065 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 14066 return true; 14067 14068 default: 14069 // Nothing to do 14070 return false; 14071 } 14072 } 14073 14074 private static boolean isMultiArch(ApplicationInfo info) { 14075 return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0; 14076 } 14077 14078 private static boolean isExternal(PackageParser.Package pkg) { 14079 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 14080 } 14081 14082 private static boolean isExternal(PackageSetting ps) { 14083 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 14084 } 14085 14086 private static boolean isEphemeral(PackageParser.Package pkg) { 14087 return pkg.applicationInfo.isEphemeralApp(); 14088 } 14089 14090 private static boolean isEphemeral(PackageSetting ps) { 14091 return ps.pkg != null && isEphemeral(ps.pkg); 14092 } 14093 14094 private static boolean isSystemApp(PackageParser.Package pkg) { 14095 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 14096 } 14097 14098 private static boolean isPrivilegedApp(PackageParser.Package pkg) { 14099 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; 14100 } 14101 14102 private static boolean hasDomainURLs(PackageParser.Package pkg) { 14103 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0; 14104 } 14105 14106 private static boolean isSystemApp(PackageSetting ps) { 14107 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0; 14108 } 14109 14110 private static boolean isUpdatedSystemApp(PackageSetting ps) { 14111 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; 14112 } 14113 14114 private int packageFlagsToInstallFlags(PackageSetting ps) { 14115 int installFlags = 0; 14116 if (isEphemeral(ps)) { 14117 installFlags |= PackageManager.INSTALL_EPHEMERAL; 14118 } 14119 if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) { 14120 // This existing package was an external ASEC install when we have 14121 // the external flag without a UUID 14122 installFlags |= PackageManager.INSTALL_EXTERNAL; 14123 } 14124 if (ps.isForwardLocked()) { 14125 installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 14126 } 14127 return installFlags; 14128 } 14129 14130 private String getVolumeUuidForPackage(PackageParser.Package pkg) { 14131 if (isExternal(pkg)) { 14132 if (TextUtils.isEmpty(pkg.volumeUuid)) { 14133 return StorageManager.UUID_PRIMARY_PHYSICAL; 14134 } else { 14135 return pkg.volumeUuid; 14136 } 14137 } else { 14138 return StorageManager.UUID_PRIVATE_INTERNAL; 14139 } 14140 } 14141 14142 private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) { 14143 if (isExternal(pkg)) { 14144 if (TextUtils.isEmpty(pkg.volumeUuid)) { 14145 return mSettings.getExternalVersion(); 14146 } else { 14147 return mSettings.findOrCreateVersion(pkg.volumeUuid); 14148 } 14149 } else { 14150 return mSettings.getInternalVersion(); 14151 } 14152 } 14153 14154 private void deleteTempPackageFiles() { 14155 final FilenameFilter filter = new FilenameFilter() { 14156 public boolean accept(File dir, String name) { 14157 return name.startsWith("vmdl") && name.endsWith(".tmp"); 14158 } 14159 }; 14160 for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) { 14161 file.delete(); 14162 } 14163 } 14164 14165 @Override 14166 public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId, 14167 int flags) { 14168 deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId, 14169 flags); 14170 } 14171 14172 @Override 14173 public void deletePackage(final String packageName, 14174 final IPackageDeleteObserver2 observer, final int userId, final int flags) { 14175 mContext.enforceCallingOrSelfPermission( 14176 android.Manifest.permission.DELETE_PACKAGES, null); 14177 Preconditions.checkNotNull(packageName); 14178 Preconditions.checkNotNull(observer); 14179 final int uid = Binder.getCallingUid(); 14180 final boolean deleteAllUsers = (flags & PackageManager.DELETE_ALL_USERS) != 0; 14181 final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId }; 14182 if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) { 14183 mContext.enforceCallingOrSelfPermission( 14184 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 14185 "deletePackage for user " + userId); 14186 } 14187 14188 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) { 14189 try { 14190 observer.onPackageDeleted(packageName, 14191 PackageManager.DELETE_FAILED_USER_RESTRICTED, null); 14192 } catch (RemoteException re) { 14193 } 14194 return; 14195 } 14196 14197 if (!deleteAllUsers && getBlockUninstallForUser(packageName, userId)) { 14198 try { 14199 observer.onPackageDeleted(packageName, 14200 PackageManager.DELETE_FAILED_OWNER_BLOCKED, null); 14201 } catch (RemoteException re) { 14202 } 14203 return; 14204 } 14205 14206 if (DEBUG_REMOVE) { 14207 Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId 14208 + " deleteAllUsers: " + deleteAllUsers ); 14209 } 14210 // Queue up an async operation since the package deletion may take a little while. 14211 mHandler.post(new Runnable() { 14212 public void run() { 14213 mHandler.removeCallbacks(this); 14214 int returnCode; 14215 if (!deleteAllUsers) { 14216 returnCode = deletePackageX(packageName, userId, flags); 14217 } else { 14218 int[] blockUninstallUserIds = getBlockUninstallForUsers(packageName, users); 14219 // If nobody is blocking uninstall, proceed with delete for all users 14220 if (ArrayUtils.isEmpty(blockUninstallUserIds)) { 14221 returnCode = deletePackageX(packageName, userId, flags); 14222 } else { 14223 // Otherwise uninstall individually for users with blockUninstalls=false 14224 final int userFlags = flags & ~PackageManager.DELETE_ALL_USERS; 14225 for (int userId : users) { 14226 if (!ArrayUtils.contains(blockUninstallUserIds, userId)) { 14227 returnCode = deletePackageX(packageName, userId, userFlags); 14228 if (returnCode != PackageManager.DELETE_SUCCEEDED) { 14229 Slog.w(TAG, "Package delete failed for user " + userId 14230 + ", returnCode " + returnCode); 14231 } 14232 } 14233 } 14234 // The app has only been marked uninstalled for certain users. 14235 // We still need to report that delete was blocked 14236 returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED; 14237 } 14238 } 14239 try { 14240 observer.onPackageDeleted(packageName, returnCode, null); 14241 } catch (RemoteException e) { 14242 Log.i(TAG, "Observer no longer exists."); 14243 } //end catch 14244 } //end run 14245 }); 14246 } 14247 14248 private int[] getBlockUninstallForUsers(String packageName, int[] userIds) { 14249 int[] result = EMPTY_INT_ARRAY; 14250 for (int userId : userIds) { 14251 if (getBlockUninstallForUser(packageName, userId)) { 14252 result = ArrayUtils.appendInt(result, userId); 14253 } 14254 } 14255 return result; 14256 } 14257 14258 @Override 14259 public boolean isPackageDeviceAdminOnAnyUser(String packageName) { 14260 return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL); 14261 } 14262 14263 private boolean isPackageDeviceAdmin(String packageName, int userId) { 14264 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface( 14265 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); 14266 try { 14267 if (dpm != null) { 14268 final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent( 14269 /* callingUserOnly =*/ false); 14270 final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null 14271 : deviceOwnerComponentName.getPackageName(); 14272 // Does the package contains the device owner? 14273 // TODO Do we have to do it even if userId != UserHandle.USER_ALL? Otherwise, 14274 // this check is probably not needed, since DO should be registered as a device 14275 // admin on some user too. (Original bug for this: b/17657954) 14276 if (packageName.equals(deviceOwnerPackageName)) { 14277 return true; 14278 } 14279 // Does it contain a device admin for any user? 14280 int[] users; 14281 if (userId == UserHandle.USER_ALL) { 14282 users = sUserManager.getUserIds(); 14283 } else { 14284 users = new int[]{userId}; 14285 } 14286 for (int i = 0; i < users.length; ++i) { 14287 if (dpm.packageHasActiveAdmins(packageName, users[i])) { 14288 return true; 14289 } 14290 } 14291 } 14292 } catch (RemoteException e) { 14293 } 14294 return false; 14295 } 14296 14297 private boolean shouldKeepUninstalledPackageLPr(String packageName) { 14298 return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName); 14299 } 14300 14301 /** 14302 * This method is an internal method that could be get invoked either 14303 * to delete an installed package or to clean up a failed installation. 14304 * After deleting an installed package, a broadcast is sent to notify any 14305 * listeners that the package has been installed. For cleaning up a failed 14306 * installation, the broadcast is not necessary since the package's 14307 * installation wouldn't have sent the initial broadcast either 14308 * The key steps in deleting a package are 14309 * deleting the package information in internal structures like mPackages, 14310 * deleting the packages base directories through installd 14311 * updating mSettings to reflect current status 14312 * persisting settings for later use 14313 * sending a broadcast if necessary 14314 */ 14315 private int deletePackageX(String packageName, int userId, int flags) { 14316 final PackageRemovedInfo info = new PackageRemovedInfo(); 14317 final boolean res; 14318 14319 final UserHandle removeForUser = (flags & PackageManager.DELETE_ALL_USERS) != 0 14320 ? UserHandle.ALL : new UserHandle(userId); 14321 14322 if (isPackageDeviceAdmin(packageName, removeForUser.getIdentifier())) { 14323 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin"); 14324 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER; 14325 } 14326 14327 PackageSetting uninstalledPs = null; 14328 14329 // for the uninstall-updates case and restricted profiles, remember the per- 14330 // user handle installed state 14331 int[] allUsers; 14332 synchronized (mPackages) { 14333 uninstalledPs = mSettings.mPackages.get(packageName); 14334 if (uninstalledPs == null) { 14335 Slog.w(TAG, "Not removing non-existent package " + packageName); 14336 return PackageManager.DELETE_FAILED_INTERNAL_ERROR; 14337 } 14338 allUsers = sUserManager.getUserIds(); 14339 info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true); 14340 } 14341 14342 synchronized (mInstallLock) { 14343 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId); 14344 res = deletePackageLI(packageName, removeForUser, true, allUsers, 14345 flags | REMOVE_CHATTY, info, true, null); 14346 synchronized (mPackages) { 14347 if (res) { 14348 mEphemeralApplicationRegistry.onPackageUninstalledLPw(uninstalledPs.pkg); 14349 } 14350 } 14351 } 14352 14353 if (res) { 14354 final boolean killApp = (flags & PackageManager.INSTALL_DONT_KILL_APP) == 0; 14355 info.sendPackageRemovedBroadcasts(killApp); 14356 info.sendSystemPackageUpdatedBroadcasts(); 14357 info.sendSystemPackageAppearedBroadcasts(); 14358 } 14359 // Force a gc here. 14360 Runtime.getRuntime().gc(); 14361 // Delete the resources here after sending the broadcast to let 14362 // other processes clean up before deleting resources. 14363 if (info.args != null) { 14364 synchronized (mInstallLock) { 14365 info.args.doPostDeleteLI(true); 14366 } 14367 } 14368 14369 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR; 14370 } 14371 14372 class PackageRemovedInfo { 14373 String removedPackage; 14374 int uid = -1; 14375 int removedAppId = -1; 14376 int[] origUsers; 14377 int[] removedUsers = null; 14378 boolean isRemovedPackageSystemUpdate = false; 14379 boolean isUpdate; 14380 boolean dataRemoved; 14381 boolean removedForAllUsers; 14382 // Clean up resources deleted packages. 14383 InstallArgs args = null; 14384 ArrayMap<String, PackageRemovedInfo> removedChildPackages; 14385 ArrayMap<String, PackageInstalledInfo> appearedChildPackages; 14386 14387 void sendPackageRemovedBroadcasts(boolean killApp) { 14388 sendPackageRemovedBroadcastInternal(killApp); 14389 final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0; 14390 for (int i = 0; i < childCount; i++) { 14391 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i); 14392 childInfo.sendPackageRemovedBroadcastInternal(killApp); 14393 } 14394 } 14395 14396 void sendSystemPackageUpdatedBroadcasts() { 14397 if (isRemovedPackageSystemUpdate) { 14398 sendSystemPackageUpdatedBroadcastsInternal(); 14399 final int childCount = (removedChildPackages != null) 14400 ? removedChildPackages.size() : 0; 14401 for (int i = 0; i < childCount; i++) { 14402 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i); 14403 if (childInfo.isRemovedPackageSystemUpdate) { 14404 childInfo.sendSystemPackageUpdatedBroadcastsInternal(); 14405 } 14406 } 14407 } 14408 } 14409 14410 void sendSystemPackageAppearedBroadcasts() { 14411 final int packageCount = (appearedChildPackages != null) 14412 ? appearedChildPackages.size() : 0; 14413 for (int i = 0; i < packageCount; i++) { 14414 PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i); 14415 for (int userId : installedInfo.newUsers) { 14416 sendPackageAddedForUser(installedInfo.name, true, 14417 UserHandle.getAppId(installedInfo.uid), userId); 14418 } 14419 } 14420 } 14421 14422 private void sendSystemPackageUpdatedBroadcastsInternal() { 14423 Bundle extras = new Bundle(2); 14424 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 14425 extras.putBoolean(Intent.EXTRA_REPLACING, true); 14426 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, removedPackage, 14427 extras, 0, null, null, null); 14428 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, removedPackage, 14429 extras, 0, null, null, null); 14430 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null, 14431 null, 0, removedPackage, null, null); 14432 } 14433 14434 private void sendPackageRemovedBroadcastInternal(boolean killApp) { 14435 Bundle extras = new Bundle(2); 14436 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 14437 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved); 14438 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp); 14439 if (isUpdate || isRemovedPackageSystemUpdate) { 14440 extras.putBoolean(Intent.EXTRA_REPLACING, true); 14441 } 14442 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers); 14443 if (removedPackage != null) { 14444 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, 14445 extras, 0, null, null, removedUsers); 14446 if (dataRemoved && !isRemovedPackageSystemUpdate) { 14447 sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, 14448 removedPackage, extras, 0, null, null, removedUsers); 14449 } 14450 } 14451 if (removedAppId >= 0) { 14452 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, 0, null, null, 14453 removedUsers); 14454 } 14455 } 14456 } 14457 14458 /* 14459 * This method deletes the package from internal data structures. If the DONT_DELETE_DATA 14460 * flag is not set, the data directory is removed as well. 14461 * make sure this flag is set for partially installed apps. If not its meaningless to 14462 * delete a partially installed application. 14463 */ 14464 private void removePackageDataLI(PackageSetting ps, int[] allUserHandles, 14465 PackageRemovedInfo outInfo, int flags, boolean writeSettings) { 14466 String packageName = ps.name; 14467 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps); 14468 removePackageLI(ps, (flags&REMOVE_CHATTY) != 0); 14469 // Retrieve object to delete permissions for shared user later on 14470 final PackageSetting deletedPs; 14471 // reader 14472 synchronized (mPackages) { 14473 deletedPs = mSettings.mPackages.get(packageName); 14474 if (outInfo != null) { 14475 outInfo.removedPackage = packageName; 14476 outInfo.removedUsers = deletedPs != null 14477 ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true) 14478 : null; 14479 } 14480 } 14481 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 14482 removeDataDirsLI(ps.volumeUuid, packageName); 14483 if (outInfo != null) { 14484 outInfo.dataRemoved = true; 14485 } 14486 schedulePackageCleaning(packageName, UserHandle.USER_ALL, true); 14487 } 14488 // writer 14489 synchronized (mPackages) { 14490 if (deletedPs != null) { 14491 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 14492 clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL); 14493 clearDefaultBrowserIfNeeded(packageName); 14494 if (outInfo != null) { 14495 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName); 14496 outInfo.removedAppId = mSettings.removePackageLPw(packageName); 14497 } 14498 updatePermissionsLPw(deletedPs.name, null, 0); 14499 if (deletedPs.sharedUser != null) { 14500 // Remove permissions associated with package. Since runtime 14501 // permissions are per user we have to kill the removed package 14502 // or packages running under the shared user of the removed 14503 // package if revoking the permissions requested only by the removed 14504 // package is successful and this causes a change in gids. 14505 for (int userId : UserManagerService.getInstance().getUserIds()) { 14506 final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs, 14507 userId); 14508 if (userIdToKill == UserHandle.USER_ALL 14509 || userIdToKill >= UserHandle.USER_SYSTEM) { 14510 // If gids changed for this user, kill all affected packages. 14511 mHandler.post(new Runnable() { 14512 @Override 14513 public void run() { 14514 // This has to happen with no lock held. 14515 killApplication(deletedPs.name, deletedPs.appId, 14516 KILL_APP_REASON_GIDS_CHANGED); 14517 } 14518 }); 14519 break; 14520 } 14521 } 14522 } 14523 clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL); 14524 } 14525 // make sure to preserve per-user disabled state if this removal was just 14526 // a downgrade of a system app to the factory package 14527 if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) { 14528 if (DEBUG_REMOVE) { 14529 Slog.d(TAG, "Propagating install state across downgrade"); 14530 } 14531 for (int userId : allUserHandles) { 14532 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId); 14533 if (DEBUG_REMOVE) { 14534 Slog.d(TAG, " user " + userId + " => " + installed); 14535 } 14536 ps.setInstalled(installed, userId); 14537 } 14538 } 14539 } 14540 // can downgrade to reader 14541 if (writeSettings) { 14542 // Save settings now 14543 mSettings.writeLPr(); 14544 } 14545 } 14546 if (outInfo != null) { 14547 // A user ID was deleted here. Go through all users and remove it 14548 // from KeyStore. 14549 removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId); 14550 } 14551 } 14552 14553 static boolean locationIsPrivileged(File path) { 14554 try { 14555 final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app") 14556 .getCanonicalPath(); 14557 return path.getCanonicalPath().startsWith(privilegedAppDir); 14558 } catch (IOException e) { 14559 Slog.e(TAG, "Unable to access code path " + path); 14560 } 14561 return false; 14562 } 14563 14564 /* 14565 * Tries to delete system package. 14566 */ 14567 private boolean deleteSystemPackageLI(PackageParser.Package deletedPkg, 14568 PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo, 14569 boolean writeSettings) { 14570 if (deletedPs.parentPackageName != null) { 14571 Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName); 14572 return false; 14573 } 14574 14575 final boolean applyUserRestrictions 14576 = (allUserHandles != null) && (outInfo.origUsers != null); 14577 final PackageSetting disabledPs; 14578 // Confirm if the system package has been updated 14579 // An updated system app can be deleted. This will also have to restore 14580 // the system pkg from system partition 14581 // reader 14582 synchronized (mPackages) { 14583 disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name); 14584 } 14585 14586 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName 14587 + " disabledPs=" + disabledPs); 14588 14589 if (disabledPs == null) { 14590 Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName); 14591 return false; 14592 } else if (DEBUG_REMOVE) { 14593 Slog.d(TAG, "Deleting system pkg from data partition"); 14594 } 14595 14596 if (DEBUG_REMOVE) { 14597 if (applyUserRestrictions) { 14598 Slog.d(TAG, "Remembering install states:"); 14599 for (int userId : allUserHandles) { 14600 final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId); 14601 Slog.d(TAG, " u=" + userId + " inst=" + finstalled); 14602 } 14603 } 14604 } 14605 14606 // Delete the updated package 14607 outInfo.isRemovedPackageSystemUpdate = true; 14608 if (outInfo.removedChildPackages != null) { 14609 final int childCount = (deletedPs.childPackageNames != null) 14610 ? deletedPs.childPackageNames.size() : 0; 14611 for (int i = 0; i < childCount; i++) { 14612 String childPackageName = deletedPs.childPackageNames.get(i); 14613 if (disabledPs.childPackageNames != null && disabledPs.childPackageNames 14614 .contains(childPackageName)) { 14615 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get( 14616 childPackageName); 14617 if (childInfo != null) { 14618 childInfo.isRemovedPackageSystemUpdate = true; 14619 } 14620 } 14621 } 14622 } 14623 14624 if (disabledPs.versionCode < deletedPs.versionCode) { 14625 // Delete data for downgrades 14626 flags &= ~PackageManager.DELETE_KEEP_DATA; 14627 } else { 14628 // Preserve data by setting flag 14629 flags |= PackageManager.DELETE_KEEP_DATA; 14630 } 14631 14632 boolean ret = deleteInstalledPackageLI(deletedPs, true, flags, allUserHandles, 14633 outInfo, writeSettings, disabledPs.pkg); 14634 if (!ret) { 14635 return false; 14636 } 14637 14638 // writer 14639 synchronized (mPackages) { 14640 // Reinstate the old system package 14641 enableSystemPackageLPw(disabledPs.pkg); 14642 // Remove any native libraries from the upgraded package. 14643 removeNativeBinariesLI(deletedPs); 14644 } 14645 14646 // Install the system package 14647 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs); 14648 int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM; 14649 if (locationIsPrivileged(disabledPs.codePath)) { 14650 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 14651 } 14652 14653 final PackageParser.Package newPkg; 14654 try { 14655 newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null); 14656 } catch (PackageManagerException e) { 14657 Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": " 14658 + e.getMessage()); 14659 return false; 14660 } 14661 14662 prepareAppDataAfterInstall(newPkg); 14663 14664 // writer 14665 synchronized (mPackages) { 14666 PackageSetting ps = mSettings.mPackages.get(newPkg.packageName); 14667 14668 // Propagate the permissions state as we do not want to drop on the floor 14669 // runtime permissions. The update permissions method below will take 14670 // care of removing obsolete permissions and grant install permissions. 14671 ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState()); 14672 updatePermissionsLPw(newPkg.packageName, newPkg, 14673 UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG); 14674 14675 if (applyUserRestrictions) { 14676 if (DEBUG_REMOVE) { 14677 Slog.d(TAG, "Propagating install state across reinstall"); 14678 } 14679 for (int userId : allUserHandles) { 14680 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId); 14681 if (DEBUG_REMOVE) { 14682 Slog.d(TAG, " user " + userId + " => " + installed); 14683 } 14684 ps.setInstalled(installed, userId); 14685 14686 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 14687 } 14688 // Regardless of writeSettings we need to ensure that this restriction 14689 // state propagation is persisted 14690 mSettings.writeAllUsersPackageRestrictionsLPr(); 14691 } 14692 // can downgrade to reader here 14693 if (writeSettings) { 14694 mSettings.writeLPr(); 14695 } 14696 } 14697 return true; 14698 } 14699 14700 private boolean deleteInstalledPackageLI(PackageSetting ps, 14701 boolean deleteCodeAndResources, int flags, int[] allUserHandles, 14702 PackageRemovedInfo outInfo, boolean writeSettings, 14703 PackageParser.Package replacingPackage) { 14704 synchronized (mPackages) { 14705 if (outInfo != null) { 14706 outInfo.uid = ps.appId; 14707 } 14708 14709 if (outInfo != null && outInfo.removedChildPackages != null) { 14710 final int childCount = (ps.childPackageNames != null) 14711 ? ps.childPackageNames.size() : 0; 14712 for (int i = 0; i < childCount; i++) { 14713 String childPackageName = ps.childPackageNames.get(i); 14714 PackageSetting childPs = mSettings.mPackages.get(childPackageName); 14715 if (childPs == null) { 14716 return false; 14717 } 14718 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get( 14719 childPackageName); 14720 if (childInfo != null) { 14721 childInfo.uid = childPs.appId; 14722 } 14723 } 14724 } 14725 } 14726 14727 // Delete package data from internal structures and also remove data if flag is set 14728 removePackageDataLI(ps, allUserHandles, outInfo, flags, writeSettings); 14729 14730 // Delete the child packages data 14731 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0; 14732 for (int i = 0; i < childCount; i++) { 14733 PackageSetting childPs; 14734 synchronized (mPackages) { 14735 childPs = mSettings.peekPackageLPr(ps.childPackageNames.get(i)); 14736 } 14737 if (childPs != null) { 14738 PackageRemovedInfo childOutInfo = (outInfo != null 14739 && outInfo.removedChildPackages != null) 14740 ? outInfo.removedChildPackages.get(childPs.name) : null; 14741 final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0 14742 && (replacingPackage != null 14743 && !replacingPackage.hasChildPackage(childPs.name)) 14744 ? flags & ~DELETE_KEEP_DATA : flags; 14745 removePackageDataLI(childPs, allUserHandles, childOutInfo, 14746 deleteFlags, writeSettings); 14747 } 14748 } 14749 14750 // Delete application code and resources only for parent packages 14751 if (ps.parentPackageName == null) { 14752 if (deleteCodeAndResources && (outInfo != null)) { 14753 outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 14754 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 14755 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args); 14756 } 14757 } 14758 14759 return true; 14760 } 14761 14762 @Override 14763 public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall, 14764 int userId) { 14765 mContext.enforceCallingOrSelfPermission( 14766 android.Manifest.permission.DELETE_PACKAGES, null); 14767 synchronized (mPackages) { 14768 PackageSetting ps = mSettings.mPackages.get(packageName); 14769 if (ps == null) { 14770 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName); 14771 return false; 14772 } 14773 if (!ps.getInstalled(userId)) { 14774 // Can't block uninstall for an app that is not installed or enabled. 14775 Log.i(TAG, "Package not installed in set block uninstall " + packageName); 14776 return false; 14777 } 14778 ps.setBlockUninstall(blockUninstall, userId); 14779 mSettings.writePackageRestrictionsLPr(userId); 14780 } 14781 return true; 14782 } 14783 14784 @Override 14785 public boolean getBlockUninstallForUser(String packageName, int userId) { 14786 synchronized (mPackages) { 14787 PackageSetting ps = mSettings.mPackages.get(packageName); 14788 if (ps == null) { 14789 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName); 14790 return false; 14791 } 14792 return ps.getBlockUninstall(userId); 14793 } 14794 } 14795 14796 @Override 14797 public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) { 14798 int callingUid = Binder.getCallingUid(); 14799 if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) { 14800 throw new SecurityException( 14801 "setRequiredForSystemUser can only be run by the system or root"); 14802 } 14803 synchronized (mPackages) { 14804 PackageSetting ps = mSettings.mPackages.get(packageName); 14805 if (ps == null) { 14806 Log.w(TAG, "Package doesn't exist: " + packageName); 14807 return false; 14808 } 14809 if (systemUserApp) { 14810 ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER; 14811 } else { 14812 ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER; 14813 } 14814 mSettings.writeLPr(); 14815 } 14816 return true; 14817 } 14818 14819 /* 14820 * This method handles package deletion in general 14821 */ 14822 private boolean deletePackageLI(String packageName, UserHandle user, 14823 boolean deleteCodeAndResources, int[] allUserHandles, int flags, 14824 PackageRemovedInfo outInfo, boolean writeSettings, 14825 PackageParser.Package replacingPackage) { 14826 if (packageName == null) { 14827 Slog.w(TAG, "Attempt to delete null packageName."); 14828 return false; 14829 } 14830 14831 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user); 14832 14833 PackageSetting ps; 14834 14835 synchronized (mPackages) { 14836 ps = mSettings.mPackages.get(packageName); 14837 if (ps == null) { 14838 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 14839 return false; 14840 } 14841 14842 if (ps.parentPackageName != null && (!isSystemApp(ps) 14843 || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) { 14844 if (DEBUG_REMOVE) { 14845 Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:" 14846 + ((user == null) ? UserHandle.USER_ALL : user)); 14847 } 14848 final int removedUserId = (user != null) ? user.getIdentifier() 14849 : UserHandle.USER_ALL; 14850 if (!clearPackageStateForUser(ps, removedUserId, outInfo)) { 14851 return false; 14852 } 14853 markPackageUninstalledForUserLPw(ps, user); 14854 scheduleWritePackageRestrictionsLocked(user); 14855 return true; 14856 } 14857 } 14858 14859 if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null 14860 && user.getIdentifier() != UserHandle.USER_ALL)) { 14861 // The caller is asking that the package only be deleted for a single 14862 // user. To do this, we just mark its uninstalled state and delete 14863 // its data. If this is a system app, we only allow this to happen if 14864 // they have set the special DELETE_SYSTEM_APP which requests different 14865 // semantics than normal for uninstalling system apps. 14866 markPackageUninstalledForUserLPw(ps, user); 14867 14868 if (!isSystemApp(ps)) { 14869 // Do not uninstall the APK if an app should be cached 14870 boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName); 14871 if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) { 14872 // Other user still have this package installed, so all 14873 // we need to do is clear this user's data and save that 14874 // it is uninstalled. 14875 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users"); 14876 if (!clearPackageStateForUser(ps, user.getIdentifier(), outInfo)) { 14877 return false; 14878 } 14879 scheduleWritePackageRestrictionsLocked(user); 14880 return true; 14881 } else { 14882 // We need to set it back to 'installed' so the uninstall 14883 // broadcasts will be sent correctly. 14884 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete"); 14885 ps.setInstalled(true, user.getIdentifier()); 14886 } 14887 } else { 14888 // This is a system app, so we assume that the 14889 // other users still have this package installed, so all 14890 // we need to do is clear this user's data and save that 14891 // it is uninstalled. 14892 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app"); 14893 if (!clearPackageStateForUser(ps, user.getIdentifier(), outInfo)) { 14894 return false; 14895 } 14896 scheduleWritePackageRestrictionsLocked(user); 14897 return true; 14898 } 14899 } 14900 14901 // If we are deleting a composite package for all users, keep track 14902 // of result for each child. 14903 if (ps.childPackageNames != null && outInfo != null) { 14904 synchronized (mPackages) { 14905 final int childCount = ps.childPackageNames.size(); 14906 outInfo.removedChildPackages = new ArrayMap<>(childCount); 14907 for (int i = 0; i < childCount; i++) { 14908 String childPackageName = ps.childPackageNames.get(i); 14909 PackageRemovedInfo childInfo = new PackageRemovedInfo(); 14910 childInfo.removedPackage = childPackageName; 14911 outInfo.removedChildPackages.put(childPackageName, childInfo); 14912 PackageSetting childPs = mSettings.peekPackageLPr(childPackageName); 14913 if (childPs != null) { 14914 childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true); 14915 } 14916 } 14917 } 14918 } 14919 14920 boolean ret = false; 14921 if (isSystemApp(ps)) { 14922 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name); 14923 // When an updated system application is deleted we delete the existing resources 14924 // as well and fall back to existing code in system partition 14925 ret = deleteSystemPackageLI(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings); 14926 } else { 14927 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name); 14928 // Kill application pre-emptively especially for apps on sd. 14929 final boolean killApp = (flags & PackageManager.DELETE_DONT_KILL_APP) == 0; 14930 if (killApp) { 14931 killApplication(packageName, ps.appId, "uninstall pkg"); 14932 } 14933 ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags, allUserHandles, 14934 outInfo, writeSettings, replacingPackage); 14935 } 14936 14937 // Take a note whether we deleted the package for all users 14938 if (outInfo != null) { 14939 outInfo.removedForAllUsers = mPackages.get(ps.name) == null; 14940 if (outInfo.removedChildPackages != null) { 14941 synchronized (mPackages) { 14942 final int childCount = outInfo.removedChildPackages.size(); 14943 for (int i = 0; i < childCount; i++) { 14944 PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i); 14945 if (childInfo != null) { 14946 childInfo.removedForAllUsers = mPackages.get( 14947 childInfo.removedPackage) == null; 14948 } 14949 } 14950 } 14951 } 14952 // If we uninstalled an update to a system app there may be some 14953 // child packages that appeared as they are declared in the system 14954 // app but were not declared in the update. 14955 if (isSystemApp(ps)) { 14956 synchronized (mPackages) { 14957 PackageSetting updatedPs = mSettings.peekPackageLPr(ps.name); 14958 final int childCount = (updatedPs.childPackageNames != null) 14959 ? updatedPs.childPackageNames.size() : 0; 14960 for (int i = 0; i < childCount; i++) { 14961 String childPackageName = updatedPs.childPackageNames.get(i); 14962 if (outInfo.removedChildPackages == null 14963 || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) { 14964 PackageSetting childPs = mSettings.peekPackageLPr(childPackageName); 14965 if (childPs == null) { 14966 continue; 14967 } 14968 PackageInstalledInfo installRes = new PackageInstalledInfo(); 14969 installRes.name = childPackageName; 14970 installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true); 14971 installRes.pkg = mPackages.get(childPackageName); 14972 installRes.uid = childPs.pkg.applicationInfo.uid; 14973 if (outInfo.appearedChildPackages == null) { 14974 outInfo.appearedChildPackages = new ArrayMap<>(); 14975 } 14976 outInfo.appearedChildPackages.put(childPackageName, installRes); 14977 } 14978 } 14979 } 14980 } 14981 } 14982 14983 return ret; 14984 } 14985 14986 private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) { 14987 final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL) 14988 ? sUserManager.getUserIds() : new int[] {user.getIdentifier()}; 14989 for (int nextUserId : userIds) { 14990 if (DEBUG_REMOVE) { 14991 Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId); 14992 } 14993 ps.setUserState(nextUserId, COMPONENT_ENABLED_STATE_DEFAULT, 14994 false /*installed*/, true /*stopped*/, true /*notLaunched*/, 14995 false /*hidden*/, false /*suspended*/, null, null, null, 14996 false /*blockUninstall*/, 14997 ps.readUserState(nextUserId).domainVerificationStatus, 0); 14998 } 14999 } 15000 15001 private boolean clearPackageStateForUser(PackageSetting ps, int userId, 15002 PackageRemovedInfo outInfo) { 15003 final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() 15004 : new int[] {userId}; 15005 for (int nextUserId : userIds) { 15006 if (DEBUG_REMOVE) { 15007 Slog.d(TAG, "Updating package:" + ps.name + " install state for user:" 15008 + nextUserId); 15009 } 15010 final int flags = StorageManager.FLAG_STORAGE_CE| StorageManager.FLAG_STORAGE_DE; 15011 try { 15012 mInstaller.destroyAppData(ps.volumeUuid, ps.name, nextUserId, flags); 15013 } catch (InstallerException e) { 15014 Slog.w(TAG, "Couldn't remove cache files for package " + ps.name, e); 15015 return false; 15016 } 15017 removeKeystoreDataIfNeeded(nextUserId, ps.appId); 15018 schedulePackageCleaning(ps.name, nextUserId, false); 15019 synchronized (mPackages) { 15020 if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) { 15021 scheduleWritePackageRestrictionsLocked(nextUserId); 15022 } 15023 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId); 15024 } 15025 } 15026 15027 if (outInfo != null) { 15028 outInfo.removedPackage = ps.name; 15029 outInfo.removedAppId = ps.appId; 15030 outInfo.removedUsers = userIds; 15031 } 15032 15033 return true; 15034 } 15035 15036 private final class ClearStorageConnection implements ServiceConnection { 15037 IMediaContainerService mContainerService; 15038 15039 @Override 15040 public void onServiceConnected(ComponentName name, IBinder service) { 15041 synchronized (this) { 15042 mContainerService = IMediaContainerService.Stub.asInterface(service); 15043 notifyAll(); 15044 } 15045 } 15046 15047 @Override 15048 public void onServiceDisconnected(ComponentName name) { 15049 } 15050 } 15051 15052 private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) { 15053 final boolean mounted; 15054 if (Environment.isExternalStorageEmulated()) { 15055 mounted = true; 15056 } else { 15057 final String status = Environment.getExternalStorageState(); 15058 15059 mounted = status.equals(Environment.MEDIA_MOUNTED) 15060 || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY); 15061 } 15062 15063 if (!mounted) { 15064 return; 15065 } 15066 15067 final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 15068 int[] users; 15069 if (userId == UserHandle.USER_ALL) { 15070 users = sUserManager.getUserIds(); 15071 } else { 15072 users = new int[] { userId }; 15073 } 15074 final ClearStorageConnection conn = new ClearStorageConnection(); 15075 if (mContext.bindServiceAsUser( 15076 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) { 15077 try { 15078 for (int curUser : users) { 15079 long timeout = SystemClock.uptimeMillis() + 5000; 15080 synchronized (conn) { 15081 long now = SystemClock.uptimeMillis(); 15082 while (conn.mContainerService == null && now < timeout) { 15083 try { 15084 conn.wait(timeout - now); 15085 } catch (InterruptedException e) { 15086 } 15087 } 15088 } 15089 if (conn.mContainerService == null) { 15090 return; 15091 } 15092 15093 final UserEnvironment userEnv = new UserEnvironment(curUser); 15094 clearDirectory(conn.mContainerService, 15095 userEnv.buildExternalStorageAppCacheDirs(packageName)); 15096 if (allData) { 15097 clearDirectory(conn.mContainerService, 15098 userEnv.buildExternalStorageAppDataDirs(packageName)); 15099 clearDirectory(conn.mContainerService, 15100 userEnv.buildExternalStorageAppMediaDirs(packageName)); 15101 } 15102 } 15103 } finally { 15104 mContext.unbindService(conn); 15105 } 15106 } 15107 } 15108 15109 @Override 15110 public void clearApplicationUserData(final String packageName, 15111 final IPackageDataObserver observer, final int userId) { 15112 mContext.enforceCallingOrSelfPermission( 15113 android.Manifest.permission.CLEAR_APP_USER_DATA, null); 15114 15115 enforceCrossUserPermission(Binder.getCallingUid(), userId, 15116 true /* requireFullPermission */, false /* checkShell */, "clear application data"); 15117 15118 final DevicePolicyManagerInternal dpmi = LocalServices 15119 .getService(DevicePolicyManagerInternal.class); 15120 if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) { 15121 throw new SecurityException("Cannot clear data for a device owner or a profile owner"); 15122 } 15123 // Queue up an async operation since the package deletion may take a little while. 15124 mHandler.post(new Runnable() { 15125 public void run() { 15126 mHandler.removeCallbacks(this); 15127 final boolean succeeded; 15128 synchronized (mInstallLock) { 15129 succeeded = clearApplicationUserDataLI(packageName, userId); 15130 } 15131 clearExternalStorageDataSync(packageName, userId, true); 15132 if (succeeded) { 15133 // invoke DeviceStorageMonitor's update method to clear any notifications 15134 DeviceStorageMonitorInternal dsm = LocalServices 15135 .getService(DeviceStorageMonitorInternal.class); 15136 if (dsm != null) { 15137 dsm.checkMemory(); 15138 } 15139 } 15140 if(observer != null) { 15141 try { 15142 observer.onRemoveCompleted(packageName, succeeded); 15143 } catch (RemoteException e) { 15144 Log.i(TAG, "Observer no longer exists."); 15145 } 15146 } //end if observer 15147 } //end run 15148 }); 15149 } 15150 15151 private boolean clearApplicationUserDataLI(String packageName, int userId) { 15152 if (packageName == null) { 15153 Slog.w(TAG, "Attempt to delete null packageName."); 15154 return false; 15155 } 15156 15157 // Try finding details about the requested package 15158 PackageParser.Package pkg; 15159 synchronized (mPackages) { 15160 pkg = mPackages.get(packageName); 15161 if (pkg == null) { 15162 final PackageSetting ps = mSettings.mPackages.get(packageName); 15163 if (ps != null) { 15164 pkg = ps.pkg; 15165 } 15166 } 15167 15168 if (pkg == null) { 15169 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 15170 return false; 15171 } 15172 15173 PackageSetting ps = (PackageSetting) pkg.mExtras; 15174 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 15175 } 15176 15177 // Always delete data directories for package, even if we found no other 15178 // record of app. This helps users recover from UID mismatches without 15179 // resorting to a full data wipe. 15180 // TODO: triage flags as part of 26466827 15181 final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE; 15182 try { 15183 mInstaller.clearAppData(pkg.volumeUuid, packageName, userId, flags); 15184 } catch (InstallerException e) { 15185 Slog.w(TAG, "Couldn't remove cache files for package " + packageName, e); 15186 return false; 15187 } 15188 15189 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); 15190 removeKeystoreDataIfNeeded(userId, appId); 15191 15192 // Create a native library symlink only if we have native libraries 15193 // and if the native libraries are 32 bit libraries. We do not provide 15194 // this symlink for 64 bit libraries. 15195 if (pkg.applicationInfo.primaryCpuAbi != null && 15196 !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) { 15197 final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir; 15198 try { 15199 mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName, 15200 nativeLibPath, userId); 15201 } catch (InstallerException e) { 15202 Slog.w(TAG, "Failed linking native library dir", e); 15203 return false; 15204 } 15205 } 15206 15207 return true; 15208 } 15209 15210 /** 15211 * Reverts user permission state changes (permissions and flags) in 15212 * all packages for a given user. 15213 * 15214 * @param userId The device user for which to do a reset. 15215 */ 15216 private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) { 15217 final int packageCount = mPackages.size(); 15218 for (int i = 0; i < packageCount; i++) { 15219 PackageParser.Package pkg = mPackages.valueAt(i); 15220 PackageSetting ps = (PackageSetting) pkg.mExtras; 15221 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 15222 } 15223 } 15224 15225 /** 15226 * Reverts user permission state changes (permissions and flags). 15227 * 15228 * @param ps The package for which to reset. 15229 * @param userId The device user for which to do a reset. 15230 */ 15231 private void resetUserChangesToRuntimePermissionsAndFlagsLPw( 15232 final PackageSetting ps, final int userId) { 15233 if (ps.pkg == null) { 15234 return; 15235 } 15236 15237 // These are flags that can change base on user actions. 15238 final int userSettableMask = FLAG_PERMISSION_USER_SET 15239 | FLAG_PERMISSION_USER_FIXED 15240 | FLAG_PERMISSION_REVOKE_ON_UPGRADE 15241 | FLAG_PERMISSION_REVIEW_REQUIRED; 15242 15243 final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED 15244 | FLAG_PERMISSION_POLICY_FIXED; 15245 15246 boolean writeInstallPermissions = false; 15247 boolean writeRuntimePermissions = false; 15248 15249 final int permissionCount = ps.pkg.requestedPermissions.size(); 15250 for (int i = 0; i < permissionCount; i++) { 15251 String permission = ps.pkg.requestedPermissions.get(i); 15252 15253 BasePermission bp = mSettings.mPermissions.get(permission); 15254 if (bp == null) { 15255 continue; 15256 } 15257 15258 // If shared user we just reset the state to which only this app contributed. 15259 if (ps.sharedUser != null) { 15260 boolean used = false; 15261 final int packageCount = ps.sharedUser.packages.size(); 15262 for (int j = 0; j < packageCount; j++) { 15263 PackageSetting pkg = ps.sharedUser.packages.valueAt(j); 15264 if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName) 15265 && pkg.pkg.requestedPermissions.contains(permission)) { 15266 used = true; 15267 break; 15268 } 15269 } 15270 if (used) { 15271 continue; 15272 } 15273 } 15274 15275 PermissionsState permissionsState = ps.getPermissionsState(); 15276 15277 final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId); 15278 15279 // Always clear the user settable flags. 15280 final boolean hasInstallState = permissionsState.getInstallPermissionState( 15281 bp.name) != null; 15282 // If permission review is enabled and this is a legacy app, mark the 15283 // permission as requiring a review as this is the initial state. 15284 int flags = 0; 15285 if (Build.PERMISSIONS_REVIEW_REQUIRED 15286 && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 15287 flags |= FLAG_PERMISSION_REVIEW_REQUIRED; 15288 } 15289 if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) { 15290 if (hasInstallState) { 15291 writeInstallPermissions = true; 15292 } else { 15293 writeRuntimePermissions = true; 15294 } 15295 } 15296 15297 // Below is only runtime permission handling. 15298 if (!bp.isRuntime()) { 15299 continue; 15300 } 15301 15302 // Never clobber system or policy. 15303 if ((oldFlags & policyOrSystemFlags) != 0) { 15304 continue; 15305 } 15306 15307 // If this permission was granted by default, make sure it is. 15308 if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) { 15309 if (permissionsState.grantRuntimePermission(bp, userId) 15310 != PERMISSION_OPERATION_FAILURE) { 15311 writeRuntimePermissions = true; 15312 } 15313 // If permission review is enabled the permissions for a legacy apps 15314 // are represented as constantly granted runtime ones, so don't revoke. 15315 } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) { 15316 // Otherwise, reset the permission. 15317 final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId); 15318 switch (revokeResult) { 15319 case PERMISSION_OPERATION_SUCCESS: { 15320 writeRuntimePermissions = true; 15321 } break; 15322 15323 case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 15324 writeRuntimePermissions = true; 15325 final int appId = ps.appId; 15326 mHandler.post(new Runnable() { 15327 @Override 15328 public void run() { 15329 killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED); 15330 } 15331 }); 15332 } break; 15333 } 15334 } 15335 } 15336 15337 // Synchronously write as we are taking permissions away. 15338 if (writeRuntimePermissions) { 15339 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 15340 } 15341 15342 // Synchronously write as we are taking permissions away. 15343 if (writeInstallPermissions) { 15344 mSettings.writeLPr(); 15345 } 15346 } 15347 15348 /** 15349 * Remove entries from the keystore daemon. Will only remove it if the 15350 * {@code appId} is valid. 15351 */ 15352 private static void removeKeystoreDataIfNeeded(int userId, int appId) { 15353 if (appId < 0) { 15354 return; 15355 } 15356 15357 final KeyStore keyStore = KeyStore.getInstance(); 15358 if (keyStore != null) { 15359 if (userId == UserHandle.USER_ALL) { 15360 for (final int individual : sUserManager.getUserIds()) { 15361 keyStore.clearUid(UserHandle.getUid(individual, appId)); 15362 } 15363 } else { 15364 keyStore.clearUid(UserHandle.getUid(userId, appId)); 15365 } 15366 } else { 15367 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId); 15368 } 15369 } 15370 15371 @Override 15372 public void deleteApplicationCacheFiles(final String packageName, 15373 final IPackageDataObserver observer) { 15374 mContext.enforceCallingOrSelfPermission( 15375 android.Manifest.permission.DELETE_CACHE_FILES, null); 15376 // Queue up an async operation since the package deletion may take a little while. 15377 final int userId = UserHandle.getCallingUserId(); 15378 mHandler.post(new Runnable() { 15379 public void run() { 15380 mHandler.removeCallbacks(this); 15381 final boolean succeded; 15382 synchronized (mInstallLock) { 15383 succeded = deleteApplicationCacheFilesLI(packageName, userId); 15384 } 15385 clearExternalStorageDataSync(packageName, userId, false); 15386 if (observer != null) { 15387 try { 15388 observer.onRemoveCompleted(packageName, succeded); 15389 } catch (RemoteException e) { 15390 Log.i(TAG, "Observer no longer exists."); 15391 } 15392 } //end if observer 15393 } //end run 15394 }); 15395 } 15396 15397 private boolean deleteApplicationCacheFilesLI(String packageName, int userId) { 15398 if (packageName == null) { 15399 Slog.w(TAG, "Attempt to delete null packageName."); 15400 return false; 15401 } 15402 PackageParser.Package p; 15403 synchronized (mPackages) { 15404 p = mPackages.get(packageName); 15405 } 15406 if (p == null) { 15407 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 15408 return false; 15409 } 15410 final ApplicationInfo applicationInfo = p.applicationInfo; 15411 if (applicationInfo == null) { 15412 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 15413 return false; 15414 } 15415 // TODO: triage flags as part of 26466827 15416 final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE; 15417 try { 15418 mInstaller.clearAppData(p.volumeUuid, packageName, userId, 15419 flags | Installer.FLAG_CLEAR_CACHE_ONLY); 15420 } catch (InstallerException e) { 15421 Slog.w(TAG, "Couldn't remove cache files for package " 15422 + packageName + " u" + userId, e); 15423 return false; 15424 } 15425 return true; 15426 } 15427 15428 @Override 15429 public void getPackageSizeInfo(final String packageName, int userHandle, 15430 final IPackageStatsObserver observer) { 15431 mContext.enforceCallingOrSelfPermission( 15432 android.Manifest.permission.GET_PACKAGE_SIZE, null); 15433 if (packageName == null) { 15434 throw new IllegalArgumentException("Attempt to get size of null packageName"); 15435 } 15436 15437 PackageStats stats = new PackageStats(packageName, userHandle); 15438 15439 /* 15440 * Queue up an async operation since the package measurement may take a 15441 * little while. 15442 */ 15443 Message msg = mHandler.obtainMessage(INIT_COPY); 15444 msg.obj = new MeasureParams(stats, observer); 15445 mHandler.sendMessage(msg); 15446 } 15447 15448 private boolean getPackageSizeInfoLI(String packageName, int userHandle, 15449 PackageStats pStats) { 15450 if (packageName == null) { 15451 Slog.w(TAG, "Attempt to get size of null packageName."); 15452 return false; 15453 } 15454 PackageParser.Package p; 15455 boolean dataOnly = false; 15456 String libDirRoot = null; 15457 String asecPath = null; 15458 PackageSetting ps = null; 15459 synchronized (mPackages) { 15460 p = mPackages.get(packageName); 15461 ps = mSettings.mPackages.get(packageName); 15462 if(p == null) { 15463 dataOnly = true; 15464 if((ps == null) || (ps.pkg == null)) { 15465 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 15466 return false; 15467 } 15468 p = ps.pkg; 15469 } 15470 if (ps != null) { 15471 libDirRoot = ps.legacyNativeLibraryPathString; 15472 } 15473 if (p != null && (p.isForwardLocked() || p.applicationInfo.isExternalAsec())) { 15474 final long token = Binder.clearCallingIdentity(); 15475 try { 15476 String secureContainerId = cidFromCodePath(p.applicationInfo.getBaseCodePath()); 15477 if (secureContainerId != null) { 15478 asecPath = PackageHelper.getSdFilesystem(secureContainerId); 15479 } 15480 } finally { 15481 Binder.restoreCallingIdentity(token); 15482 } 15483 } 15484 } 15485 String publicSrcDir = null; 15486 if(!dataOnly) { 15487 final ApplicationInfo applicationInfo = p.applicationInfo; 15488 if (applicationInfo == null) { 15489 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 15490 return false; 15491 } 15492 if (p.isForwardLocked()) { 15493 publicSrcDir = applicationInfo.getBaseResourcePath(); 15494 } 15495 } 15496 // TODO: extend to measure size of split APKs 15497 // TODO(multiArch): Extend getSizeInfo to look at the full subdirectory tree, 15498 // not just the first level. 15499 // TODO(multiArch): Extend getSizeInfo to look at *all* instruction sets, not 15500 // just the primary. 15501 String[] dexCodeInstructionSets = getDexCodeInstructionSets(getAppDexInstructionSets(ps)); 15502 15503 String apkPath; 15504 File packageDir = new File(p.codePath); 15505 15506 if (packageDir.isDirectory() && p.canHaveOatDir()) { 15507 apkPath = packageDir.getAbsolutePath(); 15508 // If libDirRoot is inside a package dir, set it to null to avoid it being counted twice 15509 if (libDirRoot != null && libDirRoot.startsWith(apkPath)) { 15510 libDirRoot = null; 15511 } 15512 } else { 15513 apkPath = p.baseCodePath; 15514 } 15515 15516 // TODO: triage flags as part of 26466827 15517 final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE; 15518 try { 15519 mInstaller.getAppSize(p.volumeUuid, packageName, userHandle, flags, apkPath, 15520 libDirRoot, publicSrcDir, asecPath, dexCodeInstructionSets, pStats); 15521 } catch (InstallerException e) { 15522 return false; 15523 } 15524 15525 // Fix-up for forward-locked applications in ASEC containers. 15526 if (!isExternal(p)) { 15527 pStats.codeSize += pStats.externalCodeSize; 15528 pStats.externalCodeSize = 0L; 15529 } 15530 15531 return true; 15532 } 15533 15534 15535 @Override 15536 public void addPackageToPreferred(String packageName) { 15537 Slog.w(TAG, "addPackageToPreferred: this is now a no-op"); 15538 } 15539 15540 @Override 15541 public void removePackageFromPreferred(String packageName) { 15542 Slog.w(TAG, "removePackageFromPreferred: this is now a no-op"); 15543 } 15544 15545 @Override 15546 public List<PackageInfo> getPreferredPackages(int flags) { 15547 return new ArrayList<PackageInfo>(); 15548 } 15549 15550 private int getUidTargetSdkVersionLockedLPr(int uid) { 15551 Object obj = mSettings.getUserIdLPr(uid); 15552 if (obj instanceof SharedUserSetting) { 15553 final SharedUserSetting sus = (SharedUserSetting) obj; 15554 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT; 15555 final Iterator<PackageSetting> it = sus.packages.iterator(); 15556 while (it.hasNext()) { 15557 final PackageSetting ps = it.next(); 15558 if (ps.pkg != null) { 15559 int v = ps.pkg.applicationInfo.targetSdkVersion; 15560 if (v < vers) vers = v; 15561 } 15562 } 15563 return vers; 15564 } else if (obj instanceof PackageSetting) { 15565 final PackageSetting ps = (PackageSetting) obj; 15566 if (ps.pkg != null) { 15567 return ps.pkg.applicationInfo.targetSdkVersion; 15568 } 15569 } 15570 return Build.VERSION_CODES.CUR_DEVELOPMENT; 15571 } 15572 15573 @Override 15574 public void addPreferredActivity(IntentFilter filter, int match, 15575 ComponentName[] set, ComponentName activity, int userId) { 15576 addPreferredActivityInternal(filter, match, set, activity, true, userId, 15577 "Adding preferred"); 15578 } 15579 15580 private void addPreferredActivityInternal(IntentFilter filter, int match, 15581 ComponentName[] set, ComponentName activity, boolean always, int userId, 15582 String opname) { 15583 // writer 15584 int callingUid = Binder.getCallingUid(); 15585 enforceCrossUserPermission(callingUid, userId, 15586 true /* requireFullPermission */, false /* checkShell */, "add preferred activity"); 15587 if (filter.countActions() == 0) { 15588 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 15589 return; 15590 } 15591 synchronized (mPackages) { 15592 if (mContext.checkCallingOrSelfPermission( 15593 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 15594 != PackageManager.PERMISSION_GRANTED) { 15595 if (getUidTargetSdkVersionLockedLPr(callingUid) 15596 < Build.VERSION_CODES.FROYO) { 15597 Slog.w(TAG, "Ignoring addPreferredActivity() from uid " 15598 + callingUid); 15599 return; 15600 } 15601 mContext.enforceCallingOrSelfPermission( 15602 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 15603 } 15604 15605 PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId); 15606 Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user " 15607 + userId + ":"); 15608 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 15609 pir.addFilter(new PreferredActivity(filter, match, set, activity, always)); 15610 scheduleWritePackageRestrictionsLocked(userId); 15611 } 15612 } 15613 15614 @Override 15615 public void replacePreferredActivity(IntentFilter filter, int match, 15616 ComponentName[] set, ComponentName activity, int userId) { 15617 if (filter.countActions() != 1) { 15618 throw new IllegalArgumentException( 15619 "replacePreferredActivity expects filter to have only 1 action."); 15620 } 15621 if (filter.countDataAuthorities() != 0 15622 || filter.countDataPaths() != 0 15623 || filter.countDataSchemes() > 1 15624 || filter.countDataTypes() != 0) { 15625 throw new IllegalArgumentException( 15626 "replacePreferredActivity expects filter to have no data authorities, " + 15627 "paths, or types; and at most one scheme."); 15628 } 15629 15630 final int callingUid = Binder.getCallingUid(); 15631 enforceCrossUserPermission(callingUid, userId, 15632 true /* requireFullPermission */, false /* checkShell */, 15633 "replace preferred activity"); 15634 synchronized (mPackages) { 15635 if (mContext.checkCallingOrSelfPermission( 15636 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 15637 != PackageManager.PERMISSION_GRANTED) { 15638 if (getUidTargetSdkVersionLockedLPr(callingUid) 15639 < Build.VERSION_CODES.FROYO) { 15640 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid " 15641 + Binder.getCallingUid()); 15642 return; 15643 } 15644 mContext.enforceCallingOrSelfPermission( 15645 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 15646 } 15647 15648 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 15649 if (pir != null) { 15650 // Get all of the existing entries that exactly match this filter. 15651 ArrayList<PreferredActivity> existing = pir.findFilters(filter); 15652 if (existing != null && existing.size() == 1) { 15653 PreferredActivity cur = existing.get(0); 15654 if (DEBUG_PREFERRED) { 15655 Slog.i(TAG, "Checking replace of preferred:"); 15656 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 15657 if (!cur.mPref.mAlways) { 15658 Slog.i(TAG, " -- CUR; not mAlways!"); 15659 } else { 15660 Slog.i(TAG, " -- CUR: mMatch=" + cur.mPref.mMatch); 15661 Slog.i(TAG, " -- CUR: mSet=" 15662 + Arrays.toString(cur.mPref.mSetComponents)); 15663 Slog.i(TAG, " -- CUR: mComponent=" + cur.mPref.mShortComponent); 15664 Slog.i(TAG, " -- NEW: mMatch=" 15665 + (match&IntentFilter.MATCH_CATEGORY_MASK)); 15666 Slog.i(TAG, " -- CUR: mSet=" + Arrays.toString(set)); 15667 Slog.i(TAG, " -- CUR: mComponent=" + activity.flattenToShortString()); 15668 } 15669 } 15670 if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity) 15671 && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK) 15672 && cur.mPref.sameSet(set)) { 15673 // Setting the preferred activity to what it happens to be already 15674 if (DEBUG_PREFERRED) { 15675 Slog.i(TAG, "Replacing with same preferred activity " 15676 + cur.mPref.mShortComponent + " for user " 15677 + userId + ":"); 15678 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 15679 } 15680 return; 15681 } 15682 } 15683 15684 if (existing != null) { 15685 if (DEBUG_PREFERRED) { 15686 Slog.i(TAG, existing.size() + " existing preferred matches for:"); 15687 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 15688 } 15689 for (int i = 0; i < existing.size(); i++) { 15690 PreferredActivity pa = existing.get(i); 15691 if (DEBUG_PREFERRED) { 15692 Slog.i(TAG, "Removing existing preferred activity " 15693 + pa.mPref.mComponent + ":"); 15694 pa.dump(new LogPrinter(Log.INFO, TAG), " "); 15695 } 15696 pir.removeFilter(pa); 15697 } 15698 } 15699 } 15700 addPreferredActivityInternal(filter, match, set, activity, true, userId, 15701 "Replacing preferred"); 15702 } 15703 } 15704 15705 @Override 15706 public void clearPackagePreferredActivities(String packageName) { 15707 final int uid = Binder.getCallingUid(); 15708 // writer 15709 synchronized (mPackages) { 15710 PackageParser.Package pkg = mPackages.get(packageName); 15711 if (pkg == null || pkg.applicationInfo.uid != uid) { 15712 if (mContext.checkCallingOrSelfPermission( 15713 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 15714 != PackageManager.PERMISSION_GRANTED) { 15715 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid()) 15716 < Build.VERSION_CODES.FROYO) { 15717 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid " 15718 + Binder.getCallingUid()); 15719 return; 15720 } 15721 mContext.enforceCallingOrSelfPermission( 15722 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 15723 } 15724 } 15725 15726 int user = UserHandle.getCallingUserId(); 15727 if (clearPackagePreferredActivitiesLPw(packageName, user)) { 15728 scheduleWritePackageRestrictionsLocked(user); 15729 } 15730 } 15731 } 15732 15733 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 15734 boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) { 15735 ArrayList<PreferredActivity> removed = null; 15736 boolean changed = false; 15737 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 15738 final int thisUserId = mSettings.mPreferredActivities.keyAt(i); 15739 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 15740 if (userId != UserHandle.USER_ALL && userId != thisUserId) { 15741 continue; 15742 } 15743 Iterator<PreferredActivity> it = pir.filterIterator(); 15744 while (it.hasNext()) { 15745 PreferredActivity pa = it.next(); 15746 // Mark entry for removal only if it matches the package name 15747 // and the entry is of type "always". 15748 if (packageName == null || 15749 (pa.mPref.mComponent.getPackageName().equals(packageName) 15750 && pa.mPref.mAlways)) { 15751 if (removed == null) { 15752 removed = new ArrayList<PreferredActivity>(); 15753 } 15754 removed.add(pa); 15755 } 15756 } 15757 if (removed != null) { 15758 for (int j=0; j<removed.size(); j++) { 15759 PreferredActivity pa = removed.get(j); 15760 pir.removeFilter(pa); 15761 } 15762 changed = true; 15763 } 15764 } 15765 return changed; 15766 } 15767 15768 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 15769 private void clearIntentFilterVerificationsLPw(int userId) { 15770 final int packageCount = mPackages.size(); 15771 for (int i = 0; i < packageCount; i++) { 15772 PackageParser.Package pkg = mPackages.valueAt(i); 15773 clearIntentFilterVerificationsLPw(pkg.packageName, userId); 15774 } 15775 } 15776 15777 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 15778 void clearIntentFilterVerificationsLPw(String packageName, int userId) { 15779 if (userId == UserHandle.USER_ALL) { 15780 if (mSettings.removeIntentFilterVerificationLPw(packageName, 15781 sUserManager.getUserIds())) { 15782 for (int oneUserId : sUserManager.getUserIds()) { 15783 scheduleWritePackageRestrictionsLocked(oneUserId); 15784 } 15785 } 15786 } else { 15787 if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) { 15788 scheduleWritePackageRestrictionsLocked(userId); 15789 } 15790 } 15791 } 15792 15793 void clearDefaultBrowserIfNeeded(String packageName) { 15794 for (int oneUserId : sUserManager.getUserIds()) { 15795 String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId); 15796 if (TextUtils.isEmpty(defaultBrowserPackageName)) continue; 15797 if (packageName.equals(defaultBrowserPackageName)) { 15798 setDefaultBrowserPackageName(null, oneUserId); 15799 } 15800 } 15801 } 15802 15803 @Override 15804 public void resetApplicationPreferences(int userId) { 15805 mContext.enforceCallingOrSelfPermission( 15806 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 15807 // writer 15808 synchronized (mPackages) { 15809 final long identity = Binder.clearCallingIdentity(); 15810 try { 15811 clearPackagePreferredActivitiesLPw(null, userId); 15812 mSettings.applyDefaultPreferredAppsLPw(this, userId); 15813 // TODO: We have to reset the default SMS and Phone. This requires 15814 // significant refactoring to keep all default apps in the package 15815 // manager (cleaner but more work) or have the services provide 15816 // callbacks to the package manager to request a default app reset. 15817 applyFactoryDefaultBrowserLPw(userId); 15818 clearIntentFilterVerificationsLPw(userId); 15819 primeDomainVerificationsLPw(userId); 15820 resetUserChangesToRuntimePermissionsAndFlagsLPw(userId); 15821 scheduleWritePackageRestrictionsLocked(userId); 15822 } finally { 15823 Binder.restoreCallingIdentity(identity); 15824 } 15825 } 15826 } 15827 15828 @Override 15829 public int getPreferredActivities(List<IntentFilter> outFilters, 15830 List<ComponentName> outActivities, String packageName) { 15831 15832 int num = 0; 15833 final int userId = UserHandle.getCallingUserId(); 15834 // reader 15835 synchronized (mPackages) { 15836 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 15837 if (pir != null) { 15838 final Iterator<PreferredActivity> it = pir.filterIterator(); 15839 while (it.hasNext()) { 15840 final PreferredActivity pa = it.next(); 15841 if (packageName == null 15842 || (pa.mPref.mComponent.getPackageName().equals(packageName) 15843 && pa.mPref.mAlways)) { 15844 if (outFilters != null) { 15845 outFilters.add(new IntentFilter(pa)); 15846 } 15847 if (outActivities != null) { 15848 outActivities.add(pa.mPref.mComponent); 15849 } 15850 } 15851 } 15852 } 15853 } 15854 15855 return num; 15856 } 15857 15858 @Override 15859 public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity, 15860 int userId) { 15861 int callingUid = Binder.getCallingUid(); 15862 if (callingUid != Process.SYSTEM_UID) { 15863 throw new SecurityException( 15864 "addPersistentPreferredActivity can only be run by the system"); 15865 } 15866 if (filter.countActions() == 0) { 15867 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 15868 return; 15869 } 15870 synchronized (mPackages) { 15871 Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId + 15872 ":"); 15873 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 15874 mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter( 15875 new PersistentPreferredActivity(filter, activity)); 15876 scheduleWritePackageRestrictionsLocked(userId); 15877 } 15878 } 15879 15880 @Override 15881 public void clearPackagePersistentPreferredActivities(String packageName, int userId) { 15882 int callingUid = Binder.getCallingUid(); 15883 if (callingUid != Process.SYSTEM_UID) { 15884 throw new SecurityException( 15885 "clearPackagePersistentPreferredActivities can only be run by the system"); 15886 } 15887 ArrayList<PersistentPreferredActivity> removed = null; 15888 boolean changed = false; 15889 synchronized (mPackages) { 15890 for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) { 15891 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i); 15892 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 15893 .valueAt(i); 15894 if (userId != thisUserId) { 15895 continue; 15896 } 15897 Iterator<PersistentPreferredActivity> it = ppir.filterIterator(); 15898 while (it.hasNext()) { 15899 PersistentPreferredActivity ppa = it.next(); 15900 // Mark entry for removal only if it matches the package name. 15901 if (ppa.mComponent.getPackageName().equals(packageName)) { 15902 if (removed == null) { 15903 removed = new ArrayList<PersistentPreferredActivity>(); 15904 } 15905 removed.add(ppa); 15906 } 15907 } 15908 if (removed != null) { 15909 for (int j=0; j<removed.size(); j++) { 15910 PersistentPreferredActivity ppa = removed.get(j); 15911 ppir.removeFilter(ppa); 15912 } 15913 changed = true; 15914 } 15915 } 15916 15917 if (changed) { 15918 scheduleWritePackageRestrictionsLocked(userId); 15919 } 15920 } 15921 } 15922 15923 /** 15924 * Common machinery for picking apart a restored XML blob and passing 15925 * it to a caller-supplied functor to be applied to the running system. 15926 */ 15927 private void restoreFromXml(XmlPullParser parser, int userId, 15928 String expectedStartTag, BlobXmlRestorer functor) 15929 throws IOException, XmlPullParserException { 15930 int type; 15931 while ((type = parser.next()) != XmlPullParser.START_TAG 15932 && type != XmlPullParser.END_DOCUMENT) { 15933 } 15934 if (type != XmlPullParser.START_TAG) { 15935 // oops didn't find a start tag?! 15936 if (DEBUG_BACKUP) { 15937 Slog.e(TAG, "Didn't find start tag during restore"); 15938 } 15939 return; 15940 } 15941Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName()); 15942 // this is supposed to be TAG_PREFERRED_BACKUP 15943 if (!expectedStartTag.equals(parser.getName())) { 15944 if (DEBUG_BACKUP) { 15945 Slog.e(TAG, "Found unexpected tag " + parser.getName()); 15946 } 15947 return; 15948 } 15949 15950 // skip interfering stuff, then we're aligned with the backing implementation 15951 while ((type = parser.next()) == XmlPullParser.TEXT) { } 15952Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); 15953 functor.apply(parser, userId); 15954 } 15955 15956 private interface BlobXmlRestorer { 15957 public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException; 15958 } 15959 15960 /** 15961 * Non-Binder method, support for the backup/restore mechanism: write the 15962 * full set of preferred activities in its canonical XML format. Returns the 15963 * XML output as a byte array, or null if there is none. 15964 */ 15965 @Override 15966 public byte[] getPreferredActivityBackup(int userId) { 15967 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 15968 throw new SecurityException("Only the system may call getPreferredActivityBackup()"); 15969 } 15970 15971 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 15972 try { 15973 final XmlSerializer serializer = new FastXmlSerializer(); 15974 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 15975 serializer.startDocument(null, true); 15976 serializer.startTag(null, TAG_PREFERRED_BACKUP); 15977 15978 synchronized (mPackages) { 15979 mSettings.writePreferredActivitiesLPr(serializer, userId, true); 15980 } 15981 15982 serializer.endTag(null, TAG_PREFERRED_BACKUP); 15983 serializer.endDocument(); 15984 serializer.flush(); 15985 } catch (Exception e) { 15986 if (DEBUG_BACKUP) { 15987 Slog.e(TAG, "Unable to write preferred activities for backup", e); 15988 } 15989 return null; 15990 } 15991 15992 return dataStream.toByteArray(); 15993 } 15994 15995 @Override 15996 public void restorePreferredActivities(byte[] backup, int userId) { 15997 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 15998 throw new SecurityException("Only the system may call restorePreferredActivities()"); 15999 } 16000 16001 try { 16002 final XmlPullParser parser = Xml.newPullParser(); 16003 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 16004 restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP, 16005 new BlobXmlRestorer() { 16006 @Override 16007 public void apply(XmlPullParser parser, int userId) 16008 throws XmlPullParserException, IOException { 16009 synchronized (mPackages) { 16010 mSettings.readPreferredActivitiesLPw(parser, userId); 16011 } 16012 } 16013 } ); 16014 } catch (Exception e) { 16015 if (DEBUG_BACKUP) { 16016 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 16017 } 16018 } 16019 } 16020 16021 /** 16022 * Non-Binder method, support for the backup/restore mechanism: write the 16023 * default browser (etc) settings in its canonical XML format. Returns the default 16024 * browser XML representation as a byte array, or null if there is none. 16025 */ 16026 @Override 16027 public byte[] getDefaultAppsBackup(int userId) { 16028 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16029 throw new SecurityException("Only the system may call getDefaultAppsBackup()"); 16030 } 16031 16032 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 16033 try { 16034 final XmlSerializer serializer = new FastXmlSerializer(); 16035 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 16036 serializer.startDocument(null, true); 16037 serializer.startTag(null, TAG_DEFAULT_APPS); 16038 16039 synchronized (mPackages) { 16040 mSettings.writeDefaultAppsLPr(serializer, userId); 16041 } 16042 16043 serializer.endTag(null, TAG_DEFAULT_APPS); 16044 serializer.endDocument(); 16045 serializer.flush(); 16046 } catch (Exception e) { 16047 if (DEBUG_BACKUP) { 16048 Slog.e(TAG, "Unable to write default apps for backup", e); 16049 } 16050 return null; 16051 } 16052 16053 return dataStream.toByteArray(); 16054 } 16055 16056 @Override 16057 public void restoreDefaultApps(byte[] backup, int userId) { 16058 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16059 throw new SecurityException("Only the system may call restoreDefaultApps()"); 16060 } 16061 16062 try { 16063 final XmlPullParser parser = Xml.newPullParser(); 16064 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 16065 restoreFromXml(parser, userId, TAG_DEFAULT_APPS, 16066 new BlobXmlRestorer() { 16067 @Override 16068 public void apply(XmlPullParser parser, int userId) 16069 throws XmlPullParserException, IOException { 16070 synchronized (mPackages) { 16071 mSettings.readDefaultAppsLPw(parser, userId); 16072 } 16073 } 16074 } ); 16075 } catch (Exception e) { 16076 if (DEBUG_BACKUP) { 16077 Slog.e(TAG, "Exception restoring default apps: " + e.getMessage()); 16078 } 16079 } 16080 } 16081 16082 @Override 16083 public byte[] getIntentFilterVerificationBackup(int userId) { 16084 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16085 throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()"); 16086 } 16087 16088 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 16089 try { 16090 final XmlSerializer serializer = new FastXmlSerializer(); 16091 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 16092 serializer.startDocument(null, true); 16093 serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION); 16094 16095 synchronized (mPackages) { 16096 mSettings.writeAllDomainVerificationsLPr(serializer, userId); 16097 } 16098 16099 serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION); 16100 serializer.endDocument(); 16101 serializer.flush(); 16102 } catch (Exception e) { 16103 if (DEBUG_BACKUP) { 16104 Slog.e(TAG, "Unable to write default apps for backup", e); 16105 } 16106 return null; 16107 } 16108 16109 return dataStream.toByteArray(); 16110 } 16111 16112 @Override 16113 public void restoreIntentFilterVerification(byte[] backup, int userId) { 16114 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16115 throw new SecurityException("Only the system may call restorePreferredActivities()"); 16116 } 16117 16118 try { 16119 final XmlPullParser parser = Xml.newPullParser(); 16120 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 16121 restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION, 16122 new BlobXmlRestorer() { 16123 @Override 16124 public void apply(XmlPullParser parser, int userId) 16125 throws XmlPullParserException, IOException { 16126 synchronized (mPackages) { 16127 mSettings.readAllDomainVerificationsLPr(parser, userId); 16128 mSettings.writeLPr(); 16129 } 16130 } 16131 } ); 16132 } catch (Exception e) { 16133 if (DEBUG_BACKUP) { 16134 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 16135 } 16136 } 16137 } 16138 16139 @Override 16140 public byte[] getPermissionGrantBackup(int userId) { 16141 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16142 throw new SecurityException("Only the system may call getPermissionGrantBackup()"); 16143 } 16144 16145 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 16146 try { 16147 final XmlSerializer serializer = new FastXmlSerializer(); 16148 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 16149 serializer.startDocument(null, true); 16150 serializer.startTag(null, TAG_PERMISSION_BACKUP); 16151 16152 synchronized (mPackages) { 16153 serializeRuntimePermissionGrantsLPr(serializer, userId); 16154 } 16155 16156 serializer.endTag(null, TAG_PERMISSION_BACKUP); 16157 serializer.endDocument(); 16158 serializer.flush(); 16159 } catch (Exception e) { 16160 if (DEBUG_BACKUP) { 16161 Slog.e(TAG, "Unable to write default apps for backup", e); 16162 } 16163 return null; 16164 } 16165 16166 return dataStream.toByteArray(); 16167 } 16168 16169 @Override 16170 public void restorePermissionGrants(byte[] backup, int userId) { 16171 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16172 throw new SecurityException("Only the system may call restorePermissionGrants()"); 16173 } 16174 16175 try { 16176 final XmlPullParser parser = Xml.newPullParser(); 16177 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 16178 restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP, 16179 new BlobXmlRestorer() { 16180 @Override 16181 public void apply(XmlPullParser parser, int userId) 16182 throws XmlPullParserException, IOException { 16183 synchronized (mPackages) { 16184 processRestoredPermissionGrantsLPr(parser, userId); 16185 } 16186 } 16187 } ); 16188 } catch (Exception e) { 16189 if (DEBUG_BACKUP) { 16190 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 16191 } 16192 } 16193 } 16194 16195 private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId) 16196 throws IOException { 16197 serializer.startTag(null, TAG_ALL_GRANTS); 16198 16199 final int N = mSettings.mPackages.size(); 16200 for (int i = 0; i < N; i++) { 16201 final PackageSetting ps = mSettings.mPackages.valueAt(i); 16202 boolean pkgGrantsKnown = false; 16203 16204 PermissionsState packagePerms = ps.getPermissionsState(); 16205 16206 for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) { 16207 final int grantFlags = state.getFlags(); 16208 // only look at grants that are not system/policy fixed 16209 if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) { 16210 final boolean isGranted = state.isGranted(); 16211 // And only back up the user-twiddled state bits 16212 if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) { 16213 final String packageName = mSettings.mPackages.keyAt(i); 16214 if (!pkgGrantsKnown) { 16215 serializer.startTag(null, TAG_GRANT); 16216 serializer.attribute(null, ATTR_PACKAGE_NAME, packageName); 16217 pkgGrantsKnown = true; 16218 } 16219 16220 final boolean userSet = 16221 (grantFlags & FLAG_PERMISSION_USER_SET) != 0; 16222 final boolean userFixed = 16223 (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0; 16224 final boolean revoke = 16225 (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0; 16226 16227 serializer.startTag(null, TAG_PERMISSION); 16228 serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName()); 16229 if (isGranted) { 16230 serializer.attribute(null, ATTR_IS_GRANTED, "true"); 16231 } 16232 if (userSet) { 16233 serializer.attribute(null, ATTR_USER_SET, "true"); 16234 } 16235 if (userFixed) { 16236 serializer.attribute(null, ATTR_USER_FIXED, "true"); 16237 } 16238 if (revoke) { 16239 serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true"); 16240 } 16241 serializer.endTag(null, TAG_PERMISSION); 16242 } 16243 } 16244 } 16245 16246 if (pkgGrantsKnown) { 16247 serializer.endTag(null, TAG_GRANT); 16248 } 16249 } 16250 16251 serializer.endTag(null, TAG_ALL_GRANTS); 16252 } 16253 16254 private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId) 16255 throws XmlPullParserException, IOException { 16256 String pkgName = null; 16257 int outerDepth = parser.getDepth(); 16258 int type; 16259 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 16260 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 16261 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 16262 continue; 16263 } 16264 16265 final String tagName = parser.getName(); 16266 if (tagName.equals(TAG_GRANT)) { 16267 pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME); 16268 if (DEBUG_BACKUP) { 16269 Slog.v(TAG, "+++ Restoring grants for package " + pkgName); 16270 } 16271 } else if (tagName.equals(TAG_PERMISSION)) { 16272 16273 final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED)); 16274 final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME); 16275 16276 int newFlagSet = 0; 16277 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) { 16278 newFlagSet |= FLAG_PERMISSION_USER_SET; 16279 } 16280 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) { 16281 newFlagSet |= FLAG_PERMISSION_USER_FIXED; 16282 } 16283 if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) { 16284 newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE; 16285 } 16286 if (DEBUG_BACKUP) { 16287 Slog.v(TAG, " + Restoring grant: pkg=" + pkgName + " perm=" + permName 16288 + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet)); 16289 } 16290 final PackageSetting ps = mSettings.mPackages.get(pkgName); 16291 if (ps != null) { 16292 // Already installed so we apply the grant immediately 16293 if (DEBUG_BACKUP) { 16294 Slog.v(TAG, " + already installed; applying"); 16295 } 16296 PermissionsState perms = ps.getPermissionsState(); 16297 BasePermission bp = mSettings.mPermissions.get(permName); 16298 if (bp != null) { 16299 if (isGranted) { 16300 perms.grantRuntimePermission(bp, userId); 16301 } 16302 if (newFlagSet != 0) { 16303 perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet); 16304 } 16305 } 16306 } else { 16307 // Need to wait for post-restore install to apply the grant 16308 if (DEBUG_BACKUP) { 16309 Slog.v(TAG, " - not yet installed; saving for later"); 16310 } 16311 mSettings.processRestoredPermissionGrantLPr(pkgName, permName, 16312 isGranted, newFlagSet, userId); 16313 } 16314 } else { 16315 PackageManagerService.reportSettingsProblem(Log.WARN, 16316 "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName); 16317 XmlUtils.skipCurrentTag(parser); 16318 } 16319 } 16320 16321 scheduleWriteSettingsLocked(); 16322 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 16323 } 16324 16325 @Override 16326 public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage, 16327 int sourceUserId, int targetUserId, int flags) { 16328 mContext.enforceCallingOrSelfPermission( 16329 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 16330 int callingUid = Binder.getCallingUid(); 16331 enforceOwnerRights(ownerPackage, callingUid); 16332 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 16333 if (intentFilter.countActions() == 0) { 16334 Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions"); 16335 return; 16336 } 16337 synchronized (mPackages) { 16338 CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter, 16339 ownerPackage, targetUserId, flags); 16340 CrossProfileIntentResolver resolver = 16341 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 16342 ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter); 16343 // We have all those whose filter is equal. Now checking if the rest is equal as well. 16344 if (existing != null) { 16345 int size = existing.size(); 16346 for (int i = 0; i < size; i++) { 16347 if (newFilter.equalsIgnoreFilter(existing.get(i))) { 16348 return; 16349 } 16350 } 16351 } 16352 resolver.addFilter(newFilter); 16353 scheduleWritePackageRestrictionsLocked(sourceUserId); 16354 } 16355 } 16356 16357 @Override 16358 public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) { 16359 mContext.enforceCallingOrSelfPermission( 16360 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 16361 int callingUid = Binder.getCallingUid(); 16362 enforceOwnerRights(ownerPackage, callingUid); 16363 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 16364 synchronized (mPackages) { 16365 CrossProfileIntentResolver resolver = 16366 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 16367 ArraySet<CrossProfileIntentFilter> set = 16368 new ArraySet<CrossProfileIntentFilter>(resolver.filterSet()); 16369 for (CrossProfileIntentFilter filter : set) { 16370 if (filter.getOwnerPackage().equals(ownerPackage)) { 16371 resolver.removeFilter(filter); 16372 } 16373 } 16374 scheduleWritePackageRestrictionsLocked(sourceUserId); 16375 } 16376 } 16377 16378 // Enforcing that callingUid is owning pkg on userId 16379 private void enforceOwnerRights(String pkg, int callingUid) { 16380 // The system owns everything. 16381 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) { 16382 return; 16383 } 16384 int callingUserId = UserHandle.getUserId(callingUid); 16385 PackageInfo pi = getPackageInfo(pkg, 0, callingUserId); 16386 if (pi == null) { 16387 throw new IllegalArgumentException("Unknown package " + pkg + " on user " 16388 + callingUserId); 16389 } 16390 if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) { 16391 throw new SecurityException("Calling uid " + callingUid 16392 + " does not own package " + pkg); 16393 } 16394 } 16395 16396 @Override 16397 public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) { 16398 Intent intent = new Intent(Intent.ACTION_MAIN); 16399 intent.addCategory(Intent.CATEGORY_HOME); 16400 16401 final int callingUserId = UserHandle.getCallingUserId(); 16402 List<ResolveInfo> list = queryIntentActivities(intent, null, 16403 PackageManager.GET_META_DATA, callingUserId); 16404 ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0, 16405 true, false, false, callingUserId); 16406 16407 allHomeCandidates.clear(); 16408 if (list != null) { 16409 for (ResolveInfo ri : list) { 16410 allHomeCandidates.add(ri); 16411 } 16412 } 16413 return (preferred == null || preferred.activityInfo == null) 16414 ? null 16415 : new ComponentName(preferred.activityInfo.packageName, 16416 preferred.activityInfo.name); 16417 } 16418 16419 @Override 16420 public void setApplicationEnabledSetting(String appPackageName, 16421 int newState, int flags, int userId, String callingPackage) { 16422 if (!sUserManager.exists(userId)) return; 16423 if (callingPackage == null) { 16424 callingPackage = Integer.toString(Binder.getCallingUid()); 16425 } 16426 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage); 16427 } 16428 16429 @Override 16430 public void setComponentEnabledSetting(ComponentName componentName, 16431 int newState, int flags, int userId) { 16432 if (!sUserManager.exists(userId)) return; 16433 setEnabledSetting(componentName.getPackageName(), 16434 componentName.getClassName(), newState, flags, userId, null); 16435 } 16436 16437 private void setEnabledSetting(final String packageName, String className, int newState, 16438 final int flags, int userId, String callingPackage) { 16439 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT 16440 || newState == COMPONENT_ENABLED_STATE_ENABLED 16441 || newState == COMPONENT_ENABLED_STATE_DISABLED 16442 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER 16443 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) { 16444 throw new IllegalArgumentException("Invalid new component state: " 16445 + newState); 16446 } 16447 PackageSetting pkgSetting; 16448 final int uid = Binder.getCallingUid(); 16449 final int permission = mContext.checkCallingOrSelfPermission( 16450 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 16451 enforceCrossUserPermission(uid, userId, 16452 false /* requireFullPermission */, true /* checkShell */, "set enabled"); 16453 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 16454 boolean sendNow = false; 16455 boolean isApp = (className == null); 16456 String componentName = isApp ? packageName : className; 16457 int packageUid = -1; 16458 ArrayList<String> components; 16459 16460 // writer 16461 synchronized (mPackages) { 16462 pkgSetting = mSettings.mPackages.get(packageName); 16463 if (pkgSetting == null) { 16464 if (className == null) { 16465 throw new IllegalArgumentException("Unknown package: " + packageName); 16466 } 16467 throw new IllegalArgumentException( 16468 "Unknown component: " + packageName + "/" + className); 16469 } 16470 // Allow root and verify that userId is not being specified by a different user 16471 if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) { 16472 throw new SecurityException( 16473 "Permission Denial: attempt to change component state from pid=" 16474 + Binder.getCallingPid() 16475 + ", uid=" + uid + ", package uid=" + pkgSetting.appId); 16476 } 16477 if (className == null) { 16478 // We're dealing with an application/package level state change 16479 if (pkgSetting.getEnabled(userId) == newState) { 16480 // Nothing to do 16481 return; 16482 } 16483 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT 16484 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { 16485 // Don't care about who enables an app. 16486 callingPackage = null; 16487 } 16488 pkgSetting.setEnabled(newState, userId, callingPackage); 16489 // pkgSetting.pkg.mSetEnabled = newState; 16490 } else { 16491 // We're dealing with a component level state change 16492 // First, verify that this is a valid class name. 16493 PackageParser.Package pkg = pkgSetting.pkg; 16494 if (pkg == null || !pkg.hasComponentClassName(className)) { 16495 if (pkg != null && 16496 pkg.applicationInfo.targetSdkVersion >= 16497 Build.VERSION_CODES.JELLY_BEAN) { 16498 throw new IllegalArgumentException("Component class " + className 16499 + " does not exist in " + packageName); 16500 } else { 16501 Slog.w(TAG, "Failed setComponentEnabledSetting: component class " 16502 + className + " does not exist in " + packageName); 16503 } 16504 } 16505 switch (newState) { 16506 case COMPONENT_ENABLED_STATE_ENABLED: 16507 if (!pkgSetting.enableComponentLPw(className, userId)) { 16508 return; 16509 } 16510 break; 16511 case COMPONENT_ENABLED_STATE_DISABLED: 16512 if (!pkgSetting.disableComponentLPw(className, userId)) { 16513 return; 16514 } 16515 break; 16516 case COMPONENT_ENABLED_STATE_DEFAULT: 16517 if (!pkgSetting.restoreComponentLPw(className, userId)) { 16518 return; 16519 } 16520 break; 16521 default: 16522 Slog.e(TAG, "Invalid new component state: " + newState); 16523 return; 16524 } 16525 } 16526 scheduleWritePackageRestrictionsLocked(userId); 16527 components = mPendingBroadcasts.get(userId, packageName); 16528 final boolean newPackage = components == null; 16529 if (newPackage) { 16530 components = new ArrayList<String>(); 16531 } 16532 if (!components.contains(componentName)) { 16533 components.add(componentName); 16534 } 16535 if ((flags&PackageManager.DONT_KILL_APP) == 0) { 16536 sendNow = true; 16537 // Purge entry from pending broadcast list if another one exists already 16538 // since we are sending one right away. 16539 mPendingBroadcasts.remove(userId, packageName); 16540 } else { 16541 if (newPackage) { 16542 mPendingBroadcasts.put(userId, packageName, components); 16543 } 16544 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) { 16545 // Schedule a message 16546 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY); 16547 } 16548 } 16549 } 16550 16551 long callingId = Binder.clearCallingIdentity(); 16552 try { 16553 if (sendNow) { 16554 packageUid = UserHandle.getUid(userId, pkgSetting.appId); 16555 sendPackageChangedBroadcast(packageName, 16556 (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid); 16557 } 16558 } finally { 16559 Binder.restoreCallingIdentity(callingId); 16560 } 16561 } 16562 16563 private void sendPackageChangedBroadcast(String packageName, 16564 boolean killFlag, ArrayList<String> componentNames, int packageUid) { 16565 if (DEBUG_INSTALL) 16566 Log.v(TAG, "Sending package changed: package=" + packageName + " components=" 16567 + componentNames); 16568 Bundle extras = new Bundle(4); 16569 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0)); 16570 String nameList[] = new String[componentNames.size()]; 16571 componentNames.toArray(nameList); 16572 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList); 16573 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag); 16574 extras.putInt(Intent.EXTRA_UID, packageUid); 16575 // If this is not reporting a change of the overall package, then only send it 16576 // to registered receivers. We don't want to launch a swath of apps for every 16577 // little component state change. 16578 final int flags = !componentNames.contains(packageName) 16579 ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0; 16580 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, flags, null, null, 16581 new int[] {UserHandle.getUserId(packageUid)}); 16582 } 16583 16584 @Override 16585 public void setPackageStoppedState(String packageName, boolean stopped, int userId) { 16586 if (!sUserManager.exists(userId)) return; 16587 final int uid = Binder.getCallingUid(); 16588 final int permission = mContext.checkCallingOrSelfPermission( 16589 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 16590 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 16591 enforceCrossUserPermission(uid, userId, 16592 true /* requireFullPermission */, true /* checkShell */, "stop package"); 16593 // writer 16594 synchronized (mPackages) { 16595 if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped, 16596 allowedByPermission, uid, userId)) { 16597 scheduleWritePackageRestrictionsLocked(userId); 16598 } 16599 } 16600 } 16601 16602 @Override 16603 public String getInstallerPackageName(String packageName) { 16604 // reader 16605 synchronized (mPackages) { 16606 return mSettings.getInstallerPackageNameLPr(packageName); 16607 } 16608 } 16609 16610 @Override 16611 public int getApplicationEnabledSetting(String packageName, int userId) { 16612 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 16613 int uid = Binder.getCallingUid(); 16614 enforceCrossUserPermission(uid, userId, 16615 false /* requireFullPermission */, false /* checkShell */, "get enabled"); 16616 // reader 16617 synchronized (mPackages) { 16618 return mSettings.getApplicationEnabledSettingLPr(packageName, userId); 16619 } 16620 } 16621 16622 @Override 16623 public int getComponentEnabledSetting(ComponentName componentName, int userId) { 16624 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 16625 int uid = Binder.getCallingUid(); 16626 enforceCrossUserPermission(uid, userId, 16627 false /* requireFullPermission */, false /* checkShell */, "get component enabled"); 16628 // reader 16629 synchronized (mPackages) { 16630 return mSettings.getComponentEnabledSettingLPr(componentName, userId); 16631 } 16632 } 16633 16634 @Override 16635 public void enterSafeMode() { 16636 enforceSystemOrRoot("Only the system can request entering safe mode"); 16637 16638 if (!mSystemReady) { 16639 mSafeMode = true; 16640 } 16641 } 16642 16643 @Override 16644 public void systemReady() { 16645 mSystemReady = true; 16646 16647 // Read the compatibilty setting when the system is ready. 16648 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt( 16649 mContext.getContentResolver(), 16650 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1; 16651 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled); 16652 if (DEBUG_SETTINGS) { 16653 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled); 16654 } 16655 16656 int[] grantPermissionsUserIds = EMPTY_INT_ARRAY; 16657 16658 synchronized (mPackages) { 16659 // Verify that all of the preferred activity components actually 16660 // exist. It is possible for applications to be updated and at 16661 // that point remove a previously declared activity component that 16662 // had been set as a preferred activity. We try to clean this up 16663 // the next time we encounter that preferred activity, but it is 16664 // possible for the user flow to never be able to return to that 16665 // situation so here we do a sanity check to make sure we haven't 16666 // left any junk around. 16667 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>(); 16668 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 16669 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 16670 removed.clear(); 16671 for (PreferredActivity pa : pir.filterSet()) { 16672 if (mActivities.mActivities.get(pa.mPref.mComponent) == null) { 16673 removed.add(pa); 16674 } 16675 } 16676 if (removed.size() > 0) { 16677 for (int r=0; r<removed.size(); r++) { 16678 PreferredActivity pa = removed.get(r); 16679 Slog.w(TAG, "Removing dangling preferred activity: " 16680 + pa.mPref.mComponent); 16681 pir.removeFilter(pa); 16682 } 16683 mSettings.writePackageRestrictionsLPr( 16684 mSettings.mPreferredActivities.keyAt(i)); 16685 } 16686 } 16687 16688 for (int userId : UserManagerService.getInstance().getUserIds()) { 16689 if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) { 16690 grantPermissionsUserIds = ArrayUtils.appendInt( 16691 grantPermissionsUserIds, userId); 16692 } 16693 } 16694 } 16695 sUserManager.systemReady(); 16696 16697 // If we upgraded grant all default permissions before kicking off. 16698 for (int userId : grantPermissionsUserIds) { 16699 mDefaultPermissionPolicy.grantDefaultPermissions(userId); 16700 } 16701 16702 // Kick off any messages waiting for system ready 16703 if (mPostSystemReadyMessages != null) { 16704 for (Message msg : mPostSystemReadyMessages) { 16705 msg.sendToTarget(); 16706 } 16707 mPostSystemReadyMessages = null; 16708 } 16709 16710 // Watch for external volumes that come and go over time 16711 final StorageManager storage = mContext.getSystemService(StorageManager.class); 16712 storage.registerListener(mStorageListener); 16713 16714 mInstallerService.systemReady(); 16715 mPackageDexOptimizer.systemReady(); 16716 16717 MountServiceInternal mountServiceInternal = LocalServices.getService( 16718 MountServiceInternal.class); 16719 mountServiceInternal.addExternalStoragePolicy( 16720 new MountServiceInternal.ExternalStorageMountPolicy() { 16721 @Override 16722 public int getMountMode(int uid, String packageName) { 16723 if (Process.isIsolated(uid)) { 16724 return Zygote.MOUNT_EXTERNAL_NONE; 16725 } 16726 if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) { 16727 return Zygote.MOUNT_EXTERNAL_DEFAULT; 16728 } 16729 if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { 16730 return Zygote.MOUNT_EXTERNAL_DEFAULT; 16731 } 16732 if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { 16733 return Zygote.MOUNT_EXTERNAL_READ; 16734 } 16735 return Zygote.MOUNT_EXTERNAL_WRITE; 16736 } 16737 16738 @Override 16739 public boolean hasExternalStorage(int uid, String packageName) { 16740 return true; 16741 } 16742 }); 16743 } 16744 16745 @Override 16746 public boolean isSafeMode() { 16747 return mSafeMode; 16748 } 16749 16750 @Override 16751 public boolean hasSystemUidErrors() { 16752 return mHasSystemUidErrors; 16753 } 16754 16755 static String arrayToString(int[] array) { 16756 StringBuffer buf = new StringBuffer(128); 16757 buf.append('['); 16758 if (array != null) { 16759 for (int i=0; i<array.length; i++) { 16760 if (i > 0) buf.append(", "); 16761 buf.append(array[i]); 16762 } 16763 } 16764 buf.append(']'); 16765 return buf.toString(); 16766 } 16767 16768 static class DumpState { 16769 public static final int DUMP_LIBS = 1 << 0; 16770 public static final int DUMP_FEATURES = 1 << 1; 16771 public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2; 16772 public static final int DUMP_SERVICE_RESOLVERS = 1 << 3; 16773 public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4; 16774 public static final int DUMP_CONTENT_RESOLVERS = 1 << 5; 16775 public static final int DUMP_PERMISSIONS = 1 << 6; 16776 public static final int DUMP_PACKAGES = 1 << 7; 16777 public static final int DUMP_SHARED_USERS = 1 << 8; 16778 public static final int DUMP_MESSAGES = 1 << 9; 16779 public static final int DUMP_PROVIDERS = 1 << 10; 16780 public static final int DUMP_VERIFIERS = 1 << 11; 16781 public static final int DUMP_PREFERRED = 1 << 12; 16782 public static final int DUMP_PREFERRED_XML = 1 << 13; 16783 public static final int DUMP_KEYSETS = 1 << 14; 16784 public static final int DUMP_VERSION = 1 << 15; 16785 public static final int DUMP_INSTALLS = 1 << 16; 16786 public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17; 16787 public static final int DUMP_DOMAIN_PREFERRED = 1 << 18; 16788 16789 public static final int OPTION_SHOW_FILTERS = 1 << 0; 16790 16791 private int mTypes; 16792 16793 private int mOptions; 16794 16795 private boolean mTitlePrinted; 16796 16797 private SharedUserSetting mSharedUser; 16798 16799 public boolean isDumping(int type) { 16800 if (mTypes == 0 && type != DUMP_PREFERRED_XML) { 16801 return true; 16802 } 16803 16804 return (mTypes & type) != 0; 16805 } 16806 16807 public void setDump(int type) { 16808 mTypes |= type; 16809 } 16810 16811 public boolean isOptionEnabled(int option) { 16812 return (mOptions & option) != 0; 16813 } 16814 16815 public void setOptionEnabled(int option) { 16816 mOptions |= option; 16817 } 16818 16819 public boolean onTitlePrinted() { 16820 final boolean printed = mTitlePrinted; 16821 mTitlePrinted = true; 16822 return printed; 16823 } 16824 16825 public boolean getTitlePrinted() { 16826 return mTitlePrinted; 16827 } 16828 16829 public void setTitlePrinted(boolean enabled) { 16830 mTitlePrinted = enabled; 16831 } 16832 16833 public SharedUserSetting getSharedUser() { 16834 return mSharedUser; 16835 } 16836 16837 public void setSharedUser(SharedUserSetting user) { 16838 mSharedUser = user; 16839 } 16840 } 16841 16842 @Override 16843 public void onShellCommand(FileDescriptor in, FileDescriptor out, 16844 FileDescriptor err, String[] args, ResultReceiver resultReceiver) { 16845 (new PackageManagerShellCommand(this)).exec( 16846 this, in, out, err, args, resultReceiver); 16847 } 16848 16849 @Override 16850 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 16851 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 16852 != PackageManager.PERMISSION_GRANTED) { 16853 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 16854 + Binder.getCallingPid() 16855 + ", uid=" + Binder.getCallingUid() 16856 + " without permission " 16857 + android.Manifest.permission.DUMP); 16858 return; 16859 } 16860 16861 DumpState dumpState = new DumpState(); 16862 boolean fullPreferred = false; 16863 boolean checkin = false; 16864 16865 String packageName = null; 16866 ArraySet<String> permissionNames = null; 16867 16868 int opti = 0; 16869 while (opti < args.length) { 16870 String opt = args[opti]; 16871 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 16872 break; 16873 } 16874 opti++; 16875 16876 if ("-a".equals(opt)) { 16877 // Right now we only know how to print all. 16878 } else if ("-h".equals(opt)) { 16879 pw.println("Package manager dump options:"); 16880 pw.println(" [-h] [-f] [--checkin] [cmd] ..."); 16881 pw.println(" --checkin: dump for a checkin"); 16882 pw.println(" -f: print details of intent filters"); 16883 pw.println(" -h: print this help"); 16884 pw.println(" cmd may be one of:"); 16885 pw.println(" l[ibraries]: list known shared libraries"); 16886 pw.println(" f[eatures]: list device features"); 16887 pw.println(" k[eysets]: print known keysets"); 16888 pw.println(" r[esolvers] [activity|service|receiver|content]: dump intent resolvers"); 16889 pw.println(" perm[issions]: dump permissions"); 16890 pw.println(" permission [name ...]: dump declaration and use of given permission"); 16891 pw.println(" pref[erred]: print preferred package settings"); 16892 pw.println(" preferred-xml [--full]: print preferred package settings as xml"); 16893 pw.println(" prov[iders]: dump content providers"); 16894 pw.println(" p[ackages]: dump installed packages"); 16895 pw.println(" s[hared-users]: dump shared user IDs"); 16896 pw.println(" m[essages]: print collected runtime messages"); 16897 pw.println(" v[erifiers]: print package verifier info"); 16898 pw.println(" d[omain-preferred-apps]: print domains preferred apps"); 16899 pw.println(" i[ntent-filter-verifiers]|ifv: print intent filter verifier info"); 16900 pw.println(" version: print database version info"); 16901 pw.println(" write: write current settings now"); 16902 pw.println(" installs: details about install sessions"); 16903 pw.println(" check-permission <permission> <package> [<user>]: does pkg hold perm?"); 16904 pw.println(" <package.name>: info about given package"); 16905 return; 16906 } else if ("--checkin".equals(opt)) { 16907 checkin = true; 16908 } else if ("-f".equals(opt)) { 16909 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 16910 } else { 16911 pw.println("Unknown argument: " + opt + "; use -h for help"); 16912 } 16913 } 16914 16915 // Is the caller requesting to dump a particular piece of data? 16916 if (opti < args.length) { 16917 String cmd = args[opti]; 16918 opti++; 16919 // Is this a package name? 16920 if ("android".equals(cmd) || cmd.contains(".")) { 16921 packageName = cmd; 16922 // When dumping a single package, we always dump all of its 16923 // filter information since the amount of data will be reasonable. 16924 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 16925 } else if ("check-permission".equals(cmd)) { 16926 if (opti >= args.length) { 16927 pw.println("Error: check-permission missing permission argument"); 16928 return; 16929 } 16930 String perm = args[opti]; 16931 opti++; 16932 if (opti >= args.length) { 16933 pw.println("Error: check-permission missing package argument"); 16934 return; 16935 } 16936 String pkg = args[opti]; 16937 opti++; 16938 int user = UserHandle.getUserId(Binder.getCallingUid()); 16939 if (opti < args.length) { 16940 try { 16941 user = Integer.parseInt(args[opti]); 16942 } catch (NumberFormatException e) { 16943 pw.println("Error: check-permission user argument is not a number: " 16944 + args[opti]); 16945 return; 16946 } 16947 } 16948 pw.println(checkPermission(perm, pkg, user)); 16949 return; 16950 } else if ("l".equals(cmd) || "libraries".equals(cmd)) { 16951 dumpState.setDump(DumpState.DUMP_LIBS); 16952 } else if ("f".equals(cmd) || "features".equals(cmd)) { 16953 dumpState.setDump(DumpState.DUMP_FEATURES); 16954 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) { 16955 if (opti >= args.length) { 16956 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS 16957 | DumpState.DUMP_SERVICE_RESOLVERS 16958 | DumpState.DUMP_RECEIVER_RESOLVERS 16959 | DumpState.DUMP_CONTENT_RESOLVERS); 16960 } else { 16961 while (opti < args.length) { 16962 String name = args[opti]; 16963 if ("a".equals(name) || "activity".equals(name)) { 16964 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS); 16965 } else if ("s".equals(name) || "service".equals(name)) { 16966 dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS); 16967 } else if ("r".equals(name) || "receiver".equals(name)) { 16968 dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS); 16969 } else if ("c".equals(name) || "content".equals(name)) { 16970 dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS); 16971 } else { 16972 pw.println("Error: unknown resolver table type: " + name); 16973 return; 16974 } 16975 opti++; 16976 } 16977 } 16978 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) { 16979 dumpState.setDump(DumpState.DUMP_PERMISSIONS); 16980 } else if ("permission".equals(cmd)) { 16981 if (opti >= args.length) { 16982 pw.println("Error: permission requires permission name"); 16983 return; 16984 } 16985 permissionNames = new ArraySet<>(); 16986 while (opti < args.length) { 16987 permissionNames.add(args[opti]); 16988 opti++; 16989 } 16990 dumpState.setDump(DumpState.DUMP_PERMISSIONS 16991 | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS); 16992 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) { 16993 dumpState.setDump(DumpState.DUMP_PREFERRED); 16994 } else if ("preferred-xml".equals(cmd)) { 16995 dumpState.setDump(DumpState.DUMP_PREFERRED_XML); 16996 if (opti < args.length && "--full".equals(args[opti])) { 16997 fullPreferred = true; 16998 opti++; 16999 } 17000 } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) { 17001 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED); 17002 } else if ("p".equals(cmd) || "packages".equals(cmd)) { 17003 dumpState.setDump(DumpState.DUMP_PACKAGES); 17004 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) { 17005 dumpState.setDump(DumpState.DUMP_SHARED_USERS); 17006 } else if ("prov".equals(cmd) || "providers".equals(cmd)) { 17007 dumpState.setDump(DumpState.DUMP_PROVIDERS); 17008 } else if ("m".equals(cmd) || "messages".equals(cmd)) { 17009 dumpState.setDump(DumpState.DUMP_MESSAGES); 17010 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) { 17011 dumpState.setDump(DumpState.DUMP_VERIFIERS); 17012 } else if ("i".equals(cmd) || "ifv".equals(cmd) 17013 || "intent-filter-verifiers".equals(cmd)) { 17014 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS); 17015 } else if ("version".equals(cmd)) { 17016 dumpState.setDump(DumpState.DUMP_VERSION); 17017 } else if ("k".equals(cmd) || "keysets".equals(cmd)) { 17018 dumpState.setDump(DumpState.DUMP_KEYSETS); 17019 } else if ("installs".equals(cmd)) { 17020 dumpState.setDump(DumpState.DUMP_INSTALLS); 17021 } else if ("write".equals(cmd)) { 17022 synchronized (mPackages) { 17023 mSettings.writeLPr(); 17024 pw.println("Settings written."); 17025 return; 17026 } 17027 } 17028 } 17029 17030 if (checkin) { 17031 pw.println("vers,1"); 17032 } 17033 17034 // reader 17035 synchronized (mPackages) { 17036 if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) { 17037 if (!checkin) { 17038 if (dumpState.onTitlePrinted()) 17039 pw.println(); 17040 pw.println("Database versions:"); 17041 mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, " ")); 17042 } 17043 } 17044 17045 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) { 17046 if (!checkin) { 17047 if (dumpState.onTitlePrinted()) 17048 pw.println(); 17049 pw.println("Verifiers:"); 17050 pw.print(" Required: "); 17051 pw.print(mRequiredVerifierPackage); 17052 pw.print(" (uid="); 17053 pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 17054 UserHandle.USER_SYSTEM)); 17055 pw.println(")"); 17056 } else if (mRequiredVerifierPackage != null) { 17057 pw.print("vrfy,"); pw.print(mRequiredVerifierPackage); 17058 pw.print(","); 17059 pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 17060 UserHandle.USER_SYSTEM)); 17061 } 17062 } 17063 17064 if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) && 17065 packageName == null) { 17066 if (mIntentFilterVerifierComponent != null) { 17067 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName(); 17068 if (!checkin) { 17069 if (dumpState.onTitlePrinted()) 17070 pw.println(); 17071 pw.println("Intent Filter Verifier:"); 17072 pw.print(" Using: "); 17073 pw.print(verifierPackageName); 17074 pw.print(" (uid="); 17075 pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING, 17076 UserHandle.USER_SYSTEM)); 17077 pw.println(")"); 17078 } else if (verifierPackageName != null) { 17079 pw.print("ifv,"); pw.print(verifierPackageName); 17080 pw.print(","); 17081 pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING, 17082 UserHandle.USER_SYSTEM)); 17083 } 17084 } else { 17085 pw.println(); 17086 pw.println("No Intent Filter Verifier available!"); 17087 } 17088 } 17089 17090 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) { 17091 boolean printedHeader = false; 17092 final Iterator<String> it = mSharedLibraries.keySet().iterator(); 17093 while (it.hasNext()) { 17094 String name = it.next(); 17095 SharedLibraryEntry ent = mSharedLibraries.get(name); 17096 if (!checkin) { 17097 if (!printedHeader) { 17098 if (dumpState.onTitlePrinted()) 17099 pw.println(); 17100 pw.println("Libraries:"); 17101 printedHeader = true; 17102 } 17103 pw.print(" "); 17104 } else { 17105 pw.print("lib,"); 17106 } 17107 pw.print(name); 17108 if (!checkin) { 17109 pw.print(" -> "); 17110 } 17111 if (ent.path != null) { 17112 if (!checkin) { 17113 pw.print("(jar) "); 17114 pw.print(ent.path); 17115 } else { 17116 pw.print(",jar,"); 17117 pw.print(ent.path); 17118 } 17119 } else { 17120 if (!checkin) { 17121 pw.print("(apk) "); 17122 pw.print(ent.apk); 17123 } else { 17124 pw.print(",apk,"); 17125 pw.print(ent.apk); 17126 } 17127 } 17128 pw.println(); 17129 } 17130 } 17131 17132 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) { 17133 if (dumpState.onTitlePrinted()) 17134 pw.println(); 17135 if (!checkin) { 17136 pw.println("Features:"); 17137 } 17138 17139 for (FeatureInfo feat : mAvailableFeatures.values()) { 17140 if (checkin) { 17141 pw.print("feat,"); 17142 pw.print(feat.name); 17143 pw.print(","); 17144 pw.println(feat.version); 17145 } else { 17146 pw.print(" "); 17147 pw.print(feat.name); 17148 if (feat.version > 0) { 17149 pw.print(" version="); 17150 pw.print(feat.version); 17151 } 17152 pw.println(); 17153 } 17154 } 17155 } 17156 17157 if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) { 17158 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:" 17159 : "Activity Resolver Table:", " ", packageName, 17160 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 17161 dumpState.setTitlePrinted(true); 17162 } 17163 } 17164 if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) { 17165 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:" 17166 : "Receiver Resolver Table:", " ", packageName, 17167 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 17168 dumpState.setTitlePrinted(true); 17169 } 17170 } 17171 if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) { 17172 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:" 17173 : "Service Resolver Table:", " ", packageName, 17174 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 17175 dumpState.setTitlePrinted(true); 17176 } 17177 } 17178 if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) { 17179 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:" 17180 : "Provider Resolver Table:", " ", packageName, 17181 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 17182 dumpState.setTitlePrinted(true); 17183 } 17184 } 17185 17186 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) { 17187 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 17188 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 17189 int user = mSettings.mPreferredActivities.keyAt(i); 17190 if (pir.dump(pw, 17191 dumpState.getTitlePrinted() 17192 ? "\nPreferred Activities User " + user + ":" 17193 : "Preferred Activities User " + user + ":", " ", 17194 packageName, true, false)) { 17195 dumpState.setTitlePrinted(true); 17196 } 17197 } 17198 } 17199 17200 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) { 17201 pw.flush(); 17202 FileOutputStream fout = new FileOutputStream(fd); 17203 BufferedOutputStream str = new BufferedOutputStream(fout); 17204 XmlSerializer serializer = new FastXmlSerializer(); 17205 try { 17206 serializer.setOutput(str, StandardCharsets.UTF_8.name()); 17207 serializer.startDocument(null, true); 17208 serializer.setFeature( 17209 "http://xmlpull.org/v1/doc/features.html#indent-output", true); 17210 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred); 17211 serializer.endDocument(); 17212 serializer.flush(); 17213 } catch (IllegalArgumentException e) { 17214 pw.println("Failed writing: " + e); 17215 } catch (IllegalStateException e) { 17216 pw.println("Failed writing: " + e); 17217 } catch (IOException e) { 17218 pw.println("Failed writing: " + e); 17219 } 17220 } 17221 17222 if (!checkin 17223 && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED) 17224 && packageName == null) { 17225 pw.println(); 17226 int count = mSettings.mPackages.size(); 17227 if (count == 0) { 17228 pw.println("No applications!"); 17229 pw.println(); 17230 } else { 17231 final String prefix = " "; 17232 Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values(); 17233 if (allPackageSettings.size() == 0) { 17234 pw.println("No domain preferred apps!"); 17235 pw.println(); 17236 } else { 17237 pw.println("App verification status:"); 17238 pw.println(); 17239 count = 0; 17240 for (PackageSetting ps : allPackageSettings) { 17241 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo(); 17242 if (ivi == null || ivi.getPackageName() == null) continue; 17243 pw.println(prefix + "Package: " + ivi.getPackageName()); 17244 pw.println(prefix + "Domains: " + ivi.getDomainsString()); 17245 pw.println(prefix + "Status: " + ivi.getStatusString()); 17246 pw.println(); 17247 count++; 17248 } 17249 if (count == 0) { 17250 pw.println(prefix + "No app verification established."); 17251 pw.println(); 17252 } 17253 for (int userId : sUserManager.getUserIds()) { 17254 pw.println("App linkages for user " + userId + ":"); 17255 pw.println(); 17256 count = 0; 17257 for (PackageSetting ps : allPackageSettings) { 17258 final long status = ps.getDomainVerificationStatusForUser(userId); 17259 if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 17260 continue; 17261 } 17262 pw.println(prefix + "Package: " + ps.name); 17263 pw.println(prefix + "Domains: " + dumpDomainString(ps.name)); 17264 String statusStr = IntentFilterVerificationInfo. 17265 getStatusStringFromValue(status); 17266 pw.println(prefix + "Status: " + statusStr); 17267 pw.println(); 17268 count++; 17269 } 17270 if (count == 0) { 17271 pw.println(prefix + "No configured app linkages."); 17272 pw.println(); 17273 } 17274 } 17275 } 17276 } 17277 } 17278 17279 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) { 17280 mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState); 17281 if (packageName == null && permissionNames == null) { 17282 for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) { 17283 if (iperm == 0) { 17284 if (dumpState.onTitlePrinted()) 17285 pw.println(); 17286 pw.println("AppOp Permissions:"); 17287 } 17288 pw.print(" AppOp Permission "); 17289 pw.print(mAppOpPermissionPackages.keyAt(iperm)); 17290 pw.println(":"); 17291 ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm); 17292 for (int ipkg=0; ipkg<pkgs.size(); ipkg++) { 17293 pw.print(" "); pw.println(pkgs.valueAt(ipkg)); 17294 } 17295 } 17296 } 17297 } 17298 17299 if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) { 17300 boolean printedSomething = false; 17301 for (PackageParser.Provider p : mProviders.mProviders.values()) { 17302 if (packageName != null && !packageName.equals(p.info.packageName)) { 17303 continue; 17304 } 17305 if (!printedSomething) { 17306 if (dumpState.onTitlePrinted()) 17307 pw.println(); 17308 pw.println("Registered ContentProviders:"); 17309 printedSomething = true; 17310 } 17311 pw.print(" "); p.printComponentShortName(pw); pw.println(":"); 17312 pw.print(" "); pw.println(p.toString()); 17313 } 17314 printedSomething = false; 17315 for (Map.Entry<String, PackageParser.Provider> entry : 17316 mProvidersByAuthority.entrySet()) { 17317 PackageParser.Provider p = entry.getValue(); 17318 if (packageName != null && !packageName.equals(p.info.packageName)) { 17319 continue; 17320 } 17321 if (!printedSomething) { 17322 if (dumpState.onTitlePrinted()) 17323 pw.println(); 17324 pw.println("ContentProvider Authorities:"); 17325 printedSomething = true; 17326 } 17327 pw.print(" ["); pw.print(entry.getKey()); pw.println("]:"); 17328 pw.print(" "); pw.println(p.toString()); 17329 if (p.info != null && p.info.applicationInfo != null) { 17330 final String appInfo = p.info.applicationInfo.toString(); 17331 pw.print(" applicationInfo="); pw.println(appInfo); 17332 } 17333 } 17334 } 17335 17336 if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) { 17337 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState); 17338 } 17339 17340 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) { 17341 mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin); 17342 } 17343 17344 if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) { 17345 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin); 17346 } 17347 17348 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) { 17349 mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState); 17350 } 17351 17352 if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) { 17353 // XXX should handle packageName != null by dumping only install data that 17354 // the given package is involved with. 17355 if (dumpState.onTitlePrinted()) pw.println(); 17356 mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120)); 17357 } 17358 17359 if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) { 17360 if (dumpState.onTitlePrinted()) pw.println(); 17361 mSettings.dumpReadMessagesLPr(pw, dumpState); 17362 17363 pw.println(); 17364 pw.println("Package warning messages:"); 17365 BufferedReader in = null; 17366 String line = null; 17367 try { 17368 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 17369 while ((line = in.readLine()) != null) { 17370 if (line.contains("ignored: updated version")) continue; 17371 pw.println(line); 17372 } 17373 } catch (IOException ignored) { 17374 } finally { 17375 IoUtils.closeQuietly(in); 17376 } 17377 } 17378 17379 if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) { 17380 BufferedReader in = null; 17381 String line = null; 17382 try { 17383 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 17384 while ((line = in.readLine()) != null) { 17385 if (line.contains("ignored: updated version")) continue; 17386 pw.print("msg,"); 17387 pw.println(line); 17388 } 17389 } catch (IOException ignored) { 17390 } finally { 17391 IoUtils.closeQuietly(in); 17392 } 17393 } 17394 } 17395 } 17396 17397 private String dumpDomainString(String packageName) { 17398 List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName); 17399 List<IntentFilter> filters = getAllIntentFilters(packageName); 17400 17401 ArraySet<String> result = new ArraySet<>(); 17402 if (iviList.size() > 0) { 17403 for (IntentFilterVerificationInfo ivi : iviList) { 17404 for (String host : ivi.getDomains()) { 17405 result.add(host); 17406 } 17407 } 17408 } 17409 if (filters != null && filters.size() > 0) { 17410 for (IntentFilter filter : filters) { 17411 if (filter.hasCategory(Intent.CATEGORY_BROWSABLE) 17412 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 17413 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) { 17414 result.addAll(filter.getHostsList()); 17415 } 17416 } 17417 } 17418 17419 StringBuilder sb = new StringBuilder(result.size() * 16); 17420 for (String domain : result) { 17421 if (sb.length() > 0) sb.append(" "); 17422 sb.append(domain); 17423 } 17424 return sb.toString(); 17425 } 17426 17427 // ------- apps on sdcard specific code ------- 17428 static final boolean DEBUG_SD_INSTALL = false; 17429 17430 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD"; 17431 17432 private static final String SD_ENCRYPTION_ALGORITHM = "AES"; 17433 17434 private boolean mMediaMounted = false; 17435 17436 static String getEncryptKey() { 17437 try { 17438 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString( 17439 SD_ENCRYPTION_KEYSTORE_NAME); 17440 if (sdEncKey == null) { 17441 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128, 17442 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME); 17443 if (sdEncKey == null) { 17444 Slog.e(TAG, "Failed to create encryption keys"); 17445 return null; 17446 } 17447 } 17448 return sdEncKey; 17449 } catch (NoSuchAlgorithmException nsae) { 17450 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae); 17451 return null; 17452 } catch (IOException ioe) { 17453 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe); 17454 return null; 17455 } 17456 } 17457 17458 /* 17459 * Update media status on PackageManager. 17460 */ 17461 @Override 17462 public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) { 17463 int callingUid = Binder.getCallingUid(); 17464 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 17465 throw new SecurityException("Media status can only be updated by the system"); 17466 } 17467 // reader; this apparently protects mMediaMounted, but should probably 17468 // be a different lock in that case. 17469 synchronized (mPackages) { 17470 Log.i(TAG, "Updating external media status from " 17471 + (mMediaMounted ? "mounted" : "unmounted") + " to " 17472 + (mediaStatus ? "mounted" : "unmounted")); 17473 if (DEBUG_SD_INSTALL) 17474 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus 17475 + ", mMediaMounted=" + mMediaMounted); 17476 if (mediaStatus == mMediaMounted) { 17477 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 17478 : 0, -1); 17479 mHandler.sendMessage(msg); 17480 return; 17481 } 17482 mMediaMounted = mediaStatus; 17483 } 17484 // Queue up an async operation since the package installation may take a 17485 // little while. 17486 mHandler.post(new Runnable() { 17487 public void run() { 17488 updateExternalMediaStatusInner(mediaStatus, reportStatus, true); 17489 } 17490 }); 17491 } 17492 17493 /** 17494 * Called by MountService when the initial ASECs to scan are available. 17495 * Should block until all the ASEC containers are finished being scanned. 17496 */ 17497 public void scanAvailableAsecs() { 17498 updateExternalMediaStatusInner(true, false, false); 17499 } 17500 17501 /* 17502 * Collect information of applications on external media, map them against 17503 * existing containers and update information based on current mount status. 17504 * Please note that we always have to report status if reportStatus has been 17505 * set to true especially when unloading packages. 17506 */ 17507 private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus, 17508 boolean externalStorage) { 17509 ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>(); 17510 int[] uidArr = EmptyArray.INT; 17511 17512 final String[] list = PackageHelper.getSecureContainerList(); 17513 if (ArrayUtils.isEmpty(list)) { 17514 Log.i(TAG, "No secure containers found"); 17515 } else { 17516 // Process list of secure containers and categorize them 17517 // as active or stale based on their package internal state. 17518 17519 // reader 17520 synchronized (mPackages) { 17521 for (String cid : list) { 17522 // Leave stages untouched for now; installer service owns them 17523 if (PackageInstallerService.isStageName(cid)) continue; 17524 17525 if (DEBUG_SD_INSTALL) 17526 Log.i(TAG, "Processing container " + cid); 17527 String pkgName = getAsecPackageName(cid); 17528 if (pkgName == null) { 17529 Slog.i(TAG, "Found stale container " + cid + " with no package name"); 17530 continue; 17531 } 17532 if (DEBUG_SD_INSTALL) 17533 Log.i(TAG, "Looking for pkg : " + pkgName); 17534 17535 final PackageSetting ps = mSettings.mPackages.get(pkgName); 17536 if (ps == null) { 17537 Slog.i(TAG, "Found stale container " + cid + " with no matching settings"); 17538 continue; 17539 } 17540 17541 /* 17542 * Skip packages that are not external if we're unmounting 17543 * external storage. 17544 */ 17545 if (externalStorage && !isMounted && !isExternal(ps)) { 17546 continue; 17547 } 17548 17549 final AsecInstallArgs args = new AsecInstallArgs(cid, 17550 getAppDexInstructionSets(ps), ps.isForwardLocked()); 17551 // The package status is changed only if the code path 17552 // matches between settings and the container id. 17553 if (ps.codePathString != null 17554 && ps.codePathString.startsWith(args.getCodePath())) { 17555 if (DEBUG_SD_INSTALL) { 17556 Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName 17557 + " at code path: " + ps.codePathString); 17558 } 17559 17560 // We do have a valid package installed on sdcard 17561 processCids.put(args, ps.codePathString); 17562 final int uid = ps.appId; 17563 if (uid != -1) { 17564 uidArr = ArrayUtils.appendInt(uidArr, uid); 17565 } 17566 } else { 17567 Slog.i(TAG, "Found stale container " + cid + ": expected codePath=" 17568 + ps.codePathString); 17569 } 17570 } 17571 } 17572 17573 Arrays.sort(uidArr); 17574 } 17575 17576 // Process packages with valid entries. 17577 if (isMounted) { 17578 if (DEBUG_SD_INSTALL) 17579 Log.i(TAG, "Loading packages"); 17580 loadMediaPackages(processCids, uidArr, externalStorage); 17581 startCleaningPackages(); 17582 mInstallerService.onSecureContainersAvailable(); 17583 } else { 17584 if (DEBUG_SD_INSTALL) 17585 Log.i(TAG, "Unloading packages"); 17586 unloadMediaPackages(processCids, uidArr, reportStatus); 17587 } 17588 } 17589 17590 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 17591 ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) { 17592 final int size = infos.size(); 17593 final String[] packageNames = new String[size]; 17594 final int[] packageUids = new int[size]; 17595 for (int i = 0; i < size; i++) { 17596 final ApplicationInfo info = infos.get(i); 17597 packageNames[i] = info.packageName; 17598 packageUids[i] = info.uid; 17599 } 17600 sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids, 17601 finishedReceiver); 17602 } 17603 17604 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 17605 ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 17606 sendResourcesChangedBroadcast(mediaStatus, replacing, 17607 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver); 17608 } 17609 17610 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 17611 String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 17612 int size = pkgList.length; 17613 if (size > 0) { 17614 // Send broadcasts here 17615 Bundle extras = new Bundle(); 17616 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 17617 if (uidArr != null) { 17618 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr); 17619 } 17620 if (replacing) { 17621 extras.putBoolean(Intent.EXTRA_REPLACING, replacing); 17622 } 17623 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE 17624 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE; 17625 sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null); 17626 } 17627 } 17628 17629 /* 17630 * Look at potentially valid container ids from processCids If package 17631 * information doesn't match the one on record or package scanning fails, 17632 * the cid is added to list of removeCids. We currently don't delete stale 17633 * containers. 17634 */ 17635 private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr, 17636 boolean externalStorage) { 17637 ArrayList<String> pkgList = new ArrayList<String>(); 17638 Set<AsecInstallArgs> keys = processCids.keySet(); 17639 17640 for (AsecInstallArgs args : keys) { 17641 String codePath = processCids.get(args); 17642 if (DEBUG_SD_INSTALL) 17643 Log.i(TAG, "Loading container : " + args.cid); 17644 int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 17645 try { 17646 // Make sure there are no container errors first. 17647 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) { 17648 Slog.e(TAG, "Failed to mount cid : " + args.cid 17649 + " when installing from sdcard"); 17650 continue; 17651 } 17652 // Check code path here. 17653 if (codePath == null || !codePath.startsWith(args.getCodePath())) { 17654 Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath() 17655 + " does not match one in settings " + codePath); 17656 continue; 17657 } 17658 // Parse package 17659 int parseFlags = mDefParseFlags; 17660 if (args.isExternalAsec()) { 17661 parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE; 17662 } 17663 if (args.isFwdLocked()) { 17664 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 17665 } 17666 17667 synchronized (mInstallLock) { 17668 PackageParser.Package pkg = null; 17669 try { 17670 pkg = scanPackageTracedLI(new File(codePath), parseFlags, 0, 0, null); 17671 } catch (PackageManagerException e) { 17672 Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage()); 17673 } 17674 // Scan the package 17675 if (pkg != null) { 17676 /* 17677 * TODO why is the lock being held? doPostInstall is 17678 * called in other places without the lock. This needs 17679 * to be straightened out. 17680 */ 17681 // writer 17682 synchronized (mPackages) { 17683 retCode = PackageManager.INSTALL_SUCCEEDED; 17684 pkgList.add(pkg.packageName); 17685 // Post process args 17686 args.doPostInstall(PackageManager.INSTALL_SUCCEEDED, 17687 pkg.applicationInfo.uid); 17688 } 17689 } else { 17690 Slog.i(TAG, "Failed to install pkg from " + codePath + " from sdcard"); 17691 } 17692 } 17693 17694 } finally { 17695 if (retCode != PackageManager.INSTALL_SUCCEEDED) { 17696 Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode); 17697 } 17698 } 17699 } 17700 // writer 17701 synchronized (mPackages) { 17702 // If the platform SDK has changed since the last time we booted, 17703 // we need to re-grant app permission to catch any new ones that 17704 // appear. This is really a hack, and means that apps can in some 17705 // cases get permissions that the user didn't initially explicitly 17706 // allow... it would be nice to have some better way to handle 17707 // this situation. 17708 final VersionInfo ver = externalStorage ? mSettings.getExternalVersion() 17709 : mSettings.getInternalVersion(); 17710 final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL 17711 : StorageManager.UUID_PRIVATE_INTERNAL; 17712 17713 int updateFlags = UPDATE_PERMISSIONS_ALL; 17714 if (ver.sdkVersion != mSdkVersion) { 17715 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " 17716 + mSdkVersion + "; regranting permissions for external"); 17717 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 17718 } 17719 updatePermissionsLPw(null, null, volumeUuid, updateFlags); 17720 17721 // Yay, everything is now upgraded 17722 ver.forceCurrent(); 17723 17724 // can downgrade to reader 17725 // Persist settings 17726 mSettings.writeLPr(); 17727 } 17728 // Send a broadcast to let everyone know we are done processing 17729 if (pkgList.size() > 0) { 17730 sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null); 17731 } 17732 } 17733 17734 /* 17735 * Utility method to unload a list of specified containers 17736 */ 17737 private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) { 17738 // Just unmount all valid containers. 17739 for (AsecInstallArgs arg : cidArgs) { 17740 synchronized (mInstallLock) { 17741 arg.doPostDeleteLI(false); 17742 } 17743 } 17744 } 17745 17746 /* 17747 * Unload packages mounted on external media. This involves deleting package 17748 * data from internal structures, sending broadcasts about disabled packages, 17749 * gc'ing to free up references, unmounting all secure containers 17750 * corresponding to packages on external media, and posting a 17751 * UPDATED_MEDIA_STATUS message if status has been requested. Please note 17752 * that we always have to post this message if status has been requested no 17753 * matter what. 17754 */ 17755 private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[], 17756 final boolean reportStatus) { 17757 if (DEBUG_SD_INSTALL) 17758 Log.i(TAG, "unloading media packages"); 17759 ArrayList<String> pkgList = new ArrayList<String>(); 17760 ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>(); 17761 final Set<AsecInstallArgs> keys = processCids.keySet(); 17762 for (AsecInstallArgs args : keys) { 17763 String pkgName = args.getPackageName(); 17764 if (DEBUG_SD_INSTALL) 17765 Log.i(TAG, "Trying to unload pkg : " + pkgName); 17766 // Delete package internally 17767 PackageRemovedInfo outInfo = new PackageRemovedInfo(); 17768 synchronized (mInstallLock) { 17769 boolean res = deletePackageLI(pkgName, null, false, null, 17770 PackageManager.DELETE_KEEP_DATA, outInfo, false, null); 17771 if (res) { 17772 pkgList.add(pkgName); 17773 } else { 17774 Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName); 17775 failedList.add(args); 17776 } 17777 } 17778 } 17779 17780 // reader 17781 synchronized (mPackages) { 17782 // We didn't update the settings after removing each package; 17783 // write them now for all packages. 17784 mSettings.writeLPr(); 17785 } 17786 17787 // We have to absolutely send UPDATED_MEDIA_STATUS only 17788 // after confirming that all the receivers processed the ordered 17789 // broadcast when packages get disabled, force a gc to clean things up. 17790 // and unload all the containers. 17791 if (pkgList.size() > 0) { 17792 sendResourcesChangedBroadcast(false, false, pkgList, uidArr, 17793 new IIntentReceiver.Stub() { 17794 public void performReceive(Intent intent, int resultCode, String data, 17795 Bundle extras, boolean ordered, boolean sticky, 17796 int sendingUser) throws RemoteException { 17797 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, 17798 reportStatus ? 1 : 0, 1, keys); 17799 mHandler.sendMessage(msg); 17800 } 17801 }); 17802 } else { 17803 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1, 17804 keys); 17805 mHandler.sendMessage(msg); 17806 } 17807 } 17808 17809 private void loadPrivatePackages(final VolumeInfo vol) { 17810 mHandler.post(new Runnable() { 17811 @Override 17812 public void run() { 17813 loadPrivatePackagesInner(vol); 17814 } 17815 }); 17816 } 17817 17818 private void loadPrivatePackagesInner(VolumeInfo vol) { 17819 final String volumeUuid = vol.fsUuid; 17820 if (TextUtils.isEmpty(volumeUuid)) { 17821 Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring"); 17822 return; 17823 } 17824 17825 final ArrayList<ApplicationInfo> loaded = new ArrayList<>(); 17826 final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE; 17827 17828 final VersionInfo ver; 17829 final List<PackageSetting> packages; 17830 synchronized (mPackages) { 17831 ver = mSettings.findOrCreateVersion(volumeUuid); 17832 packages = mSettings.getVolumePackagesLPr(volumeUuid); 17833 } 17834 17835 // TODO: introduce a new concept similar to "frozen" to prevent these 17836 // apps from being launched until after data has been fully reconciled 17837 for (PackageSetting ps : packages) { 17838 synchronized (mInstallLock) { 17839 final PackageParser.Package pkg; 17840 try { 17841 pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null); 17842 loaded.add(pkg.applicationInfo); 17843 17844 } catch (PackageManagerException e) { 17845 Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage()); 17846 } 17847 17848 if (!Build.FINGERPRINT.equals(ver.fingerprint)) { 17849 deleteCodeCacheDirsLI(ps.volumeUuid, ps.name); 17850 } 17851 } 17852 } 17853 17854 // Reconcile app data for all started/unlocked users 17855 final StorageManager sm = mContext.getSystemService(StorageManager.class); 17856 final UserManager um = mContext.getSystemService(UserManager.class); 17857 for (UserInfo user : um.getUsers()) { 17858 final int flags; 17859 if (um.isUserUnlocked(user.id)) { 17860 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 17861 } else if (um.isUserRunning(user.id)) { 17862 flags = StorageManager.FLAG_STORAGE_DE; 17863 } else { 17864 continue; 17865 } 17866 17867 sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags); 17868 reconcileAppsData(volumeUuid, user.id, flags); 17869 } 17870 17871 synchronized (mPackages) { 17872 int updateFlags = UPDATE_PERMISSIONS_ALL; 17873 if (ver.sdkVersion != mSdkVersion) { 17874 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " 17875 + mSdkVersion + "; regranting permissions for " + volumeUuid); 17876 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 17877 } 17878 updatePermissionsLPw(null, null, volumeUuid, updateFlags); 17879 17880 // Yay, everything is now upgraded 17881 ver.forceCurrent(); 17882 17883 mSettings.writeLPr(); 17884 } 17885 17886 if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded); 17887 sendResourcesChangedBroadcast(true, false, loaded, null); 17888 } 17889 17890 private void unloadPrivatePackages(final VolumeInfo vol) { 17891 mHandler.post(new Runnable() { 17892 @Override 17893 public void run() { 17894 unloadPrivatePackagesInner(vol); 17895 } 17896 }); 17897 } 17898 17899 private void unloadPrivatePackagesInner(VolumeInfo vol) { 17900 final String volumeUuid = vol.fsUuid; 17901 if (TextUtils.isEmpty(volumeUuid)) { 17902 Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring"); 17903 return; 17904 } 17905 17906 final ArrayList<ApplicationInfo> unloaded = new ArrayList<>(); 17907 synchronized (mInstallLock) { 17908 synchronized (mPackages) { 17909 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid); 17910 for (PackageSetting ps : packages) { 17911 if (ps.pkg == null) continue; 17912 17913 final ApplicationInfo info = ps.pkg.applicationInfo; 17914 final PackageRemovedInfo outInfo = new PackageRemovedInfo(); 17915 if (deletePackageLI(ps.name, null, false, null, 17916 PackageManager.DELETE_KEEP_DATA, outInfo, false, null)) { 17917 unloaded.add(info); 17918 } else { 17919 Slog.w(TAG, "Failed to unload " + ps.codePath); 17920 } 17921 } 17922 17923 mSettings.writeLPr(); 17924 } 17925 } 17926 17927 if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded); 17928 sendResourcesChangedBroadcast(false, false, unloaded, null); 17929 } 17930 17931 /** 17932 * Examine all users present on given mounted volume, and destroy data 17933 * belonging to users that are no longer valid, or whose user ID has been 17934 * recycled. 17935 */ 17936 private void reconcileUsers(String volumeUuid) { 17937 // TODO: also reconcile DE directories 17938 final File[] files = FileUtils 17939 .listFilesOrEmpty(Environment.getDataUserCeDirectory(volumeUuid)); 17940 for (File file : files) { 17941 if (!file.isDirectory()) continue; 17942 17943 final int userId; 17944 final UserInfo info; 17945 try { 17946 userId = Integer.parseInt(file.getName()); 17947 info = sUserManager.getUserInfo(userId); 17948 } catch (NumberFormatException e) { 17949 Slog.w(TAG, "Invalid user directory " + file); 17950 continue; 17951 } 17952 17953 boolean destroyUser = false; 17954 if (info == null) { 17955 logCriticalInfo(Log.WARN, "Destroying user directory " + file 17956 + " because no matching user was found"); 17957 destroyUser = true; 17958 } else { 17959 try { 17960 UserManagerService.enforceSerialNumber(file, info.serialNumber); 17961 } catch (IOException e) { 17962 logCriticalInfo(Log.WARN, "Destroying user directory " + file 17963 + " because we failed to enforce serial number: " + e); 17964 destroyUser = true; 17965 } 17966 } 17967 17968 if (destroyUser) { 17969 synchronized (mInstallLock) { 17970 try { 17971 mInstaller.removeUserDataDirs(volumeUuid, userId); 17972 } catch (InstallerException e) { 17973 Slog.w(TAG, "Failed to clean up user dirs", e); 17974 } 17975 } 17976 } 17977 } 17978 } 17979 17980 private void assertPackageKnown(String volumeUuid, String packageName) 17981 throws PackageManagerException { 17982 synchronized (mPackages) { 17983 final PackageSetting ps = mSettings.mPackages.get(packageName); 17984 if (ps == null) { 17985 throw new PackageManagerException("Package " + packageName + " is unknown"); 17986 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) { 17987 throw new PackageManagerException( 17988 "Package " + packageName + " found on unknown volume " + volumeUuid 17989 + "; expected volume " + ps.volumeUuid); 17990 } 17991 } 17992 } 17993 17994 private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId) 17995 throws PackageManagerException { 17996 synchronized (mPackages) { 17997 final PackageSetting ps = mSettings.mPackages.get(packageName); 17998 if (ps == null) { 17999 throw new PackageManagerException("Package " + packageName + " is unknown"); 18000 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) { 18001 throw new PackageManagerException( 18002 "Package " + packageName + " found on unknown volume " + volumeUuid 18003 + "; expected volume " + ps.volumeUuid); 18004 } else if (!ps.getInstalled(userId)) { 18005 throw new PackageManagerException( 18006 "Package " + packageName + " not installed for user " + userId); 18007 } 18008 } 18009 } 18010 18011 /** 18012 * Examine all apps present on given mounted volume, and destroy apps that 18013 * aren't expected, either due to uninstallation or reinstallation on 18014 * another volume. 18015 */ 18016 private void reconcileApps(String volumeUuid) { 18017 final File[] files = FileUtils 18018 .listFilesOrEmpty(Environment.getDataAppDirectory(volumeUuid)); 18019 for (File file : files) { 18020 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 18021 && !PackageInstallerService.isStageName(file.getName()); 18022 if (!isPackage) { 18023 // Ignore entries which are not packages 18024 continue; 18025 } 18026 18027 try { 18028 final PackageLite pkg = PackageParser.parsePackageLite(file, 18029 PackageParser.PARSE_MUST_BE_APK); 18030 assertPackageKnown(volumeUuid, pkg.packageName); 18031 18032 } catch (PackageParserException | PackageManagerException e) { 18033 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 18034 synchronized (mInstallLock) { 18035 removeCodePathLI(file); 18036 } 18037 } 18038 } 18039 } 18040 18041 /** 18042 * Reconcile all app data for the given user. 18043 * <p> 18044 * Verifies that directories exist and that ownership and labeling is 18045 * correct for all installed apps on all mounted volumes. 18046 */ 18047 void reconcileAppsData(int userId, int flags) { 18048 final StorageManager storage = mContext.getSystemService(StorageManager.class); 18049 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 18050 final String volumeUuid = vol.getFsUuid(); 18051 reconcileAppsData(volumeUuid, userId, flags); 18052 } 18053 } 18054 18055 /** 18056 * Reconcile all app data on given mounted volume. 18057 * <p> 18058 * Destroys app data that isn't expected, either due to uninstallation or 18059 * reinstallation on another volume. 18060 * <p> 18061 * Verifies that directories exist and that ownership and labeling is 18062 * correct for all installed apps. 18063 */ 18064 private void reconcileAppsData(String volumeUuid, int userId, int flags) { 18065 Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x" 18066 + Integer.toHexString(flags)); 18067 18068 final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId); 18069 final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId); 18070 18071 boolean restoreconNeeded = false; 18072 18073 // First look for stale data that doesn't belong, and check if things 18074 // have changed since we did our last restorecon 18075 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 18076 if (!isUserKeyUnlocked(userId)) { 18077 throw new RuntimeException( 18078 "Yikes, someone asked us to reconcile CE storage while " + userId 18079 + " was still locked; this would have caused massive data loss!"); 18080 } 18081 18082 restoreconNeeded |= SELinuxMMAC.isRestoreconNeeded(ceDir); 18083 18084 final File[] files = FileUtils.listFilesOrEmpty(ceDir); 18085 for (File file : files) { 18086 final String packageName = file.getName(); 18087 try { 18088 assertPackageKnownAndInstalled(volumeUuid, packageName, userId); 18089 } catch (PackageManagerException e) { 18090 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 18091 synchronized (mInstallLock) { 18092 destroyAppDataLI(volumeUuid, packageName, userId, 18093 StorageManager.FLAG_STORAGE_CE); 18094 } 18095 } 18096 } 18097 } 18098 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) { 18099 restoreconNeeded |= SELinuxMMAC.isRestoreconNeeded(deDir); 18100 18101 final File[] files = FileUtils.listFilesOrEmpty(deDir); 18102 for (File file : files) { 18103 final String packageName = file.getName(); 18104 try { 18105 assertPackageKnownAndInstalled(volumeUuid, packageName, userId); 18106 } catch (PackageManagerException e) { 18107 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 18108 synchronized (mInstallLock) { 18109 destroyAppDataLI(volumeUuid, packageName, userId, 18110 StorageManager.FLAG_STORAGE_DE); 18111 } 18112 } 18113 } 18114 } 18115 18116 // Ensure that data directories are ready to roll for all packages 18117 // installed for this volume and user 18118 final List<PackageSetting> packages; 18119 synchronized (mPackages) { 18120 packages = mSettings.getVolumePackagesLPr(volumeUuid); 18121 } 18122 int preparedCount = 0; 18123 for (PackageSetting ps : packages) { 18124 final String packageName = ps.name; 18125 if (ps.pkg == null) { 18126 Slog.w(TAG, "Odd, missing scanned package " + packageName); 18127 // TODO: might be due to legacy ASEC apps; we should circle back 18128 // and reconcile again once they're scanned 18129 continue; 18130 } 18131 18132 if (ps.getInstalled(userId)) { 18133 prepareAppData(volumeUuid, userId, flags, ps.pkg, restoreconNeeded); 18134 18135 if (maybeMigrateAppData(volumeUuid, userId, ps.pkg)) { 18136 // We may have just shuffled around app data directories, so 18137 // prepare them one more time 18138 prepareAppData(volumeUuid, userId, flags, ps.pkg, restoreconNeeded); 18139 } 18140 18141 preparedCount++; 18142 } 18143 } 18144 18145 if (restoreconNeeded) { 18146 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 18147 SELinuxMMAC.setRestoreconDone(ceDir); 18148 } 18149 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) { 18150 SELinuxMMAC.setRestoreconDone(deDir); 18151 } 18152 } 18153 18154 Slog.v(TAG, "reconcileAppsData finished " + preparedCount 18155 + " packages; restoreconNeeded was " + restoreconNeeded); 18156 } 18157 18158 /** 18159 * Prepare app data for the given app just after it was installed or 18160 * upgraded. This method carefully only touches users that it's installed 18161 * for, and it forces a restorecon to handle any seinfo changes. 18162 * <p> 18163 * Verifies that directories exist and that ownership and labeling is 18164 * correct for all installed apps. If there is an ownership mismatch, it 18165 * will try recovering system apps by wiping data; third-party app data is 18166 * left intact. 18167 * <p> 18168 * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em> 18169 */ 18170 private void prepareAppDataAfterInstall(PackageParser.Package pkg) { 18171 prepareAppDataAfterInstallInternal(pkg); 18172 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 18173 for (int i = 0; i < childCount; i++) { 18174 PackageParser.Package childPackage = pkg.childPackages.get(i); 18175 prepareAppDataAfterInstallInternal(childPackage); 18176 } 18177 } 18178 18179 private void prepareAppDataAfterInstallInternal(PackageParser.Package pkg) { 18180 final PackageSetting ps; 18181 synchronized (mPackages) { 18182 ps = mSettings.mPackages.get(pkg.packageName); 18183 mSettings.writeKernelMappingLPr(ps); 18184 } 18185 18186 final UserManager um = mContext.getSystemService(UserManager.class); 18187 for (UserInfo user : um.getUsers()) { 18188 final int flags; 18189 if (um.isUserUnlocked(user.id)) { 18190 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 18191 } else if (um.isUserRunning(user.id)) { 18192 flags = StorageManager.FLAG_STORAGE_DE; 18193 } else { 18194 continue; 18195 } 18196 18197 if (ps.getInstalled(user.id)) { 18198 // Whenever an app changes, force a restorecon of its data 18199 // TODO: when user data is locked, mark that we're still dirty 18200 prepareAppData(pkg.volumeUuid, user.id, flags, pkg, true); 18201 } 18202 } 18203 } 18204 18205 /** 18206 * Prepare app data for the given app. 18207 * <p> 18208 * Verifies that directories exist and that ownership and labeling is 18209 * correct for all installed apps. If there is an ownership mismatch, this 18210 * will try recovering system apps by wiping data; third-party app data is 18211 * left intact. 18212 */ 18213 private void prepareAppData(String volumeUuid, int userId, int flags, 18214 PackageParser.Package pkg, boolean restoreconNeeded) { 18215 if (DEBUG_APP_DATA) { 18216 Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x" 18217 + Integer.toHexString(flags) + (restoreconNeeded ? " restoreconNeeded" : "")); 18218 } 18219 18220 final String packageName = pkg.packageName; 18221 final ApplicationInfo app = pkg.applicationInfo; 18222 final int appId = UserHandle.getAppId(app.uid); 18223 18224 Preconditions.checkNotNull(app.seinfo); 18225 18226 synchronized (mInstallLock) { 18227 try { 18228 mInstaller.createAppData(volumeUuid, packageName, userId, flags, 18229 appId, app.seinfo, app.targetSdkVersion); 18230 } catch (InstallerException e) { 18231 if (app.isSystemApp()) { 18232 logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName 18233 + ", but trying to recover: " + e); 18234 destroyAppDataLI(volumeUuid, packageName, userId, flags); 18235 try { 18236 mInstaller.createAppData(volumeUuid, packageName, userId, flags, 18237 appId, app.seinfo, app.targetSdkVersion); 18238 logCriticalInfo(Log.DEBUG, "Recovery succeeded!"); 18239 } catch (InstallerException e2) { 18240 logCriticalInfo(Log.DEBUG, "Recovery failed!"); 18241 } 18242 } else { 18243 Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e); 18244 } 18245 } 18246 18247 if (restoreconNeeded) { 18248 restoreconAppDataLI(volumeUuid, packageName, userId, flags, appId, app.seinfo); 18249 } 18250 18251 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 18252 // Create a native library symlink only if we have native libraries 18253 // and if the native libraries are 32 bit libraries. We do not provide 18254 // this symlink for 64 bit libraries. 18255 if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) { 18256 final String nativeLibPath = app.nativeLibraryDir; 18257 try { 18258 mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName, 18259 nativeLibPath, userId); 18260 } catch (InstallerException e) { 18261 Slog.e(TAG, "Failed to link native for " + packageName + ": " + e); 18262 } 18263 } 18264 } 18265 } 18266 } 18267 18268 /** 18269 * For system apps on non-FBE devices, this method migrates any existing 18270 * CE/DE data to match the {@code forceDeviceEncrypted} flag requested by 18271 * the app. 18272 */ 18273 private boolean maybeMigrateAppData(String volumeUuid, int userId, PackageParser.Package pkg) { 18274 if (pkg.isSystemApp() && !StorageManager.isFileBasedEncryptionEnabled() 18275 && PackageManager.APPLY_FORCE_DEVICE_ENCRYPTED) { 18276 final int storageTarget = pkg.applicationInfo.isForceDeviceEncrypted() 18277 ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE; 18278 synchronized (mInstallLock) { 18279 try { 18280 mInstaller.migrateAppData(volumeUuid, pkg.packageName, userId, storageTarget); 18281 } catch (InstallerException e) { 18282 logCriticalInfo(Log.WARN, 18283 "Failed to migrate " + pkg.packageName + ": " + e.getMessage()); 18284 } 18285 } 18286 return true; 18287 } else { 18288 return false; 18289 } 18290 } 18291 18292 private void unfreezePackage(String packageName) { 18293 synchronized (mPackages) { 18294 final PackageSetting ps = mSettings.mPackages.get(packageName); 18295 if (ps != null) { 18296 ps.frozen = false; 18297 } 18298 } 18299 } 18300 18301 @Override 18302 public int movePackage(final String packageName, final String volumeUuid) { 18303 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 18304 18305 final int moveId = mNextMoveId.getAndIncrement(); 18306 mHandler.post(new Runnable() { 18307 @Override 18308 public void run() { 18309 try { 18310 movePackageInternal(packageName, volumeUuid, moveId); 18311 } catch (PackageManagerException e) { 18312 Slog.w(TAG, "Failed to move " + packageName, e); 18313 mMoveCallbacks.notifyStatusChanged(moveId, 18314 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 18315 } 18316 } 18317 }); 18318 return moveId; 18319 } 18320 18321 private void movePackageInternal(final String packageName, final String volumeUuid, 18322 final int moveId) throws PackageManagerException { 18323 final UserHandle user = new UserHandle(UserHandle.getCallingUserId()); 18324 final StorageManager storage = mContext.getSystemService(StorageManager.class); 18325 final PackageManager pm = mContext.getPackageManager(); 18326 18327 final boolean currentAsec; 18328 final String currentVolumeUuid; 18329 final File codeFile; 18330 final String installerPackageName; 18331 final String packageAbiOverride; 18332 final int appId; 18333 final String seinfo; 18334 final String label; 18335 final int targetSdkVersion; 18336 18337 // reader 18338 synchronized (mPackages) { 18339 final PackageParser.Package pkg = mPackages.get(packageName); 18340 final PackageSetting ps = mSettings.mPackages.get(packageName); 18341 if (pkg == null || ps == null) { 18342 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package"); 18343 } 18344 18345 if (pkg.applicationInfo.isSystemApp()) { 18346 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE, 18347 "Cannot move system application"); 18348 } 18349 18350 if (pkg.applicationInfo.isExternalAsec()) { 18351 currentAsec = true; 18352 currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL; 18353 } else if (pkg.applicationInfo.isForwardLocked()) { 18354 currentAsec = true; 18355 currentVolumeUuid = "forward_locked"; 18356 } else { 18357 currentAsec = false; 18358 currentVolumeUuid = ps.volumeUuid; 18359 18360 final File probe = new File(pkg.codePath); 18361 final File probeOat = new File(probe, "oat"); 18362 if (!probe.isDirectory() || !probeOat.isDirectory()) { 18363 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 18364 "Move only supported for modern cluster style installs"); 18365 } 18366 } 18367 18368 if (Objects.equals(currentVolumeUuid, volumeUuid)) { 18369 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 18370 "Package already moved to " + volumeUuid); 18371 } 18372 if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) { 18373 throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN, 18374 "Device admin cannot be moved"); 18375 } 18376 18377 if (ps.frozen) { 18378 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING, 18379 "Failed to move already frozen package"); 18380 } 18381 ps.frozen = true; 18382 18383 codeFile = new File(pkg.codePath); 18384 installerPackageName = ps.installerPackageName; 18385 packageAbiOverride = ps.cpuAbiOverrideString; 18386 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 18387 seinfo = pkg.applicationInfo.seinfo; 18388 label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo)); 18389 targetSdkVersion = pkg.applicationInfo.targetSdkVersion; 18390 } 18391 18392 // Now that we're guarded by frozen state, kill app during move 18393 final long token = Binder.clearCallingIdentity(); 18394 try { 18395 killApplication(packageName, appId, "move pkg"); 18396 } finally { 18397 Binder.restoreCallingIdentity(token); 18398 } 18399 18400 final Bundle extras = new Bundle(); 18401 extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName); 18402 extras.putString(Intent.EXTRA_TITLE, label); 18403 mMoveCallbacks.notifyCreated(moveId, extras); 18404 18405 int installFlags; 18406 final boolean moveCompleteApp; 18407 final File measurePath; 18408 18409 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) { 18410 installFlags = INSTALL_INTERNAL; 18411 moveCompleteApp = !currentAsec; 18412 measurePath = Environment.getDataAppDirectory(volumeUuid); 18413 } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) { 18414 installFlags = INSTALL_EXTERNAL; 18415 moveCompleteApp = false; 18416 measurePath = storage.getPrimaryPhysicalVolume().getPath(); 18417 } else { 18418 final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid); 18419 if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE 18420 || !volume.isMountedWritable()) { 18421 unfreezePackage(packageName); 18422 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 18423 "Move location not mounted private volume"); 18424 } 18425 18426 Preconditions.checkState(!currentAsec); 18427 18428 installFlags = INSTALL_INTERNAL; 18429 moveCompleteApp = true; 18430 measurePath = Environment.getDataAppDirectory(volumeUuid); 18431 } 18432 18433 final PackageStats stats = new PackageStats(null, -1); 18434 synchronized (mInstaller) { 18435 if (!getPackageSizeInfoLI(packageName, -1, stats)) { 18436 unfreezePackage(packageName); 18437 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 18438 "Failed to measure package size"); 18439 } 18440 } 18441 18442 if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size " 18443 + stats.dataSize); 18444 18445 final long startFreeBytes = measurePath.getFreeSpace(); 18446 final long sizeBytes; 18447 if (moveCompleteApp) { 18448 sizeBytes = stats.codeSize + stats.dataSize; 18449 } else { 18450 sizeBytes = stats.codeSize; 18451 } 18452 18453 if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) { 18454 unfreezePackage(packageName); 18455 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 18456 "Not enough free space to move"); 18457 } 18458 18459 mMoveCallbacks.notifyStatusChanged(moveId, 10); 18460 18461 final CountDownLatch installedLatch = new CountDownLatch(1); 18462 final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() { 18463 @Override 18464 public void onUserActionRequired(Intent intent) throws RemoteException { 18465 throw new IllegalStateException(); 18466 } 18467 18468 @Override 18469 public void onPackageInstalled(String basePackageName, int returnCode, String msg, 18470 Bundle extras) throws RemoteException { 18471 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: " 18472 + PackageManager.installStatusToString(returnCode, msg)); 18473 18474 installedLatch.countDown(); 18475 18476 // Regardless of success or failure of the move operation, 18477 // always unfreeze the package 18478 unfreezePackage(packageName); 18479 18480 final int status = PackageManager.installStatusToPublicStatus(returnCode); 18481 switch (status) { 18482 case PackageInstaller.STATUS_SUCCESS: 18483 mMoveCallbacks.notifyStatusChanged(moveId, 18484 PackageManager.MOVE_SUCCEEDED); 18485 break; 18486 case PackageInstaller.STATUS_FAILURE_STORAGE: 18487 mMoveCallbacks.notifyStatusChanged(moveId, 18488 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE); 18489 break; 18490 default: 18491 mMoveCallbacks.notifyStatusChanged(moveId, 18492 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 18493 break; 18494 } 18495 } 18496 }; 18497 18498 final MoveInfo move; 18499 if (moveCompleteApp) { 18500 // Kick off a thread to report progress estimates 18501 new Thread() { 18502 @Override 18503 public void run() { 18504 while (true) { 18505 try { 18506 if (installedLatch.await(1, TimeUnit.SECONDS)) { 18507 break; 18508 } 18509 } catch (InterruptedException ignored) { 18510 } 18511 18512 final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace(); 18513 final int progress = 10 + (int) MathUtils.constrain( 18514 ((deltaFreeBytes * 80) / sizeBytes), 0, 80); 18515 mMoveCallbacks.notifyStatusChanged(moveId, progress); 18516 } 18517 } 18518 }.start(); 18519 18520 final String dataAppName = codeFile.getName(); 18521 move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName, 18522 dataAppName, appId, seinfo, targetSdkVersion); 18523 } else { 18524 move = null; 18525 } 18526 18527 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 18528 18529 final Message msg = mHandler.obtainMessage(INIT_COPY); 18530 final OriginInfo origin = OriginInfo.fromExistingFile(codeFile); 18531 final InstallParams params = new InstallParams(origin, move, installObserver, installFlags, 18532 installerPackageName, volumeUuid, null /*verificationInfo*/, user, 18533 packageAbiOverride, null); 18534 params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params)); 18535 msg.obj = params; 18536 18537 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage", 18538 System.identityHashCode(msg.obj)); 18539 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 18540 System.identityHashCode(msg.obj)); 18541 18542 mHandler.sendMessage(msg); 18543 } 18544 18545 @Override 18546 public int movePrimaryStorage(String volumeUuid) throws RemoteException { 18547 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 18548 18549 final int realMoveId = mNextMoveId.getAndIncrement(); 18550 final Bundle extras = new Bundle(); 18551 extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid); 18552 mMoveCallbacks.notifyCreated(realMoveId, extras); 18553 18554 final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() { 18555 @Override 18556 public void onCreated(int moveId, Bundle extras) { 18557 // Ignored 18558 } 18559 18560 @Override 18561 public void onStatusChanged(int moveId, int status, long estMillis) { 18562 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis); 18563 } 18564 }; 18565 18566 final StorageManager storage = mContext.getSystemService(StorageManager.class); 18567 storage.setPrimaryStorageUuid(volumeUuid, callback); 18568 return realMoveId; 18569 } 18570 18571 @Override 18572 public int getMoveStatus(int moveId) { 18573 mContext.enforceCallingOrSelfPermission( 18574 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 18575 return mMoveCallbacks.mLastStatus.get(moveId); 18576 } 18577 18578 @Override 18579 public void registerMoveCallback(IPackageMoveObserver callback) { 18580 mContext.enforceCallingOrSelfPermission( 18581 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 18582 mMoveCallbacks.register(callback); 18583 } 18584 18585 @Override 18586 public void unregisterMoveCallback(IPackageMoveObserver callback) { 18587 mContext.enforceCallingOrSelfPermission( 18588 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 18589 mMoveCallbacks.unregister(callback); 18590 } 18591 18592 @Override 18593 public boolean setInstallLocation(int loc) { 18594 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, 18595 null); 18596 if (getInstallLocation() == loc) { 18597 return true; 18598 } 18599 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL 18600 || loc == PackageHelper.APP_INSTALL_EXTERNAL) { 18601 android.provider.Settings.Global.putInt(mContext.getContentResolver(), 18602 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc); 18603 return true; 18604 } 18605 return false; 18606 } 18607 18608 @Override 18609 public int getInstallLocation() { 18610 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 18611 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, 18612 PackageHelper.APP_INSTALL_AUTO); 18613 } 18614 18615 /** Called by UserManagerService */ 18616 void cleanUpUser(UserManagerService userManager, int userHandle) { 18617 synchronized (mPackages) { 18618 mDirtyUsers.remove(userHandle); 18619 mUserNeedsBadging.delete(userHandle); 18620 mSettings.removeUserLPw(userHandle); 18621 mPendingBroadcasts.remove(userHandle); 18622 mEphemeralApplicationRegistry.onUserRemovedLPw(userHandle); 18623 } 18624 synchronized (mInstallLock) { 18625 final StorageManager storage = mContext.getSystemService(StorageManager.class); 18626 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 18627 final String volumeUuid = vol.getFsUuid(); 18628 if (DEBUG_INSTALL) Slog.d(TAG, "Removing user data on volume " + volumeUuid); 18629 try { 18630 mInstaller.removeUserDataDirs(volumeUuid, userHandle); 18631 } catch (InstallerException e) { 18632 Slog.w(TAG, "Failed to remove user data", e); 18633 } 18634 } 18635 synchronized (mPackages) { 18636 removeUnusedPackagesLILPw(userManager, userHandle); 18637 } 18638 } 18639 } 18640 18641 /** 18642 * We're removing userHandle and would like to remove any downloaded packages 18643 * that are no longer in use by any other user. 18644 * @param userHandle the user being removed 18645 */ 18646 private void removeUnusedPackagesLILPw(UserManagerService userManager, final int userHandle) { 18647 final boolean DEBUG_CLEAN_APKS = false; 18648 int [] users = userManager.getUserIds(); 18649 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 18650 while (psit.hasNext()) { 18651 PackageSetting ps = psit.next(); 18652 if (ps.pkg == null) { 18653 continue; 18654 } 18655 final String packageName = ps.pkg.packageName; 18656 // Skip over if system app 18657 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) { 18658 continue; 18659 } 18660 if (DEBUG_CLEAN_APKS) { 18661 Slog.i(TAG, "Checking package " + packageName); 18662 } 18663 boolean keep = shouldKeepUninstalledPackageLPr(packageName); 18664 if (keep) { 18665 if (DEBUG_CLEAN_APKS) { 18666 Slog.i(TAG, " Keeping package " + packageName + " - requested by DO"); 18667 } 18668 } else { 18669 for (int i = 0; i < users.length; i++) { 18670 if (users[i] != userHandle && ps.getInstalled(users[i])) { 18671 keep = true; 18672 if (DEBUG_CLEAN_APKS) { 18673 Slog.i(TAG, " Keeping package " + packageName + " for user " 18674 + users[i]); 18675 } 18676 break; 18677 } 18678 } 18679 } 18680 if (!keep) { 18681 if (DEBUG_CLEAN_APKS) { 18682 Slog.i(TAG, " Removing package " + packageName); 18683 } 18684 mHandler.post(new Runnable() { 18685 public void run() { 18686 deletePackageX(packageName, userHandle, 0); 18687 } //end run 18688 }); 18689 } 18690 } 18691 } 18692 18693 /** Called by UserManagerService */ 18694 void createNewUser(int userHandle) { 18695 synchronized (mInstallLock) { 18696 try { 18697 mInstaller.createUserConfig(userHandle); 18698 } catch (InstallerException e) { 18699 Slog.w(TAG, "Failed to create user config", e); 18700 } 18701 mSettings.createNewUserLI(this, mInstaller, userHandle); 18702 } 18703 synchronized (mPackages) { 18704 applyFactoryDefaultBrowserLPw(userHandle); 18705 primeDomainVerificationsLPw(userHandle); 18706 } 18707 } 18708 18709 void newUserCreated(final int userHandle) { 18710 mDefaultPermissionPolicy.grantDefaultPermissions(userHandle); 18711 // If permission review for legacy apps is required, we represent 18712 // dagerous permissions for such apps as always granted runtime 18713 // permissions to keep per user flag state whether review is needed. 18714 // Hence, if a new user is added we have to propagate dangerous 18715 // permission grants for these legacy apps. 18716 if (Build.PERMISSIONS_REVIEW_REQUIRED) { 18717 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL 18718 | UPDATE_PERMISSIONS_REPLACE_ALL); 18719 } 18720 } 18721 18722 @Override 18723 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException { 18724 mContext.enforceCallingOrSelfPermission( 18725 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 18726 "Only package verification agents can read the verifier device identity"); 18727 18728 synchronized (mPackages) { 18729 return mSettings.getVerifierDeviceIdentityLPw(); 18730 } 18731 } 18732 18733 @Override 18734 public void setPermissionEnforced(String permission, boolean enforced) { 18735 // TODO: Now that we no longer change GID for storage, this should to away. 18736 mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 18737 "setPermissionEnforced"); 18738 if (READ_EXTERNAL_STORAGE.equals(permission)) { 18739 synchronized (mPackages) { 18740 if (mSettings.mReadExternalStorageEnforced == null 18741 || mSettings.mReadExternalStorageEnforced != enforced) { 18742 mSettings.mReadExternalStorageEnforced = enforced; 18743 mSettings.writeLPr(); 18744 } 18745 } 18746 // kill any non-foreground processes so we restart them and 18747 // grant/revoke the GID. 18748 final IActivityManager am = ActivityManagerNative.getDefault(); 18749 if (am != null) { 18750 final long token = Binder.clearCallingIdentity(); 18751 try { 18752 am.killProcessesBelowForeground("setPermissionEnforcement"); 18753 } catch (RemoteException e) { 18754 } finally { 18755 Binder.restoreCallingIdentity(token); 18756 } 18757 } 18758 } else { 18759 throw new IllegalArgumentException("No selective enforcement for " + permission); 18760 } 18761 } 18762 18763 @Override 18764 @Deprecated 18765 public boolean isPermissionEnforced(String permission) { 18766 return true; 18767 } 18768 18769 @Override 18770 public boolean isStorageLow() { 18771 final long token = Binder.clearCallingIdentity(); 18772 try { 18773 final DeviceStorageMonitorInternal 18774 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 18775 if (dsm != null) { 18776 return dsm.isMemoryLow(); 18777 } else { 18778 return false; 18779 } 18780 } finally { 18781 Binder.restoreCallingIdentity(token); 18782 } 18783 } 18784 18785 @Override 18786 public IPackageInstaller getPackageInstaller() { 18787 return mInstallerService; 18788 } 18789 18790 private boolean userNeedsBadging(int userId) { 18791 int index = mUserNeedsBadging.indexOfKey(userId); 18792 if (index < 0) { 18793 final UserInfo userInfo; 18794 final long token = Binder.clearCallingIdentity(); 18795 try { 18796 userInfo = sUserManager.getUserInfo(userId); 18797 } finally { 18798 Binder.restoreCallingIdentity(token); 18799 } 18800 final boolean b; 18801 if (userInfo != null && userInfo.isManagedProfile()) { 18802 b = true; 18803 } else { 18804 b = false; 18805 } 18806 mUserNeedsBadging.put(userId, b); 18807 return b; 18808 } 18809 return mUserNeedsBadging.valueAt(index); 18810 } 18811 18812 @Override 18813 public KeySet getKeySetByAlias(String packageName, String alias) { 18814 if (packageName == null || alias == null) { 18815 return null; 18816 } 18817 synchronized(mPackages) { 18818 final PackageParser.Package pkg = mPackages.get(packageName); 18819 if (pkg == null) { 18820 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 18821 throw new IllegalArgumentException("Unknown package: " + packageName); 18822 } 18823 KeySetManagerService ksms = mSettings.mKeySetManagerService; 18824 return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias)); 18825 } 18826 } 18827 18828 @Override 18829 public KeySet getSigningKeySet(String packageName) { 18830 if (packageName == null) { 18831 return null; 18832 } 18833 synchronized(mPackages) { 18834 final PackageParser.Package pkg = mPackages.get(packageName); 18835 if (pkg == null) { 18836 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 18837 throw new IllegalArgumentException("Unknown package: " + packageName); 18838 } 18839 if (pkg.applicationInfo.uid != Binder.getCallingUid() 18840 && Process.SYSTEM_UID != Binder.getCallingUid()) { 18841 throw new SecurityException("May not access signing KeySet of other apps."); 18842 } 18843 KeySetManagerService ksms = mSettings.mKeySetManagerService; 18844 return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName)); 18845 } 18846 } 18847 18848 @Override 18849 public boolean isPackageSignedByKeySet(String packageName, KeySet ks) { 18850 if (packageName == null || ks == null) { 18851 return false; 18852 } 18853 synchronized(mPackages) { 18854 final PackageParser.Package pkg = mPackages.get(packageName); 18855 if (pkg == null) { 18856 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 18857 throw new IllegalArgumentException("Unknown package: " + packageName); 18858 } 18859 IBinder ksh = ks.getToken(); 18860 if (ksh instanceof KeySetHandle) { 18861 KeySetManagerService ksms = mSettings.mKeySetManagerService; 18862 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh); 18863 } 18864 return false; 18865 } 18866 } 18867 18868 @Override 18869 public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) { 18870 if (packageName == null || ks == null) { 18871 return false; 18872 } 18873 synchronized(mPackages) { 18874 final PackageParser.Package pkg = mPackages.get(packageName); 18875 if (pkg == null) { 18876 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 18877 throw new IllegalArgumentException("Unknown package: " + packageName); 18878 } 18879 IBinder ksh = ks.getToken(); 18880 if (ksh instanceof KeySetHandle) { 18881 KeySetManagerService ksms = mSettings.mKeySetManagerService; 18882 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh); 18883 } 18884 return false; 18885 } 18886 } 18887 18888 private void deletePackageIfUnusedLPr(final String packageName) { 18889 PackageSetting ps = mSettings.mPackages.get(packageName); 18890 if (ps == null) { 18891 return; 18892 } 18893 if (!ps.isAnyInstalled(sUserManager.getUserIds())) { 18894 // TODO Implement atomic delete if package is unused 18895 // It is currently possible that the package will be deleted even if it is installed 18896 // after this method returns. 18897 mHandler.post(new Runnable() { 18898 public void run() { 18899 deletePackageX(packageName, 0, PackageManager.DELETE_ALL_USERS); 18900 } 18901 }); 18902 } 18903 } 18904 18905 /** 18906 * Check and throw if the given before/after packages would be considered a 18907 * downgrade. 18908 */ 18909 private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after) 18910 throws PackageManagerException { 18911 if (after.versionCode < before.mVersionCode) { 18912 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 18913 "Update version code " + after.versionCode + " is older than current " 18914 + before.mVersionCode); 18915 } else if (after.versionCode == before.mVersionCode) { 18916 if (after.baseRevisionCode < before.baseRevisionCode) { 18917 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 18918 "Update base revision code " + after.baseRevisionCode 18919 + " is older than current " + before.baseRevisionCode); 18920 } 18921 18922 if (!ArrayUtils.isEmpty(after.splitNames)) { 18923 for (int i = 0; i < after.splitNames.length; i++) { 18924 final String splitName = after.splitNames[i]; 18925 final int j = ArrayUtils.indexOf(before.splitNames, splitName); 18926 if (j != -1) { 18927 if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) { 18928 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 18929 "Update split " + splitName + " revision code " 18930 + after.splitRevisionCodes[i] + " is older than current " 18931 + before.splitRevisionCodes[j]); 18932 } 18933 } 18934 } 18935 } 18936 } 18937 } 18938 18939 private static class MoveCallbacks extends Handler { 18940 private static final int MSG_CREATED = 1; 18941 private static final int MSG_STATUS_CHANGED = 2; 18942 18943 private final RemoteCallbackList<IPackageMoveObserver> 18944 mCallbacks = new RemoteCallbackList<>(); 18945 18946 private final SparseIntArray mLastStatus = new SparseIntArray(); 18947 18948 public MoveCallbacks(Looper looper) { 18949 super(looper); 18950 } 18951 18952 public void register(IPackageMoveObserver callback) { 18953 mCallbacks.register(callback); 18954 } 18955 18956 public void unregister(IPackageMoveObserver callback) { 18957 mCallbacks.unregister(callback); 18958 } 18959 18960 @Override 18961 public void handleMessage(Message msg) { 18962 final SomeArgs args = (SomeArgs) msg.obj; 18963 final int n = mCallbacks.beginBroadcast(); 18964 for (int i = 0; i < n; i++) { 18965 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i); 18966 try { 18967 invokeCallback(callback, msg.what, args); 18968 } catch (RemoteException ignored) { 18969 } 18970 } 18971 mCallbacks.finishBroadcast(); 18972 args.recycle(); 18973 } 18974 18975 private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args) 18976 throws RemoteException { 18977 switch (what) { 18978 case MSG_CREATED: { 18979 callback.onCreated(args.argi1, (Bundle) args.arg2); 18980 break; 18981 } 18982 case MSG_STATUS_CHANGED: { 18983 callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3); 18984 break; 18985 } 18986 } 18987 } 18988 18989 private void notifyCreated(int moveId, Bundle extras) { 18990 Slog.v(TAG, "Move " + moveId + " created " + extras.toString()); 18991 18992 final SomeArgs args = SomeArgs.obtain(); 18993 args.argi1 = moveId; 18994 args.arg2 = extras; 18995 obtainMessage(MSG_CREATED, args).sendToTarget(); 18996 } 18997 18998 private void notifyStatusChanged(int moveId, int status) { 18999 notifyStatusChanged(moveId, status, -1); 19000 } 19001 19002 private void notifyStatusChanged(int moveId, int status, long estMillis) { 19003 Slog.v(TAG, "Move " + moveId + " status " + status); 19004 19005 final SomeArgs args = SomeArgs.obtain(); 19006 args.argi1 = moveId; 19007 args.argi2 = status; 19008 args.arg3 = estMillis; 19009 obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget(); 19010 19011 synchronized (mLastStatus) { 19012 mLastStatus.put(moveId, status); 19013 } 19014 } 19015 } 19016 19017 private final static class OnPermissionChangeListeners extends Handler { 19018 private static final int MSG_ON_PERMISSIONS_CHANGED = 1; 19019 19020 private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners = 19021 new RemoteCallbackList<>(); 19022 19023 public OnPermissionChangeListeners(Looper looper) { 19024 super(looper); 19025 } 19026 19027 @Override 19028 public void handleMessage(Message msg) { 19029 switch (msg.what) { 19030 case MSG_ON_PERMISSIONS_CHANGED: { 19031 final int uid = msg.arg1; 19032 handleOnPermissionsChanged(uid); 19033 } break; 19034 } 19035 } 19036 19037 public void addListenerLocked(IOnPermissionsChangeListener listener) { 19038 mPermissionListeners.register(listener); 19039 19040 } 19041 19042 public void removeListenerLocked(IOnPermissionsChangeListener listener) { 19043 mPermissionListeners.unregister(listener); 19044 } 19045 19046 public void onPermissionsChanged(int uid) { 19047 if (mPermissionListeners.getRegisteredCallbackCount() > 0) { 19048 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget(); 19049 } 19050 } 19051 19052 private void handleOnPermissionsChanged(int uid) { 19053 final int count = mPermissionListeners.beginBroadcast(); 19054 try { 19055 for (int i = 0; i < count; i++) { 19056 IOnPermissionsChangeListener callback = mPermissionListeners 19057 .getBroadcastItem(i); 19058 try { 19059 callback.onPermissionsChanged(uid); 19060 } catch (RemoteException e) { 19061 Log.e(TAG, "Permission listener is dead", e); 19062 } 19063 } 19064 } finally { 19065 mPermissionListeners.finishBroadcast(); 19066 } 19067 } 19068 } 19069 19070 private class PackageManagerInternalImpl extends PackageManagerInternal { 19071 @Override 19072 public void setLocationPackagesProvider(PackagesProvider provider) { 19073 synchronized (mPackages) { 19074 mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider); 19075 } 19076 } 19077 19078 @Override 19079 public void setVoiceInteractionPackagesProvider(PackagesProvider provider) { 19080 synchronized (mPackages) { 19081 mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider); 19082 } 19083 } 19084 19085 @Override 19086 public void setSmsAppPackagesProvider(PackagesProvider provider) { 19087 synchronized (mPackages) { 19088 mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider); 19089 } 19090 } 19091 19092 @Override 19093 public void setDialerAppPackagesProvider(PackagesProvider provider) { 19094 synchronized (mPackages) { 19095 mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider); 19096 } 19097 } 19098 19099 @Override 19100 public void setSimCallManagerPackagesProvider(PackagesProvider provider) { 19101 synchronized (mPackages) { 19102 mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider); 19103 } 19104 } 19105 19106 @Override 19107 public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) { 19108 synchronized (mPackages) { 19109 mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider); 19110 } 19111 } 19112 19113 @Override 19114 public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) { 19115 synchronized (mPackages) { 19116 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr( 19117 packageName, userId); 19118 } 19119 } 19120 19121 @Override 19122 public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) { 19123 synchronized (mPackages) { 19124 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr( 19125 packageName, userId); 19126 } 19127 } 19128 19129 @Override 19130 public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) { 19131 synchronized (mPackages) { 19132 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr( 19133 packageName, userId); 19134 } 19135 } 19136 19137 @Override 19138 public void setKeepUninstalledPackages(final List<String> packageList) { 19139 Preconditions.checkNotNull(packageList); 19140 List<String> removedFromList = null; 19141 synchronized (mPackages) { 19142 if (mKeepUninstalledPackages != null) { 19143 final int packagesCount = mKeepUninstalledPackages.size(); 19144 for (int i = 0; i < packagesCount; i++) { 19145 String oldPackage = mKeepUninstalledPackages.get(i); 19146 if (packageList != null && packageList.contains(oldPackage)) { 19147 continue; 19148 } 19149 if (removedFromList == null) { 19150 removedFromList = new ArrayList<>(); 19151 } 19152 removedFromList.add(oldPackage); 19153 } 19154 } 19155 mKeepUninstalledPackages = new ArrayList<>(packageList); 19156 if (removedFromList != null) { 19157 final int removedCount = removedFromList.size(); 19158 for (int i = 0; i < removedCount; i++) { 19159 deletePackageIfUnusedLPr(removedFromList.get(i)); 19160 } 19161 } 19162 } 19163 } 19164 19165 @Override 19166 public boolean isPermissionsReviewRequired(String packageName, int userId) { 19167 synchronized (mPackages) { 19168 // If we do not support permission review, done. 19169 if (!Build.PERMISSIONS_REVIEW_REQUIRED) { 19170 return false; 19171 } 19172 19173 PackageSetting packageSetting = mSettings.mPackages.get(packageName); 19174 if (packageSetting == null) { 19175 return false; 19176 } 19177 19178 // Permission review applies only to apps not supporting the new permission model. 19179 if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) { 19180 return false; 19181 } 19182 19183 // Legacy apps have the permission and get user consent on launch. 19184 PermissionsState permissionsState = packageSetting.getPermissionsState(); 19185 return permissionsState.isPermissionReviewRequired(userId); 19186 } 19187 } 19188 19189 @Override 19190 public ApplicationInfo getApplicationInfo(String packageName, int userId) { 19191 return PackageManagerService.this.getApplicationInfo(packageName, 0 /*flags*/, userId); 19192 } 19193 } 19194 19195 @Override 19196 public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) { 19197 enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps"); 19198 synchronized (mPackages) { 19199 final long identity = Binder.clearCallingIdentity(); 19200 try { 19201 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr( 19202 packageNames, userId); 19203 } finally { 19204 Binder.restoreCallingIdentity(identity); 19205 } 19206 } 19207 } 19208 19209 private static void enforceSystemOrPhoneCaller(String tag) { 19210 int callingUid = Binder.getCallingUid(); 19211 if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) { 19212 throw new SecurityException( 19213 "Cannot call " + tag + " from UID " + callingUid); 19214 } 19215 } 19216 19217 boolean isHistoricalPackageUsageAvailable() { 19218 return mPackageUsage.isHistoricalPackageUsageAvailable(); 19219 } 19220 19221 /** 19222 * Return a <b>copy</b> of the collection of packages known to the package manager. 19223 * @return A copy of the values of mPackages. 19224 */ 19225 Collection<PackageParser.Package> getPackages() { 19226 synchronized (mPackages) { 19227 return new ArrayList<>(mPackages.values()); 19228 } 19229 } 19230} 19231