PackageManagerService.java revision c289922beed948220bc876feb5929ab4f86096e9
1/* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.pm; 18 19import static android.Manifest.permission.READ_EXTERNAL_STORAGE; 20import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE; 21import static android.Manifest.permission.WRITE_MEDIA_STORAGE; 22import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; 23import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED; 24import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED; 25import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER; 26import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; 27import static android.content.pm.PackageManager.DELETE_KEEP_DATA; 28import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 29import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED; 30import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 31import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE; 32import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 33import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED; 34import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET; 35import static android.content.pm.PackageManager.INSTALL_EXTERNAL; 36import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 37import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER; 38import static android.content.pm.PackageManager.INSTALL_FAILED_DEXOPT; 39import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE; 40import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION; 41import static android.content.pm.PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID; 42import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 43import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 44import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK; 45import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 46import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY; 47import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED; 48import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE; 49import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE; 50import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY; 51import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE; 52import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED; 53import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 54import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK; 55import static android.content.pm.PackageManager.INSTALL_INTERNAL; 56import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; 57import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 58import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK; 59import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 60import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER; 61import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 62import static android.content.pm.PackageManager.MATCH_ALL; 63import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING; 64import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE; 65import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE; 66import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS; 67import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY; 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.PackageManagerServiceCompilerMapping.getCompilerFilterForReason; 97import static com.android.server.pm.PackageManagerServiceCompilerMapping.getFullCompilerFilter; 98import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE; 99import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS; 100import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED; 101 102import android.Manifest; 103import android.annotation.NonNull; 104import android.annotation.Nullable; 105import android.app.ActivityManager; 106import android.app.ActivityManagerNative; 107import android.app.IActivityManager; 108import android.app.admin.DevicePolicyManagerInternal; 109import android.app.admin.IDevicePolicyManager; 110import android.app.admin.SecurityLog; 111import android.app.backup.IBackupManager; 112import android.app.usage.UsageStatsManager; 113import android.content.BroadcastReceiver; 114import android.content.ComponentName; 115import android.content.Context; 116import android.content.IIntentReceiver; 117import android.content.Intent; 118import android.content.IntentFilter; 119import android.content.IntentSender; 120import android.content.IntentSender.SendIntentException; 121import android.content.ServiceConnection; 122import android.content.pm.ActivityInfo; 123import android.content.pm.ApplicationInfo; 124import android.content.pm.AppsQueryHelper; 125import android.content.pm.ComponentInfo; 126import android.content.pm.EphemeralApplicationInfo; 127import android.content.pm.EphemeralResolveInfo; 128import android.content.pm.EphemeralResolveInfo.EphemeralResolveIntentInfo; 129import android.content.pm.FeatureInfo; 130import android.content.pm.IOnPermissionsChangeListener; 131import android.content.pm.IPackageDataObserver; 132import android.content.pm.IPackageDeleteObserver; 133import android.content.pm.IPackageDeleteObserver2; 134import android.content.pm.IPackageInstallObserver2; 135import android.content.pm.IPackageInstaller; 136import android.content.pm.IPackageManager; 137import android.content.pm.IPackageMoveObserver; 138import android.content.pm.IPackageStatsObserver; 139import android.content.pm.InstrumentationInfo; 140import android.content.pm.IntentFilterVerificationInfo; 141import android.content.pm.KeySet; 142import android.content.pm.PackageCleanItem; 143import android.content.pm.PackageInfo; 144import android.content.pm.PackageInfoLite; 145import android.content.pm.PackageInstaller; 146import android.content.pm.PackageManager; 147import android.content.pm.PackageManager.LegacyPackageDeleteObserver; 148import android.content.pm.PackageManagerInternal; 149import android.content.pm.PackageParser; 150import android.content.pm.PackageParser.ActivityIntentInfo; 151import android.content.pm.PackageParser.PackageLite; 152import android.content.pm.PackageParser.PackageParserException; 153import android.content.pm.PackageStats; 154import android.content.pm.PackageUserState; 155import android.content.pm.ParceledListSlice; 156import android.content.pm.PermissionGroupInfo; 157import android.content.pm.PermissionInfo; 158import android.content.pm.ProviderInfo; 159import android.content.pm.ResolveInfo; 160import android.content.pm.ServiceInfo; 161import android.content.pm.Signature; 162import android.content.pm.UserInfo; 163import android.content.pm.VerifierDeviceIdentity; 164import android.content.pm.VerifierInfo; 165import android.content.res.Resources; 166import android.graphics.Bitmap; 167import android.hardware.display.DisplayManager; 168import android.net.Uri; 169import android.os.Binder; 170import android.os.Build; 171import android.os.Bundle; 172import android.os.Debug; 173import android.os.Environment; 174import android.os.Environment.UserEnvironment; 175import android.os.FileUtils; 176import android.os.Handler; 177import android.os.IBinder; 178import android.os.Looper; 179import android.os.Message; 180import android.os.Parcel; 181import android.os.ParcelFileDescriptor; 182import android.os.Process; 183import android.os.RemoteCallbackList; 184import android.os.RemoteException; 185import android.os.ResultReceiver; 186import android.os.SELinux; 187import android.os.ServiceManager; 188import android.os.SystemClock; 189import android.os.SystemProperties; 190import android.os.Trace; 191import android.os.UserHandle; 192import android.os.UserManager; 193import android.os.storage.IMountService; 194import android.os.storage.MountServiceInternal; 195import android.os.storage.StorageEventListener; 196import android.os.storage.StorageManager; 197import android.os.storage.VolumeInfo; 198import android.os.storage.VolumeRecord; 199import android.security.KeyStore; 200import android.security.SystemKeyStore; 201import android.system.ErrnoException; 202import android.system.Os; 203import android.text.TextUtils; 204import android.text.format.DateUtils; 205import android.util.ArrayMap; 206import android.util.ArraySet; 207import android.util.AtomicFile; 208import android.util.DisplayMetrics; 209import android.util.EventLog; 210import android.util.ExceptionUtils; 211import android.util.Log; 212import android.util.LogPrinter; 213import android.util.MathUtils; 214import android.util.PrintStreamPrinter; 215import android.util.Slog; 216import android.util.SparseArray; 217import android.util.SparseBooleanArray; 218import android.util.SparseIntArray; 219import android.util.Xml; 220import android.view.Display; 221 222import com.android.internal.R; 223import com.android.internal.annotations.GuardedBy; 224import com.android.internal.app.IMediaContainerService; 225import com.android.internal.app.ResolverActivity; 226import com.android.internal.content.NativeLibraryHelper; 227import com.android.internal.content.PackageHelper; 228import com.android.internal.os.IParcelFileDescriptorFactory; 229import com.android.internal.os.InstallerConnection.InstallerException; 230import com.android.internal.os.SomeArgs; 231import com.android.internal.os.Zygote; 232import com.android.internal.util.ArrayUtils; 233import com.android.internal.util.FastPrintWriter; 234import com.android.internal.util.FastXmlSerializer; 235import com.android.internal.util.IndentingPrintWriter; 236import com.android.internal.util.Preconditions; 237import com.android.internal.util.XmlUtils; 238import com.android.server.EventLogTags; 239import com.android.server.FgThread; 240import com.android.server.IntentResolver; 241import com.android.server.LocalServices; 242import com.android.server.ServiceThread; 243import com.android.server.SystemConfig; 244import com.android.server.Watchdog; 245import com.android.server.pm.PermissionsState.PermissionState; 246import com.android.server.pm.Settings.DatabaseVersion; 247import com.android.server.pm.Settings.VersionInfo; 248import com.android.server.storage.DeviceStorageMonitorInternal; 249 250import dalvik.system.DexFile; 251import dalvik.system.VMRuntime; 252 253import libcore.io.IoUtils; 254import libcore.util.EmptyArray; 255 256import org.xmlpull.v1.XmlPullParser; 257import org.xmlpull.v1.XmlPullParserException; 258import org.xmlpull.v1.XmlSerializer; 259 260import java.io.BufferedInputStream; 261import java.io.BufferedOutputStream; 262import java.io.BufferedReader; 263import java.io.ByteArrayInputStream; 264import java.io.ByteArrayOutputStream; 265import java.io.File; 266import java.io.FileDescriptor; 267import java.io.FileNotFoundException; 268import java.io.FileOutputStream; 269import java.io.FileReader; 270import java.io.FilenameFilter; 271import java.io.IOException; 272import java.io.InputStream; 273import java.io.PrintWriter; 274import java.nio.charset.StandardCharsets; 275import java.security.MessageDigest; 276import java.security.NoSuchAlgorithmException; 277import java.security.PublicKey; 278import java.security.cert.Certificate; 279import java.security.cert.CertificateEncodingException; 280import java.security.cert.CertificateException; 281import java.text.SimpleDateFormat; 282import java.util.ArrayList; 283import java.util.Arrays; 284import java.util.Collection; 285import java.util.Collections; 286import java.util.Comparator; 287import java.util.Date; 288import java.util.HashSet; 289import java.util.Iterator; 290import java.util.List; 291import java.util.Map; 292import java.util.Objects; 293import java.util.Set; 294import java.util.concurrent.CountDownLatch; 295import java.util.concurrent.TimeUnit; 296import java.util.concurrent.atomic.AtomicBoolean; 297import java.util.concurrent.atomic.AtomicInteger; 298import java.util.concurrent.atomic.AtomicLong; 299 300/** 301 * Keep track of all those .apks everywhere. 302 * 303 * This is very central to the platform's security; please run the unit 304 * tests whenever making modifications here: 305 * 306runtest -c android.content.pm.PackageManagerTests frameworks-core 307 * 308 * {@hide} 309 */ 310public class PackageManagerService extends IPackageManager.Stub { 311 static final String TAG = "PackageManager"; 312 static final boolean DEBUG_SETTINGS = false; 313 static final boolean DEBUG_PREFERRED = false; 314 static final boolean DEBUG_UPGRADE = false; 315 static final boolean DEBUG_DOMAIN_VERIFICATION = false; 316 private static final boolean DEBUG_BACKUP = false; 317 private static final boolean DEBUG_INSTALL = false; 318 private static final boolean DEBUG_REMOVE = false; 319 private static final boolean DEBUG_BROADCASTS = false; 320 private static final boolean DEBUG_SHOW_INFO = false; 321 private static final boolean DEBUG_PACKAGE_INFO = false; 322 private static final boolean DEBUG_INTENT_MATCHING = false; 323 private static final boolean DEBUG_PACKAGE_SCANNING = false; 324 private static final boolean DEBUG_VERIFY = false; 325 private static final boolean DEBUG_FILTERS = false; 326 327 // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService 328 // and PackageDexOptimizer. All these classes have their own flag to allow switching a single 329 // user, but by default initialize to this. 330 static final boolean DEBUG_DEXOPT = false; 331 332 private static final boolean DEBUG_ABI_SELECTION = false; 333 private static final boolean DEBUG_EPHEMERAL = false; 334 private static final boolean DEBUG_TRIAGED_MISSING = false; 335 private static final boolean DEBUG_APP_DATA = false; 336 337 static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false; 338 339 private static final boolean DISABLE_EPHEMERAL_APPS = true; 340 341 private static final int RADIO_UID = Process.PHONE_UID; 342 private static final int LOG_UID = Process.LOG_UID; 343 private static final int NFC_UID = Process.NFC_UID; 344 private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID; 345 private static final int SHELL_UID = Process.SHELL_UID; 346 347 // Cap the size of permission trees that 3rd party apps can define 348 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768; // characters of text 349 350 // Suffix used during package installation when copying/moving 351 // package apks to install directory. 352 private static final String INSTALL_PACKAGE_SUFFIX = "-"; 353 354 static final int SCAN_NO_DEX = 1<<1; 355 static final int SCAN_FORCE_DEX = 1<<2; 356 static final int SCAN_UPDATE_SIGNATURE = 1<<3; 357 static final int SCAN_NEW_INSTALL = 1<<4; 358 static final int SCAN_NO_PATHS = 1<<5; 359 static final int SCAN_UPDATE_TIME = 1<<6; 360 static final int SCAN_DEFER_DEX = 1<<7; 361 static final int SCAN_BOOTING = 1<<8; 362 static final int SCAN_TRUSTED_OVERLAY = 1<<9; 363 static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10; 364 static final int SCAN_REPLACING = 1<<11; 365 static final int SCAN_REQUIRE_KNOWN = 1<<12; 366 static final int SCAN_MOVE = 1<<13; 367 static final int SCAN_INITIAL = 1<<14; 368 static final int SCAN_CHECK_ONLY = 1<<15; 369 static final int SCAN_DONT_KILL_APP = 1<<17; 370 371 static final int REMOVE_CHATTY = 1<<16; 372 373 private static final int[] EMPTY_INT_ARRAY = new int[0]; 374 375 /** 376 * Timeout (in milliseconds) after which the watchdog should declare that 377 * our handler thread is wedged. The usual default for such things is one 378 * minute but we sometimes do very lengthy I/O operations on this thread, 379 * such as installing multi-gigabyte applications, so ours needs to be longer. 380 */ 381 private static final long WATCHDOG_TIMEOUT = 1000*60*10; // ten minutes 382 383 /** 384 * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim 385 * be run on this device. We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL 386 * settings entry if available, otherwise we use the hardcoded default. If it's been 387 * more than this long since the last fstrim, we force one during the boot sequence. 388 * 389 * This backstops other fstrim scheduling: if the device is alive at midnight+idle, 390 * one gets run at the next available charging+idle time. This final mandatory 391 * no-fstrim check kicks in only of the other scheduling criteria is never met. 392 */ 393 private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS; 394 395 /** 396 * Whether verification is enabled by default. 397 */ 398 private static final boolean DEFAULT_VERIFY_ENABLE = true; 399 400 /** 401 * The default maximum time to wait for the verification agent to return in 402 * milliseconds. 403 */ 404 private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000; 405 406 /** 407 * The default response for package verification timeout. 408 * 409 * This can be either PackageManager.VERIFICATION_ALLOW or 410 * PackageManager.VERIFICATION_REJECT. 411 */ 412 private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW; 413 414 static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer"; 415 416 static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName( 417 DEFAULT_CONTAINER_PACKAGE, 418 "com.android.defcontainer.DefaultContainerService"); 419 420 private static final String KILL_APP_REASON_GIDS_CHANGED = 421 "permission grant or revoke changed gids"; 422 423 private static final String KILL_APP_REASON_PERMISSIONS_REVOKED = 424 "permissions revoked"; 425 426 private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive"; 427 428 private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay"; 429 430 /** Permission grant: not grant the permission. */ 431 private static final int GRANT_DENIED = 1; 432 433 /** Permission grant: grant the permission as an install permission. */ 434 private static final int GRANT_INSTALL = 2; 435 436 /** Permission grant: grant the permission as a runtime one. */ 437 private static final int GRANT_RUNTIME = 3; 438 439 /** Permission grant: grant as runtime a permission that was granted as an install time one. */ 440 private static final int GRANT_UPGRADE = 4; 441 442 /** Canonical intent used to identify what counts as a "web browser" app */ 443 private static final Intent sBrowserIntent; 444 static { 445 sBrowserIntent = new Intent(); 446 sBrowserIntent.setAction(Intent.ACTION_VIEW); 447 sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE); 448 sBrowserIntent.setData(Uri.parse("http:")); 449 } 450 451 /** 452 * The set of all protected actions [i.e. those actions for which a high priority 453 * intent filter is disallowed]. 454 */ 455 private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>(); 456 static { 457 PROTECTED_ACTIONS.add(Intent.ACTION_SEND); 458 PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO); 459 PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE); 460 PROTECTED_ACTIONS.add(Intent.ACTION_VIEW); 461 } 462 463 // Compilation reasons. 464 public static final int REASON_FIRST_BOOT = 0; 465 public static final int REASON_BOOT = 1; 466 public static final int REASON_INSTALL = 2; 467 public static final int REASON_BACKGROUND_DEXOPT = 3; 468 public static final int REASON_AB_OTA = 4; 469 public static final int REASON_NON_SYSTEM_LIBRARY = 5; 470 public static final int REASON_SHARED_APK = 6; 471 public static final int REASON_FORCED_DEXOPT = 7; 472 473 public static final int REASON_LAST = REASON_FORCED_DEXOPT; 474 475 final ServiceThread mHandlerThread; 476 477 final PackageHandler mHandler; 478 479 private final ProcessLoggingHandler mProcessLoggingHandler; 480 481 /** 482 * Messages for {@link #mHandler} that need to wait for system ready before 483 * being dispatched. 484 */ 485 private ArrayList<Message> mPostSystemReadyMessages; 486 487 final int mSdkVersion = Build.VERSION.SDK_INT; 488 489 final Context mContext; 490 final boolean mFactoryTest; 491 final boolean mOnlyCore; 492 final DisplayMetrics mMetrics; 493 final int mDefParseFlags; 494 final String[] mSeparateProcesses; 495 final boolean mIsUpgrade; 496 final boolean mIsPreNUpgrade; 497 498 /** The location for ASEC container files on internal storage. */ 499 final String mAsecInternalPath; 500 501 // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages 502 // LOCK HELD. Can be called with mInstallLock held. 503 @GuardedBy("mInstallLock") 504 final Installer mInstaller; 505 506 /** Directory where installed third-party apps stored */ 507 final File mAppInstallDir; 508 final File mEphemeralInstallDir; 509 510 /** 511 * Directory to which applications installed internally have their 512 * 32 bit native libraries copied. 513 */ 514 private File mAppLib32InstallDir; 515 516 // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked 517 // apps. 518 final File mDrmAppPrivateInstallDir; 519 520 // ---------------------------------------------------------------- 521 522 // Lock for state used when installing and doing other long running 523 // operations. Methods that must be called with this lock held have 524 // the suffix "LI". 525 final Object mInstallLock = new Object(); 526 527 // ---------------------------------------------------------------- 528 529 // Keys are String (package name), values are Package. This also serves 530 // as the lock for the global state. Methods that must be called with 531 // this lock held have the prefix "LP". 532 @GuardedBy("mPackages") 533 final ArrayMap<String, PackageParser.Package> mPackages = 534 new ArrayMap<String, PackageParser.Package>(); 535 536 final ArrayMap<String, Set<String>> mKnownCodebase = 537 new ArrayMap<String, Set<String>>(); 538 539 // Tracks available target package names -> overlay package paths. 540 final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays = 541 new ArrayMap<String, ArrayMap<String, PackageParser.Package>>(); 542 543 /** 544 * Tracks new system packages [received in an OTA] that we expect to 545 * find updated user-installed versions. Keys are package name, values 546 * are package location. 547 */ 548 final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>(); 549 /** 550 * Tracks high priority intent filters for protected actions. During boot, certain 551 * filter actions are protected and should never be allowed to have a high priority 552 * intent filter for them. However, there is one, and only one exception -- the 553 * setup wizard. It must be able to define a high priority intent filter for these 554 * actions to ensure there are no escapes from the wizard. We need to delay processing 555 * of these during boot as we need to look at all of the system packages in order 556 * to know which component is the setup wizard. 557 */ 558 private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>(); 559 /** 560 * Whether or not processing protected filters should be deferred. 561 */ 562 private boolean mDeferProtectedFilters = true; 563 564 /** 565 * Tracks existing system packages prior to receiving an OTA. Keys are package name. 566 */ 567 final private ArraySet<String> mExistingSystemPackages = new ArraySet<>(); 568 /** 569 * Whether or not system app permissions should be promoted from install to runtime. 570 */ 571 boolean mPromoteSystemApps; 572 573 final Settings mSettings; 574 boolean mRestoredSettings; 575 576 // System configuration read by SystemConfig. 577 final int[] mGlobalGids; 578 final SparseArray<ArraySet<String>> mSystemPermissions; 579 final ArrayMap<String, FeatureInfo> mAvailableFeatures; 580 581 // If mac_permissions.xml was found for seinfo labeling. 582 boolean mFoundPolicyFile; 583 584 private final EphemeralApplicationRegistry mEphemeralApplicationRegistry; 585 586 public static final class SharedLibraryEntry { 587 public final String path; 588 public final String apk; 589 590 SharedLibraryEntry(String _path, String _apk) { 591 path = _path; 592 apk = _apk; 593 } 594 } 595 596 // Currently known shared libraries. 597 final ArrayMap<String, SharedLibraryEntry> mSharedLibraries = 598 new ArrayMap<String, SharedLibraryEntry>(); 599 600 // All available activities, for your resolving pleasure. 601 final ActivityIntentResolver mActivities = 602 new ActivityIntentResolver(); 603 604 // All available receivers, for your resolving pleasure. 605 final ActivityIntentResolver mReceivers = 606 new ActivityIntentResolver(); 607 608 // All available services, for your resolving pleasure. 609 final ServiceIntentResolver mServices = new ServiceIntentResolver(); 610 611 // All available providers, for your resolving pleasure. 612 final ProviderIntentResolver mProviders = new ProviderIntentResolver(); 613 614 // Mapping from provider base names (first directory in content URI codePath) 615 // to the provider information. 616 final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority = 617 new ArrayMap<String, PackageParser.Provider>(); 618 619 // Mapping from instrumentation class names to info about them. 620 final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation = 621 new ArrayMap<ComponentName, PackageParser.Instrumentation>(); 622 623 // Mapping from permission names to info about them. 624 final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups = 625 new ArrayMap<String, PackageParser.PermissionGroup>(); 626 627 // Packages whose data we have transfered into another package, thus 628 // should no longer exist. 629 final ArraySet<String> mTransferedPackages = new ArraySet<String>(); 630 631 // Broadcast actions that are only available to the system. 632 final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>(); 633 634 /** List of packages waiting for verification. */ 635 final SparseArray<PackageVerificationState> mPendingVerification 636 = new SparseArray<PackageVerificationState>(); 637 638 /** Set of packages associated with each app op permission. */ 639 final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>(); 640 641 final PackageInstallerService mInstallerService; 642 643 private final PackageDexOptimizer mPackageDexOptimizer; 644 645 private AtomicInteger mNextMoveId = new AtomicInteger(); 646 private final MoveCallbacks mMoveCallbacks; 647 648 private final OnPermissionChangeListeners mOnPermissionChangeListeners; 649 650 // Cache of users who need badging. 651 SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray(); 652 653 /** Token for keys in mPendingVerification. */ 654 private int mPendingVerificationToken = 0; 655 656 volatile boolean mSystemReady; 657 volatile boolean mSafeMode; 658 volatile boolean mHasSystemUidErrors; 659 660 ApplicationInfo mAndroidApplication; 661 final ActivityInfo mResolveActivity = new ActivityInfo(); 662 final ResolveInfo mResolveInfo = new ResolveInfo(); 663 ComponentName mResolveComponentName; 664 PackageParser.Package mPlatformPackage; 665 ComponentName mCustomResolverComponentName; 666 667 boolean mResolverReplaced = false; 668 669 private final @Nullable ComponentName mIntentFilterVerifierComponent; 670 private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier; 671 672 private int mIntentFilterVerificationToken = 0; 673 674 /** Component that knows whether or not an ephemeral application exists */ 675 final ComponentName mEphemeralResolverComponent; 676 /** The service connection to the ephemeral resolver */ 677 final EphemeralResolverConnection mEphemeralResolverConnection; 678 679 /** Component used to install ephemeral applications */ 680 final ComponentName mEphemeralInstallerComponent; 681 final ActivityInfo mEphemeralInstallerActivity = new ActivityInfo(); 682 final ResolveInfo mEphemeralInstallerInfo = new ResolveInfo(); 683 684 final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates 685 = new SparseArray<IntentFilterVerificationState>(); 686 687 final DefaultPermissionGrantPolicy mDefaultPermissionPolicy = 688 new DefaultPermissionGrantPolicy(this); 689 690 // List of packages names to keep cached, even if they are uninstalled for all users 691 private List<String> mKeepUninstalledPackages; 692 693 private static class IFVerificationParams { 694 PackageParser.Package pkg; 695 boolean replacing; 696 int userId; 697 int verifierUid; 698 699 public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing, 700 int _userId, int _verifierUid) { 701 pkg = _pkg; 702 replacing = _replacing; 703 userId = _userId; 704 replacing = _replacing; 705 verifierUid = _verifierUid; 706 } 707 } 708 709 private interface IntentFilterVerifier<T extends IntentFilter> { 710 boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId, 711 T filter, String packageName); 712 void startVerifications(int userId); 713 void receiveVerificationResponse(int verificationId); 714 } 715 716 private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> { 717 private Context mContext; 718 private ComponentName mIntentFilterVerifierComponent; 719 private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>(); 720 721 public IntentVerifierProxy(Context context, ComponentName verifierComponent) { 722 mContext = context; 723 mIntentFilterVerifierComponent = verifierComponent; 724 } 725 726 private String getDefaultScheme() { 727 return IntentFilter.SCHEME_HTTPS; 728 } 729 730 @Override 731 public void startVerifications(int userId) { 732 // Launch verifications requests 733 int count = mCurrentIntentFilterVerifications.size(); 734 for (int n=0; n<count; n++) { 735 int verificationId = mCurrentIntentFilterVerifications.get(n); 736 final IntentFilterVerificationState ivs = 737 mIntentFilterVerificationStates.get(verificationId); 738 739 String packageName = ivs.getPackageName(); 740 741 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 742 final int filterCount = filters.size(); 743 ArraySet<String> domainsSet = new ArraySet<>(); 744 for (int m=0; m<filterCount; m++) { 745 PackageParser.ActivityIntentInfo filter = filters.get(m); 746 domainsSet.addAll(filter.getHostsList()); 747 } 748 ArrayList<String> domainsList = new ArrayList<>(domainsSet); 749 synchronized (mPackages) { 750 if (mSettings.createIntentFilterVerificationIfNeededLPw( 751 packageName, domainsList) != null) { 752 scheduleWriteSettingsLocked(); 753 } 754 } 755 sendVerificationRequest(userId, verificationId, ivs); 756 } 757 mCurrentIntentFilterVerifications.clear(); 758 } 759 760 private void sendVerificationRequest(int userId, int verificationId, 761 IntentFilterVerificationState ivs) { 762 763 Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 764 verificationIntent.putExtra( 765 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID, 766 verificationId); 767 verificationIntent.putExtra( 768 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME, 769 getDefaultScheme()); 770 verificationIntent.putExtra( 771 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS, 772 ivs.getHostsString()); 773 verificationIntent.putExtra( 774 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME, 775 ivs.getPackageName()); 776 verificationIntent.setComponent(mIntentFilterVerifierComponent); 777 verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 778 779 UserHandle user = new UserHandle(userId); 780 mContext.sendBroadcastAsUser(verificationIntent, user); 781 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 782 "Sending IntentFilter verification broadcast"); 783 } 784 785 public void receiveVerificationResponse(int verificationId) { 786 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 787 788 final boolean verified = ivs.isVerified(); 789 790 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 791 final int count = filters.size(); 792 if (DEBUG_DOMAIN_VERIFICATION) { 793 Slog.i(TAG, "Received verification response " + verificationId 794 + " for " + count + " filters, verified=" + verified); 795 } 796 for (int n=0; n<count; n++) { 797 PackageParser.ActivityIntentInfo filter = filters.get(n); 798 filter.setVerified(verified); 799 800 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString() 801 + " verified with result:" + verified + " and hosts:" 802 + ivs.getHostsString()); 803 } 804 805 mIntentFilterVerificationStates.remove(verificationId); 806 807 final String packageName = ivs.getPackageName(); 808 IntentFilterVerificationInfo ivi = null; 809 810 synchronized (mPackages) { 811 ivi = mSettings.getIntentFilterVerificationLPr(packageName); 812 } 813 if (ivi == null) { 814 Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:" 815 + verificationId + " packageName:" + packageName); 816 return; 817 } 818 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 819 "Updating IntentFilterVerificationInfo for package " + packageName 820 +" verificationId:" + verificationId); 821 822 synchronized (mPackages) { 823 if (verified) { 824 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS); 825 } else { 826 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK); 827 } 828 scheduleWriteSettingsLocked(); 829 830 final int userId = ivs.getUserId(); 831 if (userId != UserHandle.USER_ALL) { 832 final int userStatus = 833 mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 834 835 int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 836 boolean needUpdate = false; 837 838 // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have 839 // already been set by the User thru the Disambiguation dialog 840 switch (userStatus) { 841 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 842 if (verified) { 843 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 844 } else { 845 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 846 } 847 needUpdate = true; 848 break; 849 850 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 851 if (verified) { 852 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 853 needUpdate = true; 854 } 855 break; 856 857 default: 858 // Nothing to do 859 } 860 861 if (needUpdate) { 862 mSettings.updateIntentFilterVerificationStatusLPw( 863 packageName, updatedStatus, userId); 864 scheduleWritePackageRestrictionsLocked(userId); 865 } 866 } 867 } 868 } 869 870 @Override 871 public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId, 872 ActivityIntentInfo filter, String packageName) { 873 if (!hasValidDomains(filter)) { 874 return false; 875 } 876 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 877 if (ivs == null) { 878 ivs = createDomainVerificationState(verifierUid, userId, verificationId, 879 packageName); 880 } 881 if (DEBUG_DOMAIN_VERIFICATION) { 882 Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter); 883 } 884 ivs.addFilter(filter); 885 return true; 886 } 887 888 private IntentFilterVerificationState createDomainVerificationState(int verifierUid, 889 int userId, int verificationId, String packageName) { 890 IntentFilterVerificationState ivs = new IntentFilterVerificationState( 891 verifierUid, userId, packageName); 892 ivs.setPendingState(); 893 synchronized (mPackages) { 894 mIntentFilterVerificationStates.append(verificationId, ivs); 895 mCurrentIntentFilterVerifications.add(verificationId); 896 } 897 return ivs; 898 } 899 } 900 901 private static boolean hasValidDomains(ActivityIntentInfo filter) { 902 return filter.hasCategory(Intent.CATEGORY_BROWSABLE) 903 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 904 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS)); 905 } 906 907 // Set of pending broadcasts for aggregating enable/disable of components. 908 static class PendingPackageBroadcasts { 909 // for each user id, a map of <package name -> components within that package> 910 final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap; 911 912 public PendingPackageBroadcasts() { 913 mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2); 914 } 915 916 public ArrayList<String> get(int userId, String packageName) { 917 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 918 return packages.get(packageName); 919 } 920 921 public void put(int userId, String packageName, ArrayList<String> components) { 922 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 923 packages.put(packageName, components); 924 } 925 926 public void remove(int userId, String packageName) { 927 ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId); 928 if (packages != null) { 929 packages.remove(packageName); 930 } 931 } 932 933 public void remove(int userId) { 934 mUidMap.remove(userId); 935 } 936 937 public int userIdCount() { 938 return mUidMap.size(); 939 } 940 941 public int userIdAt(int n) { 942 return mUidMap.keyAt(n); 943 } 944 945 public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) { 946 return mUidMap.get(userId); 947 } 948 949 public int size() { 950 // total number of pending broadcast entries across all userIds 951 int num = 0; 952 for (int i = 0; i< mUidMap.size(); i++) { 953 num += mUidMap.valueAt(i).size(); 954 } 955 return num; 956 } 957 958 public void clear() { 959 mUidMap.clear(); 960 } 961 962 private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) { 963 ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId); 964 if (map == null) { 965 map = new ArrayMap<String, ArrayList<String>>(); 966 mUidMap.put(userId, map); 967 } 968 return map; 969 } 970 } 971 final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts(); 972 973 // Service Connection to remote media container service to copy 974 // package uri's from external media onto secure containers 975 // or internal storage. 976 private IMediaContainerService mContainerService = null; 977 978 static final int SEND_PENDING_BROADCAST = 1; 979 static final int MCS_BOUND = 3; 980 static final int END_COPY = 4; 981 static final int INIT_COPY = 5; 982 static final int MCS_UNBIND = 6; 983 static final int START_CLEANING_PACKAGE = 7; 984 static final int FIND_INSTALL_LOC = 8; 985 static final int POST_INSTALL = 9; 986 static final int MCS_RECONNECT = 10; 987 static final int MCS_GIVE_UP = 11; 988 static final int UPDATED_MEDIA_STATUS = 12; 989 static final int WRITE_SETTINGS = 13; 990 static final int WRITE_PACKAGE_RESTRICTIONS = 14; 991 static final int PACKAGE_VERIFIED = 15; 992 static final int CHECK_PENDING_VERIFICATION = 16; 993 static final int START_INTENT_FILTER_VERIFICATIONS = 17; 994 static final int INTENT_FILTER_VERIFIED = 18; 995 996 static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds 997 998 // Delay time in millisecs 999 static final int BROADCAST_DELAY = 10 * 1000; 1000 1001 static UserManagerService sUserManager; 1002 1003 // Stores a list of users whose package restrictions file needs to be updated 1004 private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>(); 1005 1006 final private DefaultContainerConnection mDefContainerConn = 1007 new DefaultContainerConnection(); 1008 class DefaultContainerConnection implements ServiceConnection { 1009 public void onServiceConnected(ComponentName name, IBinder service) { 1010 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected"); 1011 IMediaContainerService imcs = 1012 IMediaContainerService.Stub.asInterface(service); 1013 mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs)); 1014 } 1015 1016 public void onServiceDisconnected(ComponentName name) { 1017 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected"); 1018 } 1019 } 1020 1021 // Recordkeeping of restore-after-install operations that are currently in flight 1022 // between the Package Manager and the Backup Manager 1023 static class PostInstallData { 1024 public InstallArgs args; 1025 public PackageInstalledInfo res; 1026 1027 PostInstallData(InstallArgs _a, PackageInstalledInfo _r) { 1028 args = _a; 1029 res = _r; 1030 } 1031 } 1032 1033 final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>(); 1034 int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows 1035 1036 // XML tags for backup/restore of various bits of state 1037 private static final String TAG_PREFERRED_BACKUP = "pa"; 1038 private static final String TAG_DEFAULT_APPS = "da"; 1039 private static final String TAG_INTENT_FILTER_VERIFICATION = "iv"; 1040 1041 private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup"; 1042 private static final String TAG_ALL_GRANTS = "rt-grants"; 1043 private static final String TAG_GRANT = "grant"; 1044 private static final String ATTR_PACKAGE_NAME = "pkg"; 1045 1046 private static final String TAG_PERMISSION = "perm"; 1047 private static final String ATTR_PERMISSION_NAME = "name"; 1048 private static final String ATTR_IS_GRANTED = "g"; 1049 private static final String ATTR_USER_SET = "set"; 1050 private static final String ATTR_USER_FIXED = "fixed"; 1051 private static final String ATTR_REVOKE_ON_UPGRADE = "rou"; 1052 1053 // System/policy permission grants are not backed up 1054 private static final int SYSTEM_RUNTIME_GRANT_MASK = 1055 FLAG_PERMISSION_POLICY_FIXED 1056 | FLAG_PERMISSION_SYSTEM_FIXED 1057 | FLAG_PERMISSION_GRANTED_BY_DEFAULT; 1058 1059 // And we back up these user-adjusted states 1060 private static final int USER_RUNTIME_GRANT_MASK = 1061 FLAG_PERMISSION_USER_SET 1062 | FLAG_PERMISSION_USER_FIXED 1063 | FLAG_PERMISSION_REVOKE_ON_UPGRADE; 1064 1065 final @Nullable String mRequiredVerifierPackage; 1066 final @NonNull String mRequiredInstallerPackage; 1067 final @Nullable String mSetupWizardPackage; 1068 final @NonNull String mServicesSystemSharedLibraryPackageName; 1069 1070 private final PackageUsage mPackageUsage = new PackageUsage(); 1071 1072 private class PackageUsage { 1073 private static final int WRITE_INTERVAL 1074 = (DEBUG_DEXOPT) ? 0 : 30*60*1000; // 30m in ms 1075 1076 private final Object mFileLock = new Object(); 1077 private final AtomicLong mLastWritten = new AtomicLong(0); 1078 private final AtomicBoolean mBackgroundWriteRunning = new AtomicBoolean(false); 1079 1080 private boolean mIsHistoricalPackageUsageAvailable = true; 1081 1082 boolean isHistoricalPackageUsageAvailable() { 1083 return mIsHistoricalPackageUsageAvailable; 1084 } 1085 1086 void write(boolean force) { 1087 if (force) { 1088 writeInternal(); 1089 return; 1090 } 1091 if (SystemClock.elapsedRealtime() - mLastWritten.get() < WRITE_INTERVAL 1092 && !DEBUG_DEXOPT) { 1093 return; 1094 } 1095 if (mBackgroundWriteRunning.compareAndSet(false, true)) { 1096 new Thread("PackageUsage_DiskWriter") { 1097 @Override 1098 public void run() { 1099 try { 1100 writeInternal(); 1101 } finally { 1102 mBackgroundWriteRunning.set(false); 1103 } 1104 } 1105 }.start(); 1106 } 1107 } 1108 1109 private void writeInternal() { 1110 synchronized (mPackages) { 1111 synchronized (mFileLock) { 1112 AtomicFile file = getFile(); 1113 FileOutputStream f = null; 1114 try { 1115 f = file.startWrite(); 1116 BufferedOutputStream out = new BufferedOutputStream(f); 1117 FileUtils.setPermissions(file.getBaseFile().getPath(), 0640, SYSTEM_UID, PACKAGE_INFO_GID); 1118 StringBuilder sb = new StringBuilder(); 1119 for (PackageParser.Package pkg : mPackages.values()) { 1120 if (pkg.mLastPackageUsageTimeInMills == 0) { 1121 continue; 1122 } 1123 sb.setLength(0); 1124 sb.append(pkg.packageName); 1125 sb.append(' '); 1126 sb.append((long)pkg.mLastPackageUsageTimeInMills); 1127 sb.append('\n'); 1128 out.write(sb.toString().getBytes(StandardCharsets.US_ASCII)); 1129 } 1130 out.flush(); 1131 file.finishWrite(f); 1132 } catch (IOException e) { 1133 if (f != null) { 1134 file.failWrite(f); 1135 } 1136 Log.e(TAG, "Failed to write package usage times", e); 1137 } 1138 } 1139 } 1140 mLastWritten.set(SystemClock.elapsedRealtime()); 1141 } 1142 1143 void readLP() { 1144 synchronized (mFileLock) { 1145 AtomicFile file = getFile(); 1146 BufferedInputStream in = null; 1147 try { 1148 in = new BufferedInputStream(file.openRead()); 1149 StringBuffer sb = new StringBuffer(); 1150 while (true) { 1151 String packageName = readToken(in, sb, ' '); 1152 if (packageName == null) { 1153 break; 1154 } 1155 String timeInMillisString = readToken(in, sb, '\n'); 1156 if (timeInMillisString == null) { 1157 throw new IOException("Failed to find last usage time for package " 1158 + packageName); 1159 } 1160 PackageParser.Package pkg = mPackages.get(packageName); 1161 if (pkg == null) { 1162 continue; 1163 } 1164 long timeInMillis; 1165 try { 1166 timeInMillis = Long.parseLong(timeInMillisString); 1167 } catch (NumberFormatException e) { 1168 throw new IOException("Failed to parse " + timeInMillisString 1169 + " as a long.", e); 1170 } 1171 pkg.mLastPackageUsageTimeInMills = timeInMillis; 1172 } 1173 } catch (FileNotFoundException expected) { 1174 mIsHistoricalPackageUsageAvailable = false; 1175 } catch (IOException e) { 1176 Log.w(TAG, "Failed to read package usage times", e); 1177 } finally { 1178 IoUtils.closeQuietly(in); 1179 } 1180 } 1181 mLastWritten.set(SystemClock.elapsedRealtime()); 1182 } 1183 1184 private String readToken(InputStream in, StringBuffer sb, char endOfToken) 1185 throws IOException { 1186 sb.setLength(0); 1187 while (true) { 1188 int ch = in.read(); 1189 if (ch == -1) { 1190 if (sb.length() == 0) { 1191 return null; 1192 } 1193 throw new IOException("Unexpected EOF"); 1194 } 1195 if (ch == endOfToken) { 1196 return sb.toString(); 1197 } 1198 sb.append((char)ch); 1199 } 1200 } 1201 1202 private AtomicFile getFile() { 1203 File dataDir = Environment.getDataDirectory(); 1204 File systemDir = new File(dataDir, "system"); 1205 File fname = new File(systemDir, "package-usage.list"); 1206 return new AtomicFile(fname); 1207 } 1208 } 1209 1210 class PackageHandler extends Handler { 1211 private boolean mBound = false; 1212 final ArrayList<HandlerParams> mPendingInstalls = 1213 new ArrayList<HandlerParams>(); 1214 1215 private boolean connectToService() { 1216 if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" + 1217 " DefaultContainerService"); 1218 Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 1219 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1220 if (mContext.bindServiceAsUser(service, mDefContainerConn, 1221 Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) { 1222 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1223 mBound = true; 1224 return true; 1225 } 1226 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1227 return false; 1228 } 1229 1230 private void disconnectService() { 1231 mContainerService = null; 1232 mBound = false; 1233 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1234 mContext.unbindService(mDefContainerConn); 1235 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1236 } 1237 1238 PackageHandler(Looper looper) { 1239 super(looper); 1240 } 1241 1242 public void handleMessage(Message msg) { 1243 try { 1244 doHandleMessage(msg); 1245 } finally { 1246 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1247 } 1248 } 1249 1250 void doHandleMessage(Message msg) { 1251 switch (msg.what) { 1252 case INIT_COPY: { 1253 HandlerParams params = (HandlerParams) msg.obj; 1254 int idx = mPendingInstalls.size(); 1255 if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params); 1256 // If a bind was already initiated we dont really 1257 // need to do anything. The pending install 1258 // will be processed later on. 1259 if (!mBound) { 1260 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1261 System.identityHashCode(mHandler)); 1262 // If this is the only one pending we might 1263 // have to bind to the service again. 1264 if (!connectToService()) { 1265 Slog.e(TAG, "Failed to bind to media container service"); 1266 params.serviceError(); 1267 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1268 System.identityHashCode(mHandler)); 1269 if (params.traceMethod != null) { 1270 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod, 1271 params.traceCookie); 1272 } 1273 return; 1274 } else { 1275 // Once we bind to the service, the first 1276 // pending request will be processed. 1277 mPendingInstalls.add(idx, params); 1278 } 1279 } else { 1280 mPendingInstalls.add(idx, params); 1281 // Already bound to the service. Just make 1282 // sure we trigger off processing the first request. 1283 if (idx == 0) { 1284 mHandler.sendEmptyMessage(MCS_BOUND); 1285 } 1286 } 1287 break; 1288 } 1289 case MCS_BOUND: { 1290 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound"); 1291 if (msg.obj != null) { 1292 mContainerService = (IMediaContainerService) msg.obj; 1293 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1294 System.identityHashCode(mHandler)); 1295 } 1296 if (mContainerService == null) { 1297 if (!mBound) { 1298 // Something seriously wrong since we are not bound and we are not 1299 // waiting for connection. Bail out. 1300 Slog.e(TAG, "Cannot bind to media container service"); 1301 for (HandlerParams params : mPendingInstalls) { 1302 // Indicate service bind error 1303 params.serviceError(); 1304 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1305 System.identityHashCode(params)); 1306 if (params.traceMethod != null) { 1307 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, 1308 params.traceMethod, params.traceCookie); 1309 } 1310 return; 1311 } 1312 mPendingInstalls.clear(); 1313 } else { 1314 Slog.w(TAG, "Waiting to connect to media container service"); 1315 } 1316 } else if (mPendingInstalls.size() > 0) { 1317 HandlerParams params = mPendingInstalls.get(0); 1318 if (params != null) { 1319 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1320 System.identityHashCode(params)); 1321 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy"); 1322 if (params.startCopy()) { 1323 // We are done... look for more work or to 1324 // go idle. 1325 if (DEBUG_SD_INSTALL) Log.i(TAG, 1326 "Checking for more work or unbind..."); 1327 // Delete pending install 1328 if (mPendingInstalls.size() > 0) { 1329 mPendingInstalls.remove(0); 1330 } 1331 if (mPendingInstalls.size() == 0) { 1332 if (mBound) { 1333 if (DEBUG_SD_INSTALL) Log.i(TAG, 1334 "Posting delayed MCS_UNBIND"); 1335 removeMessages(MCS_UNBIND); 1336 Message ubmsg = obtainMessage(MCS_UNBIND); 1337 // Unbind after a little delay, to avoid 1338 // continual thrashing. 1339 sendMessageDelayed(ubmsg, 10000); 1340 } 1341 } else { 1342 // There are more pending requests in queue. 1343 // Just post MCS_BOUND message to trigger processing 1344 // of next pending install. 1345 if (DEBUG_SD_INSTALL) Log.i(TAG, 1346 "Posting MCS_BOUND for next work"); 1347 mHandler.sendEmptyMessage(MCS_BOUND); 1348 } 1349 } 1350 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 1351 } 1352 } else { 1353 // Should never happen ideally. 1354 Slog.w(TAG, "Empty queue"); 1355 } 1356 break; 1357 } 1358 case MCS_RECONNECT: { 1359 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect"); 1360 if (mPendingInstalls.size() > 0) { 1361 if (mBound) { 1362 disconnectService(); 1363 } 1364 if (!connectToService()) { 1365 Slog.e(TAG, "Failed to bind to media container service"); 1366 for (HandlerParams params : mPendingInstalls) { 1367 // Indicate service bind error 1368 params.serviceError(); 1369 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1370 System.identityHashCode(params)); 1371 } 1372 mPendingInstalls.clear(); 1373 } 1374 } 1375 break; 1376 } 1377 case MCS_UNBIND: { 1378 // If there is no actual work left, then time to unbind. 1379 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind"); 1380 1381 if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) { 1382 if (mBound) { 1383 if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()"); 1384 1385 disconnectService(); 1386 } 1387 } else if (mPendingInstalls.size() > 0) { 1388 // There are more pending requests in queue. 1389 // Just post MCS_BOUND message to trigger processing 1390 // of next pending install. 1391 mHandler.sendEmptyMessage(MCS_BOUND); 1392 } 1393 1394 break; 1395 } 1396 case MCS_GIVE_UP: { 1397 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries"); 1398 HandlerParams params = mPendingInstalls.remove(0); 1399 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1400 System.identityHashCode(params)); 1401 break; 1402 } 1403 case SEND_PENDING_BROADCAST: { 1404 String packages[]; 1405 ArrayList<String> components[]; 1406 int size = 0; 1407 int uids[]; 1408 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1409 synchronized (mPackages) { 1410 if (mPendingBroadcasts == null) { 1411 return; 1412 } 1413 size = mPendingBroadcasts.size(); 1414 if (size <= 0) { 1415 // Nothing to be done. Just return 1416 return; 1417 } 1418 packages = new String[size]; 1419 components = new ArrayList[size]; 1420 uids = new int[size]; 1421 int i = 0; // filling out the above arrays 1422 1423 for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) { 1424 int packageUserId = mPendingBroadcasts.userIdAt(n); 1425 Iterator<Map.Entry<String, ArrayList<String>>> it 1426 = mPendingBroadcasts.packagesForUserId(packageUserId) 1427 .entrySet().iterator(); 1428 while (it.hasNext() && i < size) { 1429 Map.Entry<String, ArrayList<String>> ent = it.next(); 1430 packages[i] = ent.getKey(); 1431 components[i] = ent.getValue(); 1432 PackageSetting ps = mSettings.mPackages.get(ent.getKey()); 1433 uids[i] = (ps != null) 1434 ? UserHandle.getUid(packageUserId, ps.appId) 1435 : -1; 1436 i++; 1437 } 1438 } 1439 size = i; 1440 mPendingBroadcasts.clear(); 1441 } 1442 // Send broadcasts 1443 for (int i = 0; i < size; i++) { 1444 sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]); 1445 } 1446 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1447 break; 1448 } 1449 case START_CLEANING_PACKAGE: { 1450 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1451 final String packageName = (String)msg.obj; 1452 final int userId = msg.arg1; 1453 final boolean andCode = msg.arg2 != 0; 1454 synchronized (mPackages) { 1455 if (userId == UserHandle.USER_ALL) { 1456 int[] users = sUserManager.getUserIds(); 1457 for (int user : users) { 1458 mSettings.addPackageToCleanLPw( 1459 new PackageCleanItem(user, packageName, andCode)); 1460 } 1461 } else { 1462 mSettings.addPackageToCleanLPw( 1463 new PackageCleanItem(userId, packageName, andCode)); 1464 } 1465 } 1466 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1467 startCleaningPackages(); 1468 } break; 1469 case POST_INSTALL: { 1470 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1); 1471 1472 PostInstallData data = mRunningInstalls.get(msg.arg1); 1473 mRunningInstalls.delete(msg.arg1); 1474 1475 if (data != null) { 1476 InstallArgs args = data.args; 1477 PackageInstalledInfo parentRes = data.res; 1478 1479 final boolean grantPermissions = (args.installFlags 1480 & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0; 1481 final boolean killApp = (args.installFlags 1482 & PackageManager.INSTALL_DONT_KILL_APP) == 0; 1483 final String[] grantedPermissions = args.installGrantPermissions; 1484 1485 // Handle the parent package 1486 handlePackagePostInstall(parentRes, grantPermissions, killApp, 1487 grantedPermissions, args.observer); 1488 1489 // Handle the child packages 1490 final int childCount = (parentRes.addedChildPackages != null) 1491 ? parentRes.addedChildPackages.size() : 0; 1492 for (int i = 0; i < childCount; i++) { 1493 PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i); 1494 handlePackagePostInstall(childRes, grantPermissions, killApp, 1495 grantedPermissions, args.observer); 1496 } 1497 1498 // Log tracing if needed 1499 if (args.traceMethod != null) { 1500 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod, 1501 args.traceCookie); 1502 } 1503 } else { 1504 Slog.e(TAG, "Bogus post-install token " + msg.arg1); 1505 } 1506 1507 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1); 1508 } break; 1509 case UPDATED_MEDIA_STATUS: { 1510 if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS"); 1511 boolean reportStatus = msg.arg1 == 1; 1512 boolean doGc = msg.arg2 == 1; 1513 if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc); 1514 if (doGc) { 1515 // Force a gc to clear up stale containers. 1516 Runtime.getRuntime().gc(); 1517 } 1518 if (msg.obj != null) { 1519 @SuppressWarnings("unchecked") 1520 Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj; 1521 if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers"); 1522 // Unload containers 1523 unloadAllContainers(args); 1524 } 1525 if (reportStatus) { 1526 try { 1527 if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back"); 1528 PackageHelper.getMountService().finishMediaUpdate(); 1529 } catch (RemoteException e) { 1530 Log.e(TAG, "MountService not running?"); 1531 } 1532 } 1533 } break; 1534 case WRITE_SETTINGS: { 1535 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1536 synchronized (mPackages) { 1537 removeMessages(WRITE_SETTINGS); 1538 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1539 mSettings.writeLPr(); 1540 mDirtyUsers.clear(); 1541 } 1542 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1543 } break; 1544 case WRITE_PACKAGE_RESTRICTIONS: { 1545 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1546 synchronized (mPackages) { 1547 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1548 for (int userId : mDirtyUsers) { 1549 mSettings.writePackageRestrictionsLPr(userId); 1550 } 1551 mDirtyUsers.clear(); 1552 } 1553 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1554 } break; 1555 case CHECK_PENDING_VERIFICATION: { 1556 final int verificationId = msg.arg1; 1557 final PackageVerificationState state = mPendingVerification.get(verificationId); 1558 1559 if ((state != null) && !state.timeoutExtended()) { 1560 final InstallArgs args = state.getInstallArgs(); 1561 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1562 1563 Slog.i(TAG, "Verification timed out for " + originUri); 1564 mPendingVerification.remove(verificationId); 1565 1566 int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1567 1568 if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) { 1569 Slog.i(TAG, "Continuing with installation of " + originUri); 1570 state.setVerifierResponse(Binder.getCallingUid(), 1571 PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT); 1572 broadcastPackageVerified(verificationId, originUri, 1573 PackageManager.VERIFICATION_ALLOW, 1574 state.getInstallArgs().getUser()); 1575 try { 1576 ret = args.copyApk(mContainerService, true); 1577 } catch (RemoteException e) { 1578 Slog.e(TAG, "Could not contact the ContainerService"); 1579 } 1580 } else { 1581 broadcastPackageVerified(verificationId, originUri, 1582 PackageManager.VERIFICATION_REJECT, 1583 state.getInstallArgs().getUser()); 1584 } 1585 1586 Trace.asyncTraceEnd( 1587 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 1588 1589 processPendingInstall(args, ret); 1590 mHandler.sendEmptyMessage(MCS_UNBIND); 1591 } 1592 break; 1593 } 1594 case PACKAGE_VERIFIED: { 1595 final int verificationId = msg.arg1; 1596 1597 final PackageVerificationState state = mPendingVerification.get(verificationId); 1598 if (state == null) { 1599 Slog.w(TAG, "Invalid verification token " + verificationId + " received"); 1600 break; 1601 } 1602 1603 final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj; 1604 1605 state.setVerifierResponse(response.callerUid, response.code); 1606 1607 if (state.isVerificationComplete()) { 1608 mPendingVerification.remove(verificationId); 1609 1610 final InstallArgs args = state.getInstallArgs(); 1611 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1612 1613 int ret; 1614 if (state.isInstallAllowed()) { 1615 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 1616 broadcastPackageVerified(verificationId, originUri, 1617 response.code, state.getInstallArgs().getUser()); 1618 try { 1619 ret = args.copyApk(mContainerService, true); 1620 } catch (RemoteException e) { 1621 Slog.e(TAG, "Could not contact the ContainerService"); 1622 } 1623 } else { 1624 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1625 } 1626 1627 Trace.asyncTraceEnd( 1628 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 1629 1630 processPendingInstall(args, ret); 1631 mHandler.sendEmptyMessage(MCS_UNBIND); 1632 } 1633 1634 break; 1635 } 1636 case START_INTENT_FILTER_VERIFICATIONS: { 1637 IFVerificationParams params = (IFVerificationParams) msg.obj; 1638 verifyIntentFiltersIfNeeded(params.userId, params.verifierUid, 1639 params.replacing, params.pkg); 1640 break; 1641 } 1642 case INTENT_FILTER_VERIFIED: { 1643 final int verificationId = msg.arg1; 1644 1645 final IntentFilterVerificationState state = mIntentFilterVerificationStates.get( 1646 verificationId); 1647 if (state == null) { 1648 Slog.w(TAG, "Invalid IntentFilter verification token " 1649 + verificationId + " received"); 1650 break; 1651 } 1652 1653 final int userId = state.getUserId(); 1654 1655 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1656 "Processing IntentFilter verification with token:" 1657 + verificationId + " and userId:" + userId); 1658 1659 final IntentFilterVerificationResponse response = 1660 (IntentFilterVerificationResponse) msg.obj; 1661 1662 state.setVerifierResponse(response.callerUid, response.code); 1663 1664 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1665 "IntentFilter verification with token:" + verificationId 1666 + " and userId:" + userId 1667 + " is settings verifier response with response code:" 1668 + response.code); 1669 1670 if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) { 1671 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: " 1672 + response.getFailedDomainsString()); 1673 } 1674 1675 if (state.isVerificationComplete()) { 1676 mIntentFilterVerifier.receiveVerificationResponse(verificationId); 1677 } else { 1678 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1679 "IntentFilter verification with token:" + verificationId 1680 + " was not said to be complete"); 1681 } 1682 1683 break; 1684 } 1685 } 1686 } 1687 } 1688 1689 private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions, 1690 boolean killApp, String[] grantedPermissions, 1691 IPackageInstallObserver2 installObserver) { 1692 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 1693 // Send the removed broadcasts 1694 if (res.removedInfo != null) { 1695 res.removedInfo.sendPackageRemovedBroadcasts(killApp); 1696 } 1697 1698 // Now that we successfully installed the package, grant runtime 1699 // permissions if requested before broadcasting the install. 1700 if (grantPermissions && res.pkg.applicationInfo.targetSdkVersion 1701 >= Build.VERSION_CODES.M) { 1702 grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions); 1703 } 1704 1705 final boolean update = res.removedInfo != null 1706 && res.removedInfo.removedPackage != null; 1707 1708 // If this is the first time we have child packages for a disabled privileged 1709 // app that had no children, we grant requested runtime permissions to the new 1710 // children if the parent on the system image had them already granted. 1711 if (res.pkg.parentPackage != null) { 1712 synchronized (mPackages) { 1713 grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg); 1714 } 1715 } 1716 1717 synchronized (mPackages) { 1718 mEphemeralApplicationRegistry.onPackageInstalledLPw(res.pkg); 1719 } 1720 1721 final String packageName = res.pkg.applicationInfo.packageName; 1722 Bundle extras = new Bundle(1); 1723 extras.putInt(Intent.EXTRA_UID, res.uid); 1724 1725 // Determine the set of users who are adding this package for 1726 // the first time vs. those who are seeing an update. 1727 int[] firstUsers = EMPTY_INT_ARRAY; 1728 int[] updateUsers = EMPTY_INT_ARRAY; 1729 if (res.origUsers == null || res.origUsers.length == 0) { 1730 firstUsers = res.newUsers; 1731 } else { 1732 for (int newUser : res.newUsers) { 1733 boolean isNew = true; 1734 for (int origUser : res.origUsers) { 1735 if (origUser == newUser) { 1736 isNew = false; 1737 break; 1738 } 1739 } 1740 if (isNew) { 1741 firstUsers = ArrayUtils.appendInt(firstUsers, newUser); 1742 } else { 1743 updateUsers = ArrayUtils.appendInt(updateUsers, newUser); 1744 } 1745 } 1746 } 1747 1748 // Send installed broadcasts if the install/update is not ephemeral 1749 if (!isEphemeral(res.pkg)) { 1750 mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath); 1751 1752 // Send added for users that see the package for the first time 1753 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, 1754 extras, 0 /*flags*/, null /*targetPackage*/, 1755 null /*finishedReceiver*/, firstUsers); 1756 1757 // Send added for users that don't see the package for the first time 1758 if (update) { 1759 extras.putBoolean(Intent.EXTRA_REPLACING, true); 1760 } 1761 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, 1762 extras, 0 /*flags*/, null /*targetPackage*/, 1763 null /*finishedReceiver*/, updateUsers); 1764 1765 // Send replaced for users that don't see the package for the first time 1766 if (update) { 1767 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, 1768 packageName, extras, 0 /*flags*/, 1769 null /*targetPackage*/, null /*finishedReceiver*/, 1770 updateUsers); 1771 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, 1772 null /*package*/, null /*extras*/, 0 /*flags*/, 1773 packageName /*targetPackage*/, 1774 null /*finishedReceiver*/, updateUsers); 1775 } 1776 1777 // Send broadcast package appeared if forward locked/external for all users 1778 // treat asec-hosted packages like removable media on upgrade 1779 if (res.pkg.isForwardLocked() || isExternal(res.pkg)) { 1780 if (DEBUG_INSTALL) { 1781 Slog.i(TAG, "upgrading pkg " + res.pkg 1782 + " is ASEC-hosted -> AVAILABLE"); 1783 } 1784 final int[] uidArray = new int[]{res.pkg.applicationInfo.uid}; 1785 ArrayList<String> pkgList = new ArrayList<>(1); 1786 pkgList.add(packageName); 1787 sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null); 1788 } 1789 } 1790 1791 // Work that needs to happen on first install within each user 1792 if (firstUsers != null && firstUsers.length > 0) { 1793 synchronized (mPackages) { 1794 for (int userId : firstUsers) { 1795 // If this app is a browser and it's newly-installed for some 1796 // users, clear any default-browser state in those users. The 1797 // app's nature doesn't depend on the user, so we can just check 1798 // its browser nature in any user and generalize. 1799 if (packageIsBrowser(packageName, userId)) { 1800 mSettings.setDefaultBrowserPackageNameLPw(null, userId); 1801 } 1802 1803 // We may also need to apply pending (restored) runtime 1804 // permission grants within these users. 1805 mSettings.applyPendingPermissionGrantsLPw(packageName, userId); 1806 } 1807 } 1808 } 1809 1810 // Log current value of "unknown sources" setting 1811 EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED, 1812 getUnknownSourcesSettings()); 1813 1814 // Force a gc to clear up things 1815 Runtime.getRuntime().gc(); 1816 1817 // Remove the replaced package's older resources safely now 1818 // We delete after a gc for applications on sdcard. 1819 if (res.removedInfo != null && res.removedInfo.args != null) { 1820 synchronized (mInstallLock) { 1821 res.removedInfo.args.doPostDeleteLI(true); 1822 } 1823 } 1824 } 1825 1826 // If someone is watching installs - notify them 1827 if (installObserver != null) { 1828 try { 1829 Bundle extras = extrasForInstallResult(res); 1830 installObserver.onPackageInstalled(res.name, res.returnCode, 1831 res.returnMsg, extras); 1832 } catch (RemoteException e) { 1833 Slog.i(TAG, "Observer no longer exists."); 1834 } 1835 } 1836 } 1837 1838 private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw( 1839 PackageParser.Package pkg) { 1840 if (pkg.parentPackage == null) { 1841 return; 1842 } 1843 if (pkg.requestedPermissions == null) { 1844 return; 1845 } 1846 final PackageSetting disabledSysParentPs = mSettings 1847 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName); 1848 if (disabledSysParentPs == null || disabledSysParentPs.pkg == null 1849 || !disabledSysParentPs.isPrivileged() 1850 || (disabledSysParentPs.childPackageNames != null 1851 && !disabledSysParentPs.childPackageNames.isEmpty())) { 1852 return; 1853 } 1854 final int[] allUserIds = sUserManager.getUserIds(); 1855 final int permCount = pkg.requestedPermissions.size(); 1856 for (int i = 0; i < permCount; i++) { 1857 String permission = pkg.requestedPermissions.get(i); 1858 BasePermission bp = mSettings.mPermissions.get(permission); 1859 if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) { 1860 continue; 1861 } 1862 for (int userId : allUserIds) { 1863 if (disabledSysParentPs.getPermissionsState().hasRuntimePermission( 1864 permission, userId)) { 1865 grantRuntimePermission(pkg.packageName, permission, userId); 1866 } 1867 } 1868 } 1869 } 1870 1871 private StorageEventListener mStorageListener = new StorageEventListener() { 1872 @Override 1873 public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) { 1874 if (vol.type == VolumeInfo.TYPE_PRIVATE) { 1875 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1876 final String volumeUuid = vol.getFsUuid(); 1877 1878 // Clean up any users or apps that were removed or recreated 1879 // while this volume was missing 1880 reconcileUsers(volumeUuid); 1881 reconcileApps(volumeUuid); 1882 1883 // Clean up any install sessions that expired or were 1884 // cancelled while this volume was missing 1885 mInstallerService.onPrivateVolumeMounted(volumeUuid); 1886 1887 loadPrivatePackages(vol); 1888 1889 } else if (vol.state == VolumeInfo.STATE_EJECTING) { 1890 unloadPrivatePackages(vol); 1891 } 1892 } 1893 1894 if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) { 1895 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1896 updateExternalMediaStatus(true, false); 1897 } else if (vol.state == VolumeInfo.STATE_EJECTING) { 1898 updateExternalMediaStatus(false, false); 1899 } 1900 } 1901 } 1902 1903 @Override 1904 public void onVolumeForgotten(String fsUuid) { 1905 if (TextUtils.isEmpty(fsUuid)) { 1906 Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring"); 1907 return; 1908 } 1909 1910 // Remove any apps installed on the forgotten volume 1911 synchronized (mPackages) { 1912 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid); 1913 for (PackageSetting ps : packages) { 1914 Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten"); 1915 deletePackage(ps.name, new LegacyPackageDeleteObserver(null).getBinder(), 1916 UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS); 1917 } 1918 1919 mSettings.onVolumeForgotten(fsUuid); 1920 mSettings.writeLPr(); 1921 } 1922 } 1923 }; 1924 1925 private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds, 1926 String[] grantedPermissions) { 1927 for (int userId : userIds) { 1928 grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions); 1929 } 1930 1931 // We could have touched GID membership, so flush out packages.list 1932 synchronized (mPackages) { 1933 mSettings.writePackageListLPr(); 1934 } 1935 } 1936 1937 private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId, 1938 String[] grantedPermissions) { 1939 SettingBase sb = (SettingBase) pkg.mExtras; 1940 if (sb == null) { 1941 return; 1942 } 1943 1944 PermissionsState permissionsState = sb.getPermissionsState(); 1945 1946 final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 1947 | PackageManager.FLAG_PERMISSION_POLICY_FIXED; 1948 1949 synchronized (mPackages) { 1950 for (String permission : pkg.requestedPermissions) { 1951 BasePermission bp = mSettings.mPermissions.get(permission); 1952 if (bp != null && (bp.isRuntime() || bp.isDevelopment()) 1953 && (grantedPermissions == null 1954 || ArrayUtils.contains(grantedPermissions, permission))) { 1955 final int flags = permissionsState.getPermissionFlags(permission, userId); 1956 // Installer cannot change immutable permissions. 1957 if ((flags & immutableFlags) == 0) { 1958 grantRuntimePermission(pkg.packageName, permission, userId); 1959 } 1960 } 1961 } 1962 } 1963 } 1964 1965 Bundle extrasForInstallResult(PackageInstalledInfo res) { 1966 Bundle extras = null; 1967 switch (res.returnCode) { 1968 case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: { 1969 extras = new Bundle(); 1970 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION, 1971 res.origPermission); 1972 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE, 1973 res.origPackage); 1974 break; 1975 } 1976 case PackageManager.INSTALL_SUCCEEDED: { 1977 extras = new Bundle(); 1978 extras.putBoolean(Intent.EXTRA_REPLACING, 1979 res.removedInfo != null && res.removedInfo.removedPackage != null); 1980 break; 1981 } 1982 } 1983 return extras; 1984 } 1985 1986 void scheduleWriteSettingsLocked() { 1987 if (!mHandler.hasMessages(WRITE_SETTINGS)) { 1988 mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY); 1989 } 1990 } 1991 1992 void scheduleWritePackageRestrictionsLocked(UserHandle user) { 1993 final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier(); 1994 scheduleWritePackageRestrictionsLocked(userId); 1995 } 1996 1997 void scheduleWritePackageRestrictionsLocked(int userId) { 1998 final int[] userIds = (userId == UserHandle.USER_ALL) 1999 ? sUserManager.getUserIds() : new int[]{userId}; 2000 for (int nextUserId : userIds) { 2001 if (!sUserManager.exists(nextUserId)) return; 2002 mDirtyUsers.add(nextUserId); 2003 if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) { 2004 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY); 2005 } 2006 } 2007 } 2008 2009 public static PackageManagerService main(Context context, Installer installer, 2010 boolean factoryTest, boolean onlyCore) { 2011 // Self-check for initial settings. 2012 PackageManagerServiceCompilerMapping.checkProperties(); 2013 2014 PackageManagerService m = new PackageManagerService(context, installer, 2015 factoryTest, onlyCore); 2016 m.enableSystemUserPackages(); 2017 ServiceManager.addService("package", m); 2018 return m; 2019 } 2020 2021 private void enableSystemUserPackages() { 2022 if (!UserManager.isSplitSystemUser()) { 2023 return; 2024 } 2025 // For system user, enable apps based on the following conditions: 2026 // - app is whitelisted or belong to one of these groups: 2027 // -- system app which has no launcher icons 2028 // -- system app which has INTERACT_ACROSS_USERS permission 2029 // -- system IME app 2030 // - app is not in the blacklist 2031 AppsQueryHelper queryHelper = new AppsQueryHelper(this); 2032 Set<String> enableApps = new ArraySet<>(); 2033 enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS 2034 | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM 2035 | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM)); 2036 ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps(); 2037 enableApps.addAll(wlApps); 2038 enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER, 2039 /* systemAppsOnly */ false, UserHandle.SYSTEM)); 2040 ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps(); 2041 enableApps.removeAll(blApps); 2042 Log.i(TAG, "Applications installed for system user: " + enableApps); 2043 List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false, 2044 UserHandle.SYSTEM); 2045 final int allAppsSize = allAps.size(); 2046 synchronized (mPackages) { 2047 for (int i = 0; i < allAppsSize; i++) { 2048 String pName = allAps.get(i); 2049 PackageSetting pkgSetting = mSettings.mPackages.get(pName); 2050 // Should not happen, but we shouldn't be failing if it does 2051 if (pkgSetting == null) { 2052 continue; 2053 } 2054 boolean install = enableApps.contains(pName); 2055 if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) { 2056 Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName 2057 + " for system user"); 2058 pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM); 2059 } 2060 } 2061 } 2062 } 2063 2064 private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) { 2065 DisplayManager displayManager = (DisplayManager) context.getSystemService( 2066 Context.DISPLAY_SERVICE); 2067 displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics); 2068 } 2069 2070 public PackageManagerService(Context context, Installer installer, 2071 boolean factoryTest, boolean onlyCore) { 2072 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START, 2073 SystemClock.uptimeMillis()); 2074 2075 if (mSdkVersion <= 0) { 2076 Slog.w(TAG, "**** ro.build.version.sdk not set!"); 2077 } 2078 2079 mContext = context; 2080 mFactoryTest = factoryTest; 2081 mOnlyCore = onlyCore; 2082 mMetrics = new DisplayMetrics(); 2083 mSettings = new Settings(mPackages); 2084 mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID, 2085 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2086 mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, 2087 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2088 mSettings.addSharedUserLPw("android.uid.log", LOG_UID, 2089 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2090 mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, 2091 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2092 mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID, 2093 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2094 mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID, 2095 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2096 2097 String separateProcesses = SystemProperties.get("debug.separate_processes"); 2098 if (separateProcesses != null && separateProcesses.length() > 0) { 2099 if ("*".equals(separateProcesses)) { 2100 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES; 2101 mSeparateProcesses = null; 2102 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)"); 2103 } else { 2104 mDefParseFlags = 0; 2105 mSeparateProcesses = separateProcesses.split(","); 2106 Slog.w(TAG, "Running with debug.separate_processes: " 2107 + separateProcesses); 2108 } 2109 } else { 2110 mDefParseFlags = 0; 2111 mSeparateProcesses = null; 2112 } 2113 2114 mInstaller = installer; 2115 mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context, 2116 "*dexopt*"); 2117 mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper()); 2118 2119 mOnPermissionChangeListeners = new OnPermissionChangeListeners( 2120 FgThread.get().getLooper()); 2121 2122 getDefaultDisplayMetrics(context, mMetrics); 2123 2124 SystemConfig systemConfig = SystemConfig.getInstance(); 2125 mGlobalGids = systemConfig.getGlobalGids(); 2126 mSystemPermissions = systemConfig.getSystemPermissions(); 2127 mAvailableFeatures = systemConfig.getAvailableFeatures(); 2128 2129 synchronized (mInstallLock) { 2130 // writer 2131 synchronized (mPackages) { 2132 mHandlerThread = new ServiceThread(TAG, 2133 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/); 2134 mHandlerThread.start(); 2135 mHandler = new PackageHandler(mHandlerThread.getLooper()); 2136 mProcessLoggingHandler = new ProcessLoggingHandler(); 2137 Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT); 2138 2139 File dataDir = Environment.getDataDirectory(); 2140 mAppInstallDir = new File(dataDir, "app"); 2141 mAppLib32InstallDir = new File(dataDir, "app-lib"); 2142 mEphemeralInstallDir = new File(dataDir, "app-ephemeral"); 2143 mAsecInternalPath = new File(dataDir, "app-asec").getPath(); 2144 mDrmAppPrivateInstallDir = new File(dataDir, "app-private"); 2145 2146 sUserManager = new UserManagerService(context, this, mPackages); 2147 2148 // Propagate permission configuration in to package manager. 2149 ArrayMap<String, SystemConfig.PermissionEntry> permConfig 2150 = systemConfig.getPermissions(); 2151 for (int i=0; i<permConfig.size(); i++) { 2152 SystemConfig.PermissionEntry perm = permConfig.valueAt(i); 2153 BasePermission bp = mSettings.mPermissions.get(perm.name); 2154 if (bp == null) { 2155 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN); 2156 mSettings.mPermissions.put(perm.name, bp); 2157 } 2158 if (perm.gids != null) { 2159 bp.setGids(perm.gids, perm.perUser); 2160 } 2161 } 2162 2163 ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries(); 2164 for (int i=0; i<libConfig.size(); i++) { 2165 mSharedLibraries.put(libConfig.keyAt(i), 2166 new SharedLibraryEntry(libConfig.valueAt(i), null)); 2167 } 2168 2169 mFoundPolicyFile = SELinuxMMAC.readInstallPolicy(); 2170 2171 mRestoredSettings = mSettings.readLPw(sUserManager.getUsers(false)); 2172 2173 String customResolverActivity = Resources.getSystem().getString( 2174 R.string.config_customResolverActivity); 2175 if (TextUtils.isEmpty(customResolverActivity)) { 2176 customResolverActivity = null; 2177 } else { 2178 mCustomResolverComponentName = ComponentName.unflattenFromString( 2179 customResolverActivity); 2180 } 2181 2182 long startTime = SystemClock.uptimeMillis(); 2183 2184 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START, 2185 startTime); 2186 2187 // Set flag to monitor and not change apk file paths when 2188 // scanning install directories. 2189 final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING | SCAN_INITIAL; 2190 2191 final String bootClassPath = System.getenv("BOOTCLASSPATH"); 2192 final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH"); 2193 2194 if (bootClassPath == null) { 2195 Slog.w(TAG, "No BOOTCLASSPATH found!"); 2196 } 2197 2198 if (systemServerClassPath == null) { 2199 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!"); 2200 } 2201 2202 final List<String> allInstructionSets = InstructionSets.getAllInstructionSets(); 2203 final String[] dexCodeInstructionSets = 2204 getDexCodeInstructionSets( 2205 allInstructionSets.toArray(new String[allInstructionSets.size()])); 2206 2207 /** 2208 * Ensure all external libraries have had dexopt run on them. 2209 */ 2210 if (mSharedLibraries.size() > 0) { 2211 // NOTE: For now, we're compiling these system "shared libraries" 2212 // (and framework jars) into all available architectures. It's possible 2213 // to compile them only when we come across an app that uses them (there's 2214 // already logic for that in scanPackageLI) but that adds some complexity. 2215 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 2216 for (SharedLibraryEntry libEntry : mSharedLibraries.values()) { 2217 final String lib = libEntry.path; 2218 if (lib == null) { 2219 continue; 2220 } 2221 2222 try { 2223 // Shared libraries do not have profiles so we perform a full 2224 // AOT compilation (if needed). 2225 int dexoptNeeded = DexFile.getDexOptNeeded( 2226 lib, dexCodeInstructionSet, 2227 getCompilerFilterForReason(REASON_SHARED_APK), 2228 false /* newProfile */); 2229 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { 2230 mInstaller.dexopt(lib, Process.SYSTEM_UID, dexCodeInstructionSet, 2231 dexoptNeeded, DEXOPT_PUBLIC /*dexFlags*/, 2232 getCompilerFilterForReason(REASON_SHARED_APK), 2233 StorageManager.UUID_PRIVATE_INTERNAL); 2234 } 2235 } catch (FileNotFoundException e) { 2236 Slog.w(TAG, "Library not found: " + lib); 2237 } catch (IOException | InstallerException e) { 2238 Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? " 2239 + e.getMessage()); 2240 } 2241 } 2242 } 2243 } 2244 2245 File frameworkDir = new File(Environment.getRootDirectory(), "framework"); 2246 2247 final VersionInfo ver = mSettings.getInternalVersion(); 2248 mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint); 2249 2250 // when upgrading from pre-M, promote system app permissions from install to runtime 2251 mPromoteSystemApps = 2252 mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1; 2253 2254 // save off the names of pre-existing system packages prior to scanning; we don't 2255 // want to automatically grant runtime permissions for new system apps 2256 if (mPromoteSystemApps) { 2257 Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator(); 2258 while (pkgSettingIter.hasNext()) { 2259 PackageSetting ps = pkgSettingIter.next(); 2260 if (isSystemApp(ps)) { 2261 mExistingSystemPackages.add(ps.name); 2262 } 2263 } 2264 } 2265 2266 // When upgrading from pre-N, we need to handle package extraction like first boot, 2267 // as there is no profiling data available. 2268 mIsPreNUpgrade = !mSettings.isNWorkDone(); 2269 mSettings.setNWorkDone(); 2270 2271 // Collect vendor overlay packages. 2272 // (Do this before scanning any apps.) 2273 // For security and version matching reason, only consider 2274 // overlay packages if they reside in VENDOR_OVERLAY_DIR. 2275 File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR); 2276 scanDirTracedLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM 2277 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags | SCAN_TRUSTED_OVERLAY, 0); 2278 2279 // Find base frameworks (resource packages without code). 2280 scanDirTracedLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM 2281 | PackageParser.PARSE_IS_SYSTEM_DIR 2282 | PackageParser.PARSE_IS_PRIVILEGED, 2283 scanFlags | SCAN_NO_DEX, 0); 2284 2285 // Collected privileged system packages. 2286 final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app"); 2287 scanDirTracedLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM 2288 | PackageParser.PARSE_IS_SYSTEM_DIR 2289 | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0); 2290 2291 // Collect ordinary system packages. 2292 final File systemAppDir = new File(Environment.getRootDirectory(), "app"); 2293 scanDirTracedLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM 2294 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2295 2296 // Collect all vendor packages. 2297 File vendorAppDir = new File("/vendor/app"); 2298 try { 2299 vendorAppDir = vendorAppDir.getCanonicalFile(); 2300 } catch (IOException e) { 2301 // failed to look up canonical path, continue with original one 2302 } 2303 scanDirTracedLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM 2304 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2305 2306 // Collect all OEM packages. 2307 final File oemAppDir = new File(Environment.getOemDirectory(), "app"); 2308 scanDirTracedLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM 2309 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2310 2311 // Prune any system packages that no longer exist. 2312 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>(); 2313 if (!mOnlyCore) { 2314 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 2315 while (psit.hasNext()) { 2316 PackageSetting ps = psit.next(); 2317 2318 /* 2319 * If this is not a system app, it can't be a 2320 * disable system app. 2321 */ 2322 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) { 2323 continue; 2324 } 2325 2326 /* 2327 * If the package is scanned, it's not erased. 2328 */ 2329 final PackageParser.Package scannedPkg = mPackages.get(ps.name); 2330 if (scannedPkg != null) { 2331 /* 2332 * If the system app is both scanned and in the 2333 * disabled packages list, then it must have been 2334 * added via OTA. Remove it from the currently 2335 * scanned package so the previously user-installed 2336 * application can be scanned. 2337 */ 2338 if (mSettings.isDisabledSystemPackageLPr(ps.name)) { 2339 logCriticalInfo(Log.WARN, "Expecting better updated system app for " 2340 + ps.name + "; removing system app. Last known codePath=" 2341 + ps.codePathString + ", installStatus=" + ps.installStatus 2342 + ", versionCode=" + ps.versionCode + "; scanned versionCode=" 2343 + scannedPkg.mVersionCode); 2344 removePackageLI(scannedPkg, true); 2345 mExpectingBetter.put(ps.name, ps.codePath); 2346 } 2347 2348 continue; 2349 } 2350 2351 if (!mSettings.isDisabledSystemPackageLPr(ps.name)) { 2352 psit.remove(); 2353 logCriticalInfo(Log.WARN, "System package " + ps.name 2354 + " no longer exists; wiping its data"); 2355 removeDataDirsLI(null, ps.name); 2356 } else { 2357 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name); 2358 if (disabledPs.codePath == null || !disabledPs.codePath.exists()) { 2359 possiblyDeletedUpdatedSystemApps.add(ps.name); 2360 } 2361 } 2362 } 2363 } 2364 2365 //look for any incomplete package installations 2366 ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr(); 2367 //clean up list 2368 for(int i = 0; i < deletePkgsList.size(); i++) { 2369 //clean up here 2370 cleanupInstallFailedPackage(deletePkgsList.get(i)); 2371 } 2372 //delete tmp files 2373 deleteTempPackageFiles(); 2374 2375 // Remove any shared userIDs that have no associated packages 2376 mSettings.pruneSharedUsersLPw(); 2377 2378 if (!mOnlyCore) { 2379 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START, 2380 SystemClock.uptimeMillis()); 2381 scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0); 2382 2383 scanDirTracedLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK, 2384 scanFlags | SCAN_REQUIRE_KNOWN, 0); 2385 2386 scanDirLI(mEphemeralInstallDir, PackageParser.PARSE_IS_EPHEMERAL, 2387 scanFlags | SCAN_REQUIRE_KNOWN, 0); 2388 2389 /** 2390 * Remove disable package settings for any updated system 2391 * apps that were removed via an OTA. If they're not a 2392 * previously-updated app, remove them completely. 2393 * Otherwise, just revoke their system-level permissions. 2394 */ 2395 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) { 2396 PackageParser.Package deletedPkg = mPackages.get(deletedAppName); 2397 mSettings.removeDisabledSystemPackageLPw(deletedAppName); 2398 2399 String msg; 2400 if (deletedPkg == null) { 2401 msg = "Updated system package " + deletedAppName 2402 + " no longer exists; wiping its data"; 2403 removeDataDirsLI(null, deletedAppName); 2404 } else { 2405 msg = "Updated system app + " + deletedAppName 2406 + " no longer present; removing system privileges for " 2407 + deletedAppName; 2408 2409 deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM; 2410 2411 PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName); 2412 deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM; 2413 } 2414 logCriticalInfo(Log.WARN, msg); 2415 } 2416 2417 /** 2418 * Make sure all system apps that we expected to appear on 2419 * the userdata partition actually showed up. If they never 2420 * appeared, crawl back and revive the system version. 2421 */ 2422 for (int i = 0; i < mExpectingBetter.size(); i++) { 2423 final String packageName = mExpectingBetter.keyAt(i); 2424 if (!mPackages.containsKey(packageName)) { 2425 final File scanFile = mExpectingBetter.valueAt(i); 2426 2427 logCriticalInfo(Log.WARN, "Expected better " + packageName 2428 + " but never showed up; reverting to system"); 2429 2430 final int reparseFlags; 2431 if (FileUtils.contains(privilegedAppDir, scanFile)) { 2432 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2433 | PackageParser.PARSE_IS_SYSTEM_DIR 2434 | PackageParser.PARSE_IS_PRIVILEGED; 2435 } else if (FileUtils.contains(systemAppDir, scanFile)) { 2436 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2437 | PackageParser.PARSE_IS_SYSTEM_DIR; 2438 } else if (FileUtils.contains(vendorAppDir, scanFile)) { 2439 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2440 | PackageParser.PARSE_IS_SYSTEM_DIR; 2441 } else if (FileUtils.contains(oemAppDir, scanFile)) { 2442 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2443 | PackageParser.PARSE_IS_SYSTEM_DIR; 2444 } else { 2445 Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile); 2446 continue; 2447 } 2448 2449 mSettings.enableSystemPackageLPw(packageName); 2450 2451 try { 2452 scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null); 2453 } catch (PackageManagerException e) { 2454 Slog.e(TAG, "Failed to parse original system package: " 2455 + e.getMessage()); 2456 } 2457 } 2458 } 2459 } 2460 mExpectingBetter.clear(); 2461 2462 // Resolve protected action filters. Only the setup wizard is allowed to 2463 // have a high priority filter for these actions. 2464 mSetupWizardPackage = getSetupWizardPackageName(); 2465 if (mProtectedFilters.size() > 0) { 2466 if (DEBUG_FILTERS && mSetupWizardPackage == null) { 2467 Slog.i(TAG, "No setup wizard;" 2468 + " All protected intents capped to priority 0"); 2469 } 2470 for (ActivityIntentInfo filter : mProtectedFilters) { 2471 if (filter.activity.info.packageName.equals(mSetupWizardPackage)) { 2472 if (DEBUG_FILTERS) { 2473 Slog.i(TAG, "Found setup wizard;" 2474 + " allow priority " + filter.getPriority() + ";" 2475 + " package: " + filter.activity.info.packageName 2476 + " activity: " + filter.activity.className 2477 + " priority: " + filter.getPriority()); 2478 } 2479 // skip setup wizard; allow it to keep the high priority filter 2480 continue; 2481 } 2482 Slog.w(TAG, "Protected action; cap priority to 0;" 2483 + " package: " + filter.activity.info.packageName 2484 + " activity: " + filter.activity.className 2485 + " origPrio: " + filter.getPriority()); 2486 filter.setPriority(0); 2487 } 2488 } 2489 mDeferProtectedFilters = false; 2490 mProtectedFilters.clear(); 2491 2492 // Now that we know all of the shared libraries, update all clients to have 2493 // the correct library paths. 2494 updateAllSharedLibrariesLPw(); 2495 2496 for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) { 2497 // NOTE: We ignore potential failures here during a system scan (like 2498 // the rest of the commands above) because there's precious little we 2499 // can do about it. A settings error is reported, though. 2500 adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */, 2501 false /* boot complete */); 2502 } 2503 2504 // Now that we know all the packages we are keeping, 2505 // read and update their last usage times. 2506 mPackageUsage.readLP(); 2507 2508 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END, 2509 SystemClock.uptimeMillis()); 2510 Slog.i(TAG, "Time to scan packages: " 2511 + ((SystemClock.uptimeMillis()-startTime)/1000f) 2512 + " seconds"); 2513 2514 // If the platform SDK has changed since the last time we booted, 2515 // we need to re-grant app permission to catch any new ones that 2516 // appear. This is really a hack, and means that apps can in some 2517 // cases get permissions that the user didn't initially explicitly 2518 // allow... it would be nice to have some better way to handle 2519 // this situation. 2520 int updateFlags = UPDATE_PERMISSIONS_ALL; 2521 if (ver.sdkVersion != mSdkVersion) { 2522 Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to " 2523 + mSdkVersion + "; regranting permissions for internal storage"); 2524 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 2525 } 2526 updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags); 2527 ver.sdkVersion = mSdkVersion; 2528 2529 // If this is the first boot or an update from pre-M, and it is a normal 2530 // boot, then we need to initialize the default preferred apps across 2531 // all defined users. 2532 if (!onlyCore && (mPromoteSystemApps || !mRestoredSettings)) { 2533 for (UserInfo user : sUserManager.getUsers(true)) { 2534 mSettings.applyDefaultPreferredAppsLPw(this, user.id); 2535 applyFactoryDefaultBrowserLPw(user.id); 2536 primeDomainVerificationsLPw(user.id); 2537 } 2538 } 2539 2540 // Prepare storage for system user really early during boot, 2541 // since core system apps like SettingsProvider and SystemUI 2542 // can't wait for user to start 2543 final int storageFlags; 2544 if (StorageManager.isFileEncryptedNativeOrEmulated()) { 2545 storageFlags = StorageManager.FLAG_STORAGE_DE; 2546 } else { 2547 storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 2548 } 2549 reconcileAppsData(StorageManager.UUID_PRIVATE_INTERNAL, UserHandle.USER_SYSTEM, 2550 storageFlags); 2551 2552 // If this is first boot after an OTA, and a normal boot, then 2553 // we need to clear code cache directories. 2554 if (mIsUpgrade && !onlyCore) { 2555 Slog.i(TAG, "Build fingerprint changed; clearing code caches"); 2556 for (int i = 0; i < mSettings.mPackages.size(); i++) { 2557 final PackageSetting ps = mSettings.mPackages.valueAt(i); 2558 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) { 2559 deleteCodeCacheDirsLI(ps.volumeUuid, ps.name); 2560 } 2561 } 2562 ver.fingerprint = Build.FINGERPRINT; 2563 } 2564 2565 checkDefaultBrowser(); 2566 2567 // clear only after permissions and other defaults have been updated 2568 mExistingSystemPackages.clear(); 2569 mPromoteSystemApps = false; 2570 2571 // All the changes are done during package scanning. 2572 ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION; 2573 2574 // can downgrade to reader 2575 mSettings.writeLPr(); 2576 2577 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY, 2578 SystemClock.uptimeMillis()); 2579 2580 if (!mOnlyCore) { 2581 mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr(); 2582 mRequiredInstallerPackage = getRequiredInstallerLPr(); 2583 mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr(); 2584 mIntentFilterVerifier = new IntentVerifierProxy(mContext, 2585 mIntentFilterVerifierComponent); 2586 mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr( 2587 PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES); 2588 getRequiredSharedLibraryLPr( 2589 PackageManager.SYSTEM_SHARED_LIBRARY_SHARED); 2590 } else { 2591 mRequiredVerifierPackage = null; 2592 mRequiredInstallerPackage = null; 2593 mIntentFilterVerifierComponent = null; 2594 mIntentFilterVerifier = null; 2595 mServicesSystemSharedLibraryPackageName = null; 2596 } 2597 2598 mInstallerService = new PackageInstallerService(context, this); 2599 2600 final ComponentName ephemeralResolverComponent = getEphemeralResolverLPr(); 2601 final ComponentName ephemeralInstallerComponent = getEphemeralInstallerLPr(); 2602 // both the installer and resolver must be present to enable ephemeral 2603 if (ephemeralInstallerComponent != null && ephemeralResolverComponent != null) { 2604 if (DEBUG_EPHEMERAL) { 2605 Slog.i(TAG, "Ephemeral activated; resolver: " + ephemeralResolverComponent 2606 + " installer:" + ephemeralInstallerComponent); 2607 } 2608 mEphemeralResolverComponent = ephemeralResolverComponent; 2609 mEphemeralInstallerComponent = ephemeralInstallerComponent; 2610 setUpEphemeralInstallerActivityLP(mEphemeralInstallerComponent); 2611 mEphemeralResolverConnection = 2612 new EphemeralResolverConnection(mContext, mEphemeralResolverComponent); 2613 } else { 2614 if (DEBUG_EPHEMERAL) { 2615 final String missingComponent = 2616 (ephemeralResolverComponent == null) 2617 ? (ephemeralInstallerComponent == null) 2618 ? "resolver and installer" 2619 : "resolver" 2620 : "installer"; 2621 Slog.i(TAG, "Ephemeral deactivated; missing " + missingComponent); 2622 } 2623 mEphemeralResolverComponent = null; 2624 mEphemeralInstallerComponent = null; 2625 mEphemeralResolverConnection = null; 2626 } 2627 2628 mEphemeralApplicationRegistry = new EphemeralApplicationRegistry(this); 2629 } // synchronized (mPackages) 2630 } // synchronized (mInstallLock) 2631 2632 // Now after opening every single application zip, make sure they 2633 // are all flushed. Not really needed, but keeps things nice and 2634 // tidy. 2635 Runtime.getRuntime().gc(); 2636 2637 // The initial scanning above does many calls into installd while 2638 // holding the mPackages lock, but we're mostly interested in yelling 2639 // once we have a booted system. 2640 mInstaller.setWarnIfHeld(mPackages); 2641 2642 // Expose private service for system components to use. 2643 LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl()); 2644 } 2645 2646 @Override 2647 public boolean isFirstBoot() { 2648 return !mRestoredSettings; 2649 } 2650 2651 @Override 2652 public boolean isOnlyCoreApps() { 2653 return mOnlyCore; 2654 } 2655 2656 @Override 2657 public boolean isUpgrade() { 2658 return mIsUpgrade; 2659 } 2660 2661 private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() { 2662 final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 2663 2664 final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE, 2665 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 2666 UserHandle.USER_SYSTEM); 2667 if (matches.size() == 1) { 2668 return matches.get(0).getComponentInfo().packageName; 2669 } else { 2670 Log.e(TAG, "There should probably be exactly one verifier; found " + matches); 2671 return null; 2672 } 2673 } 2674 2675 private @NonNull String getRequiredSharedLibraryLPr(String libraryName) { 2676 synchronized (mPackages) { 2677 SharedLibraryEntry libraryEntry = mSharedLibraries.get(libraryName); 2678 if (libraryEntry == null) { 2679 throw new IllegalStateException("Missing required shared library:" + libraryName); 2680 } 2681 return libraryEntry.apk; 2682 } 2683 } 2684 2685 private @NonNull String getRequiredInstallerLPr() { 2686 final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE); 2687 intent.addCategory(Intent.CATEGORY_DEFAULT); 2688 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE); 2689 2690 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE, 2691 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 2692 UserHandle.USER_SYSTEM); 2693 if (matches.size() == 1) { 2694 ResolveInfo resolveInfo = matches.get(0); 2695 if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) { 2696 throw new RuntimeException("The installer must be a privileged app"); 2697 } 2698 return matches.get(0).getComponentInfo().packageName; 2699 } else { 2700 throw new RuntimeException("There must be exactly one installer; found " + matches); 2701 } 2702 } 2703 2704 private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() { 2705 final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 2706 2707 final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE, 2708 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 2709 UserHandle.USER_SYSTEM); 2710 ResolveInfo best = null; 2711 final int N = matches.size(); 2712 for (int i = 0; i < N; i++) { 2713 final ResolveInfo cur = matches.get(i); 2714 final String packageName = cur.getComponentInfo().packageName; 2715 if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 2716 packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) { 2717 continue; 2718 } 2719 2720 if (best == null || cur.priority > best.priority) { 2721 best = cur; 2722 } 2723 } 2724 2725 if (best != null) { 2726 return best.getComponentInfo().getComponentName(); 2727 } else { 2728 throw new RuntimeException("There must be at least one intent filter verifier"); 2729 } 2730 } 2731 2732 private @Nullable ComponentName getEphemeralResolverLPr() { 2733 final String[] packageArray = 2734 mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage); 2735 if (packageArray.length == 0) { 2736 if (DEBUG_EPHEMERAL) { 2737 Slog.d(TAG, "Ephemeral resolver NOT found; empty package list"); 2738 } 2739 return null; 2740 } 2741 2742 final Intent resolverIntent = new Intent(Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE); 2743 final List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null, 2744 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 2745 UserHandle.USER_SYSTEM); 2746 2747 final int N = resolvers.size(); 2748 if (N == 0) { 2749 if (DEBUG_EPHEMERAL) { 2750 Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters"); 2751 } 2752 return null; 2753 } 2754 2755 final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray)); 2756 for (int i = 0; i < N; i++) { 2757 final ResolveInfo info = resolvers.get(i); 2758 2759 if (info.serviceInfo == null) { 2760 continue; 2761 } 2762 2763 final String packageName = info.serviceInfo.packageName; 2764 if (!possiblePackages.contains(packageName)) { 2765 if (DEBUG_EPHEMERAL) { 2766 Slog.d(TAG, "Ephemeral resolver not in allowed package list;" 2767 + " pkg: " + packageName + ", info:" + info); 2768 } 2769 continue; 2770 } 2771 2772 if (DEBUG_EPHEMERAL) { 2773 Slog.v(TAG, "Ephemeral resolver found;" 2774 + " pkg: " + packageName + ", info:" + info); 2775 } 2776 return new ComponentName(packageName, info.serviceInfo.name); 2777 } 2778 if (DEBUG_EPHEMERAL) { 2779 Slog.v(TAG, "Ephemeral resolver NOT found"); 2780 } 2781 return null; 2782 } 2783 2784 private @Nullable ComponentName getEphemeralInstallerLPr() { 2785 final Intent intent = new Intent(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE); 2786 intent.addCategory(Intent.CATEGORY_DEFAULT); 2787 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE); 2788 2789 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE, 2790 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 2791 UserHandle.USER_SYSTEM); 2792 if (matches.size() == 0) { 2793 return null; 2794 } else if (matches.size() == 1) { 2795 return matches.get(0).getComponentInfo().getComponentName(); 2796 } else { 2797 throw new RuntimeException( 2798 "There must be at most one ephemeral installer; found " + matches); 2799 } 2800 } 2801 2802 private void primeDomainVerificationsLPw(int userId) { 2803 if (DEBUG_DOMAIN_VERIFICATION) { 2804 Slog.d(TAG, "Priming domain verifications in user " + userId); 2805 } 2806 2807 SystemConfig systemConfig = SystemConfig.getInstance(); 2808 ArraySet<String> packages = systemConfig.getLinkedApps(); 2809 ArraySet<String> domains = new ArraySet<String>(); 2810 2811 for (String packageName : packages) { 2812 PackageParser.Package pkg = mPackages.get(packageName); 2813 if (pkg != null) { 2814 if (!pkg.isSystemApp()) { 2815 Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>"); 2816 continue; 2817 } 2818 2819 domains.clear(); 2820 for (PackageParser.Activity a : pkg.activities) { 2821 for (ActivityIntentInfo filter : a.intents) { 2822 if (hasValidDomains(filter)) { 2823 domains.addAll(filter.getHostsList()); 2824 } 2825 } 2826 } 2827 2828 if (domains.size() > 0) { 2829 if (DEBUG_DOMAIN_VERIFICATION) { 2830 Slog.v(TAG, " + " + packageName); 2831 } 2832 // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual 2833 // state w.r.t. the formal app-linkage "no verification attempted" state; 2834 // and then 'always' in the per-user state actually used for intent resolution. 2835 final IntentFilterVerificationInfo ivi; 2836 ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, 2837 new ArrayList<String>(domains)); 2838 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED); 2839 mSettings.updateIntentFilterVerificationStatusLPw(packageName, 2840 INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId); 2841 } else { 2842 Slog.w(TAG, "Sysconfig <app-link> package '" + packageName 2843 + "' does not handle web links"); 2844 } 2845 } else { 2846 Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>"); 2847 } 2848 } 2849 2850 scheduleWritePackageRestrictionsLocked(userId); 2851 scheduleWriteSettingsLocked(); 2852 } 2853 2854 private void applyFactoryDefaultBrowserLPw(int userId) { 2855 // The default browser app's package name is stored in a string resource, 2856 // with a product-specific overlay used for vendor customization. 2857 String browserPkg = mContext.getResources().getString( 2858 com.android.internal.R.string.default_browser); 2859 if (!TextUtils.isEmpty(browserPkg)) { 2860 // non-empty string => required to be a known package 2861 PackageSetting ps = mSettings.mPackages.get(browserPkg); 2862 if (ps == null) { 2863 Slog.e(TAG, "Product default browser app does not exist: " + browserPkg); 2864 browserPkg = null; 2865 } else { 2866 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId); 2867 } 2868 } 2869 2870 // Nothing valid explicitly set? Make the factory-installed browser the explicit 2871 // default. If there's more than one, just leave everything alone. 2872 if (browserPkg == null) { 2873 calculateDefaultBrowserLPw(userId); 2874 } 2875 } 2876 2877 private void calculateDefaultBrowserLPw(int userId) { 2878 List<String> allBrowsers = resolveAllBrowserApps(userId); 2879 final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null; 2880 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId); 2881 } 2882 2883 private List<String> resolveAllBrowserApps(int userId) { 2884 // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set 2885 List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null, 2886 PackageManager.MATCH_ALL, userId); 2887 2888 final int count = list.size(); 2889 List<String> result = new ArrayList<String>(count); 2890 for (int i=0; i<count; i++) { 2891 ResolveInfo info = list.get(i); 2892 if (info.activityInfo == null 2893 || !info.handleAllWebDataURI 2894 || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0 2895 || result.contains(info.activityInfo.packageName)) { 2896 continue; 2897 } 2898 result.add(info.activityInfo.packageName); 2899 } 2900 2901 return result; 2902 } 2903 2904 private boolean packageIsBrowser(String packageName, int userId) { 2905 List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null, 2906 PackageManager.MATCH_ALL, userId); 2907 final int N = list.size(); 2908 for (int i = 0; i < N; i++) { 2909 ResolveInfo info = list.get(i); 2910 if (packageName.equals(info.activityInfo.packageName)) { 2911 return true; 2912 } 2913 } 2914 return false; 2915 } 2916 2917 private void checkDefaultBrowser() { 2918 final int myUserId = UserHandle.myUserId(); 2919 final String packageName = getDefaultBrowserPackageName(myUserId); 2920 if (packageName != null) { 2921 PackageInfo info = getPackageInfo(packageName, 0, myUserId); 2922 if (info == null) { 2923 Slog.w(TAG, "Default browser no longer installed: " + packageName); 2924 synchronized (mPackages) { 2925 applyFactoryDefaultBrowserLPw(myUserId); // leaves ambiguous when > 1 2926 } 2927 } 2928 } 2929 } 2930 2931 @Override 2932 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2933 throws RemoteException { 2934 try { 2935 return super.onTransact(code, data, reply, flags); 2936 } catch (RuntimeException e) { 2937 if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) { 2938 Slog.wtf(TAG, "Package Manager Crash", e); 2939 } 2940 throw e; 2941 } 2942 } 2943 2944 void cleanupInstallFailedPackage(PackageSetting ps) { 2945 logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + ps.name); 2946 2947 removeDataDirsLI(ps.volumeUuid, ps.name); 2948 if (ps.codePath != null) { 2949 removeCodePathLI(ps.codePath); 2950 } 2951 if (ps.resourcePath != null && !ps.resourcePath.equals(ps.codePath)) { 2952 if (ps.resourcePath.isDirectory()) { 2953 FileUtils.deleteContents(ps.resourcePath); 2954 } 2955 ps.resourcePath.delete(); 2956 } 2957 mSettings.removePackageLPw(ps.name); 2958 } 2959 2960 static int[] appendInts(int[] cur, int[] add) { 2961 if (add == null) return cur; 2962 if (cur == null) return add; 2963 final int N = add.length; 2964 for (int i=0; i<N; i++) { 2965 cur = appendInt(cur, add[i]); 2966 } 2967 return cur; 2968 } 2969 2970 private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) { 2971 if (!sUserManager.exists(userId)) return null; 2972 if (ps == null) { 2973 return null; 2974 } 2975 final PackageParser.Package p = ps.pkg; 2976 if (p == null) { 2977 return null; 2978 } 2979 2980 final PermissionsState permissionsState = ps.getPermissionsState(); 2981 2982 final int[] gids = permissionsState.computeGids(userId); 2983 final Set<String> permissions = permissionsState.getPermissions(userId); 2984 final PackageUserState state = ps.readUserState(userId); 2985 2986 return PackageParser.generatePackageInfo(p, gids, flags, 2987 ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId); 2988 } 2989 2990 @Override 2991 public void checkPackageStartable(String packageName, int userId) { 2992 final boolean userKeyUnlocked = isUserKeyUnlocked(userId); 2993 2994 synchronized (mPackages) { 2995 final PackageSetting ps = mSettings.mPackages.get(packageName); 2996 if (ps == null) { 2997 throw new SecurityException("Package " + packageName + " was not found!"); 2998 } 2999 3000 if (!ps.getInstalled(userId)) { 3001 throw new SecurityException( 3002 "Package " + packageName + " was not installed for user " + userId + "!"); 3003 } 3004 3005 if (mSafeMode && !ps.isSystem()) { 3006 throw new SecurityException("Package " + packageName + " not a system app!"); 3007 } 3008 3009 if (ps.frozen) { 3010 throw new SecurityException("Package " + packageName + " is currently frozen!"); 3011 } 3012 3013 if (!userKeyUnlocked && !(ps.pkg.applicationInfo.isDirectBootAware() 3014 || ps.pkg.applicationInfo.isPartiallyDirectBootAware())) { 3015 throw new SecurityException("Package " + packageName + " is not encryption aware!"); 3016 } 3017 } 3018 } 3019 3020 @Override 3021 public boolean isPackageAvailable(String packageName, int userId) { 3022 if (!sUserManager.exists(userId)) return false; 3023 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3024 false /* requireFullPermission */, false /* checkShell */, "is package available"); 3025 synchronized (mPackages) { 3026 PackageParser.Package p = mPackages.get(packageName); 3027 if (p != null) { 3028 final PackageSetting ps = (PackageSetting) p.mExtras; 3029 if (ps != null) { 3030 final PackageUserState state = ps.readUserState(userId); 3031 if (state != null) { 3032 return PackageParser.isAvailable(state); 3033 } 3034 } 3035 } 3036 } 3037 return false; 3038 } 3039 3040 @Override 3041 public PackageInfo getPackageInfo(String packageName, int flags, int userId) { 3042 if (!sUserManager.exists(userId)) return null; 3043 flags = updateFlagsForPackage(flags, userId, packageName); 3044 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3045 false /* requireFullPermission */, false /* checkShell */, "get package info"); 3046 // reader 3047 synchronized (mPackages) { 3048 final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0; 3049 PackageParser.Package p = null; 3050 if (matchFactoryOnly) { 3051 final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName); 3052 if (ps != null) { 3053 return generatePackageInfo(ps, flags, userId); 3054 } 3055 } 3056 if (p == null) { 3057 p = mPackages.get(packageName); 3058 if (matchFactoryOnly && p != null && !isSystemApp(p)) { 3059 return null; 3060 } 3061 } 3062 if (DEBUG_PACKAGE_INFO) 3063 Log.v(TAG, "getPackageInfo " + packageName + ": " + p); 3064 if (p != null) { 3065 return generatePackageInfo((PackageSetting)p.mExtras, flags, userId); 3066 } 3067 if (!matchFactoryOnly && (flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 3068 final PackageSetting ps = mSettings.mPackages.get(packageName); 3069 return generatePackageInfo(ps, flags, userId); 3070 } 3071 } 3072 return null; 3073 } 3074 3075 @Override 3076 public String[] currentToCanonicalPackageNames(String[] names) { 3077 String[] out = new String[names.length]; 3078 // reader 3079 synchronized (mPackages) { 3080 for (int i=names.length-1; i>=0; i--) { 3081 PackageSetting ps = mSettings.mPackages.get(names[i]); 3082 out[i] = ps != null && ps.realName != null ? ps.realName : names[i]; 3083 } 3084 } 3085 return out; 3086 } 3087 3088 @Override 3089 public String[] canonicalToCurrentPackageNames(String[] names) { 3090 String[] out = new String[names.length]; 3091 // reader 3092 synchronized (mPackages) { 3093 for (int i=names.length-1; i>=0; i--) { 3094 String cur = mSettings.mRenamedPackages.get(names[i]); 3095 out[i] = cur != null ? cur : names[i]; 3096 } 3097 } 3098 return out; 3099 } 3100 3101 @Override 3102 public int getPackageUid(String packageName, int flags, int userId) { 3103 if (!sUserManager.exists(userId)) return -1; 3104 flags = updateFlagsForPackage(flags, userId, packageName); 3105 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3106 false /* requireFullPermission */, false /* checkShell */, "get package uid"); 3107 3108 // reader 3109 synchronized (mPackages) { 3110 final PackageParser.Package p = mPackages.get(packageName); 3111 if (p != null && p.isMatch(flags)) { 3112 return UserHandle.getUid(userId, p.applicationInfo.uid); 3113 } 3114 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 3115 final PackageSetting ps = mSettings.mPackages.get(packageName); 3116 if (ps != null && ps.isMatch(flags)) { 3117 return UserHandle.getUid(userId, ps.appId); 3118 } 3119 } 3120 } 3121 3122 return -1; 3123 } 3124 3125 @Override 3126 public int[] getPackageGids(String packageName, int flags, int userId) { 3127 if (!sUserManager.exists(userId)) return null; 3128 flags = updateFlagsForPackage(flags, userId, packageName); 3129 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3130 false /* requireFullPermission */, false /* checkShell */, 3131 "getPackageGids"); 3132 3133 // reader 3134 synchronized (mPackages) { 3135 final PackageParser.Package p = mPackages.get(packageName); 3136 if (p != null && p.isMatch(flags)) { 3137 PackageSetting ps = (PackageSetting) p.mExtras; 3138 return ps.getPermissionsState().computeGids(userId); 3139 } 3140 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 3141 final PackageSetting ps = mSettings.mPackages.get(packageName); 3142 if (ps != null && ps.isMatch(flags)) { 3143 return ps.getPermissionsState().computeGids(userId); 3144 } 3145 } 3146 } 3147 3148 return null; 3149 } 3150 3151 static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) { 3152 if (bp.perm != null) { 3153 return PackageParser.generatePermissionInfo(bp.perm, flags); 3154 } 3155 PermissionInfo pi = new PermissionInfo(); 3156 pi.name = bp.name; 3157 pi.packageName = bp.sourcePackage; 3158 pi.nonLocalizedLabel = bp.name; 3159 pi.protectionLevel = bp.protectionLevel; 3160 return pi; 3161 } 3162 3163 @Override 3164 public PermissionInfo getPermissionInfo(String name, int flags) { 3165 // reader 3166 synchronized (mPackages) { 3167 final BasePermission p = mSettings.mPermissions.get(name); 3168 if (p != null) { 3169 return generatePermissionInfo(p, flags); 3170 } 3171 return null; 3172 } 3173 } 3174 3175 @Override 3176 public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group, 3177 int flags) { 3178 // reader 3179 synchronized (mPackages) { 3180 if (group != null && !mPermissionGroups.containsKey(group)) { 3181 // This is thrown as NameNotFoundException 3182 return null; 3183 } 3184 3185 ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10); 3186 for (BasePermission p : mSettings.mPermissions.values()) { 3187 if (group == null) { 3188 if (p.perm == null || p.perm.info.group == null) { 3189 out.add(generatePermissionInfo(p, flags)); 3190 } 3191 } else { 3192 if (p.perm != null && group.equals(p.perm.info.group)) { 3193 out.add(PackageParser.generatePermissionInfo(p.perm, flags)); 3194 } 3195 } 3196 } 3197 return new ParceledListSlice<>(out); 3198 } 3199 } 3200 3201 @Override 3202 public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) { 3203 // reader 3204 synchronized (mPackages) { 3205 return PackageParser.generatePermissionGroupInfo( 3206 mPermissionGroups.get(name), flags); 3207 } 3208 } 3209 3210 @Override 3211 public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) { 3212 // reader 3213 synchronized (mPackages) { 3214 final int N = mPermissionGroups.size(); 3215 ArrayList<PermissionGroupInfo> out 3216 = new ArrayList<PermissionGroupInfo>(N); 3217 for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) { 3218 out.add(PackageParser.generatePermissionGroupInfo(pg, flags)); 3219 } 3220 return new ParceledListSlice<>(out); 3221 } 3222 } 3223 3224 private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags, 3225 int userId) { 3226 if (!sUserManager.exists(userId)) return null; 3227 PackageSetting ps = mSettings.mPackages.get(packageName); 3228 if (ps != null) { 3229 if (ps.pkg == null) { 3230 final PackageInfo pInfo = generatePackageInfo(ps, flags, userId); 3231 if (pInfo != null) { 3232 return pInfo.applicationInfo; 3233 } 3234 return null; 3235 } 3236 return PackageParser.generateApplicationInfo(ps.pkg, flags, 3237 ps.readUserState(userId), userId); 3238 } 3239 return null; 3240 } 3241 3242 @Override 3243 public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) { 3244 if (!sUserManager.exists(userId)) return null; 3245 flags = updateFlagsForApplication(flags, userId, packageName); 3246 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3247 false /* requireFullPermission */, false /* checkShell */, "get application info"); 3248 // writer 3249 synchronized (mPackages) { 3250 PackageParser.Package p = mPackages.get(packageName); 3251 if (DEBUG_PACKAGE_INFO) Log.v( 3252 TAG, "getApplicationInfo " + packageName 3253 + ": " + p); 3254 if (p != null) { 3255 PackageSetting ps = mSettings.mPackages.get(packageName); 3256 if (ps == null) return null; 3257 // Note: isEnabledLP() does not apply here - always return info 3258 return PackageParser.generateApplicationInfo( 3259 p, flags, ps.readUserState(userId), userId); 3260 } 3261 if ("android".equals(packageName)||"system".equals(packageName)) { 3262 return mAndroidApplication; 3263 } 3264 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 3265 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId); 3266 } 3267 } 3268 return null; 3269 } 3270 3271 @Override 3272 public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize, 3273 final IPackageDataObserver observer) { 3274 mContext.enforceCallingOrSelfPermission( 3275 android.Manifest.permission.CLEAR_APP_CACHE, null); 3276 // Queue up an async operation since clearing cache may take a little while. 3277 mHandler.post(new Runnable() { 3278 public void run() { 3279 mHandler.removeCallbacks(this); 3280 boolean success = true; 3281 synchronized (mInstallLock) { 3282 try { 3283 mInstaller.freeCache(volumeUuid, freeStorageSize); 3284 } catch (InstallerException e) { 3285 Slog.w(TAG, "Couldn't clear application caches: " + e); 3286 success = false; 3287 } 3288 } 3289 if (observer != null) { 3290 try { 3291 observer.onRemoveCompleted(null, success); 3292 } catch (RemoteException e) { 3293 Slog.w(TAG, "RemoveException when invoking call back"); 3294 } 3295 } 3296 } 3297 }); 3298 } 3299 3300 @Override 3301 public void freeStorage(final String volumeUuid, final long freeStorageSize, 3302 final IntentSender pi) { 3303 mContext.enforceCallingOrSelfPermission( 3304 android.Manifest.permission.CLEAR_APP_CACHE, null); 3305 // Queue up an async operation since clearing cache may take a little while. 3306 mHandler.post(new Runnable() { 3307 public void run() { 3308 mHandler.removeCallbacks(this); 3309 boolean success = true; 3310 synchronized (mInstallLock) { 3311 try { 3312 mInstaller.freeCache(volumeUuid, freeStorageSize); 3313 } catch (InstallerException e) { 3314 Slog.w(TAG, "Couldn't clear application caches: " + e); 3315 success = false; 3316 } 3317 } 3318 if(pi != null) { 3319 try { 3320 // Callback via pending intent 3321 int code = success ? 1 : 0; 3322 pi.sendIntent(null, code, null, 3323 null, null); 3324 } catch (SendIntentException e1) { 3325 Slog.i(TAG, "Failed to send pending intent"); 3326 } 3327 } 3328 } 3329 }); 3330 } 3331 3332 void freeStorage(String volumeUuid, long freeStorageSize) throws IOException { 3333 synchronized (mInstallLock) { 3334 try { 3335 mInstaller.freeCache(volumeUuid, freeStorageSize); 3336 } catch (InstallerException e) { 3337 throw new IOException("Failed to free enough space", e); 3338 } 3339 } 3340 } 3341 3342 /** 3343 * Return if the user key is currently unlocked. 3344 */ 3345 private boolean isUserKeyUnlocked(int userId) { 3346 if (StorageManager.isFileEncryptedNativeOrEmulated()) { 3347 final IMountService mount = IMountService.Stub 3348 .asInterface(ServiceManager.getService("mount")); 3349 if (mount == null) { 3350 Slog.w(TAG, "Early during boot, assuming locked"); 3351 return false; 3352 } 3353 final long token = Binder.clearCallingIdentity(); 3354 try { 3355 return mount.isUserKeyUnlocked(userId); 3356 } catch (RemoteException e) { 3357 throw e.rethrowAsRuntimeException(); 3358 } finally { 3359 Binder.restoreCallingIdentity(token); 3360 } 3361 } else { 3362 return true; 3363 } 3364 } 3365 3366 /** 3367 * Update given flags based on encryption status of current user. 3368 */ 3369 private int updateFlags(int flags, int userId) { 3370 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE 3371 | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) { 3372 // Caller expressed an explicit opinion about what encryption 3373 // aware/unaware components they want to see, so fall through and 3374 // give them what they want 3375 } else { 3376 // Caller expressed no opinion, so match based on user state 3377 if (isUserKeyUnlocked(userId)) { 3378 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE; 3379 } else { 3380 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE; 3381 } 3382 } 3383 return flags; 3384 } 3385 3386 /** 3387 * Update given flags when being used to request {@link PackageInfo}. 3388 */ 3389 private int updateFlagsForPackage(int flags, int userId, Object cookie) { 3390 boolean triaged = true; 3391 if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS 3392 | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) { 3393 // Caller is asking for component details, so they'd better be 3394 // asking for specific encryption matching behavior, or be triaged 3395 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE 3396 | PackageManager.MATCH_DIRECT_BOOT_AWARE 3397 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3398 triaged = false; 3399 } 3400 } 3401 if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES 3402 | PackageManager.MATCH_SYSTEM_ONLY 3403 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3404 triaged = false; 3405 } 3406 if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) { 3407 Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie 3408 + " with flags 0x" + Integer.toHexString(flags), new Throwable()); 3409 } 3410 return updateFlags(flags, userId); 3411 } 3412 3413 /** 3414 * Update given flags when being used to request {@link ApplicationInfo}. 3415 */ 3416 private int updateFlagsForApplication(int flags, int userId, Object cookie) { 3417 return updateFlagsForPackage(flags, userId, cookie); 3418 } 3419 3420 /** 3421 * Update given flags when being used to request {@link ComponentInfo}. 3422 */ 3423 private int updateFlagsForComponent(int flags, int userId, Object cookie) { 3424 if (cookie instanceof Intent) { 3425 if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) { 3426 flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING; 3427 } 3428 } 3429 3430 boolean triaged = true; 3431 // Caller is asking for component details, so they'd better be 3432 // asking for specific encryption matching behavior, or be triaged 3433 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE 3434 | PackageManager.MATCH_DIRECT_BOOT_AWARE 3435 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3436 triaged = false; 3437 } 3438 if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) { 3439 Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie 3440 + " with flags 0x" + Integer.toHexString(flags), new Throwable()); 3441 } 3442 3443 return updateFlags(flags, userId); 3444 } 3445 3446 /** 3447 * Update given flags when being used to request {@link ResolveInfo}. 3448 */ 3449 int updateFlagsForResolve(int flags, int userId, Object cookie) { 3450 // Safe mode means we shouldn't match any third-party components 3451 if (mSafeMode) { 3452 flags |= PackageManager.MATCH_SYSTEM_ONLY; 3453 } 3454 3455 return updateFlagsForComponent(flags, userId, cookie); 3456 } 3457 3458 @Override 3459 public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) { 3460 if (!sUserManager.exists(userId)) return null; 3461 flags = updateFlagsForComponent(flags, userId, component); 3462 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3463 false /* requireFullPermission */, false /* checkShell */, "get activity info"); 3464 synchronized (mPackages) { 3465 PackageParser.Activity a = mActivities.mActivities.get(component); 3466 3467 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a); 3468 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) { 3469 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3470 if (ps == null) return null; 3471 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 3472 userId); 3473 } 3474 if (mResolveComponentName.equals(component)) { 3475 return PackageParser.generateActivityInfo(mResolveActivity, flags, 3476 new PackageUserState(), userId); 3477 } 3478 } 3479 return null; 3480 } 3481 3482 @Override 3483 public boolean activitySupportsIntent(ComponentName component, Intent intent, 3484 String resolvedType) { 3485 synchronized (mPackages) { 3486 if (component.equals(mResolveComponentName)) { 3487 // The resolver supports EVERYTHING! 3488 return true; 3489 } 3490 PackageParser.Activity a = mActivities.mActivities.get(component); 3491 if (a == null) { 3492 return false; 3493 } 3494 for (int i=0; i<a.intents.size(); i++) { 3495 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(), 3496 intent.getData(), intent.getCategories(), TAG) >= 0) { 3497 return true; 3498 } 3499 } 3500 return false; 3501 } 3502 } 3503 3504 @Override 3505 public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) { 3506 if (!sUserManager.exists(userId)) return null; 3507 flags = updateFlagsForComponent(flags, userId, component); 3508 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3509 false /* requireFullPermission */, false /* checkShell */, "get receiver info"); 3510 synchronized (mPackages) { 3511 PackageParser.Activity a = mReceivers.mActivities.get(component); 3512 if (DEBUG_PACKAGE_INFO) Log.v( 3513 TAG, "getReceiverInfo " + component + ": " + a); 3514 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) { 3515 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3516 if (ps == null) return null; 3517 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 3518 userId); 3519 } 3520 } 3521 return null; 3522 } 3523 3524 @Override 3525 public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) { 3526 if (!sUserManager.exists(userId)) return null; 3527 flags = updateFlagsForComponent(flags, userId, component); 3528 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3529 false /* requireFullPermission */, false /* checkShell */, "get service info"); 3530 synchronized (mPackages) { 3531 PackageParser.Service s = mServices.mServices.get(component); 3532 if (DEBUG_PACKAGE_INFO) Log.v( 3533 TAG, "getServiceInfo " + component + ": " + s); 3534 if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) { 3535 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3536 if (ps == null) return null; 3537 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId), 3538 userId); 3539 } 3540 } 3541 return null; 3542 } 3543 3544 @Override 3545 public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) { 3546 if (!sUserManager.exists(userId)) return null; 3547 flags = updateFlagsForComponent(flags, userId, component); 3548 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3549 false /* requireFullPermission */, false /* checkShell */, "get provider info"); 3550 synchronized (mPackages) { 3551 PackageParser.Provider p = mProviders.mProviders.get(component); 3552 if (DEBUG_PACKAGE_INFO) Log.v( 3553 TAG, "getProviderInfo " + component + ": " + p); 3554 if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) { 3555 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3556 if (ps == null) return null; 3557 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId), 3558 userId); 3559 } 3560 } 3561 return null; 3562 } 3563 3564 @Override 3565 public String[] getSystemSharedLibraryNames() { 3566 Set<String> libSet; 3567 synchronized (mPackages) { 3568 libSet = mSharedLibraries.keySet(); 3569 int size = libSet.size(); 3570 if (size > 0) { 3571 String[] libs = new String[size]; 3572 libSet.toArray(libs); 3573 return libs; 3574 } 3575 } 3576 return null; 3577 } 3578 3579 @Override 3580 public @NonNull String getServicesSystemSharedLibraryPackageName() { 3581 synchronized (mPackages) { 3582 return mServicesSystemSharedLibraryPackageName; 3583 } 3584 } 3585 3586 @Override 3587 public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() { 3588 synchronized (mPackages) { 3589 final ArrayList<FeatureInfo> res = new ArrayList<>(mAvailableFeatures.values()); 3590 3591 final FeatureInfo fi = new FeatureInfo(); 3592 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version", 3593 FeatureInfo.GL_ES_VERSION_UNDEFINED); 3594 res.add(fi); 3595 3596 return new ParceledListSlice<>(res); 3597 } 3598 } 3599 3600 @Override 3601 public boolean hasSystemFeature(String name, int version) { 3602 synchronized (mPackages) { 3603 final FeatureInfo feat = mAvailableFeatures.get(name); 3604 if (feat == null) { 3605 return false; 3606 } else { 3607 return feat.version >= version; 3608 } 3609 } 3610 } 3611 3612 @Override 3613 public int checkPermission(String permName, String pkgName, int userId) { 3614 if (!sUserManager.exists(userId)) { 3615 return PackageManager.PERMISSION_DENIED; 3616 } 3617 3618 synchronized (mPackages) { 3619 final PackageParser.Package p = mPackages.get(pkgName); 3620 if (p != null && p.mExtras != null) { 3621 final PackageSetting ps = (PackageSetting) p.mExtras; 3622 final PermissionsState permissionsState = ps.getPermissionsState(); 3623 if (permissionsState.hasPermission(permName, userId)) { 3624 return PackageManager.PERMISSION_GRANTED; 3625 } 3626 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION 3627 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState 3628 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { 3629 return PackageManager.PERMISSION_GRANTED; 3630 } 3631 } 3632 } 3633 3634 return PackageManager.PERMISSION_DENIED; 3635 } 3636 3637 @Override 3638 public int checkUidPermission(String permName, int uid) { 3639 final int userId = UserHandle.getUserId(uid); 3640 3641 if (!sUserManager.exists(userId)) { 3642 return PackageManager.PERMISSION_DENIED; 3643 } 3644 3645 synchronized (mPackages) { 3646 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 3647 if (obj != null) { 3648 final SettingBase ps = (SettingBase) obj; 3649 final PermissionsState permissionsState = ps.getPermissionsState(); 3650 if (permissionsState.hasPermission(permName, userId)) { 3651 return PackageManager.PERMISSION_GRANTED; 3652 } 3653 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION 3654 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState 3655 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { 3656 return PackageManager.PERMISSION_GRANTED; 3657 } 3658 } else { 3659 ArraySet<String> perms = mSystemPermissions.get(uid); 3660 if (perms != null) { 3661 if (perms.contains(permName)) { 3662 return PackageManager.PERMISSION_GRANTED; 3663 } 3664 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms 3665 .contains(Manifest.permission.ACCESS_FINE_LOCATION)) { 3666 return PackageManager.PERMISSION_GRANTED; 3667 } 3668 } 3669 } 3670 } 3671 3672 return PackageManager.PERMISSION_DENIED; 3673 } 3674 3675 @Override 3676 public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) { 3677 if (UserHandle.getCallingUserId() != userId) { 3678 mContext.enforceCallingPermission( 3679 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 3680 "isPermissionRevokedByPolicy for user " + userId); 3681 } 3682 3683 if (checkPermission(permission, packageName, userId) 3684 == PackageManager.PERMISSION_GRANTED) { 3685 return false; 3686 } 3687 3688 final long identity = Binder.clearCallingIdentity(); 3689 try { 3690 final int flags = getPermissionFlags(permission, packageName, userId); 3691 return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0; 3692 } finally { 3693 Binder.restoreCallingIdentity(identity); 3694 } 3695 } 3696 3697 @Override 3698 public String getPermissionControllerPackageName() { 3699 synchronized (mPackages) { 3700 return mRequiredInstallerPackage; 3701 } 3702 } 3703 3704 /** 3705 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS 3706 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller. 3707 * @param checkShell whether to prevent shell from access if there's a debugging restriction 3708 * @param message the message to log on security exception 3709 */ 3710 void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, 3711 boolean checkShell, String message) { 3712 if (userId < 0) { 3713 throw new IllegalArgumentException("Invalid userId " + userId); 3714 } 3715 if (checkShell) { 3716 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); 3717 } 3718 if (userId == UserHandle.getUserId(callingUid)) return; 3719 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 3720 if (requireFullPermission) { 3721 mContext.enforceCallingOrSelfPermission( 3722 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 3723 } else { 3724 try { 3725 mContext.enforceCallingOrSelfPermission( 3726 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 3727 } catch (SecurityException se) { 3728 mContext.enforceCallingOrSelfPermission( 3729 android.Manifest.permission.INTERACT_ACROSS_USERS, message); 3730 } 3731 } 3732 } 3733 } 3734 3735 void enforceShellRestriction(String restriction, int callingUid, int userHandle) { 3736 if (callingUid == Process.SHELL_UID) { 3737 if (userHandle >= 0 3738 && sUserManager.hasUserRestriction(restriction, userHandle)) { 3739 throw new SecurityException("Shell does not have permission to access user " 3740 + userHandle); 3741 } else if (userHandle < 0) { 3742 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t" 3743 + Debug.getCallers(3)); 3744 } 3745 } 3746 } 3747 3748 private BasePermission findPermissionTreeLP(String permName) { 3749 for(BasePermission bp : mSettings.mPermissionTrees.values()) { 3750 if (permName.startsWith(bp.name) && 3751 permName.length() > bp.name.length() && 3752 permName.charAt(bp.name.length()) == '.') { 3753 return bp; 3754 } 3755 } 3756 return null; 3757 } 3758 3759 private BasePermission checkPermissionTreeLP(String permName) { 3760 if (permName != null) { 3761 BasePermission bp = findPermissionTreeLP(permName); 3762 if (bp != null) { 3763 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) { 3764 return bp; 3765 } 3766 throw new SecurityException("Calling uid " 3767 + Binder.getCallingUid() 3768 + " is not allowed to add to permission tree " 3769 + bp.name + " owned by uid " + bp.uid); 3770 } 3771 } 3772 throw new SecurityException("No permission tree found for " + permName); 3773 } 3774 3775 static boolean compareStrings(CharSequence s1, CharSequence s2) { 3776 if (s1 == null) { 3777 return s2 == null; 3778 } 3779 if (s2 == null) { 3780 return false; 3781 } 3782 if (s1.getClass() != s2.getClass()) { 3783 return false; 3784 } 3785 return s1.equals(s2); 3786 } 3787 3788 static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) { 3789 if (pi1.icon != pi2.icon) return false; 3790 if (pi1.logo != pi2.logo) return false; 3791 if (pi1.protectionLevel != pi2.protectionLevel) return false; 3792 if (!compareStrings(pi1.name, pi2.name)) return false; 3793 if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false; 3794 // We'll take care of setting this one. 3795 if (!compareStrings(pi1.packageName, pi2.packageName)) return false; 3796 // These are not currently stored in settings. 3797 //if (!compareStrings(pi1.group, pi2.group)) return false; 3798 //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false; 3799 //if (pi1.labelRes != pi2.labelRes) return false; 3800 //if (pi1.descriptionRes != pi2.descriptionRes) return false; 3801 return true; 3802 } 3803 3804 int permissionInfoFootprint(PermissionInfo info) { 3805 int size = info.name.length(); 3806 if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length(); 3807 if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length(); 3808 return size; 3809 } 3810 3811 int calculateCurrentPermissionFootprintLocked(BasePermission tree) { 3812 int size = 0; 3813 for (BasePermission perm : mSettings.mPermissions.values()) { 3814 if (perm.uid == tree.uid) { 3815 size += perm.name.length() + permissionInfoFootprint(perm.perm.info); 3816 } 3817 } 3818 return size; 3819 } 3820 3821 void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) { 3822 // We calculate the max size of permissions defined by this uid and throw 3823 // if that plus the size of 'info' would exceed our stated maximum. 3824 if (tree.uid != Process.SYSTEM_UID) { 3825 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree); 3826 if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) { 3827 throw new SecurityException("Permission tree size cap exceeded"); 3828 } 3829 } 3830 } 3831 3832 boolean addPermissionLocked(PermissionInfo info, boolean async) { 3833 if (info.labelRes == 0 && info.nonLocalizedLabel == null) { 3834 throw new SecurityException("Label must be specified in permission"); 3835 } 3836 BasePermission tree = checkPermissionTreeLP(info.name); 3837 BasePermission bp = mSettings.mPermissions.get(info.name); 3838 boolean added = bp == null; 3839 boolean changed = true; 3840 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel); 3841 if (added) { 3842 enforcePermissionCapLocked(info, tree); 3843 bp = new BasePermission(info.name, tree.sourcePackage, 3844 BasePermission.TYPE_DYNAMIC); 3845 } else if (bp.type != BasePermission.TYPE_DYNAMIC) { 3846 throw new SecurityException( 3847 "Not allowed to modify non-dynamic permission " 3848 + info.name); 3849 } else { 3850 if (bp.protectionLevel == fixedLevel 3851 && bp.perm.owner.equals(tree.perm.owner) 3852 && bp.uid == tree.uid 3853 && comparePermissionInfos(bp.perm.info, info)) { 3854 changed = false; 3855 } 3856 } 3857 bp.protectionLevel = fixedLevel; 3858 info = new PermissionInfo(info); 3859 info.protectionLevel = fixedLevel; 3860 bp.perm = new PackageParser.Permission(tree.perm.owner, info); 3861 bp.perm.info.packageName = tree.perm.info.packageName; 3862 bp.uid = tree.uid; 3863 if (added) { 3864 mSettings.mPermissions.put(info.name, bp); 3865 } 3866 if (changed) { 3867 if (!async) { 3868 mSettings.writeLPr(); 3869 } else { 3870 scheduleWriteSettingsLocked(); 3871 } 3872 } 3873 return added; 3874 } 3875 3876 @Override 3877 public boolean addPermission(PermissionInfo info) { 3878 synchronized (mPackages) { 3879 return addPermissionLocked(info, false); 3880 } 3881 } 3882 3883 @Override 3884 public boolean addPermissionAsync(PermissionInfo info) { 3885 synchronized (mPackages) { 3886 return addPermissionLocked(info, true); 3887 } 3888 } 3889 3890 @Override 3891 public void removePermission(String name) { 3892 synchronized (mPackages) { 3893 checkPermissionTreeLP(name); 3894 BasePermission bp = mSettings.mPermissions.get(name); 3895 if (bp != null) { 3896 if (bp.type != BasePermission.TYPE_DYNAMIC) { 3897 throw new SecurityException( 3898 "Not allowed to modify non-dynamic permission " 3899 + name); 3900 } 3901 mSettings.mPermissions.remove(name); 3902 mSettings.writeLPr(); 3903 } 3904 } 3905 } 3906 3907 private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg, 3908 BasePermission bp) { 3909 int index = pkg.requestedPermissions.indexOf(bp.name); 3910 if (index == -1) { 3911 throw new SecurityException("Package " + pkg.packageName 3912 + " has not requested permission " + bp.name); 3913 } 3914 if (!bp.isRuntime() && !bp.isDevelopment()) { 3915 throw new SecurityException("Permission " + bp.name 3916 + " is not a changeable permission type"); 3917 } 3918 } 3919 3920 @Override 3921 public void grantRuntimePermission(String packageName, String name, final int userId) { 3922 if (!sUserManager.exists(userId)) { 3923 Log.e(TAG, "No such user:" + userId); 3924 return; 3925 } 3926 3927 mContext.enforceCallingOrSelfPermission( 3928 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 3929 "grantRuntimePermission"); 3930 3931 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3932 true /* requireFullPermission */, true /* checkShell */, 3933 "grantRuntimePermission"); 3934 3935 final int uid; 3936 final SettingBase sb; 3937 3938 synchronized (mPackages) { 3939 final PackageParser.Package pkg = mPackages.get(packageName); 3940 if (pkg == null) { 3941 throw new IllegalArgumentException("Unknown package: " + packageName); 3942 } 3943 3944 final BasePermission bp = mSettings.mPermissions.get(name); 3945 if (bp == null) { 3946 throw new IllegalArgumentException("Unknown permission: " + name); 3947 } 3948 3949 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp); 3950 3951 // If a permission review is required for legacy apps we represent 3952 // their permissions as always granted runtime ones since we need 3953 // to keep the review required permission flag per user while an 3954 // install permission's state is shared across all users. 3955 if (Build.PERMISSIONS_REVIEW_REQUIRED 3956 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M 3957 && bp.isRuntime()) { 3958 return; 3959 } 3960 3961 uid = UserHandle.getUid(userId, pkg.applicationInfo.uid); 3962 sb = (SettingBase) pkg.mExtras; 3963 if (sb == null) { 3964 throw new IllegalArgumentException("Unknown package: " + packageName); 3965 } 3966 3967 final PermissionsState permissionsState = sb.getPermissionsState(); 3968 3969 final int flags = permissionsState.getPermissionFlags(name, userId); 3970 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 3971 throw new SecurityException("Cannot grant system fixed permission " 3972 + name + " for package " + packageName); 3973 } 3974 3975 if (bp.isDevelopment()) { 3976 // Development permissions must be handled specially, since they are not 3977 // normal runtime permissions. For now they apply to all users. 3978 if (permissionsState.grantInstallPermission(bp) != 3979 PermissionsState.PERMISSION_OPERATION_FAILURE) { 3980 scheduleWriteSettingsLocked(); 3981 } 3982 return; 3983 } 3984 3985 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 3986 Slog.w(TAG, "Cannot grant runtime permission to a legacy app"); 3987 return; 3988 } 3989 3990 final int result = permissionsState.grantRuntimePermission(bp, userId); 3991 switch (result) { 3992 case PermissionsState.PERMISSION_OPERATION_FAILURE: { 3993 return; 3994 } 3995 3996 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 3997 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); 3998 mHandler.post(new Runnable() { 3999 @Override 4000 public void run() { 4001 killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED); 4002 } 4003 }); 4004 } 4005 break; 4006 } 4007 4008 mOnPermissionChangeListeners.onPermissionsChanged(uid); 4009 4010 // Not critical if that is lost - app has to request again. 4011 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 4012 } 4013 4014 // Only need to do this if user is initialized. Otherwise it's a new user 4015 // and there are no processes running as the user yet and there's no need 4016 // to make an expensive call to remount processes for the changed permissions. 4017 if (READ_EXTERNAL_STORAGE.equals(name) 4018 || WRITE_EXTERNAL_STORAGE.equals(name)) { 4019 final long token = Binder.clearCallingIdentity(); 4020 try { 4021 if (sUserManager.isInitialized(userId)) { 4022 MountServiceInternal mountServiceInternal = LocalServices.getService( 4023 MountServiceInternal.class); 4024 mountServiceInternal.onExternalStoragePolicyChanged(uid, packageName); 4025 } 4026 } finally { 4027 Binder.restoreCallingIdentity(token); 4028 } 4029 } 4030 } 4031 4032 @Override 4033 public void revokeRuntimePermission(String packageName, String name, int userId) { 4034 if (!sUserManager.exists(userId)) { 4035 Log.e(TAG, "No such user:" + userId); 4036 return; 4037 } 4038 4039 mContext.enforceCallingOrSelfPermission( 4040 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 4041 "revokeRuntimePermission"); 4042 4043 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4044 true /* requireFullPermission */, true /* checkShell */, 4045 "revokeRuntimePermission"); 4046 4047 final int appId; 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 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp); 4061 4062 // If a permission review is required for legacy apps we represent 4063 // their permissions as always granted runtime ones since we need 4064 // to keep the review required permission flag per user while an 4065 // install permission's state is shared across all users. 4066 if (Build.PERMISSIONS_REVIEW_REQUIRED 4067 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M 4068 && bp.isRuntime()) { 4069 return; 4070 } 4071 4072 SettingBase sb = (SettingBase) pkg.mExtras; 4073 if (sb == null) { 4074 throw new IllegalArgumentException("Unknown package: " + packageName); 4075 } 4076 4077 final PermissionsState permissionsState = sb.getPermissionsState(); 4078 4079 final int flags = permissionsState.getPermissionFlags(name, userId); 4080 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 4081 throw new SecurityException("Cannot revoke system fixed permission " 4082 + name + " for package " + packageName); 4083 } 4084 4085 if (bp.isDevelopment()) { 4086 // Development permissions must be handled specially, since they are not 4087 // normal runtime permissions. For now they apply to all users. 4088 if (permissionsState.revokeInstallPermission(bp) != 4089 PermissionsState.PERMISSION_OPERATION_FAILURE) { 4090 scheduleWriteSettingsLocked(); 4091 } 4092 return; 4093 } 4094 4095 if (permissionsState.revokeRuntimePermission(bp, userId) == 4096 PermissionsState.PERMISSION_OPERATION_FAILURE) { 4097 return; 4098 } 4099 4100 mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid); 4101 4102 // Critical, after this call app should never have the permission. 4103 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 4104 4105 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 4106 } 4107 4108 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED); 4109 } 4110 4111 @Override 4112 public void resetRuntimePermissions() { 4113 mContext.enforceCallingOrSelfPermission( 4114 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 4115 "revokeRuntimePermission"); 4116 4117 int callingUid = Binder.getCallingUid(); 4118 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 4119 mContext.enforceCallingOrSelfPermission( 4120 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 4121 "resetRuntimePermissions"); 4122 } 4123 4124 synchronized (mPackages) { 4125 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL); 4126 for (int userId : UserManagerService.getInstance().getUserIds()) { 4127 final int packageCount = mPackages.size(); 4128 for (int i = 0; i < packageCount; i++) { 4129 PackageParser.Package pkg = mPackages.valueAt(i); 4130 if (!(pkg.mExtras instanceof PackageSetting)) { 4131 continue; 4132 } 4133 PackageSetting ps = (PackageSetting) pkg.mExtras; 4134 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 4135 } 4136 } 4137 } 4138 } 4139 4140 @Override 4141 public int getPermissionFlags(String name, String packageName, int userId) { 4142 if (!sUserManager.exists(userId)) { 4143 return 0; 4144 } 4145 4146 enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags"); 4147 4148 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4149 true /* requireFullPermission */, false /* checkShell */, 4150 "getPermissionFlags"); 4151 4152 synchronized (mPackages) { 4153 final PackageParser.Package pkg = mPackages.get(packageName); 4154 if (pkg == null) { 4155 throw new IllegalArgumentException("Unknown package: " + packageName); 4156 } 4157 4158 final BasePermission bp = mSettings.mPermissions.get(name); 4159 if (bp == null) { 4160 throw new IllegalArgumentException("Unknown permission: " + name); 4161 } 4162 4163 SettingBase sb = (SettingBase) pkg.mExtras; 4164 if (sb == null) { 4165 throw new IllegalArgumentException("Unknown package: " + packageName); 4166 } 4167 4168 PermissionsState permissionsState = sb.getPermissionsState(); 4169 return permissionsState.getPermissionFlags(name, userId); 4170 } 4171 } 4172 4173 @Override 4174 public void updatePermissionFlags(String name, String packageName, int flagMask, 4175 int flagValues, int userId) { 4176 if (!sUserManager.exists(userId)) { 4177 return; 4178 } 4179 4180 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags"); 4181 4182 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4183 true /* requireFullPermission */, true /* checkShell */, 4184 "updatePermissionFlags"); 4185 4186 // Only the system can change these flags and nothing else. 4187 if (getCallingUid() != Process.SYSTEM_UID) { 4188 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4189 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4190 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 4191 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 4192 flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 4193 } 4194 4195 synchronized (mPackages) { 4196 final PackageParser.Package pkg = mPackages.get(packageName); 4197 if (pkg == null) { 4198 throw new IllegalArgumentException("Unknown package: " + packageName); 4199 } 4200 4201 final BasePermission bp = mSettings.mPermissions.get(name); 4202 if (bp == null) { 4203 throw new IllegalArgumentException("Unknown permission: " + name); 4204 } 4205 4206 SettingBase sb = (SettingBase) pkg.mExtras; 4207 if (sb == null) { 4208 throw new IllegalArgumentException("Unknown package: " + packageName); 4209 } 4210 4211 PermissionsState permissionsState = sb.getPermissionsState(); 4212 4213 boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null; 4214 4215 if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) { 4216 // Install and runtime permissions are stored in different places, 4217 // so figure out what permission changed and persist the change. 4218 if (permissionsState.getInstallPermissionState(name) != null) { 4219 scheduleWriteSettingsLocked(); 4220 } else if (permissionsState.getRuntimePermissionState(name, userId) != null 4221 || hadState) { 4222 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 4223 } 4224 } 4225 } 4226 } 4227 4228 /** 4229 * Update the permission flags for all packages and runtime permissions of a user in order 4230 * to allow device or profile owner to remove POLICY_FIXED. 4231 */ 4232 @Override 4233 public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) { 4234 if (!sUserManager.exists(userId)) { 4235 return; 4236 } 4237 4238 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps"); 4239 4240 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4241 true /* requireFullPermission */, true /* checkShell */, 4242 "updatePermissionFlagsForAllApps"); 4243 4244 // Only the system can change system fixed flags. 4245 if (getCallingUid() != Process.SYSTEM_UID) { 4246 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4247 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4248 } 4249 4250 synchronized (mPackages) { 4251 boolean changed = false; 4252 final int packageCount = mPackages.size(); 4253 for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) { 4254 final PackageParser.Package pkg = mPackages.valueAt(pkgIndex); 4255 SettingBase sb = (SettingBase) pkg.mExtras; 4256 if (sb == null) { 4257 continue; 4258 } 4259 PermissionsState permissionsState = sb.getPermissionsState(); 4260 changed |= permissionsState.updatePermissionFlagsForAllPermissions( 4261 userId, flagMask, flagValues); 4262 } 4263 if (changed) { 4264 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 4265 } 4266 } 4267 } 4268 4269 private void enforceGrantRevokeRuntimePermissionPermissions(String message) { 4270 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS) 4271 != PackageManager.PERMISSION_GRANTED 4272 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) 4273 != PackageManager.PERMISSION_GRANTED) { 4274 throw new SecurityException(message + " requires " 4275 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or " 4276 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS); 4277 } 4278 } 4279 4280 @Override 4281 public boolean shouldShowRequestPermissionRationale(String permissionName, 4282 String packageName, int userId) { 4283 if (UserHandle.getCallingUserId() != userId) { 4284 mContext.enforceCallingPermission( 4285 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 4286 "canShowRequestPermissionRationale for user " + userId); 4287 } 4288 4289 final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId); 4290 if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) { 4291 return false; 4292 } 4293 4294 if (checkPermission(permissionName, packageName, userId) 4295 == PackageManager.PERMISSION_GRANTED) { 4296 return false; 4297 } 4298 4299 final int flags; 4300 4301 final long identity = Binder.clearCallingIdentity(); 4302 try { 4303 flags = getPermissionFlags(permissionName, 4304 packageName, userId); 4305 } finally { 4306 Binder.restoreCallingIdentity(identity); 4307 } 4308 4309 final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 4310 | PackageManager.FLAG_PERMISSION_POLICY_FIXED 4311 | PackageManager.FLAG_PERMISSION_USER_FIXED; 4312 4313 if ((flags & fixedFlags) != 0) { 4314 return false; 4315 } 4316 4317 return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0; 4318 } 4319 4320 @Override 4321 public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 4322 mContext.enforceCallingOrSelfPermission( 4323 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS, 4324 "addOnPermissionsChangeListener"); 4325 4326 synchronized (mPackages) { 4327 mOnPermissionChangeListeners.addListenerLocked(listener); 4328 } 4329 } 4330 4331 @Override 4332 public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 4333 synchronized (mPackages) { 4334 mOnPermissionChangeListeners.removeListenerLocked(listener); 4335 } 4336 } 4337 4338 @Override 4339 public boolean isProtectedBroadcast(String actionName) { 4340 synchronized (mPackages) { 4341 if (mProtectedBroadcasts.contains(actionName)) { 4342 return true; 4343 } else if (actionName != null) { 4344 // TODO: remove these terrible hacks 4345 if (actionName.startsWith("android.net.netmon.lingerExpired") 4346 || actionName.startsWith("com.android.server.sip.SipWakeupTimer") 4347 || actionName.startsWith("com.android.internal.telephony.data-reconnect") 4348 || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) { 4349 return true; 4350 } 4351 } 4352 } 4353 return false; 4354 } 4355 4356 @Override 4357 public int checkSignatures(String pkg1, String pkg2) { 4358 synchronized (mPackages) { 4359 final PackageParser.Package p1 = mPackages.get(pkg1); 4360 final PackageParser.Package p2 = mPackages.get(pkg2); 4361 if (p1 == null || p1.mExtras == null 4362 || p2 == null || p2.mExtras == null) { 4363 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4364 } 4365 return compareSignatures(p1.mSignatures, p2.mSignatures); 4366 } 4367 } 4368 4369 @Override 4370 public int checkUidSignatures(int uid1, int uid2) { 4371 // Map to base uids. 4372 uid1 = UserHandle.getAppId(uid1); 4373 uid2 = UserHandle.getAppId(uid2); 4374 // reader 4375 synchronized (mPackages) { 4376 Signature[] s1; 4377 Signature[] s2; 4378 Object obj = mSettings.getUserIdLPr(uid1); 4379 if (obj != null) { 4380 if (obj instanceof SharedUserSetting) { 4381 s1 = ((SharedUserSetting)obj).signatures.mSignatures; 4382 } else if (obj instanceof PackageSetting) { 4383 s1 = ((PackageSetting)obj).signatures.mSignatures; 4384 } else { 4385 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4386 } 4387 } else { 4388 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4389 } 4390 obj = mSettings.getUserIdLPr(uid2); 4391 if (obj != null) { 4392 if (obj instanceof SharedUserSetting) { 4393 s2 = ((SharedUserSetting)obj).signatures.mSignatures; 4394 } else if (obj instanceof PackageSetting) { 4395 s2 = ((PackageSetting)obj).signatures.mSignatures; 4396 } else { 4397 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4398 } 4399 } else { 4400 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4401 } 4402 return compareSignatures(s1, s2); 4403 } 4404 } 4405 4406 private void killUid(int appId, int userId, String reason) { 4407 final long identity = Binder.clearCallingIdentity(); 4408 try { 4409 IActivityManager am = ActivityManagerNative.getDefault(); 4410 if (am != null) { 4411 try { 4412 am.killUid(appId, userId, reason); 4413 } catch (RemoteException e) { 4414 /* ignore - same process */ 4415 } 4416 } 4417 } finally { 4418 Binder.restoreCallingIdentity(identity); 4419 } 4420 } 4421 4422 /** 4423 * Compares two sets of signatures. Returns: 4424 * <br /> 4425 * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null, 4426 * <br /> 4427 * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null, 4428 * <br /> 4429 * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null, 4430 * <br /> 4431 * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical, 4432 * <br /> 4433 * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ. 4434 */ 4435 static int compareSignatures(Signature[] s1, Signature[] s2) { 4436 if (s1 == null) { 4437 return s2 == null 4438 ? PackageManager.SIGNATURE_NEITHER_SIGNED 4439 : PackageManager.SIGNATURE_FIRST_NOT_SIGNED; 4440 } 4441 4442 if (s2 == null) { 4443 return PackageManager.SIGNATURE_SECOND_NOT_SIGNED; 4444 } 4445 4446 if (s1.length != s2.length) { 4447 return PackageManager.SIGNATURE_NO_MATCH; 4448 } 4449 4450 // Since both signature sets are of size 1, we can compare without HashSets. 4451 if (s1.length == 1) { 4452 return s1[0].equals(s2[0]) ? 4453 PackageManager.SIGNATURE_MATCH : 4454 PackageManager.SIGNATURE_NO_MATCH; 4455 } 4456 4457 ArraySet<Signature> set1 = new ArraySet<Signature>(); 4458 for (Signature sig : s1) { 4459 set1.add(sig); 4460 } 4461 ArraySet<Signature> set2 = new ArraySet<Signature>(); 4462 for (Signature sig : s2) { 4463 set2.add(sig); 4464 } 4465 // Make sure s2 contains all signatures in s1. 4466 if (set1.equals(set2)) { 4467 return PackageManager.SIGNATURE_MATCH; 4468 } 4469 return PackageManager.SIGNATURE_NO_MATCH; 4470 } 4471 4472 /** 4473 * If the database version for this type of package (internal storage or 4474 * external storage) is less than the version where package signatures 4475 * were updated, return true. 4476 */ 4477 private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 4478 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); 4479 return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY; 4480 } 4481 4482 /** 4483 * Used for backward compatibility to make sure any packages with 4484 * certificate chains get upgraded to the new style. {@code existingSigs} 4485 * will be in the old format (since they were stored on disk from before the 4486 * system upgrade) and {@code scannedSigs} will be in the newer format. 4487 */ 4488 private int compareSignaturesCompat(PackageSignatures existingSigs, 4489 PackageParser.Package scannedPkg) { 4490 if (!isCompatSignatureUpdateNeeded(scannedPkg)) { 4491 return PackageManager.SIGNATURE_NO_MATCH; 4492 } 4493 4494 ArraySet<Signature> existingSet = new ArraySet<Signature>(); 4495 for (Signature sig : existingSigs.mSignatures) { 4496 existingSet.add(sig); 4497 } 4498 ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>(); 4499 for (Signature sig : scannedPkg.mSignatures) { 4500 try { 4501 Signature[] chainSignatures = sig.getChainSignatures(); 4502 for (Signature chainSig : chainSignatures) { 4503 scannedCompatSet.add(chainSig); 4504 } 4505 } catch (CertificateEncodingException e) { 4506 scannedCompatSet.add(sig); 4507 } 4508 } 4509 /* 4510 * Make sure the expanded scanned set contains all signatures in the 4511 * existing one. 4512 */ 4513 if (scannedCompatSet.equals(existingSet)) { 4514 // Migrate the old signatures to the new scheme. 4515 existingSigs.assignSignatures(scannedPkg.mSignatures); 4516 // The new KeySets will be re-added later in the scanning process. 4517 synchronized (mPackages) { 4518 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName); 4519 } 4520 return PackageManager.SIGNATURE_MATCH; 4521 } 4522 return PackageManager.SIGNATURE_NO_MATCH; 4523 } 4524 4525 private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 4526 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); 4527 return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER; 4528 } 4529 4530 private int compareSignaturesRecover(PackageSignatures existingSigs, 4531 PackageParser.Package scannedPkg) { 4532 if (!isRecoverSignatureUpdateNeeded(scannedPkg)) { 4533 return PackageManager.SIGNATURE_NO_MATCH; 4534 } 4535 4536 String msg = null; 4537 try { 4538 if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) { 4539 logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for " 4540 + scannedPkg.packageName); 4541 return PackageManager.SIGNATURE_MATCH; 4542 } 4543 } catch (CertificateException e) { 4544 msg = e.getMessage(); 4545 } 4546 4547 logCriticalInfo(Log.INFO, 4548 "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg); 4549 return PackageManager.SIGNATURE_NO_MATCH; 4550 } 4551 4552 @Override 4553 public List<String> getAllPackages() { 4554 synchronized (mPackages) { 4555 return new ArrayList<String>(mPackages.keySet()); 4556 } 4557 } 4558 4559 @Override 4560 public String[] getPackagesForUid(int uid) { 4561 uid = UserHandle.getAppId(uid); 4562 // reader 4563 synchronized (mPackages) { 4564 Object obj = mSettings.getUserIdLPr(uid); 4565 if (obj instanceof SharedUserSetting) { 4566 final SharedUserSetting sus = (SharedUserSetting) obj; 4567 final int N = sus.packages.size(); 4568 final String[] res = new String[N]; 4569 final Iterator<PackageSetting> it = sus.packages.iterator(); 4570 int i = 0; 4571 while (it.hasNext()) { 4572 res[i++] = it.next().name; 4573 } 4574 return res; 4575 } else if (obj instanceof PackageSetting) { 4576 final PackageSetting ps = (PackageSetting) obj; 4577 return new String[] { ps.name }; 4578 } 4579 } 4580 return null; 4581 } 4582 4583 @Override 4584 public String getNameForUid(int uid) { 4585 // reader 4586 synchronized (mPackages) { 4587 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4588 if (obj instanceof SharedUserSetting) { 4589 final SharedUserSetting sus = (SharedUserSetting) obj; 4590 return sus.name + ":" + sus.userId; 4591 } else if (obj instanceof PackageSetting) { 4592 final PackageSetting ps = (PackageSetting) obj; 4593 return ps.name; 4594 } 4595 } 4596 return null; 4597 } 4598 4599 @Override 4600 public int getUidForSharedUser(String sharedUserName) { 4601 if(sharedUserName == null) { 4602 return -1; 4603 } 4604 // reader 4605 synchronized (mPackages) { 4606 final SharedUserSetting suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false); 4607 if (suid == null) { 4608 return -1; 4609 } 4610 return suid.userId; 4611 } 4612 } 4613 4614 @Override 4615 public int getFlagsForUid(int uid) { 4616 synchronized (mPackages) { 4617 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4618 if (obj instanceof SharedUserSetting) { 4619 final SharedUserSetting sus = (SharedUserSetting) obj; 4620 return sus.pkgFlags; 4621 } else if (obj instanceof PackageSetting) { 4622 final PackageSetting ps = (PackageSetting) obj; 4623 return ps.pkgFlags; 4624 } 4625 } 4626 return 0; 4627 } 4628 4629 @Override 4630 public int getPrivateFlagsForUid(int uid) { 4631 synchronized (mPackages) { 4632 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4633 if (obj instanceof SharedUserSetting) { 4634 final SharedUserSetting sus = (SharedUserSetting) obj; 4635 return sus.pkgPrivateFlags; 4636 } else if (obj instanceof PackageSetting) { 4637 final PackageSetting ps = (PackageSetting) obj; 4638 return ps.pkgPrivateFlags; 4639 } 4640 } 4641 return 0; 4642 } 4643 4644 @Override 4645 public boolean isUidPrivileged(int uid) { 4646 uid = UserHandle.getAppId(uid); 4647 // reader 4648 synchronized (mPackages) { 4649 Object obj = mSettings.getUserIdLPr(uid); 4650 if (obj instanceof SharedUserSetting) { 4651 final SharedUserSetting sus = (SharedUserSetting) obj; 4652 final Iterator<PackageSetting> it = sus.packages.iterator(); 4653 while (it.hasNext()) { 4654 if (it.next().isPrivileged()) { 4655 return true; 4656 } 4657 } 4658 } else if (obj instanceof PackageSetting) { 4659 final PackageSetting ps = (PackageSetting) obj; 4660 return ps.isPrivileged(); 4661 } 4662 } 4663 return false; 4664 } 4665 4666 @Override 4667 public String[] getAppOpPermissionPackages(String permissionName) { 4668 synchronized (mPackages) { 4669 ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName); 4670 if (pkgs == null) { 4671 return null; 4672 } 4673 return pkgs.toArray(new String[pkgs.size()]); 4674 } 4675 } 4676 4677 @Override 4678 public ResolveInfo resolveIntent(Intent intent, String resolvedType, 4679 int flags, int userId) { 4680 if (!sUserManager.exists(userId)) return null; 4681 flags = updateFlagsForResolve(flags, userId, intent); 4682 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4683 false /* requireFullPermission */, false /* checkShell */, "resolve intent"); 4684 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags, 4685 userId); 4686 final ResolveInfo bestChoice = 4687 chooseBestActivity(intent, resolvedType, flags, query, userId); 4688 4689 if (isEphemeralAllowed(intent, query, userId)) { 4690 final EphemeralResolveInfo ai = 4691 getEphemeralResolveInfo(intent, resolvedType, userId); 4692 if (ai != null) { 4693 if (DEBUG_EPHEMERAL) { 4694 Slog.v(TAG, "Returning an EphemeralResolveInfo"); 4695 } 4696 bestChoice.ephemeralInstaller = mEphemeralInstallerInfo; 4697 bestChoice.ephemeralResolveInfo = ai; 4698 } 4699 } 4700 return bestChoice; 4701 } 4702 4703 @Override 4704 public void setLastChosenActivity(Intent intent, String resolvedType, int flags, 4705 IntentFilter filter, int match, ComponentName activity) { 4706 final int userId = UserHandle.getCallingUserId(); 4707 if (DEBUG_PREFERRED) { 4708 Log.v(TAG, "setLastChosenActivity intent=" + intent 4709 + " resolvedType=" + resolvedType 4710 + " flags=" + flags 4711 + " filter=" + filter 4712 + " match=" + match 4713 + " activity=" + activity); 4714 filter.dump(new PrintStreamPrinter(System.out), " "); 4715 } 4716 intent.setComponent(null); 4717 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags, 4718 userId); 4719 // Find any earlier preferred or last chosen entries and nuke them 4720 findPreferredActivity(intent, resolvedType, 4721 flags, query, 0, false, true, false, userId); 4722 // Add the new activity as the last chosen for this filter 4723 addPreferredActivityInternal(filter, match, null, activity, false, userId, 4724 "Setting last chosen"); 4725 } 4726 4727 @Override 4728 public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) { 4729 final int userId = UserHandle.getCallingUserId(); 4730 if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent); 4731 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags, 4732 userId); 4733 return findPreferredActivity(intent, resolvedType, flags, query, 0, 4734 false, false, false, userId); 4735 } 4736 4737 4738 private boolean isEphemeralAllowed( 4739 Intent intent, List<ResolveInfo> resolvedActivites, int userId) { 4740 // Short circuit and return early if possible. 4741 if (DISABLE_EPHEMERAL_APPS) { 4742 return false; 4743 } 4744 final int callingUser = UserHandle.getCallingUserId(); 4745 if (callingUser != UserHandle.USER_SYSTEM) { 4746 return false; 4747 } 4748 if (mEphemeralResolverConnection == null) { 4749 return false; 4750 } 4751 if (intent.getComponent() != null) { 4752 return false; 4753 } 4754 if (intent.getPackage() != null) { 4755 return false; 4756 } 4757 final boolean isWebUri = hasWebURI(intent); 4758 if (!isWebUri) { 4759 return false; 4760 } 4761 // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution. 4762 synchronized (mPackages) { 4763 final int count = resolvedActivites.size(); 4764 for (int n = 0; n < count; n++) { 4765 ResolveInfo info = resolvedActivites.get(n); 4766 String packageName = info.activityInfo.packageName; 4767 PackageSetting ps = mSettings.mPackages.get(packageName); 4768 if (ps != null) { 4769 // Try to get the status from User settings first 4770 long packedStatus = getDomainVerificationStatusLPr(ps, userId); 4771 int status = (int) (packedStatus >> 32); 4772 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS 4773 || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) { 4774 if (DEBUG_EPHEMERAL) { 4775 Slog.v(TAG, "DENY ephemeral apps;" 4776 + " pkg: " + packageName + ", status: " + status); 4777 } 4778 return false; 4779 } 4780 } 4781 } 4782 } 4783 // We've exhausted all ways to deny ephemeral application; let the system look for them. 4784 return true; 4785 } 4786 4787 private EphemeralResolveInfo getEphemeralResolveInfo(Intent intent, String resolvedType, 4788 int userId) { 4789 MessageDigest digest = null; 4790 try { 4791 digest = MessageDigest.getInstance(EphemeralResolveInfo.SHA_ALGORITHM); 4792 } catch (NoSuchAlgorithmException e) { 4793 // If we can't create a digest, ignore ephemeral apps. 4794 return null; 4795 } 4796 4797 final byte[] hostBytes = intent.getData().getHost().getBytes(); 4798 final byte[] digestBytes = digest.digest(hostBytes); 4799 int shaPrefix = 4800 digestBytes[0] << 24 4801 | digestBytes[1] << 16 4802 | digestBytes[2] << 8 4803 | digestBytes[3] << 0; 4804 final List<EphemeralResolveInfo> ephemeralResolveInfoList = 4805 mEphemeralResolverConnection.getEphemeralResolveInfoList(shaPrefix); 4806 if (ephemeralResolveInfoList == null || ephemeralResolveInfoList.size() == 0) { 4807 // No hash prefix match; there are no ephemeral apps for this domain. 4808 return null; 4809 } 4810 for (int i = ephemeralResolveInfoList.size() - 1; i >= 0; --i) { 4811 EphemeralResolveInfo ephemeralApplication = ephemeralResolveInfoList.get(i); 4812 if (!Arrays.equals(digestBytes, ephemeralApplication.getDigestBytes())) { 4813 continue; 4814 } 4815 final List<IntentFilter> filters = ephemeralApplication.getFilters(); 4816 // No filters; this should never happen. 4817 if (filters.isEmpty()) { 4818 continue; 4819 } 4820 // We have a domain match; resolve the filters to see if anything matches. 4821 final EphemeralIntentResolver ephemeralResolver = new EphemeralIntentResolver(); 4822 for (int j = filters.size() - 1; j >= 0; --j) { 4823 final EphemeralResolveIntentInfo intentInfo = 4824 new EphemeralResolveIntentInfo(filters.get(j), ephemeralApplication); 4825 ephemeralResolver.addFilter(intentInfo); 4826 } 4827 List<EphemeralResolveInfo> matchedResolveInfoList = ephemeralResolver.queryIntent( 4828 intent, resolvedType, false /*defaultOnly*/, userId); 4829 if (!matchedResolveInfoList.isEmpty()) { 4830 return matchedResolveInfoList.get(0); 4831 } 4832 } 4833 // Hash or filter mis-match; no ephemeral apps for this domain. 4834 return null; 4835 } 4836 4837 private ResolveInfo chooseBestActivity(Intent intent, String resolvedType, 4838 int flags, List<ResolveInfo> query, int userId) { 4839 if (query != null) { 4840 final int N = query.size(); 4841 if (N == 1) { 4842 return query.get(0); 4843 } else if (N > 1) { 4844 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 4845 // If there is more than one activity with the same priority, 4846 // then let the user decide between them. 4847 ResolveInfo r0 = query.get(0); 4848 ResolveInfo r1 = query.get(1); 4849 if (DEBUG_INTENT_MATCHING || debug) { 4850 Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs " 4851 + r1.activityInfo.name + "=" + r1.priority); 4852 } 4853 // If the first activity has a higher priority, or a different 4854 // default, then it is always desirable to pick it. 4855 if (r0.priority != r1.priority 4856 || r0.preferredOrder != r1.preferredOrder 4857 || r0.isDefault != r1.isDefault) { 4858 return query.get(0); 4859 } 4860 // If we have saved a preference for a preferred activity for 4861 // this Intent, use that. 4862 ResolveInfo ri = findPreferredActivity(intent, resolvedType, 4863 flags, query, r0.priority, true, false, debug, userId); 4864 if (ri != null) { 4865 return ri; 4866 } 4867 ri = new ResolveInfo(mResolveInfo); 4868 ri.activityInfo = new ActivityInfo(ri.activityInfo); 4869 ri.activityInfo.applicationInfo = new ApplicationInfo( 4870 ri.activityInfo.applicationInfo); 4871 if (userId != 0) { 4872 ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId, 4873 UserHandle.getAppId(ri.activityInfo.applicationInfo.uid)); 4874 } 4875 // Make sure that the resolver is displayable in car mode 4876 if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle(); 4877 ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true); 4878 return ri; 4879 } 4880 } 4881 return null; 4882 } 4883 4884 private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType, 4885 int flags, List<ResolveInfo> query, boolean debug, int userId) { 4886 final int N = query.size(); 4887 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 4888 .get(userId); 4889 // Get the list of persistent preferred activities that handle the intent 4890 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities..."); 4891 List<PersistentPreferredActivity> pprefs = ppir != null 4892 ? ppir.queryIntent(intent, resolvedType, 4893 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 4894 : null; 4895 if (pprefs != null && pprefs.size() > 0) { 4896 final int M = pprefs.size(); 4897 for (int i=0; i<M; i++) { 4898 final PersistentPreferredActivity ppa = pprefs.get(i); 4899 if (DEBUG_PREFERRED || debug) { 4900 Slog.v(TAG, "Checking PersistentPreferredActivity ds=" 4901 + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>") 4902 + "\n component=" + ppa.mComponent); 4903 ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4904 } 4905 final ActivityInfo ai = getActivityInfo(ppa.mComponent, 4906 flags | MATCH_DISABLED_COMPONENTS, userId); 4907 if (DEBUG_PREFERRED || debug) { 4908 Slog.v(TAG, "Found persistent preferred activity:"); 4909 if (ai != null) { 4910 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 4911 } else { 4912 Slog.v(TAG, " null"); 4913 } 4914 } 4915 if (ai == null) { 4916 // This previously registered persistent preferred activity 4917 // component is no longer known. Ignore it and do NOT remove it. 4918 continue; 4919 } 4920 for (int j=0; j<N; j++) { 4921 final ResolveInfo ri = query.get(j); 4922 if (!ri.activityInfo.applicationInfo.packageName 4923 .equals(ai.applicationInfo.packageName)) { 4924 continue; 4925 } 4926 if (!ri.activityInfo.name.equals(ai.name)) { 4927 continue; 4928 } 4929 // Found a persistent preference that can handle the intent. 4930 if (DEBUG_PREFERRED || debug) { 4931 Slog.v(TAG, "Returning persistent preferred activity: " + 4932 ri.activityInfo.packageName + "/" + ri.activityInfo.name); 4933 } 4934 return ri; 4935 } 4936 } 4937 } 4938 return null; 4939 } 4940 4941 // TODO: handle preferred activities missing while user has amnesia 4942 ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags, 4943 List<ResolveInfo> query, int priority, boolean always, 4944 boolean removeMatches, boolean debug, int userId) { 4945 if (!sUserManager.exists(userId)) return null; 4946 flags = updateFlagsForResolve(flags, userId, intent); 4947 // writer 4948 synchronized (mPackages) { 4949 if (intent.getSelector() != null) { 4950 intent = intent.getSelector(); 4951 } 4952 if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION); 4953 4954 // Try to find a matching persistent preferred activity. 4955 ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query, 4956 debug, userId); 4957 4958 // If a persistent preferred activity matched, use it. 4959 if (pri != null) { 4960 return pri; 4961 } 4962 4963 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 4964 // Get the list of preferred activities that handle the intent 4965 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities..."); 4966 List<PreferredActivity> prefs = pir != null 4967 ? pir.queryIntent(intent, resolvedType, 4968 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 4969 : null; 4970 if (prefs != null && prefs.size() > 0) { 4971 boolean changed = false; 4972 try { 4973 // First figure out how good the original match set is. 4974 // We will only allow preferred activities that came 4975 // from the same match quality. 4976 int match = 0; 4977 4978 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match..."); 4979 4980 final int N = query.size(); 4981 for (int j=0; j<N; j++) { 4982 final ResolveInfo ri = query.get(j); 4983 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo 4984 + ": 0x" + Integer.toHexString(match)); 4985 if (ri.match > match) { 4986 match = ri.match; 4987 } 4988 } 4989 4990 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x" 4991 + Integer.toHexString(match)); 4992 4993 match &= IntentFilter.MATCH_CATEGORY_MASK; 4994 final int M = prefs.size(); 4995 for (int i=0; i<M; i++) { 4996 final PreferredActivity pa = prefs.get(i); 4997 if (DEBUG_PREFERRED || debug) { 4998 Slog.v(TAG, "Checking PreferredActivity ds=" 4999 + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>") 5000 + "\n component=" + pa.mPref.mComponent); 5001 pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 5002 } 5003 if (pa.mPref.mMatch != match) { 5004 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match " 5005 + Integer.toHexString(pa.mPref.mMatch)); 5006 continue; 5007 } 5008 // If it's not an "always" type preferred activity and that's what we're 5009 // looking for, skip it. 5010 if (always && !pa.mPref.mAlways) { 5011 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry"); 5012 continue; 5013 } 5014 final ActivityInfo ai = getActivityInfo( 5015 pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS 5016 | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 5017 userId); 5018 if (DEBUG_PREFERRED || debug) { 5019 Slog.v(TAG, "Found preferred activity:"); 5020 if (ai != null) { 5021 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 5022 } else { 5023 Slog.v(TAG, " null"); 5024 } 5025 } 5026 if (ai == null) { 5027 // This previously registered preferred activity 5028 // component is no longer known. Most likely an update 5029 // to the app was installed and in the new version this 5030 // component no longer exists. Clean it up by removing 5031 // it from the preferred activities list, and skip it. 5032 Slog.w(TAG, "Removing dangling preferred activity: " 5033 + pa.mPref.mComponent); 5034 pir.removeFilter(pa); 5035 changed = true; 5036 continue; 5037 } 5038 for (int j=0; j<N; j++) { 5039 final ResolveInfo ri = query.get(j); 5040 if (!ri.activityInfo.applicationInfo.packageName 5041 .equals(ai.applicationInfo.packageName)) { 5042 continue; 5043 } 5044 if (!ri.activityInfo.name.equals(ai.name)) { 5045 continue; 5046 } 5047 5048 if (removeMatches) { 5049 pir.removeFilter(pa); 5050 changed = true; 5051 if (DEBUG_PREFERRED) { 5052 Slog.v(TAG, "Removing match " + pa.mPref.mComponent); 5053 } 5054 break; 5055 } 5056 5057 // Okay we found a previously set preferred or last chosen app. 5058 // If the result set is different from when this 5059 // was created, we need to clear it and re-ask the 5060 // user their preference, if we're looking for an "always" type entry. 5061 if (always && !pa.mPref.sameSet(query)) { 5062 Slog.i(TAG, "Result set changed, dropping preferred activity for " 5063 + intent + " type " + resolvedType); 5064 if (DEBUG_PREFERRED) { 5065 Slog.v(TAG, "Removing preferred activity since set changed " 5066 + pa.mPref.mComponent); 5067 } 5068 pir.removeFilter(pa); 5069 // Re-add the filter as a "last chosen" entry (!always) 5070 PreferredActivity lastChosen = new PreferredActivity( 5071 pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false); 5072 pir.addFilter(lastChosen); 5073 changed = true; 5074 return null; 5075 } 5076 5077 // Yay! Either the set matched or we're looking for the last chosen 5078 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: " 5079 + ri.activityInfo.packageName + "/" + ri.activityInfo.name); 5080 return ri; 5081 } 5082 } 5083 } finally { 5084 if (changed) { 5085 if (DEBUG_PREFERRED) { 5086 Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions"); 5087 } 5088 scheduleWritePackageRestrictionsLocked(userId); 5089 } 5090 } 5091 } 5092 } 5093 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return"); 5094 return null; 5095 } 5096 5097 /* 5098 * Returns if intent can be forwarded from the sourceUserId to the targetUserId 5099 */ 5100 @Override 5101 public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId, 5102 int targetUserId) { 5103 mContext.enforceCallingOrSelfPermission( 5104 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 5105 List<CrossProfileIntentFilter> matches = 5106 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId); 5107 if (matches != null) { 5108 int size = matches.size(); 5109 for (int i = 0; i < size; i++) { 5110 if (matches.get(i).getTargetUserId() == targetUserId) return true; 5111 } 5112 } 5113 if (hasWebURI(intent)) { 5114 // cross-profile app linking works only towards the parent. 5115 final UserInfo parent = getProfileParent(sourceUserId); 5116 synchronized(mPackages) { 5117 int flags = updateFlagsForResolve(0, parent.id, intent); 5118 CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr( 5119 intent, resolvedType, flags, sourceUserId, parent.id); 5120 return xpDomainInfo != null; 5121 } 5122 } 5123 return false; 5124 } 5125 5126 private UserInfo getProfileParent(int userId) { 5127 final long identity = Binder.clearCallingIdentity(); 5128 try { 5129 return sUserManager.getProfileParent(userId); 5130 } finally { 5131 Binder.restoreCallingIdentity(identity); 5132 } 5133 } 5134 5135 private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent, 5136 String resolvedType, int userId) { 5137 CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId); 5138 if (resolver != null) { 5139 return resolver.queryIntent(intent, resolvedType, false, userId); 5140 } 5141 return null; 5142 } 5143 5144 @Override 5145 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent, 5146 String resolvedType, int flags, int userId) { 5147 return new ParceledListSlice<>( 5148 queryIntentActivitiesInternal(intent, resolvedType, flags, userId)); 5149 } 5150 5151 private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, 5152 String resolvedType, int flags, int userId) { 5153 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5154 flags = updateFlagsForResolve(flags, userId, intent); 5155 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5156 false /* requireFullPermission */, false /* checkShell */, 5157 "query intent activities"); 5158 ComponentName comp = intent.getComponent(); 5159 if (comp == null) { 5160 if (intent.getSelector() != null) { 5161 intent = intent.getSelector(); 5162 comp = intent.getComponent(); 5163 } 5164 } 5165 5166 if (comp != null) { 5167 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5168 final ActivityInfo ai = getActivityInfo(comp, flags, userId); 5169 if (ai != null) { 5170 final ResolveInfo ri = new ResolveInfo(); 5171 ri.activityInfo = ai; 5172 list.add(ri); 5173 } 5174 return list; 5175 } 5176 5177 // reader 5178 synchronized (mPackages) { 5179 final String pkgName = intent.getPackage(); 5180 if (pkgName == null) { 5181 List<CrossProfileIntentFilter> matchingFilters = 5182 getMatchingCrossProfileIntentFilters(intent, resolvedType, userId); 5183 // Check for results that need to skip the current profile. 5184 ResolveInfo xpResolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent, 5185 resolvedType, flags, userId); 5186 if (xpResolveInfo != null) { 5187 List<ResolveInfo> result = new ArrayList<ResolveInfo>(1); 5188 result.add(xpResolveInfo); 5189 return filterIfNotSystemUser(result, userId); 5190 } 5191 5192 // Check for results in the current profile. 5193 List<ResolveInfo> result = mActivities.queryIntent( 5194 intent, resolvedType, flags, userId); 5195 result = filterIfNotSystemUser(result, userId); 5196 5197 // Check for cross profile results. 5198 boolean hasNonNegativePriorityResult = hasNonNegativePriority(result); 5199 xpResolveInfo = queryCrossProfileIntents( 5200 matchingFilters, intent, resolvedType, flags, userId, 5201 hasNonNegativePriorityResult); 5202 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) { 5203 boolean isVisibleToUser = filterIfNotSystemUser( 5204 Collections.singletonList(xpResolveInfo), userId).size() > 0; 5205 if (isVisibleToUser) { 5206 result.add(xpResolveInfo); 5207 Collections.sort(result, mResolvePrioritySorter); 5208 } 5209 } 5210 if (hasWebURI(intent)) { 5211 CrossProfileDomainInfo xpDomainInfo = null; 5212 final UserInfo parent = getProfileParent(userId); 5213 if (parent != null) { 5214 xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType, 5215 flags, userId, parent.id); 5216 } 5217 if (xpDomainInfo != null) { 5218 if (xpResolveInfo != null) { 5219 // If we didn't remove it, the cross-profile ResolveInfo would be twice 5220 // in the result. 5221 result.remove(xpResolveInfo); 5222 } 5223 if (result.size() == 0) { 5224 result.add(xpDomainInfo.resolveInfo); 5225 return result; 5226 } 5227 } else if (result.size() <= 1) { 5228 return result; 5229 } 5230 result = filterCandidatesWithDomainPreferredActivitiesLPr(intent, flags, result, 5231 xpDomainInfo, userId); 5232 Collections.sort(result, mResolvePrioritySorter); 5233 } 5234 return result; 5235 } 5236 final PackageParser.Package pkg = mPackages.get(pkgName); 5237 if (pkg != null) { 5238 return filterIfNotSystemUser( 5239 mActivities.queryIntentForPackage( 5240 intent, resolvedType, flags, pkg.activities, userId), 5241 userId); 5242 } 5243 return new ArrayList<ResolveInfo>(); 5244 } 5245 } 5246 5247 private static class CrossProfileDomainInfo { 5248 /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */ 5249 ResolveInfo resolveInfo; 5250 /* Best domain verification status of the activities found in the other profile */ 5251 int bestDomainVerificationStatus; 5252 } 5253 5254 private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent, 5255 String resolvedType, int flags, int sourceUserId, int parentUserId) { 5256 if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING, 5257 sourceUserId)) { 5258 return null; 5259 } 5260 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 5261 resolvedType, flags, parentUserId); 5262 5263 if (resultTargetUser == null || resultTargetUser.isEmpty()) { 5264 return null; 5265 } 5266 CrossProfileDomainInfo result = null; 5267 int size = resultTargetUser.size(); 5268 for (int i = 0; i < size; i++) { 5269 ResolveInfo riTargetUser = resultTargetUser.get(i); 5270 // Intent filter verification is only for filters that specify a host. So don't return 5271 // those that handle all web uris. 5272 if (riTargetUser.handleAllWebDataURI) { 5273 continue; 5274 } 5275 String packageName = riTargetUser.activityInfo.packageName; 5276 PackageSetting ps = mSettings.mPackages.get(packageName); 5277 if (ps == null) { 5278 continue; 5279 } 5280 long verificationState = getDomainVerificationStatusLPr(ps, parentUserId); 5281 int status = (int)(verificationState >> 32); 5282 if (result == null) { 5283 result = new CrossProfileDomainInfo(); 5284 result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(), 5285 sourceUserId, parentUserId); 5286 result.bestDomainVerificationStatus = status; 5287 } else { 5288 result.bestDomainVerificationStatus = bestDomainVerificationStatus(status, 5289 result.bestDomainVerificationStatus); 5290 } 5291 } 5292 // Don't consider matches with status NEVER across profiles. 5293 if (result != null && result.bestDomainVerificationStatus 5294 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5295 return null; 5296 } 5297 return result; 5298 } 5299 5300 /** 5301 * Verification statuses are ordered from the worse to the best, except for 5302 * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse. 5303 */ 5304 private int bestDomainVerificationStatus(int status1, int status2) { 5305 if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5306 return status2; 5307 } 5308 if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5309 return status1; 5310 } 5311 return (int) MathUtils.max(status1, status2); 5312 } 5313 5314 private boolean isUserEnabled(int userId) { 5315 long callingId = Binder.clearCallingIdentity(); 5316 try { 5317 UserInfo userInfo = sUserManager.getUserInfo(userId); 5318 return userInfo != null && userInfo.isEnabled(); 5319 } finally { 5320 Binder.restoreCallingIdentity(callingId); 5321 } 5322 } 5323 5324 /** 5325 * Filter out activities with systemUserOnly flag set, when current user is not System. 5326 * 5327 * @return filtered list 5328 */ 5329 private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) { 5330 if (userId == UserHandle.USER_SYSTEM) { 5331 return resolveInfos; 5332 } 5333 for (int i = resolveInfos.size() - 1; i >= 0; i--) { 5334 ResolveInfo info = resolveInfos.get(i); 5335 if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) { 5336 resolveInfos.remove(i); 5337 } 5338 } 5339 return resolveInfos; 5340 } 5341 5342 /** 5343 * @param resolveInfos list of resolve infos in descending priority order 5344 * @return if the list contains a resolve info with non-negative priority 5345 */ 5346 private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) { 5347 return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0; 5348 } 5349 5350 private static boolean hasWebURI(Intent intent) { 5351 if (intent.getData() == null) { 5352 return false; 5353 } 5354 final String scheme = intent.getScheme(); 5355 if (TextUtils.isEmpty(scheme)) { 5356 return false; 5357 } 5358 return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS); 5359 } 5360 5361 private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent, 5362 int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo, 5363 int userId) { 5364 final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0; 5365 5366 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) { 5367 Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " + 5368 candidates.size()); 5369 } 5370 5371 ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>(); 5372 ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>(); 5373 ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>(); 5374 ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>(); 5375 ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>(); 5376 ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>(); 5377 5378 synchronized (mPackages) { 5379 final int count = candidates.size(); 5380 // First, try to use linked apps. Partition the candidates into four lists: 5381 // one for the final results, one for the "do not use ever", one for "undefined status" 5382 // and finally one for "browser app type". 5383 for (int n=0; n<count; n++) { 5384 ResolveInfo info = candidates.get(n); 5385 String packageName = info.activityInfo.packageName; 5386 PackageSetting ps = mSettings.mPackages.get(packageName); 5387 if (ps != null) { 5388 // Add to the special match all list (Browser use case) 5389 if (info.handleAllWebDataURI) { 5390 matchAllList.add(info); 5391 continue; 5392 } 5393 // Try to get the status from User settings first 5394 long packedStatus = getDomainVerificationStatusLPr(ps, userId); 5395 int status = (int)(packedStatus >> 32); 5396 int linkGeneration = (int)(packedStatus & 0xFFFFFFFF); 5397 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) { 5398 if (DEBUG_DOMAIN_VERIFICATION) { 5399 Slog.i(TAG, " + always: " + info.activityInfo.packageName 5400 + " : linkgen=" + linkGeneration); 5401 } 5402 // Use link-enabled generation as preferredOrder, i.e. 5403 // prefer newly-enabled over earlier-enabled. 5404 info.preferredOrder = linkGeneration; 5405 alwaysList.add(info); 5406 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5407 if (DEBUG_DOMAIN_VERIFICATION) { 5408 Slog.i(TAG, " + never: " + info.activityInfo.packageName); 5409 } 5410 neverList.add(info); 5411 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) { 5412 if (DEBUG_DOMAIN_VERIFICATION) { 5413 Slog.i(TAG, " + always-ask: " + info.activityInfo.packageName); 5414 } 5415 alwaysAskList.add(info); 5416 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED || 5417 status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) { 5418 if (DEBUG_DOMAIN_VERIFICATION) { 5419 Slog.i(TAG, " + ask: " + info.activityInfo.packageName); 5420 } 5421 undefinedList.add(info); 5422 } 5423 } 5424 } 5425 5426 // We'll want to include browser possibilities in a few cases 5427 boolean includeBrowser = false; 5428 5429 // First try to add the "always" resolution(s) for the current user, if any 5430 if (alwaysList.size() > 0) { 5431 result.addAll(alwaysList); 5432 } else { 5433 // Add all undefined apps as we want them to appear in the disambiguation dialog. 5434 result.addAll(undefinedList); 5435 // Maybe add one for the other profile. 5436 if (xpDomainInfo != null && ( 5437 xpDomainInfo.bestDomainVerificationStatus 5438 != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) { 5439 result.add(xpDomainInfo.resolveInfo); 5440 } 5441 includeBrowser = true; 5442 } 5443 5444 // The presence of any 'always ask' alternatives means we'll also offer browsers. 5445 // If there were 'always' entries their preferred order has been set, so we also 5446 // back that off to make the alternatives equivalent 5447 if (alwaysAskList.size() > 0) { 5448 for (ResolveInfo i : result) { 5449 i.preferredOrder = 0; 5450 } 5451 result.addAll(alwaysAskList); 5452 includeBrowser = true; 5453 } 5454 5455 if (includeBrowser) { 5456 // Also add browsers (all of them or only the default one) 5457 if (DEBUG_DOMAIN_VERIFICATION) { 5458 Slog.v(TAG, " ...including browsers in candidate set"); 5459 } 5460 if ((matchFlags & MATCH_ALL) != 0) { 5461 result.addAll(matchAllList); 5462 } else { 5463 // Browser/generic handling case. If there's a default browser, go straight 5464 // to that (but only if there is no other higher-priority match). 5465 final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId); 5466 int maxMatchPrio = 0; 5467 ResolveInfo defaultBrowserMatch = null; 5468 final int numCandidates = matchAllList.size(); 5469 for (int n = 0; n < numCandidates; n++) { 5470 ResolveInfo info = matchAllList.get(n); 5471 // track the highest overall match priority... 5472 if (info.priority > maxMatchPrio) { 5473 maxMatchPrio = info.priority; 5474 } 5475 // ...and the highest-priority default browser match 5476 if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) { 5477 if (defaultBrowserMatch == null 5478 || (defaultBrowserMatch.priority < info.priority)) { 5479 if (debug) { 5480 Slog.v(TAG, "Considering default browser match " + info); 5481 } 5482 defaultBrowserMatch = info; 5483 } 5484 } 5485 } 5486 if (defaultBrowserMatch != null 5487 && defaultBrowserMatch.priority >= maxMatchPrio 5488 && !TextUtils.isEmpty(defaultBrowserPackageName)) 5489 { 5490 if (debug) { 5491 Slog.v(TAG, "Default browser match " + defaultBrowserMatch); 5492 } 5493 result.add(defaultBrowserMatch); 5494 } else { 5495 result.addAll(matchAllList); 5496 } 5497 } 5498 5499 // If there is nothing selected, add all candidates and remove the ones that the user 5500 // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state 5501 if (result.size() == 0) { 5502 result.addAll(candidates); 5503 result.removeAll(neverList); 5504 } 5505 } 5506 } 5507 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) { 5508 Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " + 5509 result.size()); 5510 for (ResolveInfo info : result) { 5511 Slog.v(TAG, " + " + info.activityInfo); 5512 } 5513 } 5514 return result; 5515 } 5516 5517 // Returns a packed value as a long: 5518 // 5519 // high 'int'-sized word: link status: undefined/ask/never/always. 5520 // low 'int'-sized word: relative priority among 'always' results. 5521 private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) { 5522 long result = ps.getDomainVerificationStatusForUser(userId); 5523 // if none available, get the master status 5524 if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 5525 if (ps.getIntentFilterVerificationInfo() != null) { 5526 result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32; 5527 } 5528 } 5529 return result; 5530 } 5531 5532 private ResolveInfo querySkipCurrentProfileIntents( 5533 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 5534 int flags, int sourceUserId) { 5535 if (matchingFilters != null) { 5536 int size = matchingFilters.size(); 5537 for (int i = 0; i < size; i ++) { 5538 CrossProfileIntentFilter filter = matchingFilters.get(i); 5539 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) { 5540 // Checking if there are activities in the target user that can handle the 5541 // intent. 5542 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent, 5543 resolvedType, flags, sourceUserId); 5544 if (resolveInfo != null) { 5545 return resolveInfo; 5546 } 5547 } 5548 } 5549 } 5550 return null; 5551 } 5552 5553 // Return matching ResolveInfo in target user if any. 5554 private ResolveInfo queryCrossProfileIntents( 5555 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 5556 int flags, int sourceUserId, boolean matchInCurrentProfile) { 5557 if (matchingFilters != null) { 5558 // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and 5559 // match the same intent. For performance reasons, it is better not to 5560 // run queryIntent twice for the same userId 5561 SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray(); 5562 int size = matchingFilters.size(); 5563 for (int i = 0; i < size; i++) { 5564 CrossProfileIntentFilter filter = matchingFilters.get(i); 5565 int targetUserId = filter.getTargetUserId(); 5566 boolean skipCurrentProfile = 5567 (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0; 5568 boolean skipCurrentProfileIfNoMatchFound = 5569 (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0; 5570 if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId) 5571 && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) { 5572 // Checking if there are activities in the target user that can handle the 5573 // intent. 5574 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent, 5575 resolvedType, flags, sourceUserId); 5576 if (resolveInfo != null) return resolveInfo; 5577 alreadyTriedUserIds.put(targetUserId, true); 5578 } 5579 } 5580 } 5581 return null; 5582 } 5583 5584 /** 5585 * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that 5586 * will forward the intent to the filter's target user. 5587 * Otherwise, returns null. 5588 */ 5589 private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent, 5590 String resolvedType, int flags, int sourceUserId) { 5591 int targetUserId = filter.getTargetUserId(); 5592 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 5593 resolvedType, flags, targetUserId); 5594 if (resultTargetUser != null && isUserEnabled(targetUserId)) { 5595 // If all the matches in the target profile are suspended, return null. 5596 for (int i = resultTargetUser.size() - 1; i >= 0; i--) { 5597 if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags 5598 & ApplicationInfo.FLAG_SUSPENDED) == 0) { 5599 return createForwardingResolveInfoUnchecked(filter, sourceUserId, 5600 targetUserId); 5601 } 5602 } 5603 } 5604 return null; 5605 } 5606 5607 private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter, 5608 int sourceUserId, int targetUserId) { 5609 ResolveInfo forwardingResolveInfo = new ResolveInfo(); 5610 long ident = Binder.clearCallingIdentity(); 5611 boolean targetIsProfile; 5612 try { 5613 targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile(); 5614 } finally { 5615 Binder.restoreCallingIdentity(ident); 5616 } 5617 String className; 5618 if (targetIsProfile) { 5619 className = FORWARD_INTENT_TO_MANAGED_PROFILE; 5620 } else { 5621 className = FORWARD_INTENT_TO_PARENT; 5622 } 5623 ComponentName forwardingActivityComponentName = new ComponentName( 5624 mAndroidApplication.packageName, className); 5625 ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0, 5626 sourceUserId); 5627 if (!targetIsProfile) { 5628 forwardingActivityInfo.showUserIcon = targetUserId; 5629 forwardingResolveInfo.noResourceId = true; 5630 } 5631 forwardingResolveInfo.activityInfo = forwardingActivityInfo; 5632 forwardingResolveInfo.priority = 0; 5633 forwardingResolveInfo.preferredOrder = 0; 5634 forwardingResolveInfo.match = 0; 5635 forwardingResolveInfo.isDefault = true; 5636 forwardingResolveInfo.filter = filter; 5637 forwardingResolveInfo.targetUserId = targetUserId; 5638 return forwardingResolveInfo; 5639 } 5640 5641 @Override 5642 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller, 5643 Intent[] specifics, String[] specificTypes, Intent intent, 5644 String resolvedType, int flags, int userId) { 5645 return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics, 5646 specificTypes, intent, resolvedType, flags, userId)); 5647 } 5648 5649 private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller, 5650 Intent[] specifics, String[] specificTypes, Intent intent, 5651 String resolvedType, int flags, int userId) { 5652 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5653 flags = updateFlagsForResolve(flags, userId, intent); 5654 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5655 false /* requireFullPermission */, false /* checkShell */, 5656 "query intent activity options"); 5657 final String resultsAction = intent.getAction(); 5658 5659 final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags 5660 | PackageManager.GET_RESOLVED_FILTER, userId); 5661 5662 if (DEBUG_INTENT_MATCHING) { 5663 Log.v(TAG, "Query " + intent + ": " + results); 5664 } 5665 5666 int specificsPos = 0; 5667 int N; 5668 5669 // todo: note that the algorithm used here is O(N^2). This 5670 // isn't a problem in our current environment, but if we start running 5671 // into situations where we have more than 5 or 10 matches then this 5672 // should probably be changed to something smarter... 5673 5674 // First we go through and resolve each of the specific items 5675 // that were supplied, taking care of removing any corresponding 5676 // duplicate items in the generic resolve list. 5677 if (specifics != null) { 5678 for (int i=0; i<specifics.length; i++) { 5679 final Intent sintent = specifics[i]; 5680 if (sintent == null) { 5681 continue; 5682 } 5683 5684 if (DEBUG_INTENT_MATCHING) { 5685 Log.v(TAG, "Specific #" + i + ": " + sintent); 5686 } 5687 5688 String action = sintent.getAction(); 5689 if (resultsAction != null && resultsAction.equals(action)) { 5690 // If this action was explicitly requested, then don't 5691 // remove things that have it. 5692 action = null; 5693 } 5694 5695 ResolveInfo ri = null; 5696 ActivityInfo ai = null; 5697 5698 ComponentName comp = sintent.getComponent(); 5699 if (comp == null) { 5700 ri = resolveIntent( 5701 sintent, 5702 specificTypes != null ? specificTypes[i] : null, 5703 flags, userId); 5704 if (ri == null) { 5705 continue; 5706 } 5707 if (ri == mResolveInfo) { 5708 // ACK! Must do something better with this. 5709 } 5710 ai = ri.activityInfo; 5711 comp = new ComponentName(ai.applicationInfo.packageName, 5712 ai.name); 5713 } else { 5714 ai = getActivityInfo(comp, flags, userId); 5715 if (ai == null) { 5716 continue; 5717 } 5718 } 5719 5720 // Look for any generic query activities that are duplicates 5721 // of this specific one, and remove them from the results. 5722 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai); 5723 N = results.size(); 5724 int j; 5725 for (j=specificsPos; j<N; j++) { 5726 ResolveInfo sri = results.get(j); 5727 if ((sri.activityInfo.name.equals(comp.getClassName()) 5728 && sri.activityInfo.applicationInfo.packageName.equals( 5729 comp.getPackageName())) 5730 || (action != null && sri.filter.matchAction(action))) { 5731 results.remove(j); 5732 if (DEBUG_INTENT_MATCHING) Log.v( 5733 TAG, "Removing duplicate item from " + j 5734 + " due to specific " + specificsPos); 5735 if (ri == null) { 5736 ri = sri; 5737 } 5738 j--; 5739 N--; 5740 } 5741 } 5742 5743 // Add this specific item to its proper place. 5744 if (ri == null) { 5745 ri = new ResolveInfo(); 5746 ri.activityInfo = ai; 5747 } 5748 results.add(specificsPos, ri); 5749 ri.specificIndex = i; 5750 specificsPos++; 5751 } 5752 } 5753 5754 // Now we go through the remaining generic results and remove any 5755 // duplicate actions that are found here. 5756 N = results.size(); 5757 for (int i=specificsPos; i<N-1; i++) { 5758 final ResolveInfo rii = results.get(i); 5759 if (rii.filter == null) { 5760 continue; 5761 } 5762 5763 // Iterate over all of the actions of this result's intent 5764 // filter... typically this should be just one. 5765 final Iterator<String> it = rii.filter.actionsIterator(); 5766 if (it == null) { 5767 continue; 5768 } 5769 while (it.hasNext()) { 5770 final String action = it.next(); 5771 if (resultsAction != null && resultsAction.equals(action)) { 5772 // If this action was explicitly requested, then don't 5773 // remove things that have it. 5774 continue; 5775 } 5776 for (int j=i+1; j<N; j++) { 5777 final ResolveInfo rij = results.get(j); 5778 if (rij.filter != null && rij.filter.hasAction(action)) { 5779 results.remove(j); 5780 if (DEBUG_INTENT_MATCHING) Log.v( 5781 TAG, "Removing duplicate item from " + j 5782 + " due to action " + action + " at " + i); 5783 j--; 5784 N--; 5785 } 5786 } 5787 } 5788 5789 // If the caller didn't request filter information, drop it now 5790 // so we don't have to marshall/unmarshall it. 5791 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 5792 rii.filter = null; 5793 } 5794 } 5795 5796 // Filter out the caller activity if so requested. 5797 if (caller != null) { 5798 N = results.size(); 5799 for (int i=0; i<N; i++) { 5800 ActivityInfo ainfo = results.get(i).activityInfo; 5801 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName) 5802 && caller.getClassName().equals(ainfo.name)) { 5803 results.remove(i); 5804 break; 5805 } 5806 } 5807 } 5808 5809 // If the caller didn't request filter information, 5810 // drop them now so we don't have to 5811 // marshall/unmarshall it. 5812 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 5813 N = results.size(); 5814 for (int i=0; i<N; i++) { 5815 results.get(i).filter = null; 5816 } 5817 } 5818 5819 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results); 5820 return results; 5821 } 5822 5823 @Override 5824 public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent, 5825 String resolvedType, int flags, int userId) { 5826 return new ParceledListSlice<>( 5827 queryIntentReceiversInternal(intent, resolvedType, flags, userId)); 5828 } 5829 5830 private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent, 5831 String resolvedType, int flags, int userId) { 5832 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5833 flags = updateFlagsForResolve(flags, userId, intent); 5834 ComponentName comp = intent.getComponent(); 5835 if (comp == null) { 5836 if (intent.getSelector() != null) { 5837 intent = intent.getSelector(); 5838 comp = intent.getComponent(); 5839 } 5840 } 5841 if (comp != null) { 5842 List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5843 ActivityInfo ai = getReceiverInfo(comp, flags, userId); 5844 if (ai != null) { 5845 ResolveInfo ri = new ResolveInfo(); 5846 ri.activityInfo = ai; 5847 list.add(ri); 5848 } 5849 return list; 5850 } 5851 5852 // reader 5853 synchronized (mPackages) { 5854 String pkgName = intent.getPackage(); 5855 if (pkgName == null) { 5856 return mReceivers.queryIntent(intent, resolvedType, flags, userId); 5857 } 5858 final PackageParser.Package pkg = mPackages.get(pkgName); 5859 if (pkg != null) { 5860 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers, 5861 userId); 5862 } 5863 return Collections.emptyList(); 5864 } 5865 } 5866 5867 @Override 5868 public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) { 5869 if (!sUserManager.exists(userId)) return null; 5870 flags = updateFlagsForResolve(flags, userId, intent); 5871 List<ResolveInfo> query = queryIntentServicesInternal(intent, resolvedType, flags, userId); 5872 if (query != null) { 5873 if (query.size() >= 1) { 5874 // If there is more than one service with the same priority, 5875 // just arbitrarily pick the first one. 5876 return query.get(0); 5877 } 5878 } 5879 return null; 5880 } 5881 5882 @Override 5883 public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent, 5884 String resolvedType, int flags, int userId) { 5885 return new ParceledListSlice<>( 5886 queryIntentServicesInternal(intent, resolvedType, flags, userId)); 5887 } 5888 5889 private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent, 5890 String resolvedType, int flags, int userId) { 5891 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5892 flags = updateFlagsForResolve(flags, userId, intent); 5893 ComponentName comp = intent.getComponent(); 5894 if (comp == null) { 5895 if (intent.getSelector() != null) { 5896 intent = intent.getSelector(); 5897 comp = intent.getComponent(); 5898 } 5899 } 5900 if (comp != null) { 5901 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5902 final ServiceInfo si = getServiceInfo(comp, flags, userId); 5903 if (si != null) { 5904 final ResolveInfo ri = new ResolveInfo(); 5905 ri.serviceInfo = si; 5906 list.add(ri); 5907 } 5908 return list; 5909 } 5910 5911 // reader 5912 synchronized (mPackages) { 5913 String pkgName = intent.getPackage(); 5914 if (pkgName == null) { 5915 return mServices.queryIntent(intent, resolvedType, flags, userId); 5916 } 5917 final PackageParser.Package pkg = mPackages.get(pkgName); 5918 if (pkg != null) { 5919 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services, 5920 userId); 5921 } 5922 return Collections.emptyList(); 5923 } 5924 } 5925 5926 @Override 5927 public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent, 5928 String resolvedType, int flags, int userId) { 5929 return new ParceledListSlice<>( 5930 queryIntentContentProvidersInternal(intent, resolvedType, flags, userId)); 5931 } 5932 5933 private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal( 5934 Intent intent, String resolvedType, int flags, int userId) { 5935 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5936 flags = updateFlagsForResolve(flags, userId, intent); 5937 ComponentName comp = intent.getComponent(); 5938 if (comp == null) { 5939 if (intent.getSelector() != null) { 5940 intent = intent.getSelector(); 5941 comp = intent.getComponent(); 5942 } 5943 } 5944 if (comp != null) { 5945 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5946 final ProviderInfo pi = getProviderInfo(comp, flags, userId); 5947 if (pi != null) { 5948 final ResolveInfo ri = new ResolveInfo(); 5949 ri.providerInfo = pi; 5950 list.add(ri); 5951 } 5952 return list; 5953 } 5954 5955 // reader 5956 synchronized (mPackages) { 5957 String pkgName = intent.getPackage(); 5958 if (pkgName == null) { 5959 return mProviders.queryIntent(intent, resolvedType, flags, userId); 5960 } 5961 final PackageParser.Package pkg = mPackages.get(pkgName); 5962 if (pkg != null) { 5963 return mProviders.queryIntentForPackage( 5964 intent, resolvedType, flags, pkg.providers, userId); 5965 } 5966 return Collections.emptyList(); 5967 } 5968 } 5969 5970 @Override 5971 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) { 5972 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 5973 flags = updateFlagsForPackage(flags, userId, null); 5974 final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0; 5975 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5976 true /* requireFullPermission */, false /* checkShell */, 5977 "get installed packages"); 5978 5979 // writer 5980 synchronized (mPackages) { 5981 ArrayList<PackageInfo> list; 5982 if (listUninstalled) { 5983 list = new ArrayList<PackageInfo>(mSettings.mPackages.size()); 5984 for (PackageSetting ps : mSettings.mPackages.values()) { 5985 final PackageInfo pi; 5986 if (ps.pkg != null) { 5987 pi = generatePackageInfo(ps, flags, userId); 5988 } else { 5989 pi = generatePackageInfo(ps, flags, userId); 5990 } 5991 if (pi != null) { 5992 list.add(pi); 5993 } 5994 } 5995 } else { 5996 list = new ArrayList<PackageInfo>(mPackages.size()); 5997 for (PackageParser.Package p : mPackages.values()) { 5998 final PackageInfo pi = 5999 generatePackageInfo((PackageSetting)p.mExtras, flags, userId); 6000 if (pi != null) { 6001 list.add(pi); 6002 } 6003 } 6004 } 6005 6006 return new ParceledListSlice<PackageInfo>(list); 6007 } 6008 } 6009 6010 private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps, 6011 String[] permissions, boolean[] tmp, int flags, int userId) { 6012 int numMatch = 0; 6013 final PermissionsState permissionsState = ps.getPermissionsState(); 6014 for (int i=0; i<permissions.length; i++) { 6015 final String permission = permissions[i]; 6016 if (permissionsState.hasPermission(permission, userId)) { 6017 tmp[i] = true; 6018 numMatch++; 6019 } else { 6020 tmp[i] = false; 6021 } 6022 } 6023 if (numMatch == 0) { 6024 return; 6025 } 6026 final PackageInfo pi; 6027 if (ps.pkg != null) { 6028 pi = generatePackageInfo(ps, flags, userId); 6029 } else { 6030 pi = generatePackageInfo(ps, flags, userId); 6031 } 6032 // The above might return null in cases of uninstalled apps or install-state 6033 // skew across users/profiles. 6034 if (pi != null) { 6035 if ((flags&PackageManager.GET_PERMISSIONS) == 0) { 6036 if (numMatch == permissions.length) { 6037 pi.requestedPermissions = permissions; 6038 } else { 6039 pi.requestedPermissions = new String[numMatch]; 6040 numMatch = 0; 6041 for (int i=0; i<permissions.length; i++) { 6042 if (tmp[i]) { 6043 pi.requestedPermissions[numMatch] = permissions[i]; 6044 numMatch++; 6045 } 6046 } 6047 } 6048 } 6049 list.add(pi); 6050 } 6051 } 6052 6053 @Override 6054 public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions( 6055 String[] permissions, int flags, int userId) { 6056 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 6057 flags = updateFlagsForPackage(flags, userId, permissions); 6058 final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0; 6059 6060 // writer 6061 synchronized (mPackages) { 6062 ArrayList<PackageInfo> list = new ArrayList<PackageInfo>(); 6063 boolean[] tmpBools = new boolean[permissions.length]; 6064 if (listUninstalled) { 6065 for (PackageSetting ps : mSettings.mPackages.values()) { 6066 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId); 6067 } 6068 } else { 6069 for (PackageParser.Package pkg : mPackages.values()) { 6070 PackageSetting ps = (PackageSetting)pkg.mExtras; 6071 if (ps != null) { 6072 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, 6073 userId); 6074 } 6075 } 6076 } 6077 6078 return new ParceledListSlice<PackageInfo>(list); 6079 } 6080 } 6081 6082 @Override 6083 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) { 6084 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 6085 flags = updateFlagsForApplication(flags, userId, null); 6086 final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0; 6087 6088 // writer 6089 synchronized (mPackages) { 6090 ArrayList<ApplicationInfo> list; 6091 if (listUninstalled) { 6092 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size()); 6093 for (PackageSetting ps : mSettings.mPackages.values()) { 6094 ApplicationInfo ai; 6095 if (ps.pkg != null) { 6096 ai = PackageParser.generateApplicationInfo(ps.pkg, flags, 6097 ps.readUserState(userId), userId); 6098 } else { 6099 ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId); 6100 } 6101 if (ai != null) { 6102 list.add(ai); 6103 } 6104 } 6105 } else { 6106 list = new ArrayList<ApplicationInfo>(mPackages.size()); 6107 for (PackageParser.Package p : mPackages.values()) { 6108 if (p.mExtras != null) { 6109 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 6110 ((PackageSetting)p.mExtras).readUserState(userId), userId); 6111 if (ai != null) { 6112 list.add(ai); 6113 } 6114 } 6115 } 6116 } 6117 6118 return new ParceledListSlice<ApplicationInfo>(list); 6119 } 6120 } 6121 6122 @Override 6123 public ParceledListSlice<EphemeralApplicationInfo> getEphemeralApplications(int userId) { 6124 if (DISABLE_EPHEMERAL_APPS) { 6125 return null; 6126 } 6127 6128 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS, 6129 "getEphemeralApplications"); 6130 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6131 true /* requireFullPermission */, false /* checkShell */, 6132 "getEphemeralApplications"); 6133 synchronized (mPackages) { 6134 List<EphemeralApplicationInfo> ephemeralApps = mEphemeralApplicationRegistry 6135 .getEphemeralApplicationsLPw(userId); 6136 if (ephemeralApps != null) { 6137 return new ParceledListSlice<>(ephemeralApps); 6138 } 6139 } 6140 return null; 6141 } 6142 6143 @Override 6144 public boolean isEphemeralApplication(String packageName, int userId) { 6145 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6146 true /* requireFullPermission */, false /* checkShell */, 6147 "isEphemeral"); 6148 if (DISABLE_EPHEMERAL_APPS) { 6149 return false; 6150 } 6151 6152 if (!isCallerSameApp(packageName)) { 6153 return false; 6154 } 6155 synchronized (mPackages) { 6156 PackageParser.Package pkg = mPackages.get(packageName); 6157 if (pkg != null) { 6158 return pkg.applicationInfo.isEphemeralApp(); 6159 } 6160 } 6161 return false; 6162 } 6163 6164 @Override 6165 public byte[] getEphemeralApplicationCookie(String packageName, int userId) { 6166 if (DISABLE_EPHEMERAL_APPS) { 6167 return null; 6168 } 6169 6170 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6171 true /* requireFullPermission */, false /* checkShell */, 6172 "getCookie"); 6173 if (!isCallerSameApp(packageName)) { 6174 return null; 6175 } 6176 synchronized (mPackages) { 6177 return mEphemeralApplicationRegistry.getEphemeralApplicationCookieLPw( 6178 packageName, userId); 6179 } 6180 } 6181 6182 @Override 6183 public boolean setEphemeralApplicationCookie(String packageName, byte[] cookie, int userId) { 6184 if (DISABLE_EPHEMERAL_APPS) { 6185 return true; 6186 } 6187 6188 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6189 true /* requireFullPermission */, true /* checkShell */, 6190 "setCookie"); 6191 if (!isCallerSameApp(packageName)) { 6192 return false; 6193 } 6194 synchronized (mPackages) { 6195 return mEphemeralApplicationRegistry.setEphemeralApplicationCookieLPw( 6196 packageName, cookie, userId); 6197 } 6198 } 6199 6200 @Override 6201 public Bitmap getEphemeralApplicationIcon(String packageName, int userId) { 6202 if (DISABLE_EPHEMERAL_APPS) { 6203 return null; 6204 } 6205 6206 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS, 6207 "getEphemeralApplicationIcon"); 6208 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6209 true /* requireFullPermission */, false /* checkShell */, 6210 "getEphemeralApplicationIcon"); 6211 synchronized (mPackages) { 6212 return mEphemeralApplicationRegistry.getEphemeralApplicationIconLPw( 6213 packageName, userId); 6214 } 6215 } 6216 6217 private boolean isCallerSameApp(String packageName) { 6218 PackageParser.Package pkg = mPackages.get(packageName); 6219 return pkg != null 6220 && UserHandle.getAppId(Binder.getCallingUid()) == pkg.applicationInfo.uid; 6221 } 6222 6223 @Override 6224 public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) { 6225 return new ParceledListSlice<>(getPersistentApplicationsInternal(flags)); 6226 } 6227 6228 private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) { 6229 final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>(); 6230 6231 // reader 6232 synchronized (mPackages) { 6233 final Iterator<PackageParser.Package> i = mPackages.values().iterator(); 6234 final int userId = UserHandle.getCallingUserId(); 6235 while (i.hasNext()) { 6236 final PackageParser.Package p = i.next(); 6237 if (p.applicationInfo == null) continue; 6238 6239 final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0) 6240 && !p.applicationInfo.isDirectBootAware(); 6241 final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0) 6242 && p.applicationInfo.isDirectBootAware(); 6243 6244 if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0 6245 && (!mSafeMode || isSystemApp(p)) 6246 && (matchesUnaware || matchesAware)) { 6247 PackageSetting ps = mSettings.mPackages.get(p.packageName); 6248 if (ps != null) { 6249 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 6250 ps.readUserState(userId), userId); 6251 if (ai != null) { 6252 finalList.add(ai); 6253 } 6254 } 6255 } 6256 } 6257 } 6258 6259 return finalList; 6260 } 6261 6262 @Override 6263 public ProviderInfo resolveContentProvider(String name, int flags, int userId) { 6264 if (!sUserManager.exists(userId)) return null; 6265 flags = updateFlagsForComponent(flags, userId, name); 6266 // reader 6267 synchronized (mPackages) { 6268 final PackageParser.Provider provider = mProvidersByAuthority.get(name); 6269 PackageSetting ps = provider != null 6270 ? mSettings.mPackages.get(provider.owner.packageName) 6271 : null; 6272 return ps != null 6273 && mSettings.isEnabledAndMatchLPr(provider.info, flags, userId) 6274 ? PackageParser.generateProviderInfo(provider, flags, 6275 ps.readUserState(userId), userId) 6276 : null; 6277 } 6278 } 6279 6280 /** 6281 * @deprecated 6282 */ 6283 @Deprecated 6284 public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) { 6285 // reader 6286 synchronized (mPackages) { 6287 final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority 6288 .entrySet().iterator(); 6289 final int userId = UserHandle.getCallingUserId(); 6290 while (i.hasNext()) { 6291 Map.Entry<String, PackageParser.Provider> entry = i.next(); 6292 PackageParser.Provider p = entry.getValue(); 6293 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 6294 6295 if (ps != null && p.syncable 6296 && (!mSafeMode || (p.info.applicationInfo.flags 6297 &ApplicationInfo.FLAG_SYSTEM) != 0)) { 6298 ProviderInfo info = PackageParser.generateProviderInfo(p, 0, 6299 ps.readUserState(userId), userId); 6300 if (info != null) { 6301 outNames.add(entry.getKey()); 6302 outInfo.add(info); 6303 } 6304 } 6305 } 6306 } 6307 } 6308 6309 @Override 6310 public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName, 6311 int uid, int flags) { 6312 final int userId = processName != null ? UserHandle.getUserId(uid) 6313 : UserHandle.getCallingUserId(); 6314 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 6315 flags = updateFlagsForComponent(flags, userId, processName); 6316 6317 ArrayList<ProviderInfo> finalList = null; 6318 // reader 6319 synchronized (mPackages) { 6320 final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator(); 6321 while (i.hasNext()) { 6322 final PackageParser.Provider p = i.next(); 6323 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 6324 if (ps != null && p.info.authority != null 6325 && (processName == null 6326 || (p.info.processName.equals(processName) 6327 && UserHandle.isSameApp(p.info.applicationInfo.uid, uid))) 6328 && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) { 6329 if (finalList == null) { 6330 finalList = new ArrayList<ProviderInfo>(3); 6331 } 6332 ProviderInfo info = PackageParser.generateProviderInfo(p, flags, 6333 ps.readUserState(userId), userId); 6334 if (info != null) { 6335 finalList.add(info); 6336 } 6337 } 6338 } 6339 } 6340 6341 if (finalList != null) { 6342 Collections.sort(finalList, mProviderInitOrderSorter); 6343 return new ParceledListSlice<ProviderInfo>(finalList); 6344 } 6345 6346 return ParceledListSlice.emptyList(); 6347 } 6348 6349 @Override 6350 public InstrumentationInfo getInstrumentationInfo(ComponentName name, int flags) { 6351 // reader 6352 synchronized (mPackages) { 6353 final PackageParser.Instrumentation i = mInstrumentation.get(name); 6354 return PackageParser.generateInstrumentationInfo(i, flags); 6355 } 6356 } 6357 6358 @Override 6359 public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation( 6360 String targetPackage, int flags) { 6361 return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags)); 6362 } 6363 6364 private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage, 6365 int flags) { 6366 ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>(); 6367 6368 // reader 6369 synchronized (mPackages) { 6370 final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator(); 6371 while (i.hasNext()) { 6372 final PackageParser.Instrumentation p = i.next(); 6373 if (targetPackage == null 6374 || targetPackage.equals(p.info.targetPackage)) { 6375 InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p, 6376 flags); 6377 if (ii != null) { 6378 finalList.add(ii); 6379 } 6380 } 6381 } 6382 } 6383 6384 return finalList; 6385 } 6386 6387 private void createIdmapsForPackageLI(PackageParser.Package pkg) { 6388 ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName); 6389 if (overlays == null) { 6390 Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages"); 6391 return; 6392 } 6393 for (PackageParser.Package opkg : overlays.values()) { 6394 // Not much to do if idmap fails: we already logged the error 6395 // and we certainly don't want to abort installation of pkg simply 6396 // because an overlay didn't fit properly. For these reasons, 6397 // ignore the return value of createIdmapForPackagePairLI. 6398 createIdmapForPackagePairLI(pkg, opkg); 6399 } 6400 } 6401 6402 private boolean createIdmapForPackagePairLI(PackageParser.Package pkg, 6403 PackageParser.Package opkg) { 6404 if (!opkg.mTrustedOverlay) { 6405 Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " + 6406 opkg.baseCodePath + ": overlay not trusted"); 6407 return false; 6408 } 6409 ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName); 6410 if (overlaySet == null) { 6411 Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " + 6412 opkg.baseCodePath + " but target package has no known overlays"); 6413 return false; 6414 } 6415 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 6416 // TODO: generate idmap for split APKs 6417 try { 6418 mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid); 6419 } catch (InstallerException e) { 6420 Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and " 6421 + opkg.baseCodePath); 6422 return false; 6423 } 6424 PackageParser.Package[] overlayArray = 6425 overlaySet.values().toArray(new PackageParser.Package[0]); 6426 Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() { 6427 public int compare(PackageParser.Package p1, PackageParser.Package p2) { 6428 return p1.mOverlayPriority - p2.mOverlayPriority; 6429 } 6430 }; 6431 Arrays.sort(overlayArray, cmp); 6432 6433 pkg.applicationInfo.resourceDirs = new String[overlayArray.length]; 6434 int i = 0; 6435 for (PackageParser.Package p : overlayArray) { 6436 pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath; 6437 } 6438 return true; 6439 } 6440 6441 private void scanDirTracedLI(File dir, int parseFlags, int scanFlags, long currentTime) { 6442 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir"); 6443 try { 6444 scanDirLI(dir, parseFlags, scanFlags, currentTime); 6445 } finally { 6446 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6447 } 6448 } 6449 6450 private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) { 6451 final File[] files = dir.listFiles(); 6452 if (ArrayUtils.isEmpty(files)) { 6453 Log.d(TAG, "No files in app dir " + dir); 6454 return; 6455 } 6456 6457 if (DEBUG_PACKAGE_SCANNING) { 6458 Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags 6459 + " flags=0x" + Integer.toHexString(parseFlags)); 6460 } 6461 6462 for (File file : files) { 6463 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 6464 && !PackageInstallerService.isStageName(file.getName()); 6465 if (!isPackage) { 6466 // Ignore entries which are not packages 6467 continue; 6468 } 6469 try { 6470 scanPackageTracedLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK, 6471 scanFlags, currentTime, null); 6472 } catch (PackageManagerException e) { 6473 Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage()); 6474 6475 // Delete invalid userdata apps 6476 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 && 6477 e.error == PackageManager.INSTALL_FAILED_INVALID_APK) { 6478 logCriticalInfo(Log.WARN, "Deleting invalid package at " + file); 6479 removeCodePathLI(file); 6480 } 6481 } 6482 } 6483 } 6484 6485 private static File getSettingsProblemFile() { 6486 File dataDir = Environment.getDataDirectory(); 6487 File systemDir = new File(dataDir, "system"); 6488 File fname = new File(systemDir, "uiderrors.txt"); 6489 return fname; 6490 } 6491 6492 static void reportSettingsProblem(int priority, String msg) { 6493 logCriticalInfo(priority, msg); 6494 } 6495 6496 static void logCriticalInfo(int priority, String msg) { 6497 Slog.println(priority, TAG, msg); 6498 EventLogTags.writePmCriticalInfo(msg); 6499 try { 6500 File fname = getSettingsProblemFile(); 6501 FileOutputStream out = new FileOutputStream(fname, true); 6502 PrintWriter pw = new FastPrintWriter(out); 6503 SimpleDateFormat formatter = new SimpleDateFormat(); 6504 String dateString = formatter.format(new Date(System.currentTimeMillis())); 6505 pw.println(dateString + ": " + msg); 6506 pw.close(); 6507 FileUtils.setPermissions( 6508 fname.toString(), 6509 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH, 6510 -1, -1); 6511 } catch (java.io.IOException e) { 6512 } 6513 } 6514 6515 private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile, 6516 int parseFlags) throws PackageManagerException { 6517 if (ps != null 6518 && ps.codePath.equals(srcFile) 6519 && ps.timeStamp == srcFile.lastModified() 6520 && !isCompatSignatureUpdateNeeded(pkg) 6521 && !isRecoverSignatureUpdateNeeded(pkg)) { 6522 long mSigningKeySetId = ps.keySetData.getProperSigningKeySet(); 6523 KeySetManagerService ksms = mSettings.mKeySetManagerService; 6524 ArraySet<PublicKey> signingKs; 6525 synchronized (mPackages) { 6526 signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId); 6527 } 6528 if (ps.signatures.mSignatures != null 6529 && ps.signatures.mSignatures.length != 0 6530 && signingKs != null) { 6531 // Optimization: reuse the existing cached certificates 6532 // if the package appears to be unchanged. 6533 pkg.mSignatures = ps.signatures.mSignatures; 6534 pkg.mSigningKeys = signingKs; 6535 return; 6536 } 6537 6538 Slog.w(TAG, "PackageSetting for " + ps.name 6539 + " is missing signatures. Collecting certs again to recover them."); 6540 } else { 6541 Log.i(TAG, srcFile.toString() + " changed; collecting certs"); 6542 } 6543 6544 try { 6545 PackageParser.collectCertificates(pkg, parseFlags); 6546 } catch (PackageParserException e) { 6547 throw PackageManagerException.from(e); 6548 } 6549 } 6550 6551 /** 6552 * Traces a package scan. 6553 * @see #scanPackageLI(File, int, int, long, UserHandle) 6554 */ 6555 private PackageParser.Package scanPackageTracedLI(File scanFile, int parseFlags, int scanFlags, 6556 long currentTime, UserHandle user) throws PackageManagerException { 6557 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage"); 6558 try { 6559 return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user); 6560 } finally { 6561 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6562 } 6563 } 6564 6565 /** 6566 * Scans a package and returns the newly parsed package. 6567 * Returns {@code null} in case of errors and the error code is stored in mLastScanError 6568 */ 6569 private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags, 6570 long currentTime, UserHandle user) throws PackageManagerException { 6571 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile); 6572 parseFlags |= mDefParseFlags; 6573 PackageParser pp = new PackageParser(); 6574 pp.setSeparateProcesses(mSeparateProcesses); 6575 pp.setOnlyCoreApps(mOnlyCore); 6576 pp.setDisplayMetrics(mMetrics); 6577 6578 if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) { 6579 parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY; 6580 } 6581 6582 final PackageParser.Package pkg; 6583 try { 6584 pkg = pp.parsePackage(scanFile, parseFlags); 6585 } catch (PackageParserException e) { 6586 throw PackageManagerException.from(e); 6587 } 6588 6589 return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user); 6590 } 6591 6592 /** 6593 * Scans a package and returns the newly parsed package. 6594 * @throws PackageManagerException on a parse error. 6595 */ 6596 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile, 6597 int parseFlags, int scanFlags, long currentTime, UserHandle user) 6598 throws PackageManagerException { 6599 // If the package has children and this is the first dive in the function 6600 // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all 6601 // packages (parent and children) would be successfully scanned before the 6602 // actual scan since scanning mutates internal state and we want to atomically 6603 // install the package and its children. 6604 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 6605 if (pkg.childPackages != null && pkg.childPackages.size() > 0) { 6606 scanFlags |= SCAN_CHECK_ONLY; 6607 } 6608 } else { 6609 scanFlags &= ~SCAN_CHECK_ONLY; 6610 } 6611 6612 // Scan the parent 6613 PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, parseFlags, 6614 scanFlags, currentTime, user); 6615 6616 // Scan the children 6617 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 6618 for (int i = 0; i < childCount; i++) { 6619 PackageParser.Package childPackage = pkg.childPackages.get(i); 6620 scanPackageInternalLI(childPackage, scanFile, parseFlags, scanFlags, 6621 currentTime, user); 6622 } 6623 6624 6625 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 6626 return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user); 6627 } 6628 6629 return scannedPkg; 6630 } 6631 6632 /** 6633 * Scans a package and returns the newly parsed package. 6634 * @throws PackageManagerException on a parse error. 6635 */ 6636 private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile, 6637 int parseFlags, int scanFlags, long currentTime, UserHandle user) 6638 throws PackageManagerException { 6639 PackageSetting ps = null; 6640 PackageSetting updatedPkg; 6641 // reader 6642 synchronized (mPackages) { 6643 // Look to see if we already know about this package. 6644 String oldName = mSettings.mRenamedPackages.get(pkg.packageName); 6645 if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) { 6646 // This package has been renamed to its original name. Let's 6647 // use that. 6648 ps = mSettings.peekPackageLPr(oldName); 6649 } 6650 // If there was no original package, see one for the real package name. 6651 if (ps == null) { 6652 ps = mSettings.peekPackageLPr(pkg.packageName); 6653 } 6654 // Check to see if this package could be hiding/updating a system 6655 // package. Must look for it either under the original or real 6656 // package name depending on our state. 6657 updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName); 6658 if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg); 6659 6660 // If this is a package we don't know about on the system partition, we 6661 // may need to remove disabled child packages on the system partition 6662 // or may need to not add child packages if the parent apk is updated 6663 // on the data partition and no longer defines this child package. 6664 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) != 0) { 6665 // If this is a parent package for an updated system app and this system 6666 // app got an OTA update which no longer defines some of the child packages 6667 // we have to prune them from the disabled system packages. 6668 PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName); 6669 if (disabledPs != null) { 6670 final int scannedChildCount = (pkg.childPackages != null) 6671 ? pkg.childPackages.size() : 0; 6672 final int disabledChildCount = disabledPs.childPackageNames != null 6673 ? disabledPs.childPackageNames.size() : 0; 6674 for (int i = 0; i < disabledChildCount; i++) { 6675 String disabledChildPackageName = disabledPs.childPackageNames.get(i); 6676 boolean disabledPackageAvailable = false; 6677 for (int j = 0; j < scannedChildCount; j++) { 6678 PackageParser.Package childPkg = pkg.childPackages.get(j); 6679 if (childPkg.packageName.equals(disabledChildPackageName)) { 6680 disabledPackageAvailable = true; 6681 break; 6682 } 6683 } 6684 if (!disabledPackageAvailable) { 6685 mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName); 6686 } 6687 } 6688 } 6689 } 6690 } 6691 6692 boolean updatedPkgBetter = false; 6693 // First check if this is a system package that may involve an update 6694 if (updatedPkg != null && (parseFlags & PackageParser.PARSE_IS_SYSTEM) != 0) { 6695 // If new package is not located in "/system/priv-app" (e.g. due to an OTA), 6696 // it needs to drop FLAG_PRIVILEGED. 6697 if (locationIsPrivileged(scanFile)) { 6698 updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 6699 } else { 6700 updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 6701 } 6702 6703 if (ps != null && !ps.codePath.equals(scanFile)) { 6704 // The path has changed from what was last scanned... check the 6705 // version of the new path against what we have stored to determine 6706 // what to do. 6707 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath); 6708 if (pkg.mVersionCode <= ps.versionCode) { 6709 // The system package has been updated and the code path does not match 6710 // Ignore entry. Skip it. 6711 if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile 6712 + " ignored: updated version " + ps.versionCode 6713 + " better than this " + pkg.mVersionCode); 6714 if (!updatedPkg.codePath.equals(scanFile)) { 6715 Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg " 6716 + ps.name + " changing from " + updatedPkg.codePathString 6717 + " to " + scanFile); 6718 updatedPkg.codePath = scanFile; 6719 updatedPkg.codePathString = scanFile.toString(); 6720 updatedPkg.resourcePath = scanFile; 6721 updatedPkg.resourcePathString = scanFile.toString(); 6722 } 6723 updatedPkg.pkg = pkg; 6724 updatedPkg.versionCode = pkg.mVersionCode; 6725 6726 // Update the disabled system child packages to point to the package too. 6727 final int childCount = updatedPkg.childPackageNames != null 6728 ? updatedPkg.childPackageNames.size() : 0; 6729 for (int i = 0; i < childCount; i++) { 6730 String childPackageName = updatedPkg.childPackageNames.get(i); 6731 PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr( 6732 childPackageName); 6733 if (updatedChildPkg != null) { 6734 updatedChildPkg.pkg = pkg; 6735 updatedChildPkg.versionCode = pkg.mVersionCode; 6736 } 6737 } 6738 6739 throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at " 6740 + scanFile + " ignored: updated version " + ps.versionCode 6741 + " better than this " + pkg.mVersionCode); 6742 } else { 6743 // The current app on the system partition is better than 6744 // what we have updated to on the data partition; switch 6745 // back to the system partition version. 6746 // At this point, its safely assumed that package installation for 6747 // apps in system partition will go through. If not there won't be a working 6748 // version of the app 6749 // writer 6750 synchronized (mPackages) { 6751 // Just remove the loaded entries from package lists. 6752 mPackages.remove(ps.name); 6753 } 6754 6755 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 6756 + " reverting from " + ps.codePathString 6757 + ": new version " + pkg.mVersionCode 6758 + " better than installed " + ps.versionCode); 6759 6760 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 6761 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 6762 synchronized (mInstallLock) { 6763 args.cleanUpResourcesLI(); 6764 } 6765 synchronized (mPackages) { 6766 mSettings.enableSystemPackageLPw(ps.name); 6767 } 6768 updatedPkgBetter = true; 6769 } 6770 } 6771 } 6772 6773 if (updatedPkg != null) { 6774 // An updated system app will not have the PARSE_IS_SYSTEM flag set 6775 // initially 6776 parseFlags |= PackageParser.PARSE_IS_SYSTEM; 6777 6778 // An updated privileged app will not have the PARSE_IS_PRIVILEGED 6779 // flag set initially 6780 if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) { 6781 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 6782 } 6783 } 6784 6785 // Verify certificates against what was last scanned 6786 collectCertificatesLI(ps, pkg, scanFile, parseFlags); 6787 6788 /* 6789 * A new system app appeared, but we already had a non-system one of the 6790 * same name installed earlier. 6791 */ 6792 boolean shouldHideSystemApp = false; 6793 if (updatedPkg == null && ps != null 6794 && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) { 6795 /* 6796 * Check to make sure the signatures match first. If they don't, 6797 * wipe the installed application and its data. 6798 */ 6799 if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures) 6800 != PackageManager.SIGNATURE_MATCH) { 6801 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but" 6802 + " signatures don't match existing userdata copy; removing"); 6803 deletePackageLI(pkg.packageName, null, true, null, 0, null, false, null); 6804 ps = null; 6805 } else { 6806 /* 6807 * If the newly-added system app is an older version than the 6808 * already installed version, hide it. It will be scanned later 6809 * and re-added like an update. 6810 */ 6811 if (pkg.mVersionCode <= ps.versionCode) { 6812 shouldHideSystemApp = true; 6813 logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile 6814 + " but new version " + pkg.mVersionCode + " better than installed " 6815 + ps.versionCode + "; hiding system"); 6816 } else { 6817 /* 6818 * The newly found system app is a newer version that the 6819 * one previously installed. Simply remove the 6820 * already-installed application and replace it with our own 6821 * while keeping the application data. 6822 */ 6823 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 6824 + " reverting from " + ps.codePathString + ": new version " 6825 + pkg.mVersionCode + " better than installed " + ps.versionCode); 6826 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 6827 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 6828 synchronized (mInstallLock) { 6829 args.cleanUpResourcesLI(); 6830 } 6831 } 6832 } 6833 } 6834 6835 // The apk is forward locked (not public) if its code and resources 6836 // are kept in different files. (except for app in either system or 6837 // vendor path). 6838 // TODO grab this value from PackageSettings 6839 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 6840 if (ps != null && !ps.codePath.equals(ps.resourcePath)) { 6841 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 6842 } 6843 } 6844 6845 // TODO: extend to support forward-locked splits 6846 String resourcePath = null; 6847 String baseResourcePath = null; 6848 if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) { 6849 if (ps != null && ps.resourcePathString != null) { 6850 resourcePath = ps.resourcePathString; 6851 baseResourcePath = ps.resourcePathString; 6852 } else { 6853 // Should not happen at all. Just log an error. 6854 Slog.e(TAG, "Resource path not set for package " + pkg.packageName); 6855 } 6856 } else { 6857 resourcePath = pkg.codePath; 6858 baseResourcePath = pkg.baseCodePath; 6859 } 6860 6861 // Set application objects path explicitly. 6862 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 6863 pkg.setApplicationInfoCodePath(pkg.codePath); 6864 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 6865 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 6866 pkg.setApplicationInfoResourcePath(resourcePath); 6867 pkg.setApplicationInfoBaseResourcePath(baseResourcePath); 6868 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 6869 6870 // Note that we invoke the following method only if we are about to unpack an application 6871 PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags 6872 | SCAN_UPDATE_SIGNATURE, currentTime, user); 6873 6874 /* 6875 * If the system app should be overridden by a previously installed 6876 * data, hide the system app now and let the /data/app scan pick it up 6877 * again. 6878 */ 6879 if (shouldHideSystemApp) { 6880 synchronized (mPackages) { 6881 mSettings.disableSystemPackageLPw(pkg.packageName, true); 6882 } 6883 } 6884 6885 return scannedPkg; 6886 } 6887 6888 private static String fixProcessName(String defProcessName, 6889 String processName, int uid) { 6890 if (processName == null) { 6891 return defProcessName; 6892 } 6893 return processName; 6894 } 6895 6896 private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg) 6897 throws PackageManagerException { 6898 if (pkgSetting.signatures.mSignatures != null) { 6899 // Already existing package. Make sure signatures match 6900 boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures) 6901 == PackageManager.SIGNATURE_MATCH; 6902 if (!match) { 6903 match = compareSignaturesCompat(pkgSetting.signatures, pkg) 6904 == PackageManager.SIGNATURE_MATCH; 6905 } 6906 if (!match) { 6907 match = compareSignaturesRecover(pkgSetting.signatures, pkg) 6908 == PackageManager.SIGNATURE_MATCH; 6909 } 6910 if (!match) { 6911 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 6912 + pkg.packageName + " signatures do not match the " 6913 + "previously installed version; ignoring!"); 6914 } 6915 } 6916 6917 // Check for shared user signatures 6918 if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) { 6919 // Already existing package. Make sure signatures match 6920 boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 6921 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 6922 if (!match) { 6923 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg) 6924 == PackageManager.SIGNATURE_MATCH; 6925 } 6926 if (!match) { 6927 match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg) 6928 == PackageManager.SIGNATURE_MATCH; 6929 } 6930 if (!match) { 6931 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 6932 "Package " + pkg.packageName 6933 + " has no signatures that match those in shared user " 6934 + pkgSetting.sharedUser.name + "; ignoring!"); 6935 } 6936 } 6937 } 6938 6939 /** 6940 * Enforces that only the system UID or root's UID can call a method exposed 6941 * via Binder. 6942 * 6943 * @param message used as message if SecurityException is thrown 6944 * @throws SecurityException if the caller is not system or root 6945 */ 6946 private static final void enforceSystemOrRoot(String message) { 6947 final int uid = Binder.getCallingUid(); 6948 if (uid != Process.SYSTEM_UID && uid != 0) { 6949 throw new SecurityException(message); 6950 } 6951 } 6952 6953 @Override 6954 public void performFstrimIfNeeded() { 6955 enforceSystemOrRoot("Only the system can request fstrim"); 6956 6957 // Before everything else, see whether we need to fstrim. 6958 try { 6959 IMountService ms = PackageHelper.getMountService(); 6960 if (ms != null) { 6961 final boolean isUpgrade = isUpgrade(); 6962 boolean doTrim = isUpgrade; 6963 if (doTrim) { 6964 Slog.w(TAG, "Running disk maintenance immediately due to system update"); 6965 } else { 6966 final long interval = android.provider.Settings.Global.getLong( 6967 mContext.getContentResolver(), 6968 android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL, 6969 DEFAULT_MANDATORY_FSTRIM_INTERVAL); 6970 if (interval > 0) { 6971 final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance(); 6972 if (timeSinceLast > interval) { 6973 doTrim = true; 6974 Slog.w(TAG, "No disk maintenance in " + timeSinceLast 6975 + "; running immediately"); 6976 } 6977 } 6978 } 6979 if (doTrim) { 6980 if (!isFirstBoot()) { 6981 try { 6982 ActivityManagerNative.getDefault().showBootMessage( 6983 mContext.getResources().getString( 6984 R.string.android_upgrading_fstrim), true); 6985 } catch (RemoteException e) { 6986 } 6987 } 6988 ms.runMaintenance(); 6989 } 6990 } else { 6991 Slog.e(TAG, "Mount service unavailable!"); 6992 } 6993 } catch (RemoteException e) { 6994 // Can't happen; MountService is local 6995 } 6996 } 6997 6998 @Override 6999 public void updatePackagesIfNeeded() { 7000 enforceSystemOrRoot("Only the system can request package update"); 7001 7002 // We need to re-extract after an OTA. 7003 boolean causeUpgrade = isUpgrade(); 7004 7005 // First boot or factory reset. 7006 // Note: we also handle devices that are upgrading to N right now as if it is their 7007 // first boot, as they do not have profile data. 7008 boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade; 7009 7010 // We need to re-extract after a pruned cache, as AoT-ed files will be out of date. 7011 boolean causePrunedCache = VMRuntime.didPruneDalvikCache(); 7012 7013 if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) { 7014 return; 7015 } 7016 7017 List<PackageParser.Package> pkgs; 7018 synchronized (mPackages) { 7019 pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this); 7020 } 7021 7022 UsageStatsManager usageMgr = 7023 (UsageStatsManager) mContext.getSystemService(Context.USAGE_STATS_SERVICE); 7024 7025 int curr = 0; 7026 int total = pkgs.size(); 7027 for (PackageParser.Package pkg : pkgs) { 7028 curr++; 7029 7030 if (!PackageDexOptimizer.canOptimizePackage(pkg)) { 7031 if (DEBUG_DEXOPT) { 7032 Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName); 7033 } 7034 continue; 7035 } 7036 7037 if (!causeFirstBoot && usageMgr.isAppInactive(pkg.packageName)) { 7038 if (DEBUG_DEXOPT) { 7039 Log.i(TAG, "Skipping update of of idle app " + pkg.packageName); 7040 } 7041 continue; 7042 } 7043 7044 if (DEBUG_DEXOPT) { 7045 Log.i(TAG, "Extracting app " + curr + " of " + total + ": " + pkg.packageName); 7046 } 7047 7048 if (!isFirstBoot()) { 7049 try { 7050 ActivityManagerNative.getDefault().showBootMessage( 7051 mContext.getResources().getString(R.string.android_upgrading_apk, 7052 curr, total), true); 7053 } catch (RemoteException e) { 7054 } 7055 } 7056 7057 performDexOpt(pkg.packageName, 7058 null /* instructionSet */, 7059 false /* checkProfiles */, 7060 causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT, 7061 false /* force */); 7062 } 7063 } 7064 7065 @Override 7066 public void notifyPackageUse(String packageName) { 7067 synchronized (mPackages) { 7068 PackageParser.Package p = mPackages.get(packageName); 7069 if (p == null) { 7070 return; 7071 } 7072 p.mLastPackageUsageTimeInMills = System.currentTimeMillis(); 7073 } 7074 } 7075 7076 // TODO: this is not used nor needed. Delete it. 7077 @Override 7078 public boolean performDexOptIfNeeded(String packageName, String instructionSet) { 7079 return performDexOptTraced(packageName, instructionSet, false /* checkProfiles */, 7080 getFullCompilerFilter(), false /* force */); 7081 } 7082 7083 @Override 7084 public boolean performDexOpt(String packageName, String instructionSet, 7085 boolean checkProfiles, int compileReason, boolean force) { 7086 return performDexOptTraced(packageName, instructionSet, checkProfiles, 7087 getCompilerFilterForReason(compileReason), force); 7088 } 7089 7090 @Override 7091 public boolean performDexOptMode(String packageName, String instructionSet, 7092 boolean checkProfiles, String targetCompilerFilter, boolean force) { 7093 return performDexOptTraced(packageName, instructionSet, checkProfiles, 7094 targetCompilerFilter, force); 7095 } 7096 7097 private boolean performDexOptTraced(String packageName, String instructionSet, 7098 boolean checkProfiles, String targetCompilerFilter, boolean force) { 7099 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 7100 try { 7101 return performDexOptInternal(packageName, instructionSet, checkProfiles, 7102 targetCompilerFilter, force); 7103 } finally { 7104 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7105 } 7106 } 7107 7108 private boolean performDexOptInternal(String packageName, String instructionSet, 7109 boolean checkProfiles, String targetCompilerFilter, boolean force) { 7110 PackageParser.Package p; 7111 final String targetInstructionSet; 7112 synchronized (mPackages) { 7113 p = mPackages.get(packageName); 7114 if (p == null) { 7115 return false; 7116 } 7117 mPackageUsage.write(false); 7118 7119 targetInstructionSet = instructionSet != null ? instructionSet : 7120 getPrimaryInstructionSet(p.applicationInfo); 7121 } 7122 long callingId = Binder.clearCallingIdentity(); 7123 try { 7124 synchronized (mInstallLock) { 7125 final String[] instructionSets = new String[] { targetInstructionSet }; 7126 int result = performDexOptInternalWithDependenciesLI(p, instructionSets, 7127 checkProfiles, targetCompilerFilter, force); 7128 return result == PackageDexOptimizer.DEX_OPT_PERFORMED; 7129 } 7130 } finally { 7131 Binder.restoreCallingIdentity(callingId); 7132 } 7133 } 7134 7135 public ArraySet<String> getOptimizablePackages() { 7136 ArraySet<String> pkgs = new ArraySet<String>(); 7137 synchronized (mPackages) { 7138 for (PackageParser.Package p : mPackages.values()) { 7139 if (PackageDexOptimizer.canOptimizePackage(p)) { 7140 pkgs.add(p.packageName); 7141 } 7142 } 7143 } 7144 return pkgs; 7145 } 7146 7147 private int performDexOptInternalWithDependenciesLI(PackageParser.Package p, 7148 String instructionSets[], boolean checkProfiles, String targetCompilerFilter, 7149 boolean force) { 7150 // Select the dex optimizer based on the force parameter. 7151 // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to 7152 // allocate an object here. 7153 PackageDexOptimizer pdo = force 7154 ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer) 7155 : mPackageDexOptimizer; 7156 7157 // Optimize all dependencies first. Note: we ignore the return value and march on 7158 // on errors. 7159 Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p); 7160 if (!deps.isEmpty()) { 7161 for (PackageParser.Package depPackage : deps) { 7162 // TODO: Analyze and investigate if we (should) profile libraries. 7163 // Currently this will do a full compilation of the library by default. 7164 pdo.performDexOpt(depPackage, instructionSets, false /* checkProfiles */, 7165 getCompilerFilterForReason(REASON_NON_SYSTEM_LIBRARY)); 7166 } 7167 } 7168 7169 return pdo.performDexOpt(p, instructionSets, checkProfiles, targetCompilerFilter); 7170 } 7171 7172 Collection<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) { 7173 if (p.usesLibraries != null || p.usesOptionalLibraries != null) { 7174 ArrayList<PackageParser.Package> retValue = new ArrayList<>(); 7175 Set<String> collectedNames = new HashSet<>(); 7176 findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames); 7177 7178 retValue.remove(p); 7179 7180 return retValue; 7181 } else { 7182 return Collections.emptyList(); 7183 } 7184 } 7185 7186 private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p, 7187 Collection<PackageParser.Package> collected, Set<String> collectedNames) { 7188 if (!collectedNames.contains(p.packageName)) { 7189 collectedNames.add(p.packageName); 7190 collected.add(p); 7191 7192 if (p.usesLibraries != null) { 7193 findSharedNonSystemLibrariesRecursive(p.usesLibraries, collected, collectedNames); 7194 } 7195 if (p.usesOptionalLibraries != null) { 7196 findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries, collected, 7197 collectedNames); 7198 } 7199 } 7200 } 7201 7202 private void findSharedNonSystemLibrariesRecursive(Collection<String> libs, 7203 Collection<PackageParser.Package> collected, Set<String> collectedNames) { 7204 for (String libName : libs) { 7205 PackageParser.Package libPkg = findSharedNonSystemLibrary(libName); 7206 if (libPkg != null) { 7207 findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames); 7208 } 7209 } 7210 } 7211 7212 private PackageParser.Package findSharedNonSystemLibrary(String libName) { 7213 synchronized (mPackages) { 7214 PackageManagerService.SharedLibraryEntry lib = mSharedLibraries.get(libName); 7215 if (lib != null && lib.apk != null) { 7216 return mPackages.get(lib.apk); 7217 } 7218 } 7219 return null; 7220 } 7221 7222 public void shutdown() { 7223 mPackageUsage.write(true); 7224 } 7225 7226 @Override 7227 public void forceDexOpt(String packageName) { 7228 enforceSystemOrRoot("forceDexOpt"); 7229 7230 PackageParser.Package pkg; 7231 synchronized (mPackages) { 7232 pkg = mPackages.get(packageName); 7233 if (pkg == null) { 7234 throw new IllegalArgumentException("Unknown package: " + packageName); 7235 } 7236 } 7237 7238 synchronized (mInstallLock) { 7239 final String[] instructionSets = new String[] { 7240 getPrimaryInstructionSet(pkg.applicationInfo) }; 7241 7242 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 7243 7244 // Whoever is calling forceDexOpt wants a fully compiled package. 7245 // Don't use profiles since that may cause compilation to be skipped. 7246 final int res = performDexOptInternalWithDependenciesLI(pkg, instructionSets, 7247 false /* checkProfiles */, getCompilerFilterForReason(REASON_FORCED_DEXOPT), 7248 true /* force */); 7249 7250 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7251 if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) { 7252 throw new IllegalStateException("Failed to dexopt: " + res); 7253 } 7254 } 7255 } 7256 7257 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) { 7258 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) { 7259 Slog.w(TAG, "Unable to update from " + oldPkg.name 7260 + " to " + newPkg.packageName 7261 + ": old package not in system partition"); 7262 return false; 7263 } else if (mPackages.get(oldPkg.name) != null) { 7264 Slog.w(TAG, "Unable to update from " + oldPkg.name 7265 + " to " + newPkg.packageName 7266 + ": old package still exists"); 7267 return false; 7268 } 7269 return true; 7270 } 7271 7272 private boolean removeDataDirsLI(String volumeUuid, String packageName) { 7273 // TODO: triage flags as part of 26466827 7274 final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE; 7275 7276 boolean res = true; 7277 final int[] users = sUserManager.getUserIds(); 7278 for (int user : users) { 7279 try { 7280 mInstaller.destroyAppData(volumeUuid, packageName, user, flags); 7281 } catch (InstallerException e) { 7282 Slog.w(TAG, "Failed to delete data directory", e); 7283 res = false; 7284 } 7285 } 7286 return res; 7287 } 7288 7289 void removeCodePathLI(File codePath) { 7290 if (codePath.isDirectory()) { 7291 try { 7292 mInstaller.rmPackageDir(codePath.getAbsolutePath()); 7293 } catch (InstallerException e) { 7294 Slog.w(TAG, "Failed to remove code path", e); 7295 } 7296 } else { 7297 codePath.delete(); 7298 } 7299 } 7300 7301 void destroyAppDataLI(String volumeUuid, String packageName, int userId, int flags) { 7302 try { 7303 mInstaller.destroyAppData(volumeUuid, packageName, userId, flags); 7304 } catch (InstallerException e) { 7305 Slog.w(TAG, "Failed to destroy app data", e); 7306 } 7307 } 7308 7309 void restoreconAppDataLI(String volumeUuid, String packageName, int userId, int flags, 7310 int appId, String seinfo) { 7311 try { 7312 mInstaller.restoreconAppData(volumeUuid, packageName, userId, flags, appId, seinfo); 7313 } catch (InstallerException e) { 7314 Slog.e(TAG, "Failed to restorecon for " + packageName + ": " + e); 7315 } 7316 } 7317 7318 private void deleteProfilesLI(String packageName, boolean destroy) { 7319 final PackageParser.Package pkg; 7320 synchronized (mPackages) { 7321 pkg = mPackages.get(packageName); 7322 } 7323 if (pkg == null) { 7324 Slog.w(TAG, "Failed to delete profiles. No package: " + packageName); 7325 return; 7326 } 7327 deleteProfilesLI(pkg, destroy); 7328 } 7329 7330 private void deleteProfilesLI(PackageParser.Package pkg, boolean destroy) { 7331 try { 7332 if (destroy) { 7333 mInstaller.destroyAppProfiles(pkg.packageName); 7334 } else { 7335 mInstaller.clearAppProfiles(pkg.packageName); 7336 } 7337 } catch (InstallerException ex) { 7338 Log.e(TAG, "Could not delete profiles for package " + pkg.packageName); 7339 } 7340 } 7341 7342 private void deleteCodeCacheDirsLI(String volumeUuid, String packageName) { 7343 final PackageParser.Package pkg; 7344 synchronized (mPackages) { 7345 pkg = mPackages.get(packageName); 7346 } 7347 if (pkg == null) { 7348 Slog.w(TAG, "Failed to delete code cache directory. No package: " + packageName); 7349 return; 7350 } 7351 deleteCodeCacheDirsLI(pkg); 7352 } 7353 7354 private void deleteCodeCacheDirsLI(PackageParser.Package pkg) { 7355 // TODO: triage flags as part of 26466827 7356 final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE; 7357 7358 int[] users = sUserManager.getUserIds(); 7359 int res = 0; 7360 for (int user : users) { 7361 // Remove the parent code cache 7362 try { 7363 mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, user, 7364 flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 7365 } catch (InstallerException e) { 7366 Slog.w(TAG, "Failed to delete code cache directory", e); 7367 } 7368 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7369 for (int i = 0; i < childCount; i++) { 7370 PackageParser.Package childPkg = pkg.childPackages.get(i); 7371 // Remove the child code cache 7372 try { 7373 mInstaller.clearAppData(childPkg.volumeUuid, childPkg.packageName, 7374 user, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 7375 } catch (InstallerException e) { 7376 Slog.w(TAG, "Failed to delete code cache directory", e); 7377 } 7378 } 7379 } 7380 } 7381 7382 private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime, 7383 long lastUpdateTime) { 7384 // Set parent install/update time 7385 PackageSetting ps = (PackageSetting) pkg.mExtras; 7386 if (ps != null) { 7387 ps.firstInstallTime = firstInstallTime; 7388 ps.lastUpdateTime = lastUpdateTime; 7389 } 7390 // Set children install/update time 7391 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7392 for (int i = 0; i < childCount; i++) { 7393 PackageParser.Package childPkg = pkg.childPackages.get(i); 7394 ps = (PackageSetting) childPkg.mExtras; 7395 if (ps != null) { 7396 ps.firstInstallTime = firstInstallTime; 7397 ps.lastUpdateTime = lastUpdateTime; 7398 } 7399 } 7400 } 7401 7402 private void addSharedLibraryLPw(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file, 7403 PackageParser.Package changingLib) { 7404 if (file.path != null) { 7405 usesLibraryFiles.add(file.path); 7406 return; 7407 } 7408 PackageParser.Package p = mPackages.get(file.apk); 7409 if (changingLib != null && changingLib.packageName.equals(file.apk)) { 7410 // If we are doing this while in the middle of updating a library apk, 7411 // then we need to make sure to use that new apk for determining the 7412 // dependencies here. (We haven't yet finished committing the new apk 7413 // to the package manager state.) 7414 if (p == null || p.packageName.equals(changingLib.packageName)) { 7415 p = changingLib; 7416 } 7417 } 7418 if (p != null) { 7419 usesLibraryFiles.addAll(p.getAllCodePaths()); 7420 } 7421 } 7422 7423 private void updateSharedLibrariesLPw(PackageParser.Package pkg, 7424 PackageParser.Package changingLib) throws PackageManagerException { 7425 if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) { 7426 final ArraySet<String> usesLibraryFiles = new ArraySet<>(); 7427 int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0; 7428 for (int i=0; i<N; i++) { 7429 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i)); 7430 if (file == null) { 7431 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, 7432 "Package " + pkg.packageName + " requires unavailable shared library " 7433 + pkg.usesLibraries.get(i) + "; failing!"); 7434 } 7435 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 7436 } 7437 N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0; 7438 for (int i=0; i<N; i++) { 7439 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i)); 7440 if (file == null) { 7441 Slog.w(TAG, "Package " + pkg.packageName 7442 + " desires unavailable shared library " 7443 + pkg.usesOptionalLibraries.get(i) + "; ignoring!"); 7444 } else { 7445 addSharedLibraryLPw(usesLibraryFiles, file, changingLib); 7446 } 7447 } 7448 N = usesLibraryFiles.size(); 7449 if (N > 0) { 7450 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]); 7451 } else { 7452 pkg.usesLibraryFiles = null; 7453 } 7454 } 7455 } 7456 7457 private static boolean hasString(List<String> list, List<String> which) { 7458 if (list == null) { 7459 return false; 7460 } 7461 for (int i=list.size()-1; i>=0; i--) { 7462 for (int j=which.size()-1; j>=0; j--) { 7463 if (which.get(j).equals(list.get(i))) { 7464 return true; 7465 } 7466 } 7467 } 7468 return false; 7469 } 7470 7471 private void updateAllSharedLibrariesLPw() { 7472 for (PackageParser.Package pkg : mPackages.values()) { 7473 try { 7474 updateSharedLibrariesLPw(pkg, null); 7475 } catch (PackageManagerException e) { 7476 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 7477 } 7478 } 7479 } 7480 7481 private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw( 7482 PackageParser.Package changingPkg) { 7483 ArrayList<PackageParser.Package> res = null; 7484 for (PackageParser.Package pkg : mPackages.values()) { 7485 if (hasString(pkg.usesLibraries, changingPkg.libraryNames) 7486 || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) { 7487 if (res == null) { 7488 res = new ArrayList<PackageParser.Package>(); 7489 } 7490 res.add(pkg); 7491 try { 7492 updateSharedLibrariesLPw(pkg, changingPkg); 7493 } catch (PackageManagerException e) { 7494 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 7495 } 7496 } 7497 } 7498 return res; 7499 } 7500 7501 /** 7502 * Derive the value of the {@code cpuAbiOverride} based on the provided 7503 * value and an optional stored value from the package settings. 7504 */ 7505 private static String deriveAbiOverride(String abiOverride, PackageSetting settings) { 7506 String cpuAbiOverride = null; 7507 7508 if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) { 7509 cpuAbiOverride = null; 7510 } else if (abiOverride != null) { 7511 cpuAbiOverride = abiOverride; 7512 } else if (settings != null) { 7513 cpuAbiOverride = settings.cpuAbiOverrideString; 7514 } 7515 7516 return cpuAbiOverride; 7517 } 7518 7519 private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg, int parseFlags, 7520 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 7521 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage"); 7522 // If the package has children and this is the first dive in the function 7523 // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see 7524 // whether all packages (parent and children) would be successfully scanned 7525 // before the actual scan since scanning mutates internal state and we want 7526 // to atomically install the package and its children. 7527 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 7528 if (pkg.childPackages != null && pkg.childPackages.size() > 0) { 7529 scanFlags |= SCAN_CHECK_ONLY; 7530 } 7531 } else { 7532 scanFlags &= ~SCAN_CHECK_ONLY; 7533 } 7534 7535 final PackageParser.Package scannedPkg; 7536 try { 7537 // Scan the parent 7538 scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags, currentTime, user); 7539 // Scan the children 7540 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7541 for (int i = 0; i < childCount; i++) { 7542 PackageParser.Package childPkg = pkg.childPackages.get(i); 7543 scanPackageLI(childPkg, parseFlags, 7544 scanFlags, currentTime, user); 7545 } 7546 } finally { 7547 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7548 } 7549 7550 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 7551 return scanPackageTracedLI(pkg, parseFlags, scanFlags, currentTime, user); 7552 } 7553 7554 return scannedPkg; 7555 } 7556 7557 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags, 7558 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 7559 boolean success = false; 7560 try { 7561 final PackageParser.Package res = scanPackageDirtyLI(pkg, parseFlags, scanFlags, 7562 currentTime, user); 7563 success = true; 7564 return res; 7565 } finally { 7566 if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) { 7567 removeDataDirsLI(pkg.volumeUuid, pkg.packageName); 7568 } 7569 } 7570 } 7571 7572 private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, int parseFlags, 7573 int scanFlags, long currentTime, UserHandle user) 7574 throws PackageManagerException { 7575 final File scanFile = new File(pkg.codePath); 7576 if (pkg.applicationInfo.getCodePath() == null || 7577 pkg.applicationInfo.getResourcePath() == null) { 7578 // Bail out. The resource and code paths haven't been set. 7579 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 7580 "Code and resource paths haven't been set correctly"); 7581 } 7582 7583 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 7584 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; 7585 } else { 7586 // Only allow system apps to be flagged as core apps. 7587 pkg.coreApp = false; 7588 } 7589 7590 if ((parseFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) { 7591 pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 7592 } 7593 7594 if (mCustomResolverComponentName != null && 7595 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) { 7596 setUpCustomResolverActivity(pkg); 7597 } 7598 7599 if (pkg.packageName.equals("android")) { 7600 synchronized (mPackages) { 7601 if (mAndroidApplication != null) { 7602 Slog.w(TAG, "*************************************************"); 7603 Slog.w(TAG, "Core android package being redefined. Skipping."); 7604 Slog.w(TAG, " file=" + scanFile); 7605 Slog.w(TAG, "*************************************************"); 7606 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 7607 "Core android package being redefined. Skipping."); 7608 } 7609 7610 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 7611 // Set up information for our fall-back user intent resolution activity. 7612 mPlatformPackage = pkg; 7613 pkg.mVersionCode = mSdkVersion; 7614 mAndroidApplication = pkg.applicationInfo; 7615 7616 if (!mResolverReplaced) { 7617 mResolveActivity.applicationInfo = mAndroidApplication; 7618 mResolveActivity.name = ResolverActivity.class.getName(); 7619 mResolveActivity.packageName = mAndroidApplication.packageName; 7620 mResolveActivity.processName = "system:ui"; 7621 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 7622 mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER; 7623 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS; 7624 mResolveActivity.theme = R.style.Theme_Holo_Dialog_Alert; 7625 mResolveActivity.exported = true; 7626 mResolveActivity.enabled = true; 7627 mResolveInfo.activityInfo = mResolveActivity; 7628 mResolveInfo.priority = 0; 7629 mResolveInfo.preferredOrder = 0; 7630 mResolveInfo.match = 0; 7631 mResolveComponentName = new ComponentName( 7632 mAndroidApplication.packageName, mResolveActivity.name); 7633 } 7634 } 7635 } 7636 } 7637 7638 if (DEBUG_PACKAGE_SCANNING) { 7639 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 7640 Log.d(TAG, "Scanning package " + pkg.packageName); 7641 } 7642 7643 synchronized (mPackages) { 7644 if (mPackages.containsKey(pkg.packageName) 7645 || mSharedLibraries.containsKey(pkg.packageName)) { 7646 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 7647 "Application package " + pkg.packageName 7648 + " already installed. Skipping duplicate."); 7649 } 7650 7651 // If we're only installing presumed-existing packages, require that the 7652 // scanned APK is both already known and at the path previously established 7653 // for it. Previously unknown packages we pick up normally, but if we have an 7654 // a priori expectation about this package's install presence, enforce it. 7655 // With a singular exception for new system packages. When an OTA contains 7656 // a new system package, we allow the codepath to change from a system location 7657 // to the user-installed location. If we don't allow this change, any newer, 7658 // user-installed version of the application will be ignored. 7659 if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) { 7660 if (mExpectingBetter.containsKey(pkg.packageName)) { 7661 logCriticalInfo(Log.WARN, 7662 "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName); 7663 } else { 7664 PackageSetting known = mSettings.peekPackageLPr(pkg.packageName); 7665 if (known != null) { 7666 if (DEBUG_PACKAGE_SCANNING) { 7667 Log.d(TAG, "Examining " + pkg.codePath 7668 + " and requiring known paths " + known.codePathString 7669 + " & " + known.resourcePathString); 7670 } 7671 if (!pkg.applicationInfo.getCodePath().equals(known.codePathString) 7672 || !pkg.applicationInfo.getResourcePath().equals( 7673 known.resourcePathString)) { 7674 throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED, 7675 "Application package " + pkg.packageName 7676 + " found at " + pkg.applicationInfo.getCodePath() 7677 + " but expected at " + known.codePathString 7678 + "; ignoring."); 7679 } 7680 } 7681 } 7682 } 7683 } 7684 7685 // Initialize package source and resource directories 7686 File destCodeFile = new File(pkg.applicationInfo.getCodePath()); 7687 File destResourceFile = new File(pkg.applicationInfo.getResourcePath()); 7688 7689 SharedUserSetting suid = null; 7690 PackageSetting pkgSetting = null; 7691 7692 if (!isSystemApp(pkg)) { 7693 // Only system apps can use these features. 7694 pkg.mOriginalPackages = null; 7695 pkg.mRealPackage = null; 7696 pkg.mAdoptPermissions = null; 7697 } 7698 7699 // Getting the package setting may have a side-effect, so if we 7700 // are only checking if scan would succeed, stash a copy of the 7701 // old setting to restore at the end. 7702 PackageSetting nonMutatedPs = null; 7703 7704 // writer 7705 synchronized (mPackages) { 7706 if (pkg.mSharedUserId != null) { 7707 suid = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, true); 7708 if (suid == null) { 7709 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 7710 "Creating application package " + pkg.packageName 7711 + " for shared user failed"); 7712 } 7713 if (DEBUG_PACKAGE_SCANNING) { 7714 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 7715 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId 7716 + "): packages=" + suid.packages); 7717 } 7718 } 7719 7720 // Check if we are renaming from an original package name. 7721 PackageSetting origPackage = null; 7722 String realName = null; 7723 if (pkg.mOriginalPackages != null) { 7724 // This package may need to be renamed to a previously 7725 // installed name. Let's check on that... 7726 final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage); 7727 if (pkg.mOriginalPackages.contains(renamed)) { 7728 // This package had originally been installed as the 7729 // original name, and we have already taken care of 7730 // transitioning to the new one. Just update the new 7731 // one to continue using the old name. 7732 realName = pkg.mRealPackage; 7733 if (!pkg.packageName.equals(renamed)) { 7734 // Callers into this function may have already taken 7735 // care of renaming the package; only do it here if 7736 // it is not already done. 7737 pkg.setPackageName(renamed); 7738 } 7739 7740 } else { 7741 for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) { 7742 if ((origPackage = mSettings.peekPackageLPr( 7743 pkg.mOriginalPackages.get(i))) != null) { 7744 // We do have the package already installed under its 7745 // original name... should we use it? 7746 if (!verifyPackageUpdateLPr(origPackage, pkg)) { 7747 // New package is not compatible with original. 7748 origPackage = null; 7749 continue; 7750 } else if (origPackage.sharedUser != null) { 7751 // Make sure uid is compatible between packages. 7752 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) { 7753 Slog.w(TAG, "Unable to migrate data from " + origPackage.name 7754 + " to " + pkg.packageName + ": old uid " 7755 + origPackage.sharedUser.name 7756 + " differs from " + pkg.mSharedUserId); 7757 origPackage = null; 7758 continue; 7759 } 7760 } else { 7761 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package " 7762 + pkg.packageName + " to old name " + origPackage.name); 7763 } 7764 break; 7765 } 7766 } 7767 } 7768 } 7769 7770 if (mTransferedPackages.contains(pkg.packageName)) { 7771 Slog.w(TAG, "Package " + pkg.packageName 7772 + " was transferred to another, but its .apk remains"); 7773 } 7774 7775 // See comments in nonMutatedPs declaration 7776 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 7777 PackageSetting foundPs = mSettings.peekPackageLPr(pkg.packageName); 7778 if (foundPs != null) { 7779 nonMutatedPs = new PackageSetting(foundPs); 7780 } 7781 } 7782 7783 // Just create the setting, don't add it yet. For already existing packages 7784 // the PkgSetting exists already and doesn't have to be created. 7785 pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile, 7786 destResourceFile, pkg.applicationInfo.nativeLibraryRootDir, 7787 pkg.applicationInfo.primaryCpuAbi, 7788 pkg.applicationInfo.secondaryCpuAbi, 7789 pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, 7790 user, false); 7791 if (pkgSetting == null) { 7792 throw new PackageManagerException(INSTALL_FAILED_INSUFFICIENT_STORAGE, 7793 "Creating application package " + pkg.packageName + " failed"); 7794 } 7795 7796 if (pkgSetting.origPackage != null) { 7797 // If we are first transitioning from an original package, 7798 // fix up the new package's name now. We need to do this after 7799 // looking up the package under its new name, so getPackageLP 7800 // can take care of fiddling things correctly. 7801 pkg.setPackageName(origPackage.name); 7802 7803 // File a report about this. 7804 String msg = "New package " + pkgSetting.realName 7805 + " renamed to replace old package " + pkgSetting.name; 7806 reportSettingsProblem(Log.WARN, msg); 7807 7808 // Make a note of it. 7809 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 7810 mTransferedPackages.add(origPackage.name); 7811 } 7812 7813 // No longer need to retain this. 7814 pkgSetting.origPackage = null; 7815 } 7816 7817 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) { 7818 // Make a note of it. 7819 mTransferedPackages.add(pkg.packageName); 7820 } 7821 7822 if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) { 7823 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 7824 } 7825 7826 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 7827 // Check all shared libraries and map to their actual file path. 7828 // We only do this here for apps not on a system dir, because those 7829 // are the only ones that can fail an install due to this. We 7830 // will take care of the system apps by updating all of their 7831 // library paths after the scan is done. 7832 updateSharedLibrariesLPw(pkg, null); 7833 } 7834 7835 if (mFoundPolicyFile) { 7836 SELinuxMMAC.assignSeinfoValue(pkg); 7837 } 7838 7839 pkg.applicationInfo.uid = pkgSetting.appId; 7840 pkg.mExtras = pkgSetting; 7841 if (shouldCheckUpgradeKeySetLP(pkgSetting, scanFlags)) { 7842 if (checkUpgradeKeySetLP(pkgSetting, pkg)) { 7843 // We just determined the app is signed correctly, so bring 7844 // over the latest parsed certs. 7845 pkgSetting.signatures.mSignatures = pkg.mSignatures; 7846 } else { 7847 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 7848 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 7849 "Package " + pkg.packageName + " upgrade keys do not match the " 7850 + "previously installed version"); 7851 } else { 7852 pkgSetting.signatures.mSignatures = pkg.mSignatures; 7853 String msg = "System package " + pkg.packageName 7854 + " signature changed; retaining data."; 7855 reportSettingsProblem(Log.WARN, msg); 7856 } 7857 } 7858 } else { 7859 try { 7860 verifySignaturesLP(pkgSetting, pkg); 7861 // We just determined the app is signed correctly, so bring 7862 // over the latest parsed certs. 7863 pkgSetting.signatures.mSignatures = pkg.mSignatures; 7864 } catch (PackageManagerException e) { 7865 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 7866 throw e; 7867 } 7868 // The signature has changed, but this package is in the system 7869 // image... let's recover! 7870 pkgSetting.signatures.mSignatures = pkg.mSignatures; 7871 // However... if this package is part of a shared user, but it 7872 // doesn't match the signature of the shared user, let's fail. 7873 // What this means is that you can't change the signatures 7874 // associated with an overall shared user, which doesn't seem all 7875 // that unreasonable. 7876 if (pkgSetting.sharedUser != null) { 7877 if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 7878 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { 7879 throw new PackageManagerException( 7880 INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES, 7881 "Signature mismatch for shared user: " 7882 + pkgSetting.sharedUser); 7883 } 7884 } 7885 // File a report about this. 7886 String msg = "System package " + pkg.packageName 7887 + " signature changed; retaining data."; 7888 reportSettingsProblem(Log.WARN, msg); 7889 } 7890 } 7891 // Verify that this new package doesn't have any content providers 7892 // that conflict with existing packages. Only do this if the 7893 // package isn't already installed, since we don't want to break 7894 // things that are installed. 7895 if ((scanFlags & SCAN_NEW_INSTALL) != 0) { 7896 final int N = pkg.providers.size(); 7897 int i; 7898 for (i=0; i<N; i++) { 7899 PackageParser.Provider p = pkg.providers.get(i); 7900 if (p.info.authority != null) { 7901 String names[] = p.info.authority.split(";"); 7902 for (int j = 0; j < names.length; j++) { 7903 if (mProvidersByAuthority.containsKey(names[j])) { 7904 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 7905 final String otherPackageName = 7906 ((other != null && other.getComponentName() != null) ? 7907 other.getComponentName().getPackageName() : "?"); 7908 throw new PackageManagerException( 7909 INSTALL_FAILED_CONFLICTING_PROVIDER, 7910 "Can't install because provider name " + names[j] 7911 + " (in package " + pkg.applicationInfo.packageName 7912 + ") is already used by " + otherPackageName); 7913 } 7914 } 7915 } 7916 } 7917 } 7918 7919 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) { 7920 // This package wants to adopt ownership of permissions from 7921 // another package. 7922 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) { 7923 final String origName = pkg.mAdoptPermissions.get(i); 7924 final PackageSetting orig = mSettings.peekPackageLPr(origName); 7925 if (orig != null) { 7926 if (verifyPackageUpdateLPr(orig, pkg)) { 7927 Slog.i(TAG, "Adopting permissions from " + origName + " to " 7928 + pkg.packageName); 7929 mSettings.transferPermissionsLPw(origName, pkg.packageName); 7930 } 7931 } 7932 } 7933 } 7934 } 7935 7936 final String pkgName = pkg.packageName; 7937 7938 final long scanFileTime = scanFile.lastModified(); 7939 final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0; 7940 pkg.applicationInfo.processName = fixProcessName( 7941 pkg.applicationInfo.packageName, 7942 pkg.applicationInfo.processName, 7943 pkg.applicationInfo.uid); 7944 7945 if (pkg != mPlatformPackage) { 7946 // Get all of our default paths setup 7947 pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM); 7948 } 7949 7950 final String path = scanFile.getPath(); 7951 final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting); 7952 7953 if ((scanFlags & SCAN_NEW_INSTALL) == 0) { 7954 derivePackageAbi(pkg, scanFile, cpuAbiOverride, true /* extract libs */); 7955 7956 // Some system apps still use directory structure for native libraries 7957 // in which case we might end up not detecting abi solely based on apk 7958 // structure. Try to detect abi based on directory structure. 7959 if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() && 7960 pkg.applicationInfo.primaryCpuAbi == null) { 7961 setBundledAppAbisAndRoots(pkg, pkgSetting); 7962 setNativeLibraryPaths(pkg); 7963 } 7964 7965 } else { 7966 if ((scanFlags & SCAN_MOVE) != 0) { 7967 // We haven't run dex-opt for this move (since we've moved the compiled output too) 7968 // but we already have this packages package info in the PackageSetting. We just 7969 // use that and derive the native library path based on the new codepath. 7970 pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString; 7971 pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString; 7972 } 7973 7974 // Set native library paths again. For moves, the path will be updated based on the 7975 // ABIs we've determined above. For non-moves, the path will be updated based on the 7976 // ABIs we determined during compilation, but the path will depend on the final 7977 // package path (after the rename away from the stage path). 7978 setNativeLibraryPaths(pkg); 7979 } 7980 7981 // This is a special case for the "system" package, where the ABI is 7982 // dictated by the zygote configuration (and init.rc). We should keep track 7983 // of this ABI so that we can deal with "normal" applications that run under 7984 // the same UID correctly. 7985 if (mPlatformPackage == pkg) { 7986 pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ? 7987 Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]; 7988 } 7989 7990 // If there's a mismatch between the abi-override in the package setting 7991 // and the abiOverride specified for the install. Warn about this because we 7992 // would've already compiled the app without taking the package setting into 7993 // account. 7994 if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) { 7995 if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) { 7996 Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride + 7997 " for package " + pkg.packageName); 7998 } 7999 } 8000 8001 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 8002 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 8003 pkgSetting.cpuAbiOverrideString = cpuAbiOverride; 8004 8005 // Copy the derived override back to the parsed package, so that we can 8006 // update the package settings accordingly. 8007 pkg.cpuAbiOverride = cpuAbiOverride; 8008 8009 if (DEBUG_ABI_SELECTION) { 8010 Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName 8011 + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa=" 8012 + pkg.applicationInfo.nativeLibraryRootRequiresIsa); 8013 } 8014 8015 // Push the derived path down into PackageSettings so we know what to 8016 // clean up at uninstall time. 8017 pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir; 8018 8019 if (DEBUG_ABI_SELECTION) { 8020 Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" + 8021 " primary=" + pkg.applicationInfo.primaryCpuAbi + 8022 " secondary=" + pkg.applicationInfo.secondaryCpuAbi); 8023 } 8024 8025 if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) { 8026 // We don't do this here during boot because we can do it all 8027 // at once after scanning all existing packages. 8028 // 8029 // We also do this *before* we perform dexopt on this package, so that 8030 // we can avoid redundant dexopts, and also to make sure we've got the 8031 // code and package path correct. 8032 adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, 8033 pkg, true /* boot complete */); 8034 } 8035 8036 if (mFactoryTest && pkg.requestedPermissions.contains( 8037 android.Manifest.permission.FACTORY_TEST)) { 8038 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST; 8039 } 8040 8041 ArrayList<PackageParser.Package> clientLibPkgs = null; 8042 8043 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 8044 if (nonMutatedPs != null) { 8045 synchronized (mPackages) { 8046 mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs); 8047 } 8048 } 8049 return pkg; 8050 } 8051 8052 // Only privileged apps and updated privileged apps can add child packages. 8053 if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) { 8054 if ((parseFlags & PARSE_IS_PRIVILEGED) == 0) { 8055 throw new PackageManagerException("Only privileged apps and updated " 8056 + "privileged apps can add child packages. Ignoring package " 8057 + pkg.packageName); 8058 } 8059 final int childCount = pkg.childPackages.size(); 8060 for (int i = 0; i < childCount; i++) { 8061 PackageParser.Package childPkg = pkg.childPackages.get(i); 8062 if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName, 8063 childPkg.packageName)) { 8064 throw new PackageManagerException("Cannot override a child package of " 8065 + "another disabled system app. Ignoring package " + pkg.packageName); 8066 } 8067 } 8068 } 8069 8070 // writer 8071 synchronized (mPackages) { 8072 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 8073 // Only system apps can add new shared libraries. 8074 if (pkg.libraryNames != null) { 8075 for (int i=0; i<pkg.libraryNames.size(); i++) { 8076 String name = pkg.libraryNames.get(i); 8077 boolean allowed = false; 8078 if (pkg.isUpdatedSystemApp()) { 8079 // New library entries can only be added through the 8080 // system image. This is important to get rid of a lot 8081 // of nasty edge cases: for example if we allowed a non- 8082 // system update of the app to add a library, then uninstalling 8083 // the update would make the library go away, and assumptions 8084 // we made such as through app install filtering would now 8085 // have allowed apps on the device which aren't compatible 8086 // with it. Better to just have the restriction here, be 8087 // conservative, and create many fewer cases that can negatively 8088 // impact the user experience. 8089 final PackageSetting sysPs = mSettings 8090 .getDisabledSystemPkgLPr(pkg.packageName); 8091 if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) { 8092 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) { 8093 if (name.equals(sysPs.pkg.libraryNames.get(j))) { 8094 allowed = true; 8095 break; 8096 } 8097 } 8098 } 8099 } else { 8100 allowed = true; 8101 } 8102 if (allowed) { 8103 if (!mSharedLibraries.containsKey(name)) { 8104 mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName)); 8105 } else if (!name.equals(pkg.packageName)) { 8106 Slog.w(TAG, "Package " + pkg.packageName + " library " 8107 + name + " already exists; skipping"); 8108 } 8109 } else { 8110 Slog.w(TAG, "Package " + pkg.packageName + " declares lib " 8111 + name + " that is not declared on system image; skipping"); 8112 } 8113 } 8114 if ((scanFlags & SCAN_BOOTING) == 0) { 8115 // If we are not booting, we need to update any applications 8116 // that are clients of our shared library. If we are booting, 8117 // this will all be done once the scan is complete. 8118 clientLibPkgs = updateAllSharedLibrariesLPw(pkg); 8119 } 8120 } 8121 } 8122 } 8123 8124 // Request the ActivityManager to kill the process(only for existing packages) 8125 // so that we do not end up in a confused state while the user is still using the older 8126 // version of the application while the new one gets installed. 8127 final boolean isReplacing = (scanFlags & SCAN_REPLACING) != 0; 8128 final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0; 8129 if (killApp) { 8130 if (isReplacing) { 8131 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "killApplication"); 8132 8133 killApplication(pkg.applicationInfo.packageName, 8134 pkg.applicationInfo.uid, "replace pkg"); 8135 8136 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 8137 } 8138 } 8139 8140 // Also need to kill any apps that are dependent on the library. 8141 if (clientLibPkgs != null) { 8142 for (int i=0; i<clientLibPkgs.size(); i++) { 8143 PackageParser.Package clientPkg = clientLibPkgs.get(i); 8144 killApplication(clientPkg.applicationInfo.packageName, 8145 clientPkg.applicationInfo.uid, "update lib"); 8146 } 8147 } 8148 8149 // Make sure we're not adding any bogus keyset info 8150 KeySetManagerService ksms = mSettings.mKeySetManagerService; 8151 ksms.assertScannedPackageValid(pkg); 8152 8153 // writer 8154 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 8155 8156 boolean createIdmapFailed = false; 8157 synchronized (mPackages) { 8158 // We don't expect installation to fail beyond this point 8159 8160 // Add the new setting to mSettings 8161 mSettings.insertPackageSettingLPw(pkgSetting, pkg); 8162 // Add the new setting to mPackages 8163 mPackages.put(pkg.applicationInfo.packageName, pkg); 8164 // Make sure we don't accidentally delete its data. 8165 final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator(); 8166 while (iter.hasNext()) { 8167 PackageCleanItem item = iter.next(); 8168 if (pkgName.equals(item.packageName)) { 8169 iter.remove(); 8170 } 8171 } 8172 8173 // Take care of first install / last update times. 8174 if (currentTime != 0) { 8175 if (pkgSetting.firstInstallTime == 0) { 8176 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime; 8177 } else if ((scanFlags&SCAN_UPDATE_TIME) != 0) { 8178 pkgSetting.lastUpdateTime = currentTime; 8179 } 8180 } else if (pkgSetting.firstInstallTime == 0) { 8181 // We need *something*. Take time time stamp of the file. 8182 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime; 8183 } else if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) != 0) { 8184 if (scanFileTime != pkgSetting.timeStamp) { 8185 // A package on the system image has changed; consider this 8186 // to be an update. 8187 pkgSetting.lastUpdateTime = scanFileTime; 8188 } 8189 } 8190 8191 // Add the package's KeySets to the global KeySetManagerService 8192 ksms.addScannedPackageLPw(pkg); 8193 8194 int N = pkg.providers.size(); 8195 StringBuilder r = null; 8196 int i; 8197 for (i=0; i<N; i++) { 8198 PackageParser.Provider p = pkg.providers.get(i); 8199 p.info.processName = fixProcessName(pkg.applicationInfo.processName, 8200 p.info.processName, pkg.applicationInfo.uid); 8201 mProviders.addProvider(p); 8202 p.syncable = p.info.isSyncable; 8203 if (p.info.authority != null) { 8204 String names[] = p.info.authority.split(";"); 8205 p.info.authority = null; 8206 for (int j = 0; j < names.length; j++) { 8207 if (j == 1 && p.syncable) { 8208 // We only want the first authority for a provider to possibly be 8209 // syncable, so if we already added this provider using a different 8210 // authority clear the syncable flag. We copy the provider before 8211 // changing it because the mProviders object contains a reference 8212 // to a provider that we don't want to change. 8213 // Only do this for the second authority since the resulting provider 8214 // object can be the same for all future authorities for this provider. 8215 p = new PackageParser.Provider(p); 8216 p.syncable = false; 8217 } 8218 if (!mProvidersByAuthority.containsKey(names[j])) { 8219 mProvidersByAuthority.put(names[j], p); 8220 if (p.info.authority == null) { 8221 p.info.authority = names[j]; 8222 } else { 8223 p.info.authority = p.info.authority + ";" + names[j]; 8224 } 8225 if (DEBUG_PACKAGE_SCANNING) { 8226 if ((parseFlags & PackageParser.PARSE_CHATTY) != 0) 8227 Log.d(TAG, "Registered content provider: " + names[j] 8228 + ", className = " + p.info.name + ", isSyncable = " 8229 + p.info.isSyncable); 8230 } 8231 } else { 8232 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 8233 Slog.w(TAG, "Skipping provider name " + names[j] + 8234 " (in package " + pkg.applicationInfo.packageName + 8235 "): name already used by " 8236 + ((other != null && other.getComponentName() != null) 8237 ? other.getComponentName().getPackageName() : "?")); 8238 } 8239 } 8240 } 8241 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8242 if (r == null) { 8243 r = new StringBuilder(256); 8244 } else { 8245 r.append(' '); 8246 } 8247 r.append(p.info.name); 8248 } 8249 } 8250 if (r != null) { 8251 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r); 8252 } 8253 8254 N = pkg.services.size(); 8255 r = null; 8256 for (i=0; i<N; i++) { 8257 PackageParser.Service s = pkg.services.get(i); 8258 s.info.processName = fixProcessName(pkg.applicationInfo.processName, 8259 s.info.processName, pkg.applicationInfo.uid); 8260 mServices.addService(s); 8261 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8262 if (r == null) { 8263 r = new StringBuilder(256); 8264 } else { 8265 r.append(' '); 8266 } 8267 r.append(s.info.name); 8268 } 8269 } 8270 if (r != null) { 8271 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r); 8272 } 8273 8274 N = pkg.receivers.size(); 8275 r = null; 8276 for (i=0; i<N; i++) { 8277 PackageParser.Activity a = pkg.receivers.get(i); 8278 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 8279 a.info.processName, pkg.applicationInfo.uid); 8280 mReceivers.addActivity(a, "receiver"); 8281 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8282 if (r == null) { 8283 r = new StringBuilder(256); 8284 } else { 8285 r.append(' '); 8286 } 8287 r.append(a.info.name); 8288 } 8289 } 8290 if (r != null) { 8291 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r); 8292 } 8293 8294 N = pkg.activities.size(); 8295 r = null; 8296 for (i=0; i<N; i++) { 8297 PackageParser.Activity a = pkg.activities.get(i); 8298 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 8299 a.info.processName, pkg.applicationInfo.uid); 8300 mActivities.addActivity(a, "activity"); 8301 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8302 if (r == null) { 8303 r = new StringBuilder(256); 8304 } else { 8305 r.append(' '); 8306 } 8307 r.append(a.info.name); 8308 } 8309 } 8310 if (r != null) { 8311 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r); 8312 } 8313 8314 N = pkg.permissionGroups.size(); 8315 r = null; 8316 for (i=0; i<N; i++) { 8317 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i); 8318 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name); 8319 if (cur == null) { 8320 mPermissionGroups.put(pg.info.name, pg); 8321 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8322 if (r == null) { 8323 r = new StringBuilder(256); 8324 } else { 8325 r.append(' '); 8326 } 8327 r.append(pg.info.name); 8328 } 8329 } else { 8330 Slog.w(TAG, "Permission group " + pg.info.name + " from package " 8331 + pg.info.packageName + " ignored: original from " 8332 + cur.info.packageName); 8333 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8334 if (r == null) { 8335 r = new StringBuilder(256); 8336 } else { 8337 r.append(' '); 8338 } 8339 r.append("DUP:"); 8340 r.append(pg.info.name); 8341 } 8342 } 8343 } 8344 if (r != null) { 8345 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permission Groups: " + r); 8346 } 8347 8348 N = pkg.permissions.size(); 8349 r = null; 8350 for (i=0; i<N; i++) { 8351 PackageParser.Permission p = pkg.permissions.get(i); 8352 8353 // Assume by default that we did not install this permission into the system. 8354 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED; 8355 8356 // Now that permission groups have a special meaning, we ignore permission 8357 // groups for legacy apps to prevent unexpected behavior. In particular, 8358 // permissions for one app being granted to someone just becase they happen 8359 // to be in a group defined by another app (before this had no implications). 8360 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) { 8361 p.group = mPermissionGroups.get(p.info.group); 8362 // Warn for a permission in an unknown group. 8363 if (p.info.group != null && p.group == null) { 8364 Slog.w(TAG, "Permission " + p.info.name + " from package " 8365 + p.info.packageName + " in an unknown group " + p.info.group); 8366 } 8367 } 8368 8369 ArrayMap<String, BasePermission> permissionMap = 8370 p.tree ? mSettings.mPermissionTrees 8371 : mSettings.mPermissions; 8372 BasePermission bp = permissionMap.get(p.info.name); 8373 8374 // Allow system apps to redefine non-system permissions 8375 if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) { 8376 final boolean currentOwnerIsSystem = (bp.perm != null 8377 && isSystemApp(bp.perm.owner)); 8378 if (isSystemApp(p.owner)) { 8379 if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) { 8380 // It's a built-in permission and no owner, take ownership now 8381 bp.packageSetting = pkgSetting; 8382 bp.perm = p; 8383 bp.uid = pkg.applicationInfo.uid; 8384 bp.sourcePackage = p.info.packageName; 8385 p.info.flags |= PermissionInfo.FLAG_INSTALLED; 8386 } else if (!currentOwnerIsSystem) { 8387 String msg = "New decl " + p.owner + " of permission " 8388 + p.info.name + " is system; overriding " + bp.sourcePackage; 8389 reportSettingsProblem(Log.WARN, msg); 8390 bp = null; 8391 } 8392 } 8393 } 8394 8395 if (bp == null) { 8396 bp = new BasePermission(p.info.name, p.info.packageName, 8397 BasePermission.TYPE_NORMAL); 8398 permissionMap.put(p.info.name, bp); 8399 } 8400 8401 if (bp.perm == null) { 8402 if (bp.sourcePackage == null 8403 || bp.sourcePackage.equals(p.info.packageName)) { 8404 BasePermission tree = findPermissionTreeLP(p.info.name); 8405 if (tree == null 8406 || tree.sourcePackage.equals(p.info.packageName)) { 8407 bp.packageSetting = pkgSetting; 8408 bp.perm = p; 8409 bp.uid = pkg.applicationInfo.uid; 8410 bp.sourcePackage = p.info.packageName; 8411 p.info.flags |= PermissionInfo.FLAG_INSTALLED; 8412 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8413 if (r == null) { 8414 r = new StringBuilder(256); 8415 } else { 8416 r.append(' '); 8417 } 8418 r.append(p.info.name); 8419 } 8420 } else { 8421 Slog.w(TAG, "Permission " + p.info.name + " from package " 8422 + p.info.packageName + " ignored: base tree " 8423 + tree.name + " is from package " 8424 + tree.sourcePackage); 8425 } 8426 } else { 8427 Slog.w(TAG, "Permission " + p.info.name + " from package " 8428 + p.info.packageName + " ignored: original from " 8429 + bp.sourcePackage); 8430 } 8431 } else if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8432 if (r == null) { 8433 r = new StringBuilder(256); 8434 } else { 8435 r.append(' '); 8436 } 8437 r.append("DUP:"); 8438 r.append(p.info.name); 8439 } 8440 if (bp.perm == p) { 8441 bp.protectionLevel = p.info.protectionLevel; 8442 } 8443 } 8444 8445 if (r != null) { 8446 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permissions: " + r); 8447 } 8448 8449 N = pkg.instrumentation.size(); 8450 r = null; 8451 for (i=0; i<N; i++) { 8452 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 8453 a.info.packageName = pkg.applicationInfo.packageName; 8454 a.info.sourceDir = pkg.applicationInfo.sourceDir; 8455 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir; 8456 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs; 8457 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs; 8458 a.info.dataDir = pkg.applicationInfo.dataDir; 8459 a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir; 8460 a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir; 8461 8462 // TODO: Update instrumentation.nativeLibraryDir as well ? Does it 8463 // need other information about the application, like the ABI and what not ? 8464 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir; 8465 mInstrumentation.put(a.getComponentName(), a); 8466 if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { 8467 if (r == null) { 8468 r = new StringBuilder(256); 8469 } else { 8470 r.append(' '); 8471 } 8472 r.append(a.info.name); 8473 } 8474 } 8475 if (r != null) { 8476 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r); 8477 } 8478 8479 if (pkg.protectedBroadcasts != null) { 8480 N = pkg.protectedBroadcasts.size(); 8481 for (i=0; i<N; i++) { 8482 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i)); 8483 } 8484 } 8485 8486 pkgSetting.setTimeStamp(scanFileTime); 8487 8488 // Create idmap files for pairs of (packages, overlay packages). 8489 // Note: "android", ie framework-res.apk, is handled by native layers. 8490 if (pkg.mOverlayTarget != null) { 8491 // This is an overlay package. 8492 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) { 8493 if (!mOverlays.containsKey(pkg.mOverlayTarget)) { 8494 mOverlays.put(pkg.mOverlayTarget, 8495 new ArrayMap<String, PackageParser.Package>()); 8496 } 8497 ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget); 8498 map.put(pkg.packageName, pkg); 8499 PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget); 8500 if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) { 8501 createIdmapFailed = true; 8502 } 8503 } 8504 } else if (mOverlays.containsKey(pkg.packageName) && 8505 !pkg.packageName.equals("android")) { 8506 // This is a regular package, with one or more known overlay packages. 8507 createIdmapsForPackageLI(pkg); 8508 } 8509 } 8510 8511 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 8512 8513 if (createIdmapFailed) { 8514 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 8515 "scanPackageLI failed to createIdmap"); 8516 } 8517 return pkg; 8518 } 8519 8520 /** 8521 * Derive the ABI of a non-system package located at {@code scanFile}. This information 8522 * is derived purely on the basis of the contents of {@code scanFile} and 8523 * {@code cpuAbiOverride}. 8524 * 8525 * If {@code extractLibs} is true, native libraries are extracted from the app if required. 8526 */ 8527 private void derivePackageAbi(PackageParser.Package pkg, File scanFile, 8528 String cpuAbiOverride, boolean extractLibs) 8529 throws PackageManagerException { 8530 // TODO: We can probably be smarter about this stuff. For installed apps, 8531 // we can calculate this information at install time once and for all. For 8532 // system apps, we can probably assume that this information doesn't change 8533 // after the first boot scan. As things stand, we do lots of unnecessary work. 8534 8535 // Give ourselves some initial paths; we'll come back for another 8536 // pass once we've determined ABI below. 8537 setNativeLibraryPaths(pkg); 8538 8539 // We would never need to extract libs for forward-locked and external packages, 8540 // since the container service will do it for us. We shouldn't attempt to 8541 // extract libs from system app when it was not updated. 8542 if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() || 8543 (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) { 8544 extractLibs = false; 8545 } 8546 8547 final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir; 8548 final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa; 8549 8550 NativeLibraryHelper.Handle handle = null; 8551 try { 8552 handle = NativeLibraryHelper.Handle.create(pkg); 8553 // TODO(multiArch): This can be null for apps that didn't go through the 8554 // usual installation process. We can calculate it again, like we 8555 // do during install time. 8556 // 8557 // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally 8558 // unnecessary. 8559 final File nativeLibraryRoot = new File(nativeLibraryRootStr); 8560 8561 // Null out the abis so that they can be recalculated. 8562 pkg.applicationInfo.primaryCpuAbi = null; 8563 pkg.applicationInfo.secondaryCpuAbi = null; 8564 if (isMultiArch(pkg.applicationInfo)) { 8565 // Warn if we've set an abiOverride for multi-lib packages.. 8566 // By definition, we need to copy both 32 and 64 bit libraries for 8567 // such packages. 8568 if (pkg.cpuAbiOverride != null 8569 && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) { 8570 Slog.w(TAG, "Ignoring abiOverride for multi arch application."); 8571 } 8572 8573 int abi32 = PackageManager.NO_NATIVE_LIBRARIES; 8574 int abi64 = PackageManager.NO_NATIVE_LIBRARIES; 8575 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) { 8576 if (extractLibs) { 8577 abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 8578 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS, 8579 useIsaSpecificSubdirs); 8580 } else { 8581 abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS); 8582 } 8583 } 8584 8585 maybeThrowExceptionForMultiArchCopy( 8586 "Error unpackaging 32 bit native libs for multiarch app.", abi32); 8587 8588 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) { 8589 if (extractLibs) { 8590 abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 8591 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS, 8592 useIsaSpecificSubdirs); 8593 } else { 8594 abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS); 8595 } 8596 } 8597 8598 maybeThrowExceptionForMultiArchCopy( 8599 "Error unpackaging 64 bit native libs for multiarch app.", abi64); 8600 8601 if (abi64 >= 0) { 8602 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64]; 8603 } 8604 8605 if (abi32 >= 0) { 8606 final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32]; 8607 if (abi64 >= 0) { 8608 if (pkg.use32bitAbi) { 8609 pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi; 8610 pkg.applicationInfo.primaryCpuAbi = abi; 8611 } else { 8612 pkg.applicationInfo.secondaryCpuAbi = abi; 8613 } 8614 } else { 8615 pkg.applicationInfo.primaryCpuAbi = abi; 8616 } 8617 } 8618 8619 } else { 8620 String[] abiList = (cpuAbiOverride != null) ? 8621 new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS; 8622 8623 // Enable gross and lame hacks for apps that are built with old 8624 // SDK tools. We must scan their APKs for renderscript bitcode and 8625 // not launch them if it's present. Don't bother checking on devices 8626 // that don't have 64 bit support. 8627 boolean needsRenderScriptOverride = false; 8628 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null && 8629 NativeLibraryHelper.hasRenderscriptBitcode(handle)) { 8630 abiList = Build.SUPPORTED_32_BIT_ABIS; 8631 needsRenderScriptOverride = true; 8632 } 8633 8634 final int copyRet; 8635 if (extractLibs) { 8636 copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 8637 nativeLibraryRoot, abiList, useIsaSpecificSubdirs); 8638 } else { 8639 copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList); 8640 } 8641 8642 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { 8643 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, 8644 "Error unpackaging native libs for app, errorCode=" + copyRet); 8645 } 8646 8647 if (copyRet >= 0) { 8648 pkg.applicationInfo.primaryCpuAbi = abiList[copyRet]; 8649 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) { 8650 pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride; 8651 } else if (needsRenderScriptOverride) { 8652 pkg.applicationInfo.primaryCpuAbi = abiList[0]; 8653 } 8654 } 8655 } catch (IOException ioe) { 8656 Slog.e(TAG, "Unable to get canonical file " + ioe.toString()); 8657 } finally { 8658 IoUtils.closeQuietly(handle); 8659 } 8660 8661 // Now that we've calculated the ABIs and determined if it's an internal app, 8662 // we will go ahead and populate the nativeLibraryPath. 8663 setNativeLibraryPaths(pkg); 8664 } 8665 8666 /** 8667 * Adjusts ABIs for a set of packages belonging to a shared user so that they all match. 8668 * i.e, so that all packages can be run inside a single process if required. 8669 * 8670 * Optionally, callers can pass in a parsed package via {@code newPackage} in which case 8671 * this function will either try and make the ABI for all packages in {@code packagesForUser} 8672 * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match 8673 * the ABI selected for {@code packagesForUser}. This variant is used when installing or 8674 * updating a package that belongs to a shared user. 8675 * 8676 * NOTE: We currently only match for the primary CPU abi string. Matching the secondary 8677 * adds unnecessary complexity. 8678 */ 8679 private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser, 8680 PackageParser.Package scannedPackage, boolean bootComplete) { 8681 String requiredInstructionSet = null; 8682 if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) { 8683 requiredInstructionSet = VMRuntime.getInstructionSet( 8684 scannedPackage.applicationInfo.primaryCpuAbi); 8685 } 8686 8687 PackageSetting requirer = null; 8688 for (PackageSetting ps : packagesForUser) { 8689 // If packagesForUser contains scannedPackage, we skip it. This will happen 8690 // when scannedPackage is an update of an existing package. Without this check, 8691 // we will never be able to change the ABI of any package belonging to a shared 8692 // user, even if it's compatible with other packages. 8693 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 8694 if (ps.primaryCpuAbiString == null) { 8695 continue; 8696 } 8697 8698 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString); 8699 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) { 8700 // We have a mismatch between instruction sets (say arm vs arm64) warn about 8701 // this but there's not much we can do. 8702 String errorMessage = "Instruction set mismatch, " 8703 + ((requirer == null) ? "[caller]" : requirer) 8704 + " requires " + requiredInstructionSet + " whereas " + ps 8705 + " requires " + instructionSet; 8706 Slog.w(TAG, errorMessage); 8707 } 8708 8709 if (requiredInstructionSet == null) { 8710 requiredInstructionSet = instructionSet; 8711 requirer = ps; 8712 } 8713 } 8714 } 8715 8716 if (requiredInstructionSet != null) { 8717 String adjustedAbi; 8718 if (requirer != null) { 8719 // requirer != null implies that either scannedPackage was null or that scannedPackage 8720 // did not require an ABI, in which case we have to adjust scannedPackage to match 8721 // the ABI of the set (which is the same as requirer's ABI) 8722 adjustedAbi = requirer.primaryCpuAbiString; 8723 if (scannedPackage != null) { 8724 scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi; 8725 } 8726 } else { 8727 // requirer == null implies that we're updating all ABIs in the set to 8728 // match scannedPackage. 8729 adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi; 8730 } 8731 8732 for (PackageSetting ps : packagesForUser) { 8733 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 8734 if (ps.primaryCpuAbiString != null) { 8735 continue; 8736 } 8737 8738 ps.primaryCpuAbiString = adjustedAbi; 8739 if (ps.pkg != null && ps.pkg.applicationInfo != null && 8740 !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) { 8741 ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi; 8742 Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi 8743 + " (requirer=" 8744 + (requirer == null ? "null" : requirer.pkg.packageName) 8745 + ", scannedPackage=" 8746 + (scannedPackage != null ? scannedPackage.packageName : "null") 8747 + ")"); 8748 try { 8749 mInstaller.rmdex(ps.codePathString, 8750 getDexCodeInstructionSet(getPreferredInstructionSet())); 8751 } catch (InstallerException ignored) { 8752 } 8753 } 8754 } 8755 } 8756 } 8757 } 8758 8759 private void setUpCustomResolverActivity(PackageParser.Package pkg) { 8760 synchronized (mPackages) { 8761 mResolverReplaced = true; 8762 // Set up information for custom user intent resolution activity. 8763 mResolveActivity.applicationInfo = pkg.applicationInfo; 8764 mResolveActivity.name = mCustomResolverComponentName.getClassName(); 8765 mResolveActivity.packageName = pkg.applicationInfo.packageName; 8766 mResolveActivity.processName = pkg.applicationInfo.packageName; 8767 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 8768 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS | 8769 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 8770 mResolveActivity.theme = 0; 8771 mResolveActivity.exported = true; 8772 mResolveActivity.enabled = true; 8773 mResolveInfo.activityInfo = mResolveActivity; 8774 mResolveInfo.priority = 0; 8775 mResolveInfo.preferredOrder = 0; 8776 mResolveInfo.match = 0; 8777 mResolveComponentName = mCustomResolverComponentName; 8778 Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " + 8779 mResolveComponentName); 8780 } 8781 } 8782 8783 private void setUpEphemeralInstallerActivityLP(ComponentName installerComponent) { 8784 final PackageParser.Package pkg = mPackages.get(installerComponent.getPackageName()); 8785 8786 // Set up information for ephemeral installer activity 8787 mEphemeralInstallerActivity.applicationInfo = pkg.applicationInfo; 8788 mEphemeralInstallerActivity.name = mEphemeralInstallerComponent.getClassName(); 8789 mEphemeralInstallerActivity.packageName = pkg.applicationInfo.packageName; 8790 mEphemeralInstallerActivity.processName = pkg.applicationInfo.packageName; 8791 mEphemeralInstallerActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 8792 mEphemeralInstallerActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS | 8793 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 8794 mEphemeralInstallerActivity.theme = 0; 8795 mEphemeralInstallerActivity.exported = true; 8796 mEphemeralInstallerActivity.enabled = true; 8797 mEphemeralInstallerInfo.activityInfo = mEphemeralInstallerActivity; 8798 mEphemeralInstallerInfo.priority = 0; 8799 mEphemeralInstallerInfo.preferredOrder = 0; 8800 mEphemeralInstallerInfo.match = 0; 8801 8802 if (DEBUG_EPHEMERAL) { 8803 Slog.d(TAG, "Set ephemeral installer activity: " + mEphemeralInstallerComponent); 8804 } 8805 } 8806 8807 private static String calculateBundledApkRoot(final String codePathString) { 8808 final File codePath = new File(codePathString); 8809 final File codeRoot; 8810 if (FileUtils.contains(Environment.getRootDirectory(), codePath)) { 8811 codeRoot = Environment.getRootDirectory(); 8812 } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) { 8813 codeRoot = Environment.getOemDirectory(); 8814 } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) { 8815 codeRoot = Environment.getVendorDirectory(); 8816 } else { 8817 // Unrecognized code path; take its top real segment as the apk root: 8818 // e.g. /something/app/blah.apk => /something 8819 try { 8820 File f = codePath.getCanonicalFile(); 8821 File parent = f.getParentFile(); // non-null because codePath is a file 8822 File tmp; 8823 while ((tmp = parent.getParentFile()) != null) { 8824 f = parent; 8825 parent = tmp; 8826 } 8827 codeRoot = f; 8828 Slog.w(TAG, "Unrecognized code path " 8829 + codePath + " - using " + codeRoot); 8830 } catch (IOException e) { 8831 // Can't canonicalize the code path -- shenanigans? 8832 Slog.w(TAG, "Can't canonicalize code path " + codePath); 8833 return Environment.getRootDirectory().getPath(); 8834 } 8835 } 8836 return codeRoot.getPath(); 8837 } 8838 8839 /** 8840 * Derive and set the location of native libraries for the given package, 8841 * which varies depending on where and how the package was installed. 8842 */ 8843 private void setNativeLibraryPaths(PackageParser.Package pkg) { 8844 final ApplicationInfo info = pkg.applicationInfo; 8845 final String codePath = pkg.codePath; 8846 final File codeFile = new File(codePath); 8847 final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp(); 8848 final boolean asecApp = info.isForwardLocked() || info.isExternalAsec(); 8849 8850 info.nativeLibraryRootDir = null; 8851 info.nativeLibraryRootRequiresIsa = false; 8852 info.nativeLibraryDir = null; 8853 info.secondaryNativeLibraryDir = null; 8854 8855 if (isApkFile(codeFile)) { 8856 // Monolithic install 8857 if (bundledApp) { 8858 // If "/system/lib64/apkname" exists, assume that is the per-package 8859 // native library directory to use; otherwise use "/system/lib/apkname". 8860 final String apkRoot = calculateBundledApkRoot(info.sourceDir); 8861 final boolean is64Bit = VMRuntime.is64BitInstructionSet( 8862 getPrimaryInstructionSet(info)); 8863 8864 // This is a bundled system app so choose the path based on the ABI. 8865 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this 8866 // is just the default path. 8867 final String apkName = deriveCodePathName(codePath); 8868 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME; 8869 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir, 8870 apkName).getAbsolutePath(); 8871 8872 if (info.secondaryCpuAbi != null) { 8873 final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME; 8874 info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot), 8875 secondaryLibDir, apkName).getAbsolutePath(); 8876 } 8877 } else if (asecApp) { 8878 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME) 8879 .getAbsolutePath(); 8880 } else { 8881 final String apkName = deriveCodePathName(codePath); 8882 info.nativeLibraryRootDir = new File(mAppLib32InstallDir, apkName) 8883 .getAbsolutePath(); 8884 } 8885 8886 info.nativeLibraryRootRequiresIsa = false; 8887 info.nativeLibraryDir = info.nativeLibraryRootDir; 8888 } else { 8889 // Cluster install 8890 info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath(); 8891 info.nativeLibraryRootRequiresIsa = true; 8892 8893 info.nativeLibraryDir = new File(info.nativeLibraryRootDir, 8894 getPrimaryInstructionSet(info)).getAbsolutePath(); 8895 8896 if (info.secondaryCpuAbi != null) { 8897 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir, 8898 VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath(); 8899 } 8900 } 8901 } 8902 8903 /** 8904 * Calculate the abis and roots for a bundled app. These can uniquely 8905 * be determined from the contents of the system partition, i.e whether 8906 * it contains 64 or 32 bit shared libraries etc. We do not validate any 8907 * of this information, and instead assume that the system was built 8908 * sensibly. 8909 */ 8910 private void setBundledAppAbisAndRoots(PackageParser.Package pkg, 8911 PackageSetting pkgSetting) { 8912 final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath()); 8913 8914 // If "/system/lib64/apkname" exists, assume that is the per-package 8915 // native library directory to use; otherwise use "/system/lib/apkname". 8916 final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir); 8917 setBundledAppAbi(pkg, apkRoot, apkName); 8918 // pkgSetting might be null during rescan following uninstall of updates 8919 // to a bundled app, so accommodate that possibility. The settings in 8920 // that case will be established later from the parsed package. 8921 // 8922 // If the settings aren't null, sync them up with what we've just derived. 8923 // note that apkRoot isn't stored in the package settings. 8924 if (pkgSetting != null) { 8925 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 8926 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 8927 } 8928 } 8929 8930 /** 8931 * Deduces the ABI of a bundled app and sets the relevant fields on the 8932 * parsed pkg object. 8933 * 8934 * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem} 8935 * under which system libraries are installed. 8936 * @param apkName the name of the installed package. 8937 */ 8938 private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) { 8939 final File codeFile = new File(pkg.codePath); 8940 8941 final boolean has64BitLibs; 8942 final boolean has32BitLibs; 8943 if (isApkFile(codeFile)) { 8944 // Monolithic install 8945 has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists(); 8946 has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists(); 8947 } else { 8948 // Cluster install 8949 final File rootDir = new File(codeFile, LIB_DIR_NAME); 8950 if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS) 8951 && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) { 8952 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]); 8953 has64BitLibs = (new File(rootDir, isa)).exists(); 8954 } else { 8955 has64BitLibs = false; 8956 } 8957 if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS) 8958 && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) { 8959 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]); 8960 has32BitLibs = (new File(rootDir, isa)).exists(); 8961 } else { 8962 has32BitLibs = false; 8963 } 8964 } 8965 8966 if (has64BitLibs && !has32BitLibs) { 8967 // The package has 64 bit libs, but not 32 bit libs. Its primary 8968 // ABI should be 64 bit. We can safely assume here that the bundled 8969 // native libraries correspond to the most preferred ABI in the list. 8970 8971 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 8972 pkg.applicationInfo.secondaryCpuAbi = null; 8973 } else if (has32BitLibs && !has64BitLibs) { 8974 // The package has 32 bit libs but not 64 bit libs. Its primary 8975 // ABI should be 32 bit. 8976 8977 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 8978 pkg.applicationInfo.secondaryCpuAbi = null; 8979 } else if (has32BitLibs && has64BitLibs) { 8980 // The application has both 64 and 32 bit bundled libraries. We check 8981 // here that the app declares multiArch support, and warn if it doesn't. 8982 // 8983 // We will be lenient here and record both ABIs. The primary will be the 8984 // ABI that's higher on the list, i.e, a device that's configured to prefer 8985 // 64 bit apps will see a 64 bit primary ABI, 8986 8987 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) { 8988 Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch."); 8989 } 8990 8991 if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) { 8992 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 8993 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 8994 } else { 8995 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 8996 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 8997 } 8998 } else { 8999 pkg.applicationInfo.primaryCpuAbi = null; 9000 pkg.applicationInfo.secondaryCpuAbi = null; 9001 } 9002 } 9003 9004 private void killPackage(PackageParser.Package pkg, String reason) { 9005 // Kill the parent package 9006 killApplication(pkg.packageName, pkg.applicationInfo.uid, reason); 9007 // Kill the child packages 9008 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 9009 for (int i = 0; i < childCount; i++) { 9010 PackageParser.Package childPkg = pkg.childPackages.get(i); 9011 killApplication(childPkg.packageName, childPkg.applicationInfo.uid, reason); 9012 } 9013 } 9014 9015 private void killApplication(String pkgName, int appId, String reason) { 9016 // Request the ActivityManager to kill the process(only for existing packages) 9017 // so that we do not end up in a confused state while the user is still using the older 9018 // version of the application while the new one gets installed. 9019 IActivityManager am = ActivityManagerNative.getDefault(); 9020 if (am != null) { 9021 try { 9022 am.killApplicationWithAppId(pkgName, appId, reason); 9023 } catch (RemoteException e) { 9024 } 9025 } 9026 } 9027 9028 private void removePackageLI(PackageParser.Package pkg, boolean chatty) { 9029 // Remove the parent package setting 9030 PackageSetting ps = (PackageSetting) pkg.mExtras; 9031 if (ps != null) { 9032 removePackageLI(ps, chatty); 9033 } 9034 // Remove the child package setting 9035 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 9036 for (int i = 0; i < childCount; i++) { 9037 PackageParser.Package childPkg = pkg.childPackages.get(i); 9038 ps = (PackageSetting) childPkg.mExtras; 9039 if (ps != null) { 9040 removePackageLI(ps, chatty); 9041 } 9042 } 9043 } 9044 9045 void removePackageLI(PackageSetting ps, boolean chatty) { 9046 if (DEBUG_INSTALL) { 9047 if (chatty) 9048 Log.d(TAG, "Removing package " + ps.name); 9049 } 9050 9051 // writer 9052 synchronized (mPackages) { 9053 mPackages.remove(ps.name); 9054 final PackageParser.Package pkg = ps.pkg; 9055 if (pkg != null) { 9056 cleanPackageDataStructuresLILPw(pkg, chatty); 9057 } 9058 } 9059 } 9060 9061 void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) { 9062 if (DEBUG_INSTALL) { 9063 if (chatty) 9064 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName); 9065 } 9066 9067 // writer 9068 synchronized (mPackages) { 9069 // Remove the parent package 9070 mPackages.remove(pkg.applicationInfo.packageName); 9071 cleanPackageDataStructuresLILPw(pkg, chatty); 9072 9073 // Remove the child packages 9074 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 9075 for (int i = 0; i < childCount; i++) { 9076 PackageParser.Package childPkg = pkg.childPackages.get(i); 9077 mPackages.remove(childPkg.applicationInfo.packageName); 9078 cleanPackageDataStructuresLILPw(childPkg, chatty); 9079 } 9080 } 9081 } 9082 9083 void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) { 9084 int N = pkg.providers.size(); 9085 StringBuilder r = null; 9086 int i; 9087 for (i=0; i<N; i++) { 9088 PackageParser.Provider p = pkg.providers.get(i); 9089 mProviders.removeProvider(p); 9090 if (p.info.authority == null) { 9091 9092 /* There was another ContentProvider with this authority when 9093 * this app was installed so this authority is null, 9094 * Ignore it as we don't have to unregister the provider. 9095 */ 9096 continue; 9097 } 9098 String names[] = p.info.authority.split(";"); 9099 for (int j = 0; j < names.length; j++) { 9100 if (mProvidersByAuthority.get(names[j]) == p) { 9101 mProvidersByAuthority.remove(names[j]); 9102 if (DEBUG_REMOVE) { 9103 if (chatty) 9104 Log.d(TAG, "Unregistered content provider: " + names[j] 9105 + ", className = " + p.info.name + ", isSyncable = " 9106 + p.info.isSyncable); 9107 } 9108 } 9109 } 9110 if (DEBUG_REMOVE && chatty) { 9111 if (r == null) { 9112 r = new StringBuilder(256); 9113 } else { 9114 r.append(' '); 9115 } 9116 r.append(p.info.name); 9117 } 9118 } 9119 if (r != null) { 9120 if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r); 9121 } 9122 9123 N = pkg.services.size(); 9124 r = null; 9125 for (i=0; i<N; i++) { 9126 PackageParser.Service s = pkg.services.get(i); 9127 mServices.removeService(s); 9128 if (chatty) { 9129 if (r == null) { 9130 r = new StringBuilder(256); 9131 } else { 9132 r.append(' '); 9133 } 9134 r.append(s.info.name); 9135 } 9136 } 9137 if (r != null) { 9138 if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r); 9139 } 9140 9141 N = pkg.receivers.size(); 9142 r = null; 9143 for (i=0; i<N; i++) { 9144 PackageParser.Activity a = pkg.receivers.get(i); 9145 mReceivers.removeActivity(a, "receiver"); 9146 if (DEBUG_REMOVE && chatty) { 9147 if (r == null) { 9148 r = new StringBuilder(256); 9149 } else { 9150 r.append(' '); 9151 } 9152 r.append(a.info.name); 9153 } 9154 } 9155 if (r != null) { 9156 if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r); 9157 } 9158 9159 N = pkg.activities.size(); 9160 r = null; 9161 for (i=0; i<N; i++) { 9162 PackageParser.Activity a = pkg.activities.get(i); 9163 mActivities.removeActivity(a, "activity"); 9164 if (DEBUG_REMOVE && chatty) { 9165 if (r == null) { 9166 r = new StringBuilder(256); 9167 } else { 9168 r.append(' '); 9169 } 9170 r.append(a.info.name); 9171 } 9172 } 9173 if (r != null) { 9174 if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r); 9175 } 9176 9177 N = pkg.permissions.size(); 9178 r = null; 9179 for (i=0; i<N; i++) { 9180 PackageParser.Permission p = pkg.permissions.get(i); 9181 BasePermission bp = mSettings.mPermissions.get(p.info.name); 9182 if (bp == null) { 9183 bp = mSettings.mPermissionTrees.get(p.info.name); 9184 } 9185 if (bp != null && bp.perm == p) { 9186 bp.perm = null; 9187 if (DEBUG_REMOVE && chatty) { 9188 if (r == null) { 9189 r = new StringBuilder(256); 9190 } else { 9191 r.append(' '); 9192 } 9193 r.append(p.info.name); 9194 } 9195 } 9196 if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 9197 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name); 9198 if (appOpPkgs != null) { 9199 appOpPkgs.remove(pkg.packageName); 9200 } 9201 } 9202 } 9203 if (r != null) { 9204 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 9205 } 9206 9207 N = pkg.requestedPermissions.size(); 9208 r = null; 9209 for (i=0; i<N; i++) { 9210 String perm = pkg.requestedPermissions.get(i); 9211 BasePermission bp = mSettings.mPermissions.get(perm); 9212 if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 9213 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm); 9214 if (appOpPkgs != null) { 9215 appOpPkgs.remove(pkg.packageName); 9216 if (appOpPkgs.isEmpty()) { 9217 mAppOpPermissionPackages.remove(perm); 9218 } 9219 } 9220 } 9221 } 9222 if (r != null) { 9223 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 9224 } 9225 9226 N = pkg.instrumentation.size(); 9227 r = null; 9228 for (i=0; i<N; i++) { 9229 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 9230 mInstrumentation.remove(a.getComponentName()); 9231 if (DEBUG_REMOVE && chatty) { 9232 if (r == null) { 9233 r = new StringBuilder(256); 9234 } else { 9235 r.append(' '); 9236 } 9237 r.append(a.info.name); 9238 } 9239 } 9240 if (r != null) { 9241 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r); 9242 } 9243 9244 r = null; 9245 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9246 // Only system apps can hold shared libraries. 9247 if (pkg.libraryNames != null) { 9248 for (i=0; i<pkg.libraryNames.size(); i++) { 9249 String name = pkg.libraryNames.get(i); 9250 SharedLibraryEntry cur = mSharedLibraries.get(name); 9251 if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) { 9252 mSharedLibraries.remove(name); 9253 if (DEBUG_REMOVE && chatty) { 9254 if (r == null) { 9255 r = new StringBuilder(256); 9256 } else { 9257 r.append(' '); 9258 } 9259 r.append(name); 9260 } 9261 } 9262 } 9263 } 9264 } 9265 if (r != null) { 9266 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r); 9267 } 9268 } 9269 9270 private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) { 9271 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) { 9272 if (pkgInfo.permissions.get(i).info.name.equals(perm)) { 9273 return true; 9274 } 9275 } 9276 return false; 9277 } 9278 9279 static final int UPDATE_PERMISSIONS_ALL = 1<<0; 9280 static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1; 9281 static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2; 9282 9283 private void updatePermissionsLPw(PackageParser.Package pkg, int flags) { 9284 // Update the parent permissions 9285 updatePermissionsLPw(pkg.packageName, pkg, flags); 9286 // Update the child permissions 9287 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 9288 for (int i = 0; i < childCount; i++) { 9289 PackageParser.Package childPkg = pkg.childPackages.get(i); 9290 updatePermissionsLPw(childPkg.packageName, childPkg, flags); 9291 } 9292 } 9293 9294 private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo, 9295 int flags) { 9296 final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null; 9297 updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags); 9298 } 9299 9300 private void updatePermissionsLPw(String changingPkg, 9301 PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) { 9302 // Make sure there are no dangling permission trees. 9303 Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator(); 9304 while (it.hasNext()) { 9305 final BasePermission bp = it.next(); 9306 if (bp.packageSetting == null) { 9307 // We may not yet have parsed the package, so just see if 9308 // we still know about its settings. 9309 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 9310 } 9311 if (bp.packageSetting == null) { 9312 Slog.w(TAG, "Removing dangling permission tree: " + bp.name 9313 + " from package " + bp.sourcePackage); 9314 it.remove(); 9315 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 9316 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 9317 Slog.i(TAG, "Removing old permission tree: " + bp.name 9318 + " from package " + bp.sourcePackage); 9319 flags |= UPDATE_PERMISSIONS_ALL; 9320 it.remove(); 9321 } 9322 } 9323 } 9324 9325 // Make sure all dynamic permissions have been assigned to a package, 9326 // and make sure there are no dangling permissions. 9327 it = mSettings.mPermissions.values().iterator(); 9328 while (it.hasNext()) { 9329 final BasePermission bp = it.next(); 9330 if (bp.type == BasePermission.TYPE_DYNAMIC) { 9331 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name=" 9332 + bp.name + " pkg=" + bp.sourcePackage 9333 + " info=" + bp.pendingInfo); 9334 if (bp.packageSetting == null && bp.pendingInfo != null) { 9335 final BasePermission tree = findPermissionTreeLP(bp.name); 9336 if (tree != null && tree.perm != null) { 9337 bp.packageSetting = tree.packageSetting; 9338 bp.perm = new PackageParser.Permission(tree.perm.owner, 9339 new PermissionInfo(bp.pendingInfo)); 9340 bp.perm.info.packageName = tree.perm.info.packageName; 9341 bp.perm.info.name = bp.name; 9342 bp.uid = tree.uid; 9343 } 9344 } 9345 } 9346 if (bp.packageSetting == null) { 9347 // We may not yet have parsed the package, so just see if 9348 // we still know about its settings. 9349 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 9350 } 9351 if (bp.packageSetting == null) { 9352 Slog.w(TAG, "Removing dangling permission: " + bp.name 9353 + " from package " + bp.sourcePackage); 9354 it.remove(); 9355 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 9356 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 9357 Slog.i(TAG, "Removing old permission: " + bp.name 9358 + " from package " + bp.sourcePackage); 9359 flags |= UPDATE_PERMISSIONS_ALL; 9360 it.remove(); 9361 } 9362 } 9363 } 9364 9365 // Now update the permissions for all packages, in particular 9366 // replace the granted permissions of the system packages. 9367 if ((flags&UPDATE_PERMISSIONS_ALL) != 0) { 9368 for (PackageParser.Package pkg : mPackages.values()) { 9369 if (pkg != pkgInfo) { 9370 // Only replace for packages on requested volume 9371 final String volumeUuid = getVolumeUuidForPackage(pkg); 9372 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0) 9373 && Objects.equals(replaceVolumeUuid, volumeUuid); 9374 grantPermissionsLPw(pkg, replace, changingPkg); 9375 } 9376 } 9377 } 9378 9379 if (pkgInfo != null) { 9380 // Only replace for packages on requested volume 9381 final String volumeUuid = getVolumeUuidForPackage(pkgInfo); 9382 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0) 9383 && Objects.equals(replaceVolumeUuid, volumeUuid); 9384 grantPermissionsLPw(pkgInfo, replace, changingPkg); 9385 } 9386 } 9387 9388 private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace, 9389 String packageOfInterest) { 9390 // IMPORTANT: There are two types of permissions: install and runtime. 9391 // Install time permissions are granted when the app is installed to 9392 // all device users and users added in the future. Runtime permissions 9393 // are granted at runtime explicitly to specific users. Normal and signature 9394 // protected permissions are install time permissions. Dangerous permissions 9395 // are install permissions if the app's target SDK is Lollipop MR1 or older, 9396 // otherwise they are runtime permissions. This function does not manage 9397 // runtime permissions except for the case an app targeting Lollipop MR1 9398 // being upgraded to target a newer SDK, in which case dangerous permissions 9399 // are transformed from install time to runtime ones. 9400 9401 final PackageSetting ps = (PackageSetting) pkg.mExtras; 9402 if (ps == null) { 9403 return; 9404 } 9405 9406 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions"); 9407 9408 PermissionsState permissionsState = ps.getPermissionsState(); 9409 PermissionsState origPermissions = permissionsState; 9410 9411 final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); 9412 9413 boolean runtimePermissionsRevoked = false; 9414 int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY; 9415 9416 boolean changedInstallPermission = false; 9417 9418 if (replace) { 9419 ps.installPermissionsFixed = false; 9420 if (!ps.isSharedUser()) { 9421 origPermissions = new PermissionsState(permissionsState); 9422 permissionsState.reset(); 9423 } else { 9424 // We need to know only about runtime permission changes since the 9425 // calling code always writes the install permissions state but 9426 // the runtime ones are written only if changed. The only cases of 9427 // changed runtime permissions here are promotion of an install to 9428 // runtime and revocation of a runtime from a shared user. 9429 changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw( 9430 ps.sharedUser, UserManagerService.getInstance().getUserIds()); 9431 if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) { 9432 runtimePermissionsRevoked = true; 9433 } 9434 } 9435 } 9436 9437 permissionsState.setGlobalGids(mGlobalGids); 9438 9439 final int N = pkg.requestedPermissions.size(); 9440 for (int i=0; i<N; i++) { 9441 final String name = pkg.requestedPermissions.get(i); 9442 final BasePermission bp = mSettings.mPermissions.get(name); 9443 9444 if (DEBUG_INSTALL) { 9445 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp); 9446 } 9447 9448 if (bp == null || bp.packageSetting == null) { 9449 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 9450 Slog.w(TAG, "Unknown permission " + name 9451 + " in package " + pkg.packageName); 9452 } 9453 continue; 9454 } 9455 9456 final String perm = bp.name; 9457 boolean allowedSig = false; 9458 int grant = GRANT_DENIED; 9459 9460 // Keep track of app op permissions. 9461 if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 9462 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name); 9463 if (pkgs == null) { 9464 pkgs = new ArraySet<>(); 9465 mAppOpPermissionPackages.put(bp.name, pkgs); 9466 } 9467 pkgs.add(pkg.packageName); 9468 } 9469 9470 final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; 9471 final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion 9472 >= Build.VERSION_CODES.M; 9473 switch (level) { 9474 case PermissionInfo.PROTECTION_NORMAL: { 9475 // For all apps normal permissions are install time ones. 9476 grant = GRANT_INSTALL; 9477 } break; 9478 9479 case PermissionInfo.PROTECTION_DANGEROUS: { 9480 // If a permission review is required for legacy apps we represent 9481 // their permissions as always granted runtime ones since we need 9482 // to keep the review required permission flag per user while an 9483 // install permission's state is shared across all users. 9484 if (!appSupportsRuntimePermissions && !Build.PERMISSIONS_REVIEW_REQUIRED) { 9485 // For legacy apps dangerous permissions are install time ones. 9486 grant = GRANT_INSTALL; 9487 } else if (origPermissions.hasInstallPermission(bp.name)) { 9488 // For legacy apps that became modern, install becomes runtime. 9489 grant = GRANT_UPGRADE; 9490 } else if (mPromoteSystemApps 9491 && isSystemApp(ps) 9492 && mExistingSystemPackages.contains(ps.name)) { 9493 // For legacy system apps, install becomes runtime. 9494 // We cannot check hasInstallPermission() for system apps since those 9495 // permissions were granted implicitly and not persisted pre-M. 9496 grant = GRANT_UPGRADE; 9497 } else { 9498 // For modern apps keep runtime permissions unchanged. 9499 grant = GRANT_RUNTIME; 9500 } 9501 } break; 9502 9503 case PermissionInfo.PROTECTION_SIGNATURE: { 9504 // For all apps signature permissions are install time ones. 9505 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions); 9506 if (allowedSig) { 9507 grant = GRANT_INSTALL; 9508 } 9509 } break; 9510 } 9511 9512 if (DEBUG_INSTALL) { 9513 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm); 9514 } 9515 9516 if (grant != GRANT_DENIED) { 9517 if (!isSystemApp(ps) && ps.installPermissionsFixed) { 9518 // If this is an existing, non-system package, then 9519 // we can't add any new permissions to it. 9520 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) { 9521 // Except... if this is a permission that was added 9522 // to the platform (note: need to only do this when 9523 // updating the platform). 9524 if (!isNewPlatformPermissionForPackage(perm, pkg)) { 9525 grant = GRANT_DENIED; 9526 } 9527 } 9528 } 9529 9530 switch (grant) { 9531 case GRANT_INSTALL: { 9532 // Revoke this as runtime permission to handle the case of 9533 // a runtime permission being downgraded to an install one. Also in permission review mode we keep dangerous permissions for legacy apps 9534 for (int userId : UserManagerService.getInstance().getUserIds()) { 9535 if (origPermissions.getRuntimePermissionState( 9536 bp.name, userId) != null) { 9537 // Revoke the runtime permission and clear the flags. 9538 origPermissions.revokeRuntimePermission(bp, userId); 9539 origPermissions.updatePermissionFlags(bp, userId, 9540 PackageManager.MASK_PERMISSION_FLAGS, 0); 9541 // If we revoked a permission permission, we have to write. 9542 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 9543 changedRuntimePermissionUserIds, userId); 9544 } 9545 } 9546 // Grant an install permission. 9547 if (permissionsState.grantInstallPermission(bp) != 9548 PermissionsState.PERMISSION_OPERATION_FAILURE) { 9549 changedInstallPermission = true; 9550 } 9551 } break; 9552 9553 case GRANT_RUNTIME: { 9554 // Grant previously granted runtime permissions. 9555 for (int userId : UserManagerService.getInstance().getUserIds()) { 9556 PermissionState permissionState = origPermissions 9557 .getRuntimePermissionState(bp.name, userId); 9558 int flags = permissionState != null 9559 ? permissionState.getFlags() : 0; 9560 if (origPermissions.hasRuntimePermission(bp.name, userId)) { 9561 if (permissionsState.grantRuntimePermission(bp, userId) == 9562 PermissionsState.PERMISSION_OPERATION_FAILURE) { 9563 // If we cannot put the permission as it was, we have to write. 9564 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 9565 changedRuntimePermissionUserIds, userId); 9566 } 9567 // If the app supports runtime permissions no need for a review. 9568 if (Build.PERMISSIONS_REVIEW_REQUIRED 9569 && appSupportsRuntimePermissions 9570 && (flags & PackageManager 9571 .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) { 9572 flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 9573 // Since we changed the flags, we have to write. 9574 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 9575 changedRuntimePermissionUserIds, userId); 9576 } 9577 } else if (Build.PERMISSIONS_REVIEW_REQUIRED 9578 && !appSupportsRuntimePermissions) { 9579 // For legacy apps that need a permission review, every new 9580 // runtime permission is granted but it is pending a review. 9581 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) { 9582 permissionsState.grantRuntimePermission(bp, userId); 9583 flags |= FLAG_PERMISSION_REVIEW_REQUIRED; 9584 // We changed the permission and flags, hence have to write. 9585 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 9586 changedRuntimePermissionUserIds, userId); 9587 } 9588 } 9589 // Propagate the permission flags. 9590 permissionsState.updatePermissionFlags(bp, userId, flags, flags); 9591 } 9592 } break; 9593 9594 case GRANT_UPGRADE: { 9595 // Grant runtime permissions for a previously held install permission. 9596 PermissionState permissionState = origPermissions 9597 .getInstallPermissionState(bp.name); 9598 final int flags = permissionState != null ? permissionState.getFlags() : 0; 9599 9600 if (origPermissions.revokeInstallPermission(bp) 9601 != PermissionsState.PERMISSION_OPERATION_FAILURE) { 9602 // We will be transferring the permission flags, so clear them. 9603 origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL, 9604 PackageManager.MASK_PERMISSION_FLAGS, 0); 9605 changedInstallPermission = true; 9606 } 9607 9608 // If the permission is not to be promoted to runtime we ignore it and 9609 // also its other flags as they are not applicable to install permissions. 9610 if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) { 9611 for (int userId : currentUserIds) { 9612 if (permissionsState.grantRuntimePermission(bp, userId) != 9613 PermissionsState.PERMISSION_OPERATION_FAILURE) { 9614 // Transfer the permission flags. 9615 permissionsState.updatePermissionFlags(bp, userId, 9616 flags, flags); 9617 // If we granted the permission, we have to write. 9618 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 9619 changedRuntimePermissionUserIds, userId); 9620 } 9621 } 9622 } 9623 } break; 9624 9625 default: { 9626 if (packageOfInterest == null 9627 || packageOfInterest.equals(pkg.packageName)) { 9628 Slog.w(TAG, "Not granting permission " + perm 9629 + " to package " + pkg.packageName 9630 + " because it was previously installed without"); 9631 } 9632 } break; 9633 } 9634 } else { 9635 if (permissionsState.revokeInstallPermission(bp) != 9636 PermissionsState.PERMISSION_OPERATION_FAILURE) { 9637 // Also drop the permission flags. 9638 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 9639 PackageManager.MASK_PERMISSION_FLAGS, 0); 9640 changedInstallPermission = true; 9641 Slog.i(TAG, "Un-granting permission " + perm 9642 + " from package " + pkg.packageName 9643 + " (protectionLevel=" + bp.protectionLevel 9644 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 9645 + ")"); 9646 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) { 9647 // Don't print warning for app op permissions, since it is fine for them 9648 // not to be granted, there is a UI for the user to decide. 9649 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 9650 Slog.w(TAG, "Not granting permission " + perm 9651 + " to package " + pkg.packageName 9652 + " (protectionLevel=" + bp.protectionLevel 9653 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 9654 + ")"); 9655 } 9656 } 9657 } 9658 } 9659 9660 if ((changedInstallPermission || replace) && !ps.installPermissionsFixed && 9661 !isSystemApp(ps) || isUpdatedSystemApp(ps)){ 9662 // This is the first that we have heard about this package, so the 9663 // permissions we have now selected are fixed until explicitly 9664 // changed. 9665 ps.installPermissionsFixed = true; 9666 } 9667 9668 // Persist the runtime permissions state for users with changes. If permissions 9669 // were revoked because no app in the shared user declares them we have to 9670 // write synchronously to avoid losing runtime permissions state. 9671 for (int userId : changedRuntimePermissionUserIds) { 9672 mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked); 9673 } 9674 9675 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 9676 } 9677 9678 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) { 9679 boolean allowed = false; 9680 final int NP = PackageParser.NEW_PERMISSIONS.length; 9681 for (int ip=0; ip<NP; ip++) { 9682 final PackageParser.NewPermissionInfo npi 9683 = PackageParser.NEW_PERMISSIONS[ip]; 9684 if (npi.name.equals(perm) 9685 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) { 9686 allowed = true; 9687 Log.i(TAG, "Auto-granting " + perm + " to old pkg " 9688 + pkg.packageName); 9689 break; 9690 } 9691 } 9692 return allowed; 9693 } 9694 9695 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg, 9696 BasePermission bp, PermissionsState origPermissions) { 9697 boolean allowed; 9698 allowed = (compareSignatures( 9699 bp.packageSetting.signatures.mSignatures, pkg.mSignatures) 9700 == PackageManager.SIGNATURE_MATCH) 9701 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures) 9702 == PackageManager.SIGNATURE_MATCH); 9703 if (!allowed && (bp.protectionLevel 9704 & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) { 9705 if (isSystemApp(pkg)) { 9706 // For updated system applications, a system permission 9707 // is granted only if it had been defined by the original application. 9708 if (pkg.isUpdatedSystemApp()) { 9709 final PackageSetting sysPs = mSettings 9710 .getDisabledSystemPkgLPr(pkg.packageName); 9711 if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) { 9712 // If the original was granted this permission, we take 9713 // that grant decision as read and propagate it to the 9714 // update. 9715 if (sysPs.isPrivileged()) { 9716 allowed = true; 9717 } 9718 } else { 9719 // The system apk may have been updated with an older 9720 // version of the one on the data partition, but which 9721 // granted a new system permission that it didn't have 9722 // before. In this case we do want to allow the app to 9723 // now get the new permission if the ancestral apk is 9724 // privileged to get it. 9725 if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) { 9726 for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) { 9727 if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) { 9728 allowed = true; 9729 break; 9730 } 9731 } 9732 } 9733 // Also if a privileged parent package on the system image or any of 9734 // its children requested a privileged permission, the updated child 9735 // packages can also get the permission. 9736 if (pkg.parentPackage != null) { 9737 final PackageSetting disabledSysParentPs = mSettings 9738 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName); 9739 if (disabledSysParentPs != null && disabledSysParentPs.pkg != null 9740 && disabledSysParentPs.isPrivileged()) { 9741 if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) { 9742 allowed = true; 9743 } else if (disabledSysParentPs.pkg.childPackages != null) { 9744 final int count = disabledSysParentPs.pkg.childPackages.size(); 9745 for (int i = 0; i < count; i++) { 9746 PackageParser.Package disabledSysChildPkg = 9747 disabledSysParentPs.pkg.childPackages.get(i); 9748 if (isPackageRequestingPermission(disabledSysChildPkg, 9749 perm)) { 9750 allowed = true; 9751 break; 9752 } 9753 } 9754 } 9755 } 9756 } 9757 } 9758 } else { 9759 allowed = isPrivilegedApp(pkg); 9760 } 9761 } 9762 } 9763 if (!allowed) { 9764 if (!allowed && (bp.protectionLevel 9765 & PermissionInfo.PROTECTION_FLAG_PRE23) != 0 9766 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 9767 // If this was a previously normal/dangerous permission that got moved 9768 // to a system permission as part of the runtime permission redesign, then 9769 // we still want to blindly grant it to old apps. 9770 allowed = true; 9771 } 9772 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0 9773 && pkg.packageName.equals(mRequiredInstallerPackage)) { 9774 // If this permission is to be granted to the system installer and 9775 // this app is an installer, then it gets the permission. 9776 allowed = true; 9777 } 9778 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0 9779 && pkg.packageName.equals(mRequiredVerifierPackage)) { 9780 // If this permission is to be granted to the system verifier and 9781 // this app is a verifier, then it gets the permission. 9782 allowed = true; 9783 } 9784 if (!allowed && (bp.protectionLevel 9785 & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0 9786 && isSystemApp(pkg)) { 9787 // Any pre-installed system app is allowed to get this permission. 9788 allowed = true; 9789 } 9790 if (!allowed && (bp.protectionLevel 9791 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) { 9792 // For development permissions, a development permission 9793 // is granted only if it was already granted. 9794 allowed = origPermissions.hasInstallPermission(perm); 9795 } 9796 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0 9797 && pkg.packageName.equals(mSetupWizardPackage)) { 9798 // If this permission is to be granted to the system setup wizard and 9799 // this app is a setup wizard, then it gets the permission. 9800 allowed = true; 9801 } 9802 } 9803 return allowed; 9804 } 9805 9806 private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) { 9807 final int permCount = pkg.requestedPermissions.size(); 9808 for (int j = 0; j < permCount; j++) { 9809 String requestedPermission = pkg.requestedPermissions.get(j); 9810 if (permission.equals(requestedPermission)) { 9811 return true; 9812 } 9813 } 9814 return false; 9815 } 9816 9817 final class ActivityIntentResolver 9818 extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> { 9819 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 9820 boolean defaultOnly, int userId) { 9821 if (!sUserManager.exists(userId)) return null; 9822 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 9823 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 9824 } 9825 9826 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 9827 int userId) { 9828 if (!sUserManager.exists(userId)) return null; 9829 mFlags = flags; 9830 return super.queryIntent(intent, resolvedType, 9831 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 9832 } 9833 9834 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 9835 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) { 9836 if (!sUserManager.exists(userId)) return null; 9837 if (packageActivities == null) { 9838 return null; 9839 } 9840 mFlags = flags; 9841 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 9842 final int N = packageActivities.size(); 9843 ArrayList<PackageParser.ActivityIntentInfo[]> listCut = 9844 new ArrayList<PackageParser.ActivityIntentInfo[]>(N); 9845 9846 ArrayList<PackageParser.ActivityIntentInfo> intentFilters; 9847 for (int i = 0; i < N; ++i) { 9848 intentFilters = packageActivities.get(i).intents; 9849 if (intentFilters != null && intentFilters.size() > 0) { 9850 PackageParser.ActivityIntentInfo[] array = 9851 new PackageParser.ActivityIntentInfo[intentFilters.size()]; 9852 intentFilters.toArray(array); 9853 listCut.add(array); 9854 } 9855 } 9856 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 9857 } 9858 9859 /** 9860 * Finds a privileged activity that matches the specified activity names. 9861 */ 9862 private PackageParser.Activity findMatchingActivity( 9863 List<PackageParser.Activity> activityList, ActivityInfo activityInfo) { 9864 for (PackageParser.Activity sysActivity : activityList) { 9865 if (sysActivity.info.name.equals(activityInfo.name)) { 9866 return sysActivity; 9867 } 9868 if (sysActivity.info.name.equals(activityInfo.targetActivity)) { 9869 return sysActivity; 9870 } 9871 if (sysActivity.info.targetActivity != null) { 9872 if (sysActivity.info.targetActivity.equals(activityInfo.name)) { 9873 return sysActivity; 9874 } 9875 if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) { 9876 return sysActivity; 9877 } 9878 } 9879 } 9880 return null; 9881 } 9882 9883 public class IterGenerator<E> { 9884 public Iterator<E> generate(ActivityIntentInfo info) { 9885 return null; 9886 } 9887 } 9888 9889 public class ActionIterGenerator extends IterGenerator<String> { 9890 @Override 9891 public Iterator<String> generate(ActivityIntentInfo info) { 9892 return info.actionsIterator(); 9893 } 9894 } 9895 9896 public class CategoriesIterGenerator extends IterGenerator<String> { 9897 @Override 9898 public Iterator<String> generate(ActivityIntentInfo info) { 9899 return info.categoriesIterator(); 9900 } 9901 } 9902 9903 public class SchemesIterGenerator extends IterGenerator<String> { 9904 @Override 9905 public Iterator<String> generate(ActivityIntentInfo info) { 9906 return info.schemesIterator(); 9907 } 9908 } 9909 9910 public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> { 9911 @Override 9912 public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) { 9913 return info.authoritiesIterator(); 9914 } 9915 } 9916 9917 /** 9918 * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE 9919 * MODIFIED. Do not pass in a list that should not be changed. 9920 */ 9921 private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList, 9922 IterGenerator<T> generator, Iterator<T> searchIterator) { 9923 // loop through the set of actions; every one must be found in the intent filter 9924 while (searchIterator.hasNext()) { 9925 // we must have at least one filter in the list to consider a match 9926 if (intentList.size() == 0) { 9927 break; 9928 } 9929 9930 final T searchAction = searchIterator.next(); 9931 9932 // loop through the set of intent filters 9933 final Iterator<ActivityIntentInfo> intentIter = intentList.iterator(); 9934 while (intentIter.hasNext()) { 9935 final ActivityIntentInfo intentInfo = intentIter.next(); 9936 boolean selectionFound = false; 9937 9938 // loop through the intent filter's selection criteria; at least one 9939 // of them must match the searched criteria 9940 final Iterator<T> intentSelectionIter = generator.generate(intentInfo); 9941 while (intentSelectionIter != null && intentSelectionIter.hasNext()) { 9942 final T intentSelection = intentSelectionIter.next(); 9943 if (intentSelection != null && intentSelection.equals(searchAction)) { 9944 selectionFound = true; 9945 break; 9946 } 9947 } 9948 9949 // the selection criteria wasn't found in this filter's set; this filter 9950 // is not a potential match 9951 if (!selectionFound) { 9952 intentIter.remove(); 9953 } 9954 } 9955 } 9956 } 9957 9958 private boolean isProtectedAction(ActivityIntentInfo filter) { 9959 final Iterator<String> actionsIter = filter.actionsIterator(); 9960 while (actionsIter != null && actionsIter.hasNext()) { 9961 final String filterAction = actionsIter.next(); 9962 if (PROTECTED_ACTIONS.contains(filterAction)) { 9963 return true; 9964 } 9965 } 9966 return false; 9967 } 9968 9969 /** 9970 * Adjusts the priority of the given intent filter according to policy. 9971 * <p> 9972 * <ul> 9973 * <li>The priority for non privileged applications is capped to '0'</li> 9974 * <li>The priority for protected actions on privileged applications is capped to '0'</li> 9975 * <li>The priority for unbundled updates to privileged applications is capped to the 9976 * priority defined on the system partition</li> 9977 * </ul> 9978 * <p> 9979 * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is 9980 * allowed to obtain any priority on any action. 9981 */ 9982 private void adjustPriority( 9983 List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) { 9984 // nothing to do; priority is fine as-is 9985 if (intent.getPriority() <= 0) { 9986 return; 9987 } 9988 9989 final ActivityInfo activityInfo = intent.activity.info; 9990 final ApplicationInfo applicationInfo = activityInfo.applicationInfo; 9991 9992 final boolean privilegedApp = 9993 ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0); 9994 if (!privilegedApp) { 9995 // non-privileged applications can never define a priority >0 9996 Slog.w(TAG, "Non-privileged app; cap priority to 0;" 9997 + " package: " + applicationInfo.packageName 9998 + " activity: " + intent.activity.className 9999 + " origPrio: " + intent.getPriority()); 10000 intent.setPriority(0); 10001 return; 10002 } 10003 10004 if (systemActivities == null) { 10005 // the system package is not disabled; we're parsing the system partition 10006 if (isProtectedAction(intent)) { 10007 if (mDeferProtectedFilters) { 10008 // We can't deal with these just yet. No component should ever obtain a 10009 // >0 priority for a protected actions, with ONE exception -- the setup 10010 // wizard. The setup wizard, however, cannot be known until we're able to 10011 // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do 10012 // until all intent filters have been processed. Chicken, meet egg. 10013 // Let the filter temporarily have a high priority and rectify the 10014 // priorities after all system packages have been scanned. 10015 mProtectedFilters.add(intent); 10016 if (DEBUG_FILTERS) { 10017 Slog.i(TAG, "Protected action; save for later;" 10018 + " package: " + applicationInfo.packageName 10019 + " activity: " + intent.activity.className 10020 + " origPrio: " + intent.getPriority()); 10021 } 10022 return; 10023 } else { 10024 if (DEBUG_FILTERS && mSetupWizardPackage == null) { 10025 Slog.i(TAG, "No setup wizard;" 10026 + " All protected intents capped to priority 0"); 10027 } 10028 if (intent.activity.info.packageName.equals(mSetupWizardPackage)) { 10029 if (DEBUG_FILTERS) { 10030 Slog.i(TAG, "Found setup wizard;" 10031 + " allow priority " + intent.getPriority() + ";" 10032 + " package: " + intent.activity.info.packageName 10033 + " activity: " + intent.activity.className 10034 + " priority: " + intent.getPriority()); 10035 } 10036 // setup wizard gets whatever it wants 10037 return; 10038 } 10039 Slog.w(TAG, "Protected action; cap priority to 0;" 10040 + " package: " + intent.activity.info.packageName 10041 + " activity: " + intent.activity.className 10042 + " origPrio: " + intent.getPriority()); 10043 intent.setPriority(0); 10044 return; 10045 } 10046 } 10047 // privileged apps on the system image get whatever priority they request 10048 return; 10049 } 10050 10051 // privileged app unbundled update ... try to find the same activity 10052 final PackageParser.Activity foundActivity = 10053 findMatchingActivity(systemActivities, activityInfo); 10054 if (foundActivity == null) { 10055 // this is a new activity; it cannot obtain >0 priority 10056 if (DEBUG_FILTERS) { 10057 Slog.i(TAG, "New activity; cap priority to 0;" 10058 + " package: " + applicationInfo.packageName 10059 + " activity: " + intent.activity.className 10060 + " origPrio: " + intent.getPriority()); 10061 } 10062 intent.setPriority(0); 10063 return; 10064 } 10065 10066 // found activity, now check for filter equivalence 10067 10068 // a shallow copy is enough; we modify the list, not its contents 10069 final List<ActivityIntentInfo> intentListCopy = 10070 new ArrayList<>(foundActivity.intents); 10071 final List<ActivityIntentInfo> foundFilters = findFilters(intent); 10072 10073 // find matching action subsets 10074 final Iterator<String> actionsIterator = intent.actionsIterator(); 10075 if (actionsIterator != null) { 10076 getIntentListSubset( 10077 intentListCopy, new ActionIterGenerator(), actionsIterator); 10078 if (intentListCopy.size() == 0) { 10079 // no more intents to match; we're not equivalent 10080 if (DEBUG_FILTERS) { 10081 Slog.i(TAG, "Mismatched action; cap priority to 0;" 10082 + " package: " + applicationInfo.packageName 10083 + " activity: " + intent.activity.className 10084 + " origPrio: " + intent.getPriority()); 10085 } 10086 intent.setPriority(0); 10087 return; 10088 } 10089 } 10090 10091 // find matching category subsets 10092 final Iterator<String> categoriesIterator = intent.categoriesIterator(); 10093 if (categoriesIterator != null) { 10094 getIntentListSubset(intentListCopy, new CategoriesIterGenerator(), 10095 categoriesIterator); 10096 if (intentListCopy.size() == 0) { 10097 // no more intents to match; we're not equivalent 10098 if (DEBUG_FILTERS) { 10099 Slog.i(TAG, "Mismatched category; cap priority to 0;" 10100 + " package: " + applicationInfo.packageName 10101 + " activity: " + intent.activity.className 10102 + " origPrio: " + intent.getPriority()); 10103 } 10104 intent.setPriority(0); 10105 return; 10106 } 10107 } 10108 10109 // find matching schemes subsets 10110 final Iterator<String> schemesIterator = intent.schemesIterator(); 10111 if (schemesIterator != null) { 10112 getIntentListSubset(intentListCopy, new SchemesIterGenerator(), 10113 schemesIterator); 10114 if (intentListCopy.size() == 0) { 10115 // no more intents to match; we're not equivalent 10116 if (DEBUG_FILTERS) { 10117 Slog.i(TAG, "Mismatched scheme; cap priority to 0;" 10118 + " package: " + applicationInfo.packageName 10119 + " activity: " + intent.activity.className 10120 + " origPrio: " + intent.getPriority()); 10121 } 10122 intent.setPriority(0); 10123 return; 10124 } 10125 } 10126 10127 // find matching authorities subsets 10128 final Iterator<IntentFilter.AuthorityEntry> 10129 authoritiesIterator = intent.authoritiesIterator(); 10130 if (authoritiesIterator != null) { 10131 getIntentListSubset(intentListCopy, 10132 new AuthoritiesIterGenerator(), 10133 authoritiesIterator); 10134 if (intentListCopy.size() == 0) { 10135 // no more intents to match; we're not equivalent 10136 if (DEBUG_FILTERS) { 10137 Slog.i(TAG, "Mismatched authority; cap priority to 0;" 10138 + " package: " + applicationInfo.packageName 10139 + " activity: " + intent.activity.className 10140 + " origPrio: " + intent.getPriority()); 10141 } 10142 intent.setPriority(0); 10143 return; 10144 } 10145 } 10146 10147 // we found matching filter(s); app gets the max priority of all intents 10148 int cappedPriority = 0; 10149 for (int i = intentListCopy.size() - 1; i >= 0; --i) { 10150 cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority()); 10151 } 10152 if (intent.getPriority() > cappedPriority) { 10153 if (DEBUG_FILTERS) { 10154 Slog.i(TAG, "Found matching filter(s);" 10155 + " cap priority to " + cappedPriority + ";" 10156 + " package: " + applicationInfo.packageName 10157 + " activity: " + intent.activity.className 10158 + " origPrio: " + intent.getPriority()); 10159 } 10160 intent.setPriority(cappedPriority); 10161 return; 10162 } 10163 // all this for nothing; the requested priority was <= what was on the system 10164 } 10165 10166 public final void addActivity(PackageParser.Activity a, String type) { 10167 mActivities.put(a.getComponentName(), a); 10168 if (DEBUG_SHOW_INFO) 10169 Log.v( 10170 TAG, " " + type + " " + 10171 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":"); 10172 if (DEBUG_SHOW_INFO) 10173 Log.v(TAG, " Class=" + a.info.name); 10174 final int NI = a.intents.size(); 10175 for (int j=0; j<NI; j++) { 10176 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 10177 if ("activity".equals(type)) { 10178 final PackageSetting ps = 10179 mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName); 10180 final List<PackageParser.Activity> systemActivities = 10181 ps != null && ps.pkg != null ? ps.pkg.activities : null; 10182 adjustPriority(systemActivities, intent); 10183 } 10184 if (DEBUG_SHOW_INFO) { 10185 Log.v(TAG, " IntentFilter:"); 10186 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10187 } 10188 if (!intent.debugCheck()) { 10189 Log.w(TAG, "==> For Activity " + a.info.name); 10190 } 10191 addFilter(intent); 10192 } 10193 } 10194 10195 public final void removeActivity(PackageParser.Activity a, String type) { 10196 mActivities.remove(a.getComponentName()); 10197 if (DEBUG_SHOW_INFO) { 10198 Log.v(TAG, " " + type + " " 10199 + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel 10200 : a.info.name) + ":"); 10201 Log.v(TAG, " Class=" + a.info.name); 10202 } 10203 final int NI = a.intents.size(); 10204 for (int j=0; j<NI; j++) { 10205 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 10206 if (DEBUG_SHOW_INFO) { 10207 Log.v(TAG, " IntentFilter:"); 10208 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10209 } 10210 removeFilter(intent); 10211 } 10212 } 10213 10214 @Override 10215 protected boolean allowFilterResult( 10216 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) { 10217 ActivityInfo filterAi = filter.activity.info; 10218 for (int i=dest.size()-1; i>=0; i--) { 10219 ActivityInfo destAi = dest.get(i).activityInfo; 10220 if (destAi.name == filterAi.name 10221 && destAi.packageName == filterAi.packageName) { 10222 return false; 10223 } 10224 } 10225 return true; 10226 } 10227 10228 @Override 10229 protected ActivityIntentInfo[] newArray(int size) { 10230 return new ActivityIntentInfo[size]; 10231 } 10232 10233 @Override 10234 protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) { 10235 if (!sUserManager.exists(userId)) return true; 10236 PackageParser.Package p = filter.activity.owner; 10237 if (p != null) { 10238 PackageSetting ps = (PackageSetting)p.mExtras; 10239 if (ps != null) { 10240 // System apps are never considered stopped for purposes of 10241 // filtering, because there may be no way for the user to 10242 // actually re-launch them. 10243 return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0 10244 && ps.getStopped(userId); 10245 } 10246 } 10247 return false; 10248 } 10249 10250 @Override 10251 protected boolean isPackageForFilter(String packageName, 10252 PackageParser.ActivityIntentInfo info) { 10253 return packageName.equals(info.activity.owner.packageName); 10254 } 10255 10256 @Override 10257 protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info, 10258 int match, int userId) { 10259 if (!sUserManager.exists(userId)) return null; 10260 if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) { 10261 return null; 10262 } 10263 final PackageParser.Activity activity = info.activity; 10264 PackageSetting ps = (PackageSetting) activity.owner.mExtras; 10265 if (ps == null) { 10266 return null; 10267 } 10268 ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags, 10269 ps.readUserState(userId), userId); 10270 if (ai == null) { 10271 return null; 10272 } 10273 final ResolveInfo res = new ResolveInfo(); 10274 res.activityInfo = ai; 10275 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 10276 res.filter = info; 10277 } 10278 if (info != null) { 10279 res.handleAllWebDataURI = info.handleAllWebDataURI(); 10280 } 10281 res.priority = info.getPriority(); 10282 res.preferredOrder = activity.owner.mPreferredOrder; 10283 //System.out.println("Result: " + res.activityInfo.className + 10284 // " = " + res.priority); 10285 res.match = match; 10286 res.isDefault = info.hasDefault; 10287 res.labelRes = info.labelRes; 10288 res.nonLocalizedLabel = info.nonLocalizedLabel; 10289 if (userNeedsBadging(userId)) { 10290 res.noResourceId = true; 10291 } else { 10292 res.icon = info.icon; 10293 } 10294 res.iconResourceId = info.icon; 10295 res.system = res.activityInfo.applicationInfo.isSystemApp(); 10296 return res; 10297 } 10298 10299 @Override 10300 protected void sortResults(List<ResolveInfo> results) { 10301 Collections.sort(results, mResolvePrioritySorter); 10302 } 10303 10304 @Override 10305 protected void dumpFilter(PrintWriter out, String prefix, 10306 PackageParser.ActivityIntentInfo filter) { 10307 out.print(prefix); out.print( 10308 Integer.toHexString(System.identityHashCode(filter.activity))); 10309 out.print(' '); 10310 filter.activity.printComponentShortName(out); 10311 out.print(" filter "); 10312 out.println(Integer.toHexString(System.identityHashCode(filter))); 10313 } 10314 10315 @Override 10316 protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) { 10317 return filter.activity; 10318 } 10319 10320 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 10321 PackageParser.Activity activity = (PackageParser.Activity)label; 10322 out.print(prefix); out.print( 10323 Integer.toHexString(System.identityHashCode(activity))); 10324 out.print(' '); 10325 activity.printComponentShortName(out); 10326 if (count > 1) { 10327 out.print(" ("); out.print(count); out.print(" filters)"); 10328 } 10329 out.println(); 10330 } 10331 10332 // Keys are String (activity class name), values are Activity. 10333 private final ArrayMap<ComponentName, PackageParser.Activity> mActivities 10334 = new ArrayMap<ComponentName, PackageParser.Activity>(); 10335 private int mFlags; 10336 } 10337 10338 private final class ServiceIntentResolver 10339 extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> { 10340 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 10341 boolean defaultOnly, int userId) { 10342 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 10343 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 10344 } 10345 10346 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 10347 int userId) { 10348 if (!sUserManager.exists(userId)) return null; 10349 mFlags = flags; 10350 return super.queryIntent(intent, resolvedType, 10351 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 10352 } 10353 10354 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 10355 int flags, ArrayList<PackageParser.Service> packageServices, int userId) { 10356 if (!sUserManager.exists(userId)) return null; 10357 if (packageServices == null) { 10358 return null; 10359 } 10360 mFlags = flags; 10361 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 10362 final int N = packageServices.size(); 10363 ArrayList<PackageParser.ServiceIntentInfo[]> listCut = 10364 new ArrayList<PackageParser.ServiceIntentInfo[]>(N); 10365 10366 ArrayList<PackageParser.ServiceIntentInfo> intentFilters; 10367 for (int i = 0; i < N; ++i) { 10368 intentFilters = packageServices.get(i).intents; 10369 if (intentFilters != null && intentFilters.size() > 0) { 10370 PackageParser.ServiceIntentInfo[] array = 10371 new PackageParser.ServiceIntentInfo[intentFilters.size()]; 10372 intentFilters.toArray(array); 10373 listCut.add(array); 10374 } 10375 } 10376 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 10377 } 10378 10379 public final void addService(PackageParser.Service s) { 10380 mServices.put(s.getComponentName(), s); 10381 if (DEBUG_SHOW_INFO) { 10382 Log.v(TAG, " " 10383 + (s.info.nonLocalizedLabel != null 10384 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 10385 Log.v(TAG, " Class=" + s.info.name); 10386 } 10387 final int NI = s.intents.size(); 10388 int j; 10389 for (j=0; j<NI; j++) { 10390 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 10391 if (DEBUG_SHOW_INFO) { 10392 Log.v(TAG, " IntentFilter:"); 10393 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10394 } 10395 if (!intent.debugCheck()) { 10396 Log.w(TAG, "==> For Service " + s.info.name); 10397 } 10398 addFilter(intent); 10399 } 10400 } 10401 10402 public final void removeService(PackageParser.Service s) { 10403 mServices.remove(s.getComponentName()); 10404 if (DEBUG_SHOW_INFO) { 10405 Log.v(TAG, " " + (s.info.nonLocalizedLabel != null 10406 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 10407 Log.v(TAG, " Class=" + s.info.name); 10408 } 10409 final int NI = s.intents.size(); 10410 int j; 10411 for (j=0; j<NI; j++) { 10412 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 10413 if (DEBUG_SHOW_INFO) { 10414 Log.v(TAG, " IntentFilter:"); 10415 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10416 } 10417 removeFilter(intent); 10418 } 10419 } 10420 10421 @Override 10422 protected boolean allowFilterResult( 10423 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) { 10424 ServiceInfo filterSi = filter.service.info; 10425 for (int i=dest.size()-1; i>=0; i--) { 10426 ServiceInfo destAi = dest.get(i).serviceInfo; 10427 if (destAi.name == filterSi.name 10428 && destAi.packageName == filterSi.packageName) { 10429 return false; 10430 } 10431 } 10432 return true; 10433 } 10434 10435 @Override 10436 protected PackageParser.ServiceIntentInfo[] newArray(int size) { 10437 return new PackageParser.ServiceIntentInfo[size]; 10438 } 10439 10440 @Override 10441 protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) { 10442 if (!sUserManager.exists(userId)) return true; 10443 PackageParser.Package p = filter.service.owner; 10444 if (p != null) { 10445 PackageSetting ps = (PackageSetting)p.mExtras; 10446 if (ps != null) { 10447 // System apps are never considered stopped for purposes of 10448 // filtering, because there may be no way for the user to 10449 // actually re-launch them. 10450 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 10451 && ps.getStopped(userId); 10452 } 10453 } 10454 return false; 10455 } 10456 10457 @Override 10458 protected boolean isPackageForFilter(String packageName, 10459 PackageParser.ServiceIntentInfo info) { 10460 return packageName.equals(info.service.owner.packageName); 10461 } 10462 10463 @Override 10464 protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter, 10465 int match, int userId) { 10466 if (!sUserManager.exists(userId)) return null; 10467 final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter; 10468 if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) { 10469 return null; 10470 } 10471 final PackageParser.Service service = info.service; 10472 PackageSetting ps = (PackageSetting) service.owner.mExtras; 10473 if (ps == null) { 10474 return null; 10475 } 10476 ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags, 10477 ps.readUserState(userId), userId); 10478 if (si == null) { 10479 return null; 10480 } 10481 final ResolveInfo res = new ResolveInfo(); 10482 res.serviceInfo = si; 10483 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 10484 res.filter = filter; 10485 } 10486 res.priority = info.getPriority(); 10487 res.preferredOrder = service.owner.mPreferredOrder; 10488 res.match = match; 10489 res.isDefault = info.hasDefault; 10490 res.labelRes = info.labelRes; 10491 res.nonLocalizedLabel = info.nonLocalizedLabel; 10492 res.icon = info.icon; 10493 res.system = res.serviceInfo.applicationInfo.isSystemApp(); 10494 return res; 10495 } 10496 10497 @Override 10498 protected void sortResults(List<ResolveInfo> results) { 10499 Collections.sort(results, mResolvePrioritySorter); 10500 } 10501 10502 @Override 10503 protected void dumpFilter(PrintWriter out, String prefix, 10504 PackageParser.ServiceIntentInfo filter) { 10505 out.print(prefix); out.print( 10506 Integer.toHexString(System.identityHashCode(filter.service))); 10507 out.print(' '); 10508 filter.service.printComponentShortName(out); 10509 out.print(" filter "); 10510 out.println(Integer.toHexString(System.identityHashCode(filter))); 10511 } 10512 10513 @Override 10514 protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) { 10515 return filter.service; 10516 } 10517 10518 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 10519 PackageParser.Service service = (PackageParser.Service)label; 10520 out.print(prefix); out.print( 10521 Integer.toHexString(System.identityHashCode(service))); 10522 out.print(' '); 10523 service.printComponentShortName(out); 10524 if (count > 1) { 10525 out.print(" ("); out.print(count); out.print(" filters)"); 10526 } 10527 out.println(); 10528 } 10529 10530// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 10531// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 10532// final List<ResolveInfo> retList = Lists.newArrayList(); 10533// while (i.hasNext()) { 10534// final ResolveInfo resolveInfo = (ResolveInfo) i; 10535// if (isEnabledLP(resolveInfo.serviceInfo)) { 10536// retList.add(resolveInfo); 10537// } 10538// } 10539// return retList; 10540// } 10541 10542 // Keys are String (activity class name), values are Activity. 10543 private final ArrayMap<ComponentName, PackageParser.Service> mServices 10544 = new ArrayMap<ComponentName, PackageParser.Service>(); 10545 private int mFlags; 10546 }; 10547 10548 private final class ProviderIntentResolver 10549 extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> { 10550 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 10551 boolean defaultOnly, int userId) { 10552 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 10553 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 10554 } 10555 10556 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 10557 int userId) { 10558 if (!sUserManager.exists(userId)) 10559 return null; 10560 mFlags = flags; 10561 return super.queryIntent(intent, resolvedType, 10562 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 10563 } 10564 10565 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 10566 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) { 10567 if (!sUserManager.exists(userId)) 10568 return null; 10569 if (packageProviders == null) { 10570 return null; 10571 } 10572 mFlags = flags; 10573 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; 10574 final int N = packageProviders.size(); 10575 ArrayList<PackageParser.ProviderIntentInfo[]> listCut = 10576 new ArrayList<PackageParser.ProviderIntentInfo[]>(N); 10577 10578 ArrayList<PackageParser.ProviderIntentInfo> intentFilters; 10579 for (int i = 0; i < N; ++i) { 10580 intentFilters = packageProviders.get(i).intents; 10581 if (intentFilters != null && intentFilters.size() > 0) { 10582 PackageParser.ProviderIntentInfo[] array = 10583 new PackageParser.ProviderIntentInfo[intentFilters.size()]; 10584 intentFilters.toArray(array); 10585 listCut.add(array); 10586 } 10587 } 10588 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 10589 } 10590 10591 public final void addProvider(PackageParser.Provider p) { 10592 if (mProviders.containsKey(p.getComponentName())) { 10593 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring"); 10594 return; 10595 } 10596 10597 mProviders.put(p.getComponentName(), p); 10598 if (DEBUG_SHOW_INFO) { 10599 Log.v(TAG, " " 10600 + (p.info.nonLocalizedLabel != null 10601 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 10602 Log.v(TAG, " Class=" + p.info.name); 10603 } 10604 final int NI = p.intents.size(); 10605 int j; 10606 for (j = 0; j < NI; j++) { 10607 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 10608 if (DEBUG_SHOW_INFO) { 10609 Log.v(TAG, " IntentFilter:"); 10610 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10611 } 10612 if (!intent.debugCheck()) { 10613 Log.w(TAG, "==> For Provider " + p.info.name); 10614 } 10615 addFilter(intent); 10616 } 10617 } 10618 10619 public final void removeProvider(PackageParser.Provider p) { 10620 mProviders.remove(p.getComponentName()); 10621 if (DEBUG_SHOW_INFO) { 10622 Log.v(TAG, " " + (p.info.nonLocalizedLabel != null 10623 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 10624 Log.v(TAG, " Class=" + p.info.name); 10625 } 10626 final int NI = p.intents.size(); 10627 int j; 10628 for (j = 0; j < NI; j++) { 10629 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 10630 if (DEBUG_SHOW_INFO) { 10631 Log.v(TAG, " IntentFilter:"); 10632 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10633 } 10634 removeFilter(intent); 10635 } 10636 } 10637 10638 @Override 10639 protected boolean allowFilterResult( 10640 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) { 10641 ProviderInfo filterPi = filter.provider.info; 10642 for (int i = dest.size() - 1; i >= 0; i--) { 10643 ProviderInfo destPi = dest.get(i).providerInfo; 10644 if (destPi.name == filterPi.name 10645 && destPi.packageName == filterPi.packageName) { 10646 return false; 10647 } 10648 } 10649 return true; 10650 } 10651 10652 @Override 10653 protected PackageParser.ProviderIntentInfo[] newArray(int size) { 10654 return new PackageParser.ProviderIntentInfo[size]; 10655 } 10656 10657 @Override 10658 protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) { 10659 if (!sUserManager.exists(userId)) 10660 return true; 10661 PackageParser.Package p = filter.provider.owner; 10662 if (p != null) { 10663 PackageSetting ps = (PackageSetting) p.mExtras; 10664 if (ps != null) { 10665 // System apps are never considered stopped for purposes of 10666 // filtering, because there may be no way for the user to 10667 // actually re-launch them. 10668 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 10669 && ps.getStopped(userId); 10670 } 10671 } 10672 return false; 10673 } 10674 10675 @Override 10676 protected boolean isPackageForFilter(String packageName, 10677 PackageParser.ProviderIntentInfo info) { 10678 return packageName.equals(info.provider.owner.packageName); 10679 } 10680 10681 @Override 10682 protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter, 10683 int match, int userId) { 10684 if (!sUserManager.exists(userId)) 10685 return null; 10686 final PackageParser.ProviderIntentInfo info = filter; 10687 if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) { 10688 return null; 10689 } 10690 final PackageParser.Provider provider = info.provider; 10691 PackageSetting ps = (PackageSetting) provider.owner.mExtras; 10692 if (ps == null) { 10693 return null; 10694 } 10695 ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags, 10696 ps.readUserState(userId), userId); 10697 if (pi == null) { 10698 return null; 10699 } 10700 final ResolveInfo res = new ResolveInfo(); 10701 res.providerInfo = pi; 10702 if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) { 10703 res.filter = filter; 10704 } 10705 res.priority = info.getPriority(); 10706 res.preferredOrder = provider.owner.mPreferredOrder; 10707 res.match = match; 10708 res.isDefault = info.hasDefault; 10709 res.labelRes = info.labelRes; 10710 res.nonLocalizedLabel = info.nonLocalizedLabel; 10711 res.icon = info.icon; 10712 res.system = res.providerInfo.applicationInfo.isSystemApp(); 10713 return res; 10714 } 10715 10716 @Override 10717 protected void sortResults(List<ResolveInfo> results) { 10718 Collections.sort(results, mResolvePrioritySorter); 10719 } 10720 10721 @Override 10722 protected void dumpFilter(PrintWriter out, String prefix, 10723 PackageParser.ProviderIntentInfo filter) { 10724 out.print(prefix); 10725 out.print( 10726 Integer.toHexString(System.identityHashCode(filter.provider))); 10727 out.print(' '); 10728 filter.provider.printComponentShortName(out); 10729 out.print(" filter "); 10730 out.println(Integer.toHexString(System.identityHashCode(filter))); 10731 } 10732 10733 @Override 10734 protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) { 10735 return filter.provider; 10736 } 10737 10738 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 10739 PackageParser.Provider provider = (PackageParser.Provider)label; 10740 out.print(prefix); out.print( 10741 Integer.toHexString(System.identityHashCode(provider))); 10742 out.print(' '); 10743 provider.printComponentShortName(out); 10744 if (count > 1) { 10745 out.print(" ("); out.print(count); out.print(" filters)"); 10746 } 10747 out.println(); 10748 } 10749 10750 private final ArrayMap<ComponentName, PackageParser.Provider> mProviders 10751 = new ArrayMap<ComponentName, PackageParser.Provider>(); 10752 private int mFlags; 10753 } 10754 10755 private static final class EphemeralIntentResolver 10756 extends IntentResolver<EphemeralResolveIntentInfo, EphemeralResolveInfo> { 10757 @Override 10758 protected EphemeralResolveIntentInfo[] newArray(int size) { 10759 return new EphemeralResolveIntentInfo[size]; 10760 } 10761 10762 @Override 10763 protected boolean isPackageForFilter(String packageName, EphemeralResolveIntentInfo info) { 10764 return true; 10765 } 10766 10767 @Override 10768 protected EphemeralResolveInfo newResult(EphemeralResolveIntentInfo info, int match, 10769 int userId) { 10770 if (!sUserManager.exists(userId)) { 10771 return null; 10772 } 10773 return info.getEphemeralResolveInfo(); 10774 } 10775 } 10776 10777 private static final Comparator<ResolveInfo> mResolvePrioritySorter = 10778 new Comparator<ResolveInfo>() { 10779 public int compare(ResolveInfo r1, ResolveInfo r2) { 10780 int v1 = r1.priority; 10781 int v2 = r2.priority; 10782 //System.out.println("Comparing: q1=" + q1 + " q2=" + q2); 10783 if (v1 != v2) { 10784 return (v1 > v2) ? -1 : 1; 10785 } 10786 v1 = r1.preferredOrder; 10787 v2 = r2.preferredOrder; 10788 if (v1 != v2) { 10789 return (v1 > v2) ? -1 : 1; 10790 } 10791 if (r1.isDefault != r2.isDefault) { 10792 return r1.isDefault ? -1 : 1; 10793 } 10794 v1 = r1.match; 10795 v2 = r2.match; 10796 //System.out.println("Comparing: m1=" + m1 + " m2=" + m2); 10797 if (v1 != v2) { 10798 return (v1 > v2) ? -1 : 1; 10799 } 10800 if (r1.system != r2.system) { 10801 return r1.system ? -1 : 1; 10802 } 10803 if (r1.activityInfo != null) { 10804 return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName); 10805 } 10806 if (r1.serviceInfo != null) { 10807 return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName); 10808 } 10809 if (r1.providerInfo != null) { 10810 return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName); 10811 } 10812 return 0; 10813 } 10814 }; 10815 10816 private static final Comparator<ProviderInfo> mProviderInitOrderSorter = 10817 new Comparator<ProviderInfo>() { 10818 public int compare(ProviderInfo p1, ProviderInfo p2) { 10819 final int v1 = p1.initOrder; 10820 final int v2 = p2.initOrder; 10821 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0); 10822 } 10823 }; 10824 10825 final void sendPackageBroadcast(final String action, final String pkg, final Bundle extras, 10826 final int flags, final String targetPkg, final IIntentReceiver finishedReceiver, 10827 final int[] userIds) { 10828 mHandler.post(new Runnable() { 10829 @Override 10830 public void run() { 10831 try { 10832 final IActivityManager am = ActivityManagerNative.getDefault(); 10833 if (am == null) return; 10834 final int[] resolvedUserIds; 10835 if (userIds == null) { 10836 resolvedUserIds = am.getRunningUserIds(); 10837 } else { 10838 resolvedUserIds = userIds; 10839 } 10840 for (int id : resolvedUserIds) { 10841 final Intent intent = new Intent(action, 10842 pkg != null ? Uri.fromParts("package", pkg, null) : null); 10843 if (extras != null) { 10844 intent.putExtras(extras); 10845 } 10846 if (targetPkg != null) { 10847 intent.setPackage(targetPkg); 10848 } 10849 // Modify the UID when posting to other users 10850 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); 10851 if (uid > 0 && UserHandle.getUserId(uid) != id) { 10852 uid = UserHandle.getUid(id, UserHandle.getAppId(uid)); 10853 intent.putExtra(Intent.EXTRA_UID, uid); 10854 } 10855 intent.putExtra(Intent.EXTRA_USER_HANDLE, id); 10856 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags); 10857 if (DEBUG_BROADCASTS) { 10858 RuntimeException here = new RuntimeException("here"); 10859 here.fillInStackTrace(); 10860 Slog.d(TAG, "Sending to user " + id + ": " 10861 + intent.toShortString(false, true, false, false) 10862 + " " + intent.getExtras(), here); 10863 } 10864 am.broadcastIntent(null, intent, null, finishedReceiver, 10865 0, null, null, null, android.app.AppOpsManager.OP_NONE, 10866 null, finishedReceiver != null, false, id); 10867 } 10868 } catch (RemoteException ex) { 10869 } 10870 } 10871 }); 10872 } 10873 10874 /** 10875 * Check if the external storage media is available. This is true if there 10876 * is a mounted external storage medium or if the external storage is 10877 * emulated. 10878 */ 10879 private boolean isExternalMediaAvailable() { 10880 return mMediaMounted || Environment.isExternalStorageEmulated(); 10881 } 10882 10883 @Override 10884 public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) { 10885 // writer 10886 synchronized (mPackages) { 10887 if (!isExternalMediaAvailable()) { 10888 // If the external storage is no longer mounted at this point, 10889 // the caller may not have been able to delete all of this 10890 // packages files and can not delete any more. Bail. 10891 return null; 10892 } 10893 final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned; 10894 if (lastPackage != null) { 10895 pkgs.remove(lastPackage); 10896 } 10897 if (pkgs.size() > 0) { 10898 return pkgs.get(0); 10899 } 10900 } 10901 return null; 10902 } 10903 10904 void schedulePackageCleaning(String packageName, int userId, boolean andCode) { 10905 final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE, 10906 userId, andCode ? 1 : 0, packageName); 10907 if (mSystemReady) { 10908 msg.sendToTarget(); 10909 } else { 10910 if (mPostSystemReadyMessages == null) { 10911 mPostSystemReadyMessages = new ArrayList<>(); 10912 } 10913 mPostSystemReadyMessages.add(msg); 10914 } 10915 } 10916 10917 void startCleaningPackages() { 10918 // reader 10919 if (!isExternalMediaAvailable()) { 10920 return; 10921 } 10922 synchronized (mPackages) { 10923 if (mSettings.mPackagesToBeCleaned.isEmpty()) { 10924 return; 10925 } 10926 } 10927 Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE); 10928 intent.setComponent(DEFAULT_CONTAINER_COMPONENT); 10929 IActivityManager am = ActivityManagerNative.getDefault(); 10930 if (am != null) { 10931 try { 10932 am.startService(null, intent, null, mContext.getOpPackageName(), 10933 UserHandle.USER_SYSTEM); 10934 } catch (RemoteException e) { 10935 } 10936 } 10937 } 10938 10939 @Override 10940 public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer, 10941 int installFlags, String installerPackageName, int userId) { 10942 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null); 10943 10944 final int callingUid = Binder.getCallingUid(); 10945 enforceCrossUserPermission(callingUid, userId, 10946 true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser"); 10947 10948 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 10949 try { 10950 if (observer != null) { 10951 observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null); 10952 } 10953 } catch (RemoteException re) { 10954 } 10955 return; 10956 } 10957 10958 if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) { 10959 installFlags |= PackageManager.INSTALL_FROM_ADB; 10960 10961 } else { 10962 // Caller holds INSTALL_PACKAGES permission, so we're less strict 10963 // about installerPackageName. 10964 10965 installFlags &= ~PackageManager.INSTALL_FROM_ADB; 10966 installFlags &= ~PackageManager.INSTALL_ALL_USERS; 10967 } 10968 10969 UserHandle user; 10970 if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) { 10971 user = UserHandle.ALL; 10972 } else { 10973 user = new UserHandle(userId); 10974 } 10975 10976 // Only system components can circumvent runtime permissions when installing. 10977 if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0 10978 && mContext.checkCallingOrSelfPermission(Manifest.permission 10979 .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) { 10980 throw new SecurityException("You need the " 10981 + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission " 10982 + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag"); 10983 } 10984 10985 final File originFile = new File(originPath); 10986 final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile); 10987 10988 final Message msg = mHandler.obtainMessage(INIT_COPY); 10989 final VerificationInfo verificationInfo = new VerificationInfo( 10990 null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid); 10991 final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer, 10992 installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user, 10993 null /*packageAbiOverride*/, null /*grantedPermissions*/, 10994 null /*certificates*/); 10995 params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params)); 10996 msg.obj = params; 10997 10998 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser", 10999 System.identityHashCode(msg.obj)); 11000 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 11001 System.identityHashCode(msg.obj)); 11002 11003 mHandler.sendMessage(msg); 11004 } 11005 11006 void installStage(String packageName, File stagedDir, String stagedCid, 11007 IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams, 11008 String installerPackageName, int installerUid, UserHandle user, 11009 Certificate[][] certificates) { 11010 if (DEBUG_EPHEMERAL) { 11011 if ((sessionParams.installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) { 11012 Slog.d(TAG, "Ephemeral install of " + packageName); 11013 } 11014 } 11015 final VerificationInfo verificationInfo = new VerificationInfo( 11016 sessionParams.originatingUri, sessionParams.referrerUri, 11017 sessionParams.originatingUid, installerUid); 11018 11019 final OriginInfo origin; 11020 if (stagedDir != null) { 11021 origin = OriginInfo.fromStagedFile(stagedDir); 11022 } else { 11023 origin = OriginInfo.fromStagedContainer(stagedCid); 11024 } 11025 11026 final Message msg = mHandler.obtainMessage(INIT_COPY); 11027 final InstallParams params = new InstallParams(origin, null, observer, 11028 sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid, 11029 verificationInfo, user, sessionParams.abiOverride, 11030 sessionParams.grantedRuntimePermissions, certificates); 11031 params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params)); 11032 msg.obj = params; 11033 11034 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage", 11035 System.identityHashCode(msg.obj)); 11036 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 11037 System.identityHashCode(msg.obj)); 11038 11039 mHandler.sendMessage(msg); 11040 } 11041 11042 private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, 11043 int userId) { 11044 final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting); 11045 sendPackageAddedForUser(packageName, isSystem, pkgSetting.appId, userId); 11046 } 11047 11048 private void sendPackageAddedForUser(String packageName, boolean isSystem, 11049 int appId, int userId) { 11050 Bundle extras = new Bundle(1); 11051 extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userId, appId)); 11052 11053 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 11054 packageName, extras, 0, null, null, new int[] {userId}); 11055 try { 11056 IActivityManager am = ActivityManagerNative.getDefault(); 11057 if (isSystem && am.isUserRunning(userId, 0)) { 11058 // The just-installed/enabled app is bundled on the system, so presumed 11059 // to be able to run automatically without needing an explicit launch. 11060 // Send it a BOOT_COMPLETED if it would ordinarily have gotten one. 11061 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED) 11062 .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES) 11063 .setPackage(packageName); 11064 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, null, 11065 android.app.AppOpsManager.OP_NONE, null, false, false, userId); 11066 } 11067 } catch (RemoteException e) { 11068 // shouldn't happen 11069 Slog.w(TAG, "Unable to bootstrap installed package", e); 11070 } 11071 } 11072 11073 @Override 11074 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, 11075 int userId) { 11076 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 11077 PackageSetting pkgSetting; 11078 final int uid = Binder.getCallingUid(); 11079 enforceCrossUserPermission(uid, userId, 11080 true /* requireFullPermission */, true /* checkShell */, 11081 "setApplicationHiddenSetting for user " + userId); 11082 11083 if (hidden && isPackageDeviceAdmin(packageName, userId)) { 11084 Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin"); 11085 return false; 11086 } 11087 11088 long callingId = Binder.clearCallingIdentity(); 11089 try { 11090 boolean sendAdded = false; 11091 boolean sendRemoved = false; 11092 // writer 11093 synchronized (mPackages) { 11094 pkgSetting = mSettings.mPackages.get(packageName); 11095 if (pkgSetting == null) { 11096 return false; 11097 } 11098 if (pkgSetting.getHidden(userId) != hidden) { 11099 pkgSetting.setHidden(hidden, userId); 11100 mSettings.writePackageRestrictionsLPr(userId); 11101 if (hidden) { 11102 sendRemoved = true; 11103 } else { 11104 sendAdded = true; 11105 } 11106 } 11107 } 11108 if (sendAdded) { 11109 sendPackageAddedForUser(packageName, pkgSetting, userId); 11110 return true; 11111 } 11112 if (sendRemoved) { 11113 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId), 11114 "hiding pkg"); 11115 sendApplicationHiddenForUser(packageName, pkgSetting, userId); 11116 return true; 11117 } 11118 } finally { 11119 Binder.restoreCallingIdentity(callingId); 11120 } 11121 return false; 11122 } 11123 11124 private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting, 11125 int userId) { 11126 final PackageRemovedInfo info = new PackageRemovedInfo(); 11127 info.removedPackage = packageName; 11128 info.removedUsers = new int[] {userId}; 11129 info.uid = UserHandle.getUid(userId, pkgSetting.appId); 11130 info.sendPackageRemovedBroadcasts(true /*killApp*/); 11131 } 11132 11133 private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) { 11134 if (pkgList.length > 0) { 11135 Bundle extras = new Bundle(1); 11136 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 11137 11138 sendPackageBroadcast( 11139 suspended ? Intent.ACTION_PACKAGES_SUSPENDED 11140 : Intent.ACTION_PACKAGES_UNSUSPENDED, 11141 null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null, 11142 new int[] {userId}); 11143 } 11144 } 11145 11146 /** 11147 * Returns true if application is not found or there was an error. Otherwise it returns 11148 * the hidden state of the package for the given user. 11149 */ 11150 @Override 11151 public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) { 11152 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 11153 enforceCrossUserPermission(Binder.getCallingUid(), userId, 11154 true /* requireFullPermission */, false /* checkShell */, 11155 "getApplicationHidden for user " + userId); 11156 PackageSetting pkgSetting; 11157 long callingId = Binder.clearCallingIdentity(); 11158 try { 11159 // writer 11160 synchronized (mPackages) { 11161 pkgSetting = mSettings.mPackages.get(packageName); 11162 if (pkgSetting == null) { 11163 return true; 11164 } 11165 return pkgSetting.getHidden(userId); 11166 } 11167 } finally { 11168 Binder.restoreCallingIdentity(callingId); 11169 } 11170 } 11171 11172 /** 11173 * @hide 11174 */ 11175 @Override 11176 public int installExistingPackageAsUser(String packageName, int userId) { 11177 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, 11178 null); 11179 PackageSetting pkgSetting; 11180 final int uid = Binder.getCallingUid(); 11181 enforceCrossUserPermission(uid, userId, 11182 true /* requireFullPermission */, true /* checkShell */, 11183 "installExistingPackage for user " + userId); 11184 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 11185 return PackageManager.INSTALL_FAILED_USER_RESTRICTED; 11186 } 11187 11188 long callingId = Binder.clearCallingIdentity(); 11189 try { 11190 boolean installed = false; 11191 11192 // writer 11193 synchronized (mPackages) { 11194 pkgSetting = mSettings.mPackages.get(packageName); 11195 if (pkgSetting == null) { 11196 return PackageManager.INSTALL_FAILED_INVALID_URI; 11197 } 11198 if (!pkgSetting.getInstalled(userId)) { 11199 pkgSetting.setInstalled(true, userId); 11200 pkgSetting.setHidden(false, userId); 11201 mSettings.writePackageRestrictionsLPr(userId); 11202 installed = true; 11203 } 11204 } 11205 11206 if (installed) { 11207 if (pkgSetting.pkg != null) { 11208 prepareAppDataAfterInstall(pkgSetting.pkg); 11209 } 11210 sendPackageAddedForUser(packageName, pkgSetting, userId); 11211 } 11212 } finally { 11213 Binder.restoreCallingIdentity(callingId); 11214 } 11215 11216 return PackageManager.INSTALL_SUCCEEDED; 11217 } 11218 11219 boolean isUserRestricted(int userId, String restrictionKey) { 11220 Bundle restrictions = sUserManager.getUserRestrictions(userId); 11221 if (restrictions.getBoolean(restrictionKey, false)) { 11222 Log.w(TAG, "User is restricted: " + restrictionKey); 11223 return true; 11224 } 11225 return false; 11226 } 11227 11228 @Override 11229 public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended, 11230 int userId) { 11231 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 11232 enforceCrossUserPermission(Binder.getCallingUid(), userId, 11233 true /* requireFullPermission */, true /* checkShell */, 11234 "setPackagesSuspended for user " + userId); 11235 11236 if (ArrayUtils.isEmpty(packageNames)) { 11237 return packageNames; 11238 } 11239 11240 // List of package names for whom the suspended state has changed. 11241 List<String> changedPackages = new ArrayList<>(packageNames.length); 11242 // List of package names for whom the suspended state is not set as requested in this 11243 // method. 11244 List<String> unactionedPackages = new ArrayList<>(packageNames.length); 11245 for (int i = 0; i < packageNames.length; i++) { 11246 String packageName = packageNames[i]; 11247 long callingId = Binder.clearCallingIdentity(); 11248 try { 11249 boolean changed = false; 11250 final int appId; 11251 synchronized (mPackages) { 11252 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName); 11253 if (pkgSetting == null) { 11254 Slog.w(TAG, "Could not find package setting for package \"" + packageName 11255 + "\". Skipping suspending/un-suspending."); 11256 unactionedPackages.add(packageName); 11257 continue; 11258 } 11259 appId = pkgSetting.appId; 11260 if (pkgSetting.getSuspended(userId) != suspended) { 11261 if (!canSuspendPackageForUserLocked(packageName, userId)) { 11262 unactionedPackages.add(packageName); 11263 continue; 11264 } 11265 pkgSetting.setSuspended(suspended, userId); 11266 mSettings.writePackageRestrictionsLPr(userId); 11267 changed = true; 11268 changedPackages.add(packageName); 11269 } 11270 } 11271 11272 if (changed && suspended) { 11273 killApplication(packageName, UserHandle.getUid(userId, appId), 11274 "suspending package"); 11275 } 11276 } finally { 11277 Binder.restoreCallingIdentity(callingId); 11278 } 11279 } 11280 11281 if (!changedPackages.isEmpty()) { 11282 sendPackagesSuspendedForUser(changedPackages.toArray( 11283 new String[changedPackages.size()]), userId, suspended); 11284 } 11285 11286 return unactionedPackages.toArray(new String[unactionedPackages.size()]); 11287 } 11288 11289 @Override 11290 public boolean isPackageSuspendedForUser(String packageName, int userId) { 11291 enforceCrossUserPermission(Binder.getCallingUid(), userId, 11292 true /* requireFullPermission */, false /* checkShell */, 11293 "isPackageSuspendedForUser for user " + userId); 11294 synchronized (mPackages) { 11295 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName); 11296 if (pkgSetting == null) { 11297 throw new IllegalArgumentException("Unknown target package: " + packageName); 11298 } 11299 return pkgSetting.getSuspended(userId); 11300 } 11301 } 11302 11303 /** 11304 * TODO: cache and disallow blocking the active dialer. 11305 * 11306 * @see also DefaultPermissionGrantPolicy#grantDefaultSystemHandlerPermissions 11307 */ 11308 private boolean canSuspendPackageForUserLocked(String packageName, int userId) { 11309 if (isPackageDeviceAdmin(packageName, userId)) { 11310 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 11311 + "\": has an active device admin"); 11312 return false; 11313 } 11314 11315 String activeLauncherPackageName = getActiveLauncherPackageName(userId); 11316 if (packageName.equals(activeLauncherPackageName)) { 11317 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 11318 + "\": contains the active launcher"); 11319 return false; 11320 } 11321 11322 if (packageName.equals(mRequiredInstallerPackage)) { 11323 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 11324 + "\": required for package installation"); 11325 return false; 11326 } 11327 11328 if (packageName.equals(mRequiredVerifierPackage)) { 11329 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 11330 + "\": required for package verification"); 11331 return false; 11332 } 11333 11334 final PackageParser.Package pkg = mPackages.get(packageName); 11335 if (pkg != null && isPrivilegedApp(pkg)) { 11336 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 11337 + "\": is a privileged app"); 11338 return false; 11339 } 11340 11341 return true; 11342 } 11343 11344 private String getActiveLauncherPackageName(int userId) { 11345 Intent intent = new Intent(Intent.ACTION_MAIN); 11346 intent.addCategory(Intent.CATEGORY_HOME); 11347 ResolveInfo resolveInfo = resolveIntent( 11348 intent, 11349 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 11350 PackageManager.MATCH_DEFAULT_ONLY, 11351 userId); 11352 11353 return resolveInfo == null ? null : resolveInfo.activityInfo.packageName; 11354 } 11355 11356 @Override 11357 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException { 11358 mContext.enforceCallingOrSelfPermission( 11359 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 11360 "Only package verification agents can verify applications"); 11361 11362 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 11363 final PackageVerificationResponse response = new PackageVerificationResponse( 11364 verificationCode, Binder.getCallingUid()); 11365 msg.arg1 = id; 11366 msg.obj = response; 11367 mHandler.sendMessage(msg); 11368 } 11369 11370 @Override 11371 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, 11372 long millisecondsToDelay) { 11373 mContext.enforceCallingOrSelfPermission( 11374 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 11375 "Only package verification agents can extend verification timeouts"); 11376 11377 final PackageVerificationState state = mPendingVerification.get(id); 11378 final PackageVerificationResponse response = new PackageVerificationResponse( 11379 verificationCodeAtTimeout, Binder.getCallingUid()); 11380 11381 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) { 11382 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT; 11383 } 11384 if (millisecondsToDelay < 0) { 11385 millisecondsToDelay = 0; 11386 } 11387 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW) 11388 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) { 11389 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT; 11390 } 11391 11392 if ((state != null) && !state.timeoutExtended()) { 11393 state.extendTimeout(); 11394 11395 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 11396 msg.arg1 = id; 11397 msg.obj = response; 11398 mHandler.sendMessageDelayed(msg, millisecondsToDelay); 11399 } 11400 } 11401 11402 private void broadcastPackageVerified(int verificationId, Uri packageUri, 11403 int verificationCode, UserHandle user) { 11404 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED); 11405 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE); 11406 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 11407 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 11408 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode); 11409 11410 mContext.sendBroadcastAsUser(intent, user, 11411 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT); 11412 } 11413 11414 private ComponentName matchComponentForVerifier(String packageName, 11415 List<ResolveInfo> receivers) { 11416 ActivityInfo targetReceiver = null; 11417 11418 final int NR = receivers.size(); 11419 for (int i = 0; i < NR; i++) { 11420 final ResolveInfo info = receivers.get(i); 11421 if (info.activityInfo == null) { 11422 continue; 11423 } 11424 11425 if (packageName.equals(info.activityInfo.packageName)) { 11426 targetReceiver = info.activityInfo; 11427 break; 11428 } 11429 } 11430 11431 if (targetReceiver == null) { 11432 return null; 11433 } 11434 11435 return new ComponentName(targetReceiver.packageName, targetReceiver.name); 11436 } 11437 11438 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo, 11439 List<ResolveInfo> receivers, final PackageVerificationState verificationState) { 11440 if (pkgInfo.verifiers.length == 0) { 11441 return null; 11442 } 11443 11444 final int N = pkgInfo.verifiers.length; 11445 final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1); 11446 for (int i = 0; i < N; i++) { 11447 final VerifierInfo verifierInfo = pkgInfo.verifiers[i]; 11448 11449 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName, 11450 receivers); 11451 if (comp == null) { 11452 continue; 11453 } 11454 11455 final int verifierUid = getUidForVerifier(verifierInfo); 11456 if (verifierUid == -1) { 11457 continue; 11458 } 11459 11460 if (DEBUG_VERIFY) { 11461 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName 11462 + " with the correct signature"); 11463 } 11464 sufficientVerifiers.add(comp); 11465 verificationState.addSufficientVerifier(verifierUid); 11466 } 11467 11468 return sufficientVerifiers; 11469 } 11470 11471 private int getUidForVerifier(VerifierInfo verifierInfo) { 11472 synchronized (mPackages) { 11473 final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName); 11474 if (pkg == null) { 11475 return -1; 11476 } else if (pkg.mSignatures.length != 1) { 11477 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 11478 + " has more than one signature; ignoring"); 11479 return -1; 11480 } 11481 11482 /* 11483 * If the public key of the package's signature does not match 11484 * our expected public key, then this is a different package and 11485 * we should skip. 11486 */ 11487 11488 final byte[] expectedPublicKey; 11489 try { 11490 final Signature verifierSig = pkg.mSignatures[0]; 11491 final PublicKey publicKey = verifierSig.getPublicKey(); 11492 expectedPublicKey = publicKey.getEncoded(); 11493 } catch (CertificateException e) { 11494 return -1; 11495 } 11496 11497 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded(); 11498 11499 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) { 11500 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 11501 + " does not have the expected public key; ignoring"); 11502 return -1; 11503 } 11504 11505 return pkg.applicationInfo.uid; 11506 } 11507 } 11508 11509 @Override 11510 public void finishPackageInstall(int token) { 11511 enforceSystemOrRoot("Only the system is allowed to finish installs"); 11512 11513 if (DEBUG_INSTALL) { 11514 Slog.v(TAG, "BM finishing package install for " + token); 11515 } 11516 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token); 11517 11518 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 11519 mHandler.sendMessage(msg); 11520 } 11521 11522 /** 11523 * Get the verification agent timeout. 11524 * 11525 * @return verification timeout in milliseconds 11526 */ 11527 private long getVerificationTimeout() { 11528 return android.provider.Settings.Global.getLong(mContext.getContentResolver(), 11529 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT, 11530 DEFAULT_VERIFICATION_TIMEOUT); 11531 } 11532 11533 /** 11534 * Get the default verification agent response code. 11535 * 11536 * @return default verification response code 11537 */ 11538 private int getDefaultVerificationResponse() { 11539 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 11540 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE, 11541 DEFAULT_VERIFICATION_RESPONSE); 11542 } 11543 11544 /** 11545 * Check whether or not package verification has been enabled. 11546 * 11547 * @return true if verification should be performed 11548 */ 11549 private boolean isVerificationEnabled(int userId, int installFlags) { 11550 if (!DEFAULT_VERIFY_ENABLE) { 11551 return false; 11552 } 11553 // Ephemeral apps don't get the full verification treatment 11554 if ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) { 11555 if (DEBUG_EPHEMERAL) { 11556 Slog.d(TAG, "INSTALL_EPHEMERAL so skipping verification"); 11557 } 11558 return false; 11559 } 11560 11561 boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS); 11562 11563 // Check if installing from ADB 11564 if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) { 11565 // Do not run verification in a test harness environment 11566 if (ActivityManager.isRunningInTestHarness()) { 11567 return false; 11568 } 11569 if (ensureVerifyAppsEnabled) { 11570 return true; 11571 } 11572 // Check if the developer does not want package verification for ADB installs 11573 if (android.provider.Settings.Global.getInt(mContext.getContentResolver(), 11574 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) { 11575 return false; 11576 } 11577 } 11578 11579 if (ensureVerifyAppsEnabled) { 11580 return true; 11581 } 11582 11583 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 11584 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1; 11585 } 11586 11587 @Override 11588 public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains) 11589 throws RemoteException { 11590 mContext.enforceCallingOrSelfPermission( 11591 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 11592 "Only intentfilter verification agents can verify applications"); 11593 11594 final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED); 11595 final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse( 11596 Binder.getCallingUid(), verificationCode, failedDomains); 11597 msg.arg1 = id; 11598 msg.obj = response; 11599 mHandler.sendMessage(msg); 11600 } 11601 11602 @Override 11603 public int getIntentVerificationStatus(String packageName, int userId) { 11604 synchronized (mPackages) { 11605 return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 11606 } 11607 } 11608 11609 @Override 11610 public boolean updateIntentVerificationStatus(String packageName, int status, int userId) { 11611 mContext.enforceCallingOrSelfPermission( 11612 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 11613 11614 boolean result = false; 11615 synchronized (mPackages) { 11616 result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId); 11617 } 11618 if (result) { 11619 scheduleWritePackageRestrictionsLocked(userId); 11620 } 11621 return result; 11622 } 11623 11624 @Override 11625 public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications( 11626 String packageName) { 11627 synchronized (mPackages) { 11628 return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName)); 11629 } 11630 } 11631 11632 @Override 11633 public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) { 11634 if (TextUtils.isEmpty(packageName)) { 11635 return ParceledListSlice.emptyList(); 11636 } 11637 synchronized (mPackages) { 11638 PackageParser.Package pkg = mPackages.get(packageName); 11639 if (pkg == null || pkg.activities == null) { 11640 return ParceledListSlice.emptyList(); 11641 } 11642 final int count = pkg.activities.size(); 11643 ArrayList<IntentFilter> result = new ArrayList<>(); 11644 for (int n=0; n<count; n++) { 11645 PackageParser.Activity activity = pkg.activities.get(n); 11646 if (activity.intents != null && activity.intents.size() > 0) { 11647 result.addAll(activity.intents); 11648 } 11649 } 11650 return new ParceledListSlice<>(result); 11651 } 11652 } 11653 11654 @Override 11655 public boolean setDefaultBrowserPackageName(String packageName, int userId) { 11656 mContext.enforceCallingOrSelfPermission( 11657 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 11658 11659 synchronized (mPackages) { 11660 boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId); 11661 if (packageName != null) { 11662 result |= updateIntentVerificationStatus(packageName, 11663 PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, 11664 userId); 11665 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr( 11666 packageName, userId); 11667 } 11668 return result; 11669 } 11670 } 11671 11672 @Override 11673 public String getDefaultBrowserPackageName(int userId) { 11674 synchronized (mPackages) { 11675 return mSettings.getDefaultBrowserPackageNameLPw(userId); 11676 } 11677 } 11678 11679 /** 11680 * Get the "allow unknown sources" setting. 11681 * 11682 * @return the current "allow unknown sources" setting 11683 */ 11684 private int getUnknownSourcesSettings() { 11685 return android.provider.Settings.Secure.getInt(mContext.getContentResolver(), 11686 android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS, 11687 -1); 11688 } 11689 11690 @Override 11691 public void setInstallerPackageName(String targetPackage, String installerPackageName) { 11692 final int uid = Binder.getCallingUid(); 11693 // writer 11694 synchronized (mPackages) { 11695 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage); 11696 if (targetPackageSetting == null) { 11697 throw new IllegalArgumentException("Unknown target package: " + targetPackage); 11698 } 11699 11700 PackageSetting installerPackageSetting; 11701 if (installerPackageName != null) { 11702 installerPackageSetting = mSettings.mPackages.get(installerPackageName); 11703 if (installerPackageSetting == null) { 11704 throw new IllegalArgumentException("Unknown installer package: " 11705 + installerPackageName); 11706 } 11707 } else { 11708 installerPackageSetting = null; 11709 } 11710 11711 Signature[] callerSignature; 11712 Object obj = mSettings.getUserIdLPr(uid); 11713 if (obj != null) { 11714 if (obj instanceof SharedUserSetting) { 11715 callerSignature = ((SharedUserSetting)obj).signatures.mSignatures; 11716 } else if (obj instanceof PackageSetting) { 11717 callerSignature = ((PackageSetting)obj).signatures.mSignatures; 11718 } else { 11719 throw new SecurityException("Bad object " + obj + " for uid " + uid); 11720 } 11721 } else { 11722 throw new SecurityException("Unknown calling UID: " + uid); 11723 } 11724 11725 // Verify: can't set installerPackageName to a package that is 11726 // not signed with the same cert as the caller. 11727 if (installerPackageSetting != null) { 11728 if (compareSignatures(callerSignature, 11729 installerPackageSetting.signatures.mSignatures) 11730 != PackageManager.SIGNATURE_MATCH) { 11731 throw new SecurityException( 11732 "Caller does not have same cert as new installer package " 11733 + installerPackageName); 11734 } 11735 } 11736 11737 // Verify: if target already has an installer package, it must 11738 // be signed with the same cert as the caller. 11739 if (targetPackageSetting.installerPackageName != null) { 11740 PackageSetting setting = mSettings.mPackages.get( 11741 targetPackageSetting.installerPackageName); 11742 // If the currently set package isn't valid, then it's always 11743 // okay to change it. 11744 if (setting != null) { 11745 if (compareSignatures(callerSignature, 11746 setting.signatures.mSignatures) 11747 != PackageManager.SIGNATURE_MATCH) { 11748 throw new SecurityException( 11749 "Caller does not have same cert as old installer package " 11750 + targetPackageSetting.installerPackageName); 11751 } 11752 } 11753 } 11754 11755 // Okay! 11756 targetPackageSetting.installerPackageName = installerPackageName; 11757 if (installerPackageName != null) { 11758 mSettings.mInstallerPackages.add(installerPackageName); 11759 } 11760 scheduleWriteSettingsLocked(); 11761 } 11762 } 11763 11764 private void processPendingInstall(final InstallArgs args, final int currentStatus) { 11765 // Queue up an async operation since the package installation may take a little while. 11766 mHandler.post(new Runnable() { 11767 public void run() { 11768 mHandler.removeCallbacks(this); 11769 // Result object to be returned 11770 PackageInstalledInfo res = new PackageInstalledInfo(); 11771 res.setReturnCode(currentStatus); 11772 res.uid = -1; 11773 res.pkg = null; 11774 res.removedInfo = null; 11775 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 11776 args.doPreInstall(res.returnCode); 11777 synchronized (mInstallLock) { 11778 installPackageTracedLI(args, res); 11779 } 11780 args.doPostInstall(res.returnCode, res.uid); 11781 } 11782 11783 // A restore should be performed at this point if (a) the install 11784 // succeeded, (b) the operation is not an update, and (c) the new 11785 // package has not opted out of backup participation. 11786 final boolean update = res.removedInfo != null 11787 && res.removedInfo.removedPackage != null; 11788 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags; 11789 boolean doRestore = !update 11790 && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0); 11791 11792 // Set up the post-install work request bookkeeping. This will be used 11793 // and cleaned up by the post-install event handling regardless of whether 11794 // there's a restore pass performed. Token values are >= 1. 11795 int token; 11796 if (mNextInstallToken < 0) mNextInstallToken = 1; 11797 token = mNextInstallToken++; 11798 11799 PostInstallData data = new PostInstallData(args, res); 11800 mRunningInstalls.put(token, data); 11801 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token); 11802 11803 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) { 11804 // Pass responsibility to the Backup Manager. It will perform a 11805 // restore if appropriate, then pass responsibility back to the 11806 // Package Manager to run the post-install observer callbacks 11807 // and broadcasts. 11808 IBackupManager bm = IBackupManager.Stub.asInterface( 11809 ServiceManager.getService(Context.BACKUP_SERVICE)); 11810 if (bm != null) { 11811 if (DEBUG_INSTALL) Log.v(TAG, "token " + token 11812 + " to BM for possible restore"); 11813 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token); 11814 try { 11815 // TODO: http://b/22388012 11816 if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) { 11817 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token); 11818 } else { 11819 doRestore = false; 11820 } 11821 } catch (RemoteException e) { 11822 // can't happen; the backup manager is local 11823 } catch (Exception e) { 11824 Slog.e(TAG, "Exception trying to enqueue restore", e); 11825 doRestore = false; 11826 } 11827 } else { 11828 Slog.e(TAG, "Backup Manager not found!"); 11829 doRestore = false; 11830 } 11831 } 11832 11833 if (!doRestore) { 11834 // No restore possible, or the Backup Manager was mysteriously not 11835 // available -- just fire the post-install work request directly. 11836 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token); 11837 11838 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token); 11839 11840 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 11841 mHandler.sendMessage(msg); 11842 } 11843 } 11844 }); 11845 } 11846 11847 private abstract class HandlerParams { 11848 private static final int MAX_RETRIES = 4; 11849 11850 /** 11851 * Number of times startCopy() has been attempted and had a non-fatal 11852 * error. 11853 */ 11854 private int mRetries = 0; 11855 11856 /** User handle for the user requesting the information or installation. */ 11857 private final UserHandle mUser; 11858 String traceMethod; 11859 int traceCookie; 11860 11861 HandlerParams(UserHandle user) { 11862 mUser = user; 11863 } 11864 11865 UserHandle getUser() { 11866 return mUser; 11867 } 11868 11869 HandlerParams setTraceMethod(String traceMethod) { 11870 this.traceMethod = traceMethod; 11871 return this; 11872 } 11873 11874 HandlerParams setTraceCookie(int traceCookie) { 11875 this.traceCookie = traceCookie; 11876 return this; 11877 } 11878 11879 final boolean startCopy() { 11880 boolean res; 11881 try { 11882 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this); 11883 11884 if (++mRetries > MAX_RETRIES) { 11885 Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up"); 11886 mHandler.sendEmptyMessage(MCS_GIVE_UP); 11887 handleServiceError(); 11888 return false; 11889 } else { 11890 handleStartCopy(); 11891 res = true; 11892 } 11893 } catch (RemoteException e) { 11894 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT"); 11895 mHandler.sendEmptyMessage(MCS_RECONNECT); 11896 res = false; 11897 } 11898 handleReturnCode(); 11899 return res; 11900 } 11901 11902 final void serviceError() { 11903 if (DEBUG_INSTALL) Slog.i(TAG, "serviceError"); 11904 handleServiceError(); 11905 handleReturnCode(); 11906 } 11907 11908 abstract void handleStartCopy() throws RemoteException; 11909 abstract void handleServiceError(); 11910 abstract void handleReturnCode(); 11911 } 11912 11913 class MeasureParams extends HandlerParams { 11914 private final PackageStats mStats; 11915 private boolean mSuccess; 11916 11917 private final IPackageStatsObserver mObserver; 11918 11919 public MeasureParams(PackageStats stats, IPackageStatsObserver observer) { 11920 super(new UserHandle(stats.userHandle)); 11921 mObserver = observer; 11922 mStats = stats; 11923 } 11924 11925 @Override 11926 public String toString() { 11927 return "MeasureParams{" 11928 + Integer.toHexString(System.identityHashCode(this)) 11929 + " " + mStats.packageName + "}"; 11930 } 11931 11932 @Override 11933 void handleStartCopy() throws RemoteException { 11934 synchronized (mInstallLock) { 11935 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats); 11936 } 11937 11938 if (mSuccess) { 11939 final boolean mounted; 11940 if (Environment.isExternalStorageEmulated()) { 11941 mounted = true; 11942 } else { 11943 final String status = Environment.getExternalStorageState(); 11944 mounted = (Environment.MEDIA_MOUNTED.equals(status) 11945 || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status)); 11946 } 11947 11948 if (mounted) { 11949 final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle); 11950 11951 mStats.externalCacheSize = calculateDirectorySize(mContainerService, 11952 userEnv.buildExternalStorageAppCacheDirs(mStats.packageName)); 11953 11954 mStats.externalDataSize = calculateDirectorySize(mContainerService, 11955 userEnv.buildExternalStorageAppDataDirs(mStats.packageName)); 11956 11957 // Always subtract cache size, since it's a subdirectory 11958 mStats.externalDataSize -= mStats.externalCacheSize; 11959 11960 mStats.externalMediaSize = calculateDirectorySize(mContainerService, 11961 userEnv.buildExternalStorageAppMediaDirs(mStats.packageName)); 11962 11963 mStats.externalObbSize = calculateDirectorySize(mContainerService, 11964 userEnv.buildExternalStorageAppObbDirs(mStats.packageName)); 11965 } 11966 } 11967 } 11968 11969 @Override 11970 void handleReturnCode() { 11971 if (mObserver != null) { 11972 try { 11973 mObserver.onGetStatsCompleted(mStats, mSuccess); 11974 } catch (RemoteException e) { 11975 Slog.i(TAG, "Observer no longer exists."); 11976 } 11977 } 11978 } 11979 11980 @Override 11981 void handleServiceError() { 11982 Slog.e(TAG, "Could not measure application " + mStats.packageName 11983 + " external storage"); 11984 } 11985 } 11986 11987 private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths) 11988 throws RemoteException { 11989 long result = 0; 11990 for (File path : paths) { 11991 result += mcs.calculateDirectorySize(path.getAbsolutePath()); 11992 } 11993 return result; 11994 } 11995 11996 private static void clearDirectory(IMediaContainerService mcs, File[] paths) { 11997 for (File path : paths) { 11998 try { 11999 mcs.clearDirectory(path.getAbsolutePath()); 12000 } catch (RemoteException e) { 12001 } 12002 } 12003 } 12004 12005 static class OriginInfo { 12006 /** 12007 * Location where install is coming from, before it has been 12008 * copied/renamed into place. This could be a single monolithic APK 12009 * file, or a cluster directory. This location may be untrusted. 12010 */ 12011 final File file; 12012 final String cid; 12013 12014 /** 12015 * Flag indicating that {@link #file} or {@link #cid} has already been 12016 * staged, meaning downstream users don't need to defensively copy the 12017 * contents. 12018 */ 12019 final boolean staged; 12020 12021 /** 12022 * Flag indicating that {@link #file} or {@link #cid} is an already 12023 * installed app that is being moved. 12024 */ 12025 final boolean existing; 12026 12027 final String resolvedPath; 12028 final File resolvedFile; 12029 12030 static OriginInfo fromNothing() { 12031 return new OriginInfo(null, null, false, false); 12032 } 12033 12034 static OriginInfo fromUntrustedFile(File file) { 12035 return new OriginInfo(file, null, false, false); 12036 } 12037 12038 static OriginInfo fromExistingFile(File file) { 12039 return new OriginInfo(file, null, false, true); 12040 } 12041 12042 static OriginInfo fromStagedFile(File file) { 12043 return new OriginInfo(file, null, true, false); 12044 } 12045 12046 static OriginInfo fromStagedContainer(String cid) { 12047 return new OriginInfo(null, cid, true, false); 12048 } 12049 12050 private OriginInfo(File file, String cid, boolean staged, boolean existing) { 12051 this.file = file; 12052 this.cid = cid; 12053 this.staged = staged; 12054 this.existing = existing; 12055 12056 if (cid != null) { 12057 resolvedPath = PackageHelper.getSdDir(cid); 12058 resolvedFile = new File(resolvedPath); 12059 } else if (file != null) { 12060 resolvedPath = file.getAbsolutePath(); 12061 resolvedFile = file; 12062 } else { 12063 resolvedPath = null; 12064 resolvedFile = null; 12065 } 12066 } 12067 } 12068 12069 static class MoveInfo { 12070 final int moveId; 12071 final String fromUuid; 12072 final String toUuid; 12073 final String packageName; 12074 final String dataAppName; 12075 final int appId; 12076 final String seinfo; 12077 final int targetSdkVersion; 12078 12079 public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName, 12080 String dataAppName, int appId, String seinfo, int targetSdkVersion) { 12081 this.moveId = moveId; 12082 this.fromUuid = fromUuid; 12083 this.toUuid = toUuid; 12084 this.packageName = packageName; 12085 this.dataAppName = dataAppName; 12086 this.appId = appId; 12087 this.seinfo = seinfo; 12088 this.targetSdkVersion = targetSdkVersion; 12089 } 12090 } 12091 12092 static class VerificationInfo { 12093 /** A constant used to indicate that a uid value is not present. */ 12094 public static final int NO_UID = -1; 12095 12096 /** URI referencing where the package was downloaded from. */ 12097 final Uri originatingUri; 12098 12099 /** HTTP referrer URI associated with the originatingURI. */ 12100 final Uri referrer; 12101 12102 /** UID of the application that the install request originated from. */ 12103 final int originatingUid; 12104 12105 /** UID of application requesting the install */ 12106 final int installerUid; 12107 12108 VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) { 12109 this.originatingUri = originatingUri; 12110 this.referrer = referrer; 12111 this.originatingUid = originatingUid; 12112 this.installerUid = installerUid; 12113 } 12114 } 12115 12116 class InstallParams extends HandlerParams { 12117 final OriginInfo origin; 12118 final MoveInfo move; 12119 final IPackageInstallObserver2 observer; 12120 int installFlags; 12121 final String installerPackageName; 12122 final String volumeUuid; 12123 private InstallArgs mArgs; 12124 private int mRet; 12125 final String packageAbiOverride; 12126 final String[] grantedRuntimePermissions; 12127 final VerificationInfo verificationInfo; 12128 final Certificate[][] certificates; 12129 12130 InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 12131 int installFlags, String installerPackageName, String volumeUuid, 12132 VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride, 12133 String[] grantedPermissions, Certificate[][] certificates) { 12134 super(user); 12135 this.origin = origin; 12136 this.move = move; 12137 this.observer = observer; 12138 this.installFlags = installFlags; 12139 this.installerPackageName = installerPackageName; 12140 this.volumeUuid = volumeUuid; 12141 this.verificationInfo = verificationInfo; 12142 this.packageAbiOverride = packageAbiOverride; 12143 this.grantedRuntimePermissions = grantedPermissions; 12144 this.certificates = certificates; 12145 } 12146 12147 @Override 12148 public String toString() { 12149 return "InstallParams{" + Integer.toHexString(System.identityHashCode(this)) 12150 + " file=" + origin.file + " cid=" + origin.cid + "}"; 12151 } 12152 12153 private int installLocationPolicy(PackageInfoLite pkgLite) { 12154 String packageName = pkgLite.packageName; 12155 int installLocation = pkgLite.installLocation; 12156 boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 12157 // reader 12158 synchronized (mPackages) { 12159 // Currently installed package which the new package is attempting to replace or 12160 // null if no such package is installed. 12161 PackageParser.Package installedPkg = mPackages.get(packageName); 12162 // Package which currently owns the data which the new package will own if installed. 12163 // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg 12164 // will be null whereas dataOwnerPkg will contain information about the package 12165 // which was uninstalled while keeping its data. 12166 PackageParser.Package dataOwnerPkg = installedPkg; 12167 if (dataOwnerPkg == null) { 12168 PackageSetting ps = mSettings.mPackages.get(packageName); 12169 if (ps != null) { 12170 dataOwnerPkg = ps.pkg; 12171 } 12172 } 12173 12174 if (dataOwnerPkg != null) { 12175 // If installed, the package will get access to data left on the device by its 12176 // predecessor. As a security measure, this is permited only if this is not a 12177 // version downgrade or if the predecessor package is marked as debuggable and 12178 // a downgrade is explicitly requested. 12179 // 12180 // On debuggable platform builds, downgrades are permitted even for 12181 // non-debuggable packages to make testing easier. Debuggable platform builds do 12182 // not offer security guarantees and thus it's OK to disable some security 12183 // mechanisms to make debugging/testing easier on those builds. However, even on 12184 // debuggable builds downgrades of packages are permitted only if requested via 12185 // installFlags. This is because we aim to keep the behavior of debuggable 12186 // platform builds as close as possible to the behavior of non-debuggable 12187 // platform builds. 12188 final boolean downgradeRequested = 12189 (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0; 12190 final boolean packageDebuggable = 12191 (dataOwnerPkg.applicationInfo.flags 12192 & ApplicationInfo.FLAG_DEBUGGABLE) != 0; 12193 final boolean downgradePermitted = 12194 (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable)); 12195 if (!downgradePermitted) { 12196 try { 12197 checkDowngrade(dataOwnerPkg, pkgLite); 12198 } catch (PackageManagerException e) { 12199 Slog.w(TAG, "Downgrade detected: " + e.getMessage()); 12200 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE; 12201 } 12202 } 12203 } 12204 12205 if (installedPkg != null) { 12206 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 12207 // Check for updated system application. 12208 if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 12209 if (onSd) { 12210 Slog.w(TAG, "Cannot install update to system app on sdcard"); 12211 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION; 12212 } 12213 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 12214 } else { 12215 if (onSd) { 12216 // Install flag overrides everything. 12217 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 12218 } 12219 // If current upgrade specifies particular preference 12220 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) { 12221 // Application explicitly specified internal. 12222 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 12223 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) { 12224 // App explictly prefers external. Let policy decide 12225 } else { 12226 // Prefer previous location 12227 if (isExternal(installedPkg)) { 12228 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 12229 } 12230 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 12231 } 12232 } 12233 } else { 12234 // Invalid install. Return error code 12235 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS; 12236 } 12237 } 12238 } 12239 // All the special cases have been taken care of. 12240 // Return result based on recommended install location. 12241 if (onSd) { 12242 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 12243 } 12244 return pkgLite.recommendedInstallLocation; 12245 } 12246 12247 /* 12248 * Invoke remote method to get package information and install 12249 * location values. Override install location based on default 12250 * policy if needed and then create install arguments based 12251 * on the install location. 12252 */ 12253 public void handleStartCopy() throws RemoteException { 12254 int ret = PackageManager.INSTALL_SUCCEEDED; 12255 12256 // If we're already staged, we've firmly committed to an install location 12257 if (origin.staged) { 12258 if (origin.file != null) { 12259 installFlags |= PackageManager.INSTALL_INTERNAL; 12260 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 12261 } else if (origin.cid != null) { 12262 installFlags |= PackageManager.INSTALL_EXTERNAL; 12263 installFlags &= ~PackageManager.INSTALL_INTERNAL; 12264 } else { 12265 throw new IllegalStateException("Invalid stage location"); 12266 } 12267 } 12268 12269 final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 12270 final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0; 12271 final boolean ephemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; 12272 PackageInfoLite pkgLite = null; 12273 12274 if (onInt && onSd) { 12275 // Check if both bits are set. 12276 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external"); 12277 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 12278 } else if (onSd && ephemeral) { 12279 Slog.w(TAG, "Conflicting flags specified for installing ephemeral on external"); 12280 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 12281 } else { 12282 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags, 12283 packageAbiOverride); 12284 12285 if (DEBUG_EPHEMERAL && ephemeral) { 12286 Slog.v(TAG, "pkgLite for install: " + pkgLite); 12287 } 12288 12289 /* 12290 * If we have too little free space, try to free cache 12291 * before giving up. 12292 */ 12293 if (!origin.staged && pkgLite.recommendedInstallLocation 12294 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 12295 // TODO: focus freeing disk space on the target device 12296 final StorageManager storage = StorageManager.from(mContext); 12297 final long lowThreshold = storage.getStorageLowBytes( 12298 Environment.getDataDirectory()); 12299 12300 final long sizeBytes = mContainerService.calculateInstalledSize( 12301 origin.resolvedPath, isForwardLocked(), packageAbiOverride); 12302 12303 try { 12304 mInstaller.freeCache(null, sizeBytes + lowThreshold); 12305 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, 12306 installFlags, packageAbiOverride); 12307 } catch (InstallerException e) { 12308 Slog.w(TAG, "Failed to free cache", e); 12309 } 12310 12311 /* 12312 * The cache free must have deleted the file we 12313 * downloaded to install. 12314 * 12315 * TODO: fix the "freeCache" call to not delete 12316 * the file we care about. 12317 */ 12318 if (pkgLite.recommendedInstallLocation 12319 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 12320 pkgLite.recommendedInstallLocation 12321 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE; 12322 } 12323 } 12324 } 12325 12326 if (ret == PackageManager.INSTALL_SUCCEEDED) { 12327 int loc = pkgLite.recommendedInstallLocation; 12328 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) { 12329 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 12330 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) { 12331 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 12332 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 12333 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 12334 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) { 12335 ret = PackageManager.INSTALL_FAILED_INVALID_APK; 12336 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 12337 ret = PackageManager.INSTALL_FAILED_INVALID_URI; 12338 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) { 12339 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE; 12340 } else { 12341 // Override with defaults if needed. 12342 loc = installLocationPolicy(pkgLite); 12343 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) { 12344 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 12345 } else if (!onSd && !onInt) { 12346 // Override install location with flags 12347 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) { 12348 // Set the flag to install on external media. 12349 installFlags |= PackageManager.INSTALL_EXTERNAL; 12350 installFlags &= ~PackageManager.INSTALL_INTERNAL; 12351 } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) { 12352 if (DEBUG_EPHEMERAL) { 12353 Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag"); 12354 } 12355 installFlags |= PackageManager.INSTALL_EPHEMERAL; 12356 installFlags &= ~(PackageManager.INSTALL_EXTERNAL 12357 |PackageManager.INSTALL_INTERNAL); 12358 } else { 12359 // Make sure the flag for installing on external 12360 // media is unset 12361 installFlags |= PackageManager.INSTALL_INTERNAL; 12362 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 12363 } 12364 } 12365 } 12366 } 12367 12368 final InstallArgs args = createInstallArgs(this); 12369 mArgs = args; 12370 12371 if (ret == PackageManager.INSTALL_SUCCEEDED) { 12372 // TODO: http://b/22976637 12373 // Apps installed for "all" users use the device owner to verify the app 12374 UserHandle verifierUser = getUser(); 12375 if (verifierUser == UserHandle.ALL) { 12376 verifierUser = UserHandle.SYSTEM; 12377 } 12378 12379 /* 12380 * Determine if we have any installed package verifiers. If we 12381 * do, then we'll defer to them to verify the packages. 12382 */ 12383 final int requiredUid = mRequiredVerifierPackage == null ? -1 12384 : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 12385 verifierUser.getIdentifier()); 12386 if (!origin.existing && requiredUid != -1 12387 && isVerificationEnabled(verifierUser.getIdentifier(), installFlags)) { 12388 final Intent verification = new Intent( 12389 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 12390 verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 12391 verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)), 12392 PACKAGE_MIME_TYPE); 12393 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 12394 12395 // Query all live verifiers based on current user state 12396 final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification, 12397 PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier()); 12398 12399 if (DEBUG_VERIFY) { 12400 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent " 12401 + verification.toString() + " with " + pkgLite.verifiers.length 12402 + " optional verifiers"); 12403 } 12404 12405 final int verificationId = mPendingVerificationToken++; 12406 12407 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 12408 12409 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE, 12410 installerPackageName); 12411 12412 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, 12413 installFlags); 12414 12415 verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME, 12416 pkgLite.packageName); 12417 12418 verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE, 12419 pkgLite.versionCode); 12420 12421 if (verificationInfo != null) { 12422 if (verificationInfo.originatingUri != null) { 12423 verification.putExtra(Intent.EXTRA_ORIGINATING_URI, 12424 verificationInfo.originatingUri); 12425 } 12426 if (verificationInfo.referrer != null) { 12427 verification.putExtra(Intent.EXTRA_REFERRER, 12428 verificationInfo.referrer); 12429 } 12430 if (verificationInfo.originatingUid >= 0) { 12431 verification.putExtra(Intent.EXTRA_ORIGINATING_UID, 12432 verificationInfo.originatingUid); 12433 } 12434 if (verificationInfo.installerUid >= 0) { 12435 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID, 12436 verificationInfo.installerUid); 12437 } 12438 } 12439 12440 final PackageVerificationState verificationState = new PackageVerificationState( 12441 requiredUid, args); 12442 12443 mPendingVerification.append(verificationId, verificationState); 12444 12445 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite, 12446 receivers, verificationState); 12447 12448 /* 12449 * If any sufficient verifiers were listed in the package 12450 * manifest, attempt to ask them. 12451 */ 12452 if (sufficientVerifiers != null) { 12453 final int N = sufficientVerifiers.size(); 12454 if (N == 0) { 12455 Slog.i(TAG, "Additional verifiers required, but none installed."); 12456 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 12457 } else { 12458 for (int i = 0; i < N; i++) { 12459 final ComponentName verifierComponent = sufficientVerifiers.get(i); 12460 12461 final Intent sufficientIntent = new Intent(verification); 12462 sufficientIntent.setComponent(verifierComponent); 12463 mContext.sendBroadcastAsUser(sufficientIntent, verifierUser); 12464 } 12465 } 12466 } 12467 12468 final ComponentName requiredVerifierComponent = matchComponentForVerifier( 12469 mRequiredVerifierPackage, receivers); 12470 if (ret == PackageManager.INSTALL_SUCCEEDED 12471 && mRequiredVerifierPackage != null) { 12472 Trace.asyncTraceBegin( 12473 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 12474 /* 12475 * Send the intent to the required verification agent, 12476 * but only start the verification timeout after the 12477 * target BroadcastReceivers have run. 12478 */ 12479 verification.setComponent(requiredVerifierComponent); 12480 mContext.sendOrderedBroadcastAsUser(verification, verifierUser, 12481 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 12482 new BroadcastReceiver() { 12483 @Override 12484 public void onReceive(Context context, Intent intent) { 12485 final Message msg = mHandler 12486 .obtainMessage(CHECK_PENDING_VERIFICATION); 12487 msg.arg1 = verificationId; 12488 mHandler.sendMessageDelayed(msg, getVerificationTimeout()); 12489 } 12490 }, null, 0, null, null); 12491 12492 /* 12493 * We don't want the copy to proceed until verification 12494 * succeeds, so null out this field. 12495 */ 12496 mArgs = null; 12497 } 12498 } else { 12499 /* 12500 * No package verification is enabled, so immediately start 12501 * the remote call to initiate copy using temporary file. 12502 */ 12503 ret = args.copyApk(mContainerService, true); 12504 } 12505 } 12506 12507 mRet = ret; 12508 } 12509 12510 @Override 12511 void handleReturnCode() { 12512 // If mArgs is null, then MCS couldn't be reached. When it 12513 // reconnects, it will try again to install. At that point, this 12514 // will succeed. 12515 if (mArgs != null) { 12516 processPendingInstall(mArgs, mRet); 12517 } 12518 } 12519 12520 @Override 12521 void handleServiceError() { 12522 mArgs = createInstallArgs(this); 12523 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 12524 } 12525 12526 public boolean isForwardLocked() { 12527 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 12528 } 12529 } 12530 12531 /** 12532 * Used during creation of InstallArgs 12533 * 12534 * @param installFlags package installation flags 12535 * @return true if should be installed on external storage 12536 */ 12537 private static boolean installOnExternalAsec(int installFlags) { 12538 if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) { 12539 return false; 12540 } 12541 if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) { 12542 return true; 12543 } 12544 return false; 12545 } 12546 12547 /** 12548 * Used during creation of InstallArgs 12549 * 12550 * @param installFlags package installation flags 12551 * @return true if should be installed as forward locked 12552 */ 12553 private static boolean installForwardLocked(int installFlags) { 12554 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 12555 } 12556 12557 private InstallArgs createInstallArgs(InstallParams params) { 12558 if (params.move != null) { 12559 return new MoveInstallArgs(params); 12560 } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) { 12561 return new AsecInstallArgs(params); 12562 } else { 12563 return new FileInstallArgs(params); 12564 } 12565 } 12566 12567 /** 12568 * Create args that describe an existing installed package. Typically used 12569 * when cleaning up old installs, or used as a move source. 12570 */ 12571 private InstallArgs createInstallArgsForExisting(int installFlags, String codePath, 12572 String resourcePath, String[] instructionSets) { 12573 final boolean isInAsec; 12574 if (installOnExternalAsec(installFlags)) { 12575 /* Apps on SD card are always in ASEC containers. */ 12576 isInAsec = true; 12577 } else if (installForwardLocked(installFlags) 12578 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) { 12579 /* 12580 * Forward-locked apps are only in ASEC containers if they're the 12581 * new style 12582 */ 12583 isInAsec = true; 12584 } else { 12585 isInAsec = false; 12586 } 12587 12588 if (isInAsec) { 12589 return new AsecInstallArgs(codePath, instructionSets, 12590 installOnExternalAsec(installFlags), installForwardLocked(installFlags)); 12591 } else { 12592 return new FileInstallArgs(codePath, resourcePath, instructionSets); 12593 } 12594 } 12595 12596 static abstract class InstallArgs { 12597 /** @see InstallParams#origin */ 12598 final OriginInfo origin; 12599 /** @see InstallParams#move */ 12600 final MoveInfo move; 12601 12602 final IPackageInstallObserver2 observer; 12603 // Always refers to PackageManager flags only 12604 final int installFlags; 12605 final String installerPackageName; 12606 final String volumeUuid; 12607 final UserHandle user; 12608 final String abiOverride; 12609 final String[] installGrantPermissions; 12610 /** If non-null, drop an async trace when the install completes */ 12611 final String traceMethod; 12612 final int traceCookie; 12613 final Certificate[][] certificates; 12614 12615 // The list of instruction sets supported by this app. This is currently 12616 // only used during the rmdex() phase to clean up resources. We can get rid of this 12617 // if we move dex files under the common app path. 12618 /* nullable */ String[] instructionSets; 12619 12620 InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 12621 int installFlags, String installerPackageName, String volumeUuid, 12622 UserHandle user, String[] instructionSets, 12623 String abiOverride, String[] installGrantPermissions, 12624 String traceMethod, int traceCookie, Certificate[][] certificates) { 12625 this.origin = origin; 12626 this.move = move; 12627 this.installFlags = installFlags; 12628 this.observer = observer; 12629 this.installerPackageName = installerPackageName; 12630 this.volumeUuid = volumeUuid; 12631 this.user = user; 12632 this.instructionSets = instructionSets; 12633 this.abiOverride = abiOverride; 12634 this.installGrantPermissions = installGrantPermissions; 12635 this.traceMethod = traceMethod; 12636 this.traceCookie = traceCookie; 12637 this.certificates = certificates; 12638 } 12639 12640 abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException; 12641 abstract int doPreInstall(int status); 12642 12643 /** 12644 * Rename package into final resting place. All paths on the given 12645 * scanned package should be updated to reflect the rename. 12646 */ 12647 abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath); 12648 abstract int doPostInstall(int status, int uid); 12649 12650 /** @see PackageSettingBase#codePathString */ 12651 abstract String getCodePath(); 12652 /** @see PackageSettingBase#resourcePathString */ 12653 abstract String getResourcePath(); 12654 12655 // Need installer lock especially for dex file removal. 12656 abstract void cleanUpResourcesLI(); 12657 abstract boolean doPostDeleteLI(boolean delete); 12658 12659 /** 12660 * Called before the source arguments are copied. This is used mostly 12661 * for MoveParams when it needs to read the source file to put it in the 12662 * destination. 12663 */ 12664 int doPreCopy() { 12665 return PackageManager.INSTALL_SUCCEEDED; 12666 } 12667 12668 /** 12669 * Called after the source arguments are copied. This is used mostly for 12670 * MoveParams when it needs to read the source file to put it in the 12671 * destination. 12672 */ 12673 int doPostCopy(int uid) { 12674 return PackageManager.INSTALL_SUCCEEDED; 12675 } 12676 12677 protected boolean isFwdLocked() { 12678 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 12679 } 12680 12681 protected boolean isExternalAsec() { 12682 return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 12683 } 12684 12685 protected boolean isEphemeral() { 12686 return (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; 12687 } 12688 12689 UserHandle getUser() { 12690 return user; 12691 } 12692 } 12693 12694 private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) { 12695 if (!allCodePaths.isEmpty()) { 12696 if (instructionSets == null) { 12697 throw new IllegalStateException("instructionSet == null"); 12698 } 12699 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); 12700 for (String codePath : allCodePaths) { 12701 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 12702 try { 12703 mInstaller.rmdex(codePath, dexCodeInstructionSet); 12704 } catch (InstallerException ignored) { 12705 } 12706 } 12707 } 12708 } 12709 } 12710 12711 /** 12712 * Logic to handle installation of non-ASEC applications, including copying 12713 * and renaming logic. 12714 */ 12715 class FileInstallArgs extends InstallArgs { 12716 private File codeFile; 12717 private File resourceFile; 12718 12719 // Example topology: 12720 // /data/app/com.example/base.apk 12721 // /data/app/com.example/split_foo.apk 12722 // /data/app/com.example/lib/arm/libfoo.so 12723 // /data/app/com.example/lib/arm64/libfoo.so 12724 // /data/app/com.example/dalvik/arm/base.apk@classes.dex 12725 12726 /** New install */ 12727 FileInstallArgs(InstallParams params) { 12728 super(params.origin, params.move, params.observer, params.installFlags, 12729 params.installerPackageName, params.volumeUuid, 12730 params.getUser(), null /*instructionSets*/, params.packageAbiOverride, 12731 params.grantedRuntimePermissions, 12732 params.traceMethod, params.traceCookie, params.certificates); 12733 if (isFwdLocked()) { 12734 throw new IllegalArgumentException("Forward locking only supported in ASEC"); 12735 } 12736 } 12737 12738 /** Existing install */ 12739 FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) { 12740 super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets, 12741 null, null, null, 0, null /*certificates*/); 12742 this.codeFile = (codePath != null) ? new File(codePath) : null; 12743 this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null; 12744 } 12745 12746 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 12747 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk"); 12748 try { 12749 return doCopyApk(imcs, temp); 12750 } finally { 12751 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 12752 } 12753 } 12754 12755 private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 12756 if (origin.staged) { 12757 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy"); 12758 codeFile = origin.file; 12759 resourceFile = origin.file; 12760 return PackageManager.INSTALL_SUCCEEDED; 12761 } 12762 12763 try { 12764 final boolean isEphemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; 12765 final File tempDir = 12766 mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral); 12767 codeFile = tempDir; 12768 resourceFile = tempDir; 12769 } catch (IOException e) { 12770 Slog.w(TAG, "Failed to create copy file: " + e); 12771 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 12772 } 12773 12774 final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() { 12775 @Override 12776 public ParcelFileDescriptor open(String name, int mode) throws RemoteException { 12777 if (!FileUtils.isValidExtFilename(name)) { 12778 throw new IllegalArgumentException("Invalid filename: " + name); 12779 } 12780 try { 12781 final File file = new File(codeFile, name); 12782 final FileDescriptor fd = Os.open(file.getAbsolutePath(), 12783 O_RDWR | O_CREAT, 0644); 12784 Os.chmod(file.getAbsolutePath(), 0644); 12785 return new ParcelFileDescriptor(fd); 12786 } catch (ErrnoException e) { 12787 throw new RemoteException("Failed to open: " + e.getMessage()); 12788 } 12789 } 12790 }; 12791 12792 int ret = PackageManager.INSTALL_SUCCEEDED; 12793 ret = imcs.copyPackage(origin.file.getAbsolutePath(), target); 12794 if (ret != PackageManager.INSTALL_SUCCEEDED) { 12795 Slog.e(TAG, "Failed to copy package"); 12796 return ret; 12797 } 12798 12799 final File libraryRoot = new File(codeFile, LIB_DIR_NAME); 12800 NativeLibraryHelper.Handle handle = null; 12801 try { 12802 handle = NativeLibraryHelper.Handle.create(codeFile); 12803 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot, 12804 abiOverride); 12805 } catch (IOException e) { 12806 Slog.e(TAG, "Copying native libraries failed", e); 12807 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 12808 } finally { 12809 IoUtils.closeQuietly(handle); 12810 } 12811 12812 return ret; 12813 } 12814 12815 int doPreInstall(int status) { 12816 if (status != PackageManager.INSTALL_SUCCEEDED) { 12817 cleanUp(); 12818 } 12819 return status; 12820 } 12821 12822 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 12823 if (status != PackageManager.INSTALL_SUCCEEDED) { 12824 cleanUp(); 12825 return false; 12826 } 12827 12828 final File targetDir = codeFile.getParentFile(); 12829 final File beforeCodeFile = codeFile; 12830 final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName); 12831 12832 if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile); 12833 try { 12834 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath()); 12835 } catch (ErrnoException e) { 12836 Slog.w(TAG, "Failed to rename", e); 12837 return false; 12838 } 12839 12840 if (!SELinux.restoreconRecursive(afterCodeFile)) { 12841 Slog.w(TAG, "Failed to restorecon"); 12842 return false; 12843 } 12844 12845 // Reflect the rename internally 12846 codeFile = afterCodeFile; 12847 resourceFile = afterCodeFile; 12848 12849 // Reflect the rename in scanned details 12850 pkg.setCodePath(afterCodeFile.getAbsolutePath()); 12851 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile, 12852 afterCodeFile, pkg.baseCodePath)); 12853 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile, 12854 afterCodeFile, pkg.splitCodePaths)); 12855 12856 // Reflect the rename in app info 12857 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 12858 pkg.setApplicationInfoCodePath(pkg.codePath); 12859 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 12860 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 12861 pkg.setApplicationInfoResourcePath(pkg.codePath); 12862 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 12863 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 12864 12865 return true; 12866 } 12867 12868 int doPostInstall(int status, int uid) { 12869 if (status != PackageManager.INSTALL_SUCCEEDED) { 12870 cleanUp(); 12871 } 12872 return status; 12873 } 12874 12875 @Override 12876 String getCodePath() { 12877 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 12878 } 12879 12880 @Override 12881 String getResourcePath() { 12882 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 12883 } 12884 12885 private boolean cleanUp() { 12886 if (codeFile == null || !codeFile.exists()) { 12887 return false; 12888 } 12889 12890 removeCodePathLI(codeFile); 12891 12892 if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) { 12893 resourceFile.delete(); 12894 } 12895 12896 return true; 12897 } 12898 12899 void cleanUpResourcesLI() { 12900 // Try enumerating all code paths before deleting 12901 List<String> allCodePaths = Collections.EMPTY_LIST; 12902 if (codeFile != null && codeFile.exists()) { 12903 try { 12904 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 12905 allCodePaths = pkg.getAllCodePaths(); 12906 } catch (PackageParserException e) { 12907 // Ignored; we tried our best 12908 } 12909 } 12910 12911 cleanUp(); 12912 removeDexFiles(allCodePaths, instructionSets); 12913 } 12914 12915 boolean doPostDeleteLI(boolean delete) { 12916 // XXX err, shouldn't we respect the delete flag? 12917 cleanUpResourcesLI(); 12918 return true; 12919 } 12920 } 12921 12922 private boolean isAsecExternal(String cid) { 12923 final String asecPath = PackageHelper.getSdFilesystem(cid); 12924 return !asecPath.startsWith(mAsecInternalPath); 12925 } 12926 12927 private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws 12928 PackageManagerException { 12929 if (copyRet < 0) { 12930 if (copyRet != PackageManager.NO_NATIVE_LIBRARIES && 12931 copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) { 12932 throw new PackageManagerException(copyRet, message); 12933 } 12934 } 12935 } 12936 12937 /** 12938 * Extract the MountService "container ID" from the full code path of an 12939 * .apk. 12940 */ 12941 static String cidFromCodePath(String fullCodePath) { 12942 int eidx = fullCodePath.lastIndexOf("/"); 12943 String subStr1 = fullCodePath.substring(0, eidx); 12944 int sidx = subStr1.lastIndexOf("/"); 12945 return subStr1.substring(sidx+1, eidx); 12946 } 12947 12948 /** 12949 * Logic to handle installation of ASEC applications, including copying and 12950 * renaming logic. 12951 */ 12952 class AsecInstallArgs extends InstallArgs { 12953 static final String RES_FILE_NAME = "pkg.apk"; 12954 static final String PUBLIC_RES_FILE_NAME = "res.zip"; 12955 12956 String cid; 12957 String packagePath; 12958 String resourcePath; 12959 12960 /** New install */ 12961 AsecInstallArgs(InstallParams params) { 12962 super(params.origin, params.move, params.observer, params.installFlags, 12963 params.installerPackageName, params.volumeUuid, 12964 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 12965 params.grantedRuntimePermissions, 12966 params.traceMethod, params.traceCookie, params.certificates); 12967 } 12968 12969 /** Existing install */ 12970 AsecInstallArgs(String fullCodePath, String[] instructionSets, 12971 boolean isExternal, boolean isForwardLocked) { 12972 super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0) 12973 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, 12974 instructionSets, null, null, null, 0, null /*certificates*/); 12975 // Hackily pretend we're still looking at a full code path 12976 if (!fullCodePath.endsWith(RES_FILE_NAME)) { 12977 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath(); 12978 } 12979 12980 // Extract cid from fullCodePath 12981 int eidx = fullCodePath.lastIndexOf("/"); 12982 String subStr1 = fullCodePath.substring(0, eidx); 12983 int sidx = subStr1.lastIndexOf("/"); 12984 cid = subStr1.substring(sidx+1, eidx); 12985 setMountPath(subStr1); 12986 } 12987 12988 AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) { 12989 super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0) 12990 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, 12991 instructionSets, null, null, null, 0, null /*certificates*/); 12992 this.cid = cid; 12993 setMountPath(PackageHelper.getSdDir(cid)); 12994 } 12995 12996 void createCopyFile() { 12997 cid = mInstallerService.allocateExternalStageCidLegacy(); 12998 } 12999 13000 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 13001 if (origin.staged && origin.cid != null) { 13002 if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy"); 13003 cid = origin.cid; 13004 setMountPath(PackageHelper.getSdDir(cid)); 13005 return PackageManager.INSTALL_SUCCEEDED; 13006 } 13007 13008 if (temp) { 13009 createCopyFile(); 13010 } else { 13011 /* 13012 * Pre-emptively destroy the container since it's destroyed if 13013 * copying fails due to it existing anyway. 13014 */ 13015 PackageHelper.destroySdDir(cid); 13016 } 13017 13018 final String newMountPath = imcs.copyPackageToContainer( 13019 origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(), 13020 isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */)); 13021 13022 if (newMountPath != null) { 13023 setMountPath(newMountPath); 13024 return PackageManager.INSTALL_SUCCEEDED; 13025 } else { 13026 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 13027 } 13028 } 13029 13030 @Override 13031 String getCodePath() { 13032 return packagePath; 13033 } 13034 13035 @Override 13036 String getResourcePath() { 13037 return resourcePath; 13038 } 13039 13040 int doPreInstall(int status) { 13041 if (status != PackageManager.INSTALL_SUCCEEDED) { 13042 // Destroy container 13043 PackageHelper.destroySdDir(cid); 13044 } else { 13045 boolean mounted = PackageHelper.isContainerMounted(cid); 13046 if (!mounted) { 13047 String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(), 13048 Process.SYSTEM_UID); 13049 if (newMountPath != null) { 13050 setMountPath(newMountPath); 13051 } else { 13052 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 13053 } 13054 } 13055 } 13056 return status; 13057 } 13058 13059 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 13060 String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME); 13061 String newMountPath = null; 13062 if (PackageHelper.isContainerMounted(cid)) { 13063 // Unmount the container 13064 if (!PackageHelper.unMountSdDir(cid)) { 13065 Slog.i(TAG, "Failed to unmount " + cid + " before renaming"); 13066 return false; 13067 } 13068 } 13069 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 13070 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId + 13071 " which might be stale. Will try to clean up."); 13072 // Clean up the stale container and proceed to recreate. 13073 if (!PackageHelper.destroySdDir(newCacheId)) { 13074 Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId); 13075 return false; 13076 } 13077 // Successfully cleaned up stale container. Try to rename again. 13078 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 13079 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId 13080 + " inspite of cleaning it up."); 13081 return false; 13082 } 13083 } 13084 if (!PackageHelper.isContainerMounted(newCacheId)) { 13085 Slog.w(TAG, "Mounting container " + newCacheId); 13086 newMountPath = PackageHelper.mountSdDir(newCacheId, 13087 getEncryptKey(), Process.SYSTEM_UID); 13088 } else { 13089 newMountPath = PackageHelper.getSdDir(newCacheId); 13090 } 13091 if (newMountPath == null) { 13092 Slog.w(TAG, "Failed to get cache path for " + newCacheId); 13093 return false; 13094 } 13095 Log.i(TAG, "Succesfully renamed " + cid + 13096 " to " + newCacheId + 13097 " at new path: " + newMountPath); 13098 cid = newCacheId; 13099 13100 final File beforeCodeFile = new File(packagePath); 13101 setMountPath(newMountPath); 13102 final File afterCodeFile = new File(packagePath); 13103 13104 // Reflect the rename in scanned details 13105 pkg.setCodePath(afterCodeFile.getAbsolutePath()); 13106 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile, 13107 afterCodeFile, pkg.baseCodePath)); 13108 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile, 13109 afterCodeFile, pkg.splitCodePaths)); 13110 13111 // Reflect the rename in app info 13112 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 13113 pkg.setApplicationInfoCodePath(pkg.codePath); 13114 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 13115 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 13116 pkg.setApplicationInfoResourcePath(pkg.codePath); 13117 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 13118 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 13119 13120 return true; 13121 } 13122 13123 private void setMountPath(String mountPath) { 13124 final File mountFile = new File(mountPath); 13125 13126 final File monolithicFile = new File(mountFile, RES_FILE_NAME); 13127 if (monolithicFile.exists()) { 13128 packagePath = monolithicFile.getAbsolutePath(); 13129 if (isFwdLocked()) { 13130 resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath(); 13131 } else { 13132 resourcePath = packagePath; 13133 } 13134 } else { 13135 packagePath = mountFile.getAbsolutePath(); 13136 resourcePath = packagePath; 13137 } 13138 } 13139 13140 int doPostInstall(int status, int uid) { 13141 if (status != PackageManager.INSTALL_SUCCEEDED) { 13142 cleanUp(); 13143 } else { 13144 final int groupOwner; 13145 final String protectedFile; 13146 if (isFwdLocked()) { 13147 groupOwner = UserHandle.getSharedAppGid(uid); 13148 protectedFile = RES_FILE_NAME; 13149 } else { 13150 groupOwner = -1; 13151 protectedFile = null; 13152 } 13153 13154 if (uid < Process.FIRST_APPLICATION_UID 13155 || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) { 13156 Slog.e(TAG, "Failed to finalize " + cid); 13157 PackageHelper.destroySdDir(cid); 13158 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 13159 } 13160 13161 boolean mounted = PackageHelper.isContainerMounted(cid); 13162 if (!mounted) { 13163 PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid()); 13164 } 13165 } 13166 return status; 13167 } 13168 13169 private void cleanUp() { 13170 if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp"); 13171 13172 // Destroy secure container 13173 PackageHelper.destroySdDir(cid); 13174 } 13175 13176 private List<String> getAllCodePaths() { 13177 final File codeFile = new File(getCodePath()); 13178 if (codeFile != null && codeFile.exists()) { 13179 try { 13180 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 13181 return pkg.getAllCodePaths(); 13182 } catch (PackageParserException e) { 13183 // Ignored; we tried our best 13184 } 13185 } 13186 return Collections.EMPTY_LIST; 13187 } 13188 13189 void cleanUpResourcesLI() { 13190 // Enumerate all code paths before deleting 13191 cleanUpResourcesLI(getAllCodePaths()); 13192 } 13193 13194 private void cleanUpResourcesLI(List<String> allCodePaths) { 13195 cleanUp(); 13196 removeDexFiles(allCodePaths, instructionSets); 13197 } 13198 13199 String getPackageName() { 13200 return getAsecPackageName(cid); 13201 } 13202 13203 boolean doPostDeleteLI(boolean delete) { 13204 if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete); 13205 final List<String> allCodePaths = getAllCodePaths(); 13206 boolean mounted = PackageHelper.isContainerMounted(cid); 13207 if (mounted) { 13208 // Unmount first 13209 if (PackageHelper.unMountSdDir(cid)) { 13210 mounted = false; 13211 } 13212 } 13213 if (!mounted && delete) { 13214 cleanUpResourcesLI(allCodePaths); 13215 } 13216 return !mounted; 13217 } 13218 13219 @Override 13220 int doPreCopy() { 13221 if (isFwdLocked()) { 13222 if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE, 13223 MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) { 13224 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 13225 } 13226 } 13227 13228 return PackageManager.INSTALL_SUCCEEDED; 13229 } 13230 13231 @Override 13232 int doPostCopy(int uid) { 13233 if (isFwdLocked()) { 13234 if (uid < Process.FIRST_APPLICATION_UID 13235 || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid), 13236 RES_FILE_NAME)) { 13237 Slog.e(TAG, "Failed to finalize " + cid); 13238 PackageHelper.destroySdDir(cid); 13239 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 13240 } 13241 } 13242 13243 return PackageManager.INSTALL_SUCCEEDED; 13244 } 13245 } 13246 13247 /** 13248 * Logic to handle movement of existing installed applications. 13249 */ 13250 class MoveInstallArgs extends InstallArgs { 13251 private File codeFile; 13252 private File resourceFile; 13253 13254 /** New install */ 13255 MoveInstallArgs(InstallParams params) { 13256 super(params.origin, params.move, params.observer, params.installFlags, 13257 params.installerPackageName, params.volumeUuid, 13258 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 13259 params.grantedRuntimePermissions, 13260 params.traceMethod, params.traceCookie, params.certificates); 13261 } 13262 13263 int copyApk(IMediaContainerService imcs, boolean temp) { 13264 if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from " 13265 + move.fromUuid + " to " + move.toUuid); 13266 synchronized (mInstaller) { 13267 try { 13268 mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName, 13269 move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion); 13270 } catch (InstallerException e) { 13271 Slog.w(TAG, "Failed to move app", e); 13272 return PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 13273 } 13274 } 13275 13276 codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName); 13277 resourceFile = codeFile; 13278 if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile); 13279 13280 return PackageManager.INSTALL_SUCCEEDED; 13281 } 13282 13283 int doPreInstall(int status) { 13284 if (status != PackageManager.INSTALL_SUCCEEDED) { 13285 cleanUp(move.toUuid); 13286 } 13287 return status; 13288 } 13289 13290 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 13291 if (status != PackageManager.INSTALL_SUCCEEDED) { 13292 cleanUp(move.toUuid); 13293 return false; 13294 } 13295 13296 // Reflect the move in app info 13297 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 13298 pkg.setApplicationInfoCodePath(pkg.codePath); 13299 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 13300 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 13301 pkg.setApplicationInfoResourcePath(pkg.codePath); 13302 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 13303 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 13304 13305 return true; 13306 } 13307 13308 int doPostInstall(int status, int uid) { 13309 if (status == PackageManager.INSTALL_SUCCEEDED) { 13310 cleanUp(move.fromUuid); 13311 } else { 13312 cleanUp(move.toUuid); 13313 } 13314 return status; 13315 } 13316 13317 @Override 13318 String getCodePath() { 13319 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 13320 } 13321 13322 @Override 13323 String getResourcePath() { 13324 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 13325 } 13326 13327 private boolean cleanUp(String volumeUuid) { 13328 final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid), 13329 move.dataAppName); 13330 Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid); 13331 synchronized (mInstallLock) { 13332 // Clean up both app data and code 13333 removeDataDirsLI(volumeUuid, move.packageName); 13334 removeCodePathLI(codeFile); 13335 } 13336 return true; 13337 } 13338 13339 void cleanUpResourcesLI() { 13340 throw new UnsupportedOperationException(); 13341 } 13342 13343 boolean doPostDeleteLI(boolean delete) { 13344 throw new UnsupportedOperationException(); 13345 } 13346 } 13347 13348 static String getAsecPackageName(String packageCid) { 13349 int idx = packageCid.lastIndexOf("-"); 13350 if (idx == -1) { 13351 return packageCid; 13352 } 13353 return packageCid.substring(0, idx); 13354 } 13355 13356 // Utility method used to create code paths based on package name and available index. 13357 private static String getNextCodePath(String oldCodePath, String prefix, String suffix) { 13358 String idxStr = ""; 13359 int idx = 1; 13360 // Fall back to default value of idx=1 if prefix is not 13361 // part of oldCodePath 13362 if (oldCodePath != null) { 13363 String subStr = oldCodePath; 13364 // Drop the suffix right away 13365 if (suffix != null && subStr.endsWith(suffix)) { 13366 subStr = subStr.substring(0, subStr.length() - suffix.length()); 13367 } 13368 // If oldCodePath already contains prefix find out the 13369 // ending index to either increment or decrement. 13370 int sidx = subStr.lastIndexOf(prefix); 13371 if (sidx != -1) { 13372 subStr = subStr.substring(sidx + prefix.length()); 13373 if (subStr != null) { 13374 if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) { 13375 subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length()); 13376 } 13377 try { 13378 idx = Integer.parseInt(subStr); 13379 if (idx <= 1) { 13380 idx++; 13381 } else { 13382 idx--; 13383 } 13384 } catch(NumberFormatException e) { 13385 } 13386 } 13387 } 13388 } 13389 idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx); 13390 return prefix + idxStr; 13391 } 13392 13393 private File getNextCodePath(File targetDir, String packageName) { 13394 int suffix = 1; 13395 File result; 13396 do { 13397 result = new File(targetDir, packageName + "-" + suffix); 13398 suffix++; 13399 } while (result.exists()); 13400 return result; 13401 } 13402 13403 // Utility method that returns the relative package path with respect 13404 // to the installation directory. Like say for /data/data/com.test-1.apk 13405 // string com.test-1 is returned. 13406 static String deriveCodePathName(String codePath) { 13407 if (codePath == null) { 13408 return null; 13409 } 13410 final File codeFile = new File(codePath); 13411 final String name = codeFile.getName(); 13412 if (codeFile.isDirectory()) { 13413 return name; 13414 } else if (name.endsWith(".apk") || name.endsWith(".tmp")) { 13415 final int lastDot = name.lastIndexOf('.'); 13416 return name.substring(0, lastDot); 13417 } else { 13418 Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK"); 13419 return null; 13420 } 13421 } 13422 13423 static class PackageInstalledInfo { 13424 String name; 13425 int uid; 13426 // The set of users that originally had this package installed. 13427 int[] origUsers; 13428 // The set of users that now have this package installed. 13429 int[] newUsers; 13430 PackageParser.Package pkg; 13431 int returnCode; 13432 String returnMsg; 13433 PackageRemovedInfo removedInfo; 13434 ArrayMap<String, PackageInstalledInfo> addedChildPackages; 13435 13436 public void setError(int code, String msg) { 13437 setReturnCode(code); 13438 setReturnMessage(msg); 13439 Slog.w(TAG, msg); 13440 } 13441 13442 public void setError(String msg, PackageParserException e) { 13443 setReturnCode(e.error); 13444 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e)); 13445 Slog.w(TAG, msg, e); 13446 } 13447 13448 public void setError(String msg, PackageManagerException e) { 13449 returnCode = e.error; 13450 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e)); 13451 Slog.w(TAG, msg, e); 13452 } 13453 13454 public void setReturnCode(int returnCode) { 13455 this.returnCode = returnCode; 13456 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0; 13457 for (int i = 0; i < childCount; i++) { 13458 addedChildPackages.valueAt(i).returnCode = returnCode; 13459 } 13460 } 13461 13462 private void setReturnMessage(String returnMsg) { 13463 this.returnMsg = returnMsg; 13464 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0; 13465 for (int i = 0; i < childCount; i++) { 13466 addedChildPackages.valueAt(i).returnMsg = returnMsg; 13467 } 13468 } 13469 13470 // In some error cases we want to convey more info back to the observer 13471 String origPackage; 13472 String origPermission; 13473 } 13474 13475 /* 13476 * Install a non-existing package. 13477 */ 13478 private void installNewPackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, 13479 UserHandle user, String installerPackageName, String volumeUuid, 13480 PackageInstalledInfo res) { 13481 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage"); 13482 13483 // Remember this for later, in case we need to rollback this install 13484 String pkgName = pkg.packageName; 13485 13486 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg); 13487 13488 synchronized(mPackages) { 13489 if (mSettings.mRenamedPackages.containsKey(pkgName)) { 13490 // A package with the same name is already installed, though 13491 // it has been renamed to an older name. The package we 13492 // are trying to install should be installed as an update to 13493 // the existing one, but that has not been requested, so bail. 13494 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 13495 + " without first uninstalling package running as " 13496 + mSettings.mRenamedPackages.get(pkgName)); 13497 return; 13498 } 13499 if (mPackages.containsKey(pkgName)) { 13500 // Don't allow installation over an existing package with the same name. 13501 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 13502 + " without first uninstalling."); 13503 return; 13504 } 13505 } 13506 13507 try { 13508 PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags, 13509 System.currentTimeMillis(), user); 13510 13511 updateSettingsLI(newPackage, installerPackageName, null, res, user); 13512 13513 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 13514 prepareAppDataAfterInstall(newPackage); 13515 13516 } else { 13517 // Remove package from internal structures, but keep around any 13518 // data that might have already existed 13519 deletePackageLI(pkgName, UserHandle.ALL, false, null, 13520 PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null); 13521 } 13522 } catch (PackageManagerException e) { 13523 res.setError("Package couldn't be installed in " + pkg.codePath, e); 13524 } 13525 13526 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13527 } 13528 13529 private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) { 13530 // Can't rotate keys during boot or if sharedUser. 13531 if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null 13532 || !oldPs.keySetData.isUsingUpgradeKeySets()) { 13533 return false; 13534 } 13535 // app is using upgradeKeySets; make sure all are valid 13536 KeySetManagerService ksms = mSettings.mKeySetManagerService; 13537 long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets(); 13538 for (int i = 0; i < upgradeKeySets.length; i++) { 13539 if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) { 13540 Slog.wtf(TAG, "Package " 13541 + (oldPs.name != null ? oldPs.name : "<null>") 13542 + " contains upgrade-key-set reference to unknown key-set: " 13543 + upgradeKeySets[i] 13544 + " reverting to signatures check."); 13545 return false; 13546 } 13547 } 13548 return true; 13549 } 13550 13551 private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) { 13552 // Upgrade keysets are being used. Determine if new package has a superset of the 13553 // required keys. 13554 long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets(); 13555 KeySetManagerService ksms = mSettings.mKeySetManagerService; 13556 for (int i = 0; i < upgradeKeySets.length; i++) { 13557 Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]); 13558 if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) { 13559 return true; 13560 } 13561 } 13562 return false; 13563 } 13564 13565 private void replacePackageLI(PackageParser.Package pkg, int parseFlags, int scanFlags, 13566 UserHandle user, String installerPackageName, PackageInstalledInfo res) { 13567 final boolean isEphemeral = (parseFlags & PackageParser.PARSE_IS_EPHEMERAL) != 0; 13568 13569 final PackageParser.Package oldPackage; 13570 final String pkgName = pkg.packageName; 13571 final int[] allUsers; 13572 final boolean weFroze; 13573 13574 // First find the old package info and check signatures 13575 synchronized(mPackages) { 13576 oldPackage = mPackages.get(pkgName); 13577 final boolean oldIsEphemeral = oldPackage.applicationInfo.isEphemeralApp(); 13578 if (isEphemeral && !oldIsEphemeral) { 13579 // can't downgrade from full to ephemeral 13580 Slog.w(TAG, "Can't replace app with ephemeral: " + pkgName); 13581 res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID); 13582 return; 13583 } 13584 if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage); 13585 final PackageSetting ps = mSettings.mPackages.get(pkgName); 13586 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { 13587 if (!checkUpgradeKeySetLP(ps, pkg)) { 13588 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 13589 "New package not signed by keys specified by upgrade-keysets: " 13590 + pkgName); 13591 return; 13592 } 13593 } else { 13594 // default to original signature matching 13595 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures) 13596 != PackageManager.SIGNATURE_MATCH) { 13597 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 13598 "New package has a different signature: " + pkgName); 13599 return; 13600 } 13601 } 13602 13603 // In case of rollback, remember per-user/profile install state 13604 allUsers = sUserManager.getUserIds(); 13605 13606 // Mark the app as frozen to prevent launching during the upgrade 13607 // process, and then kill all running instances 13608 if (!ps.frozen) { 13609 ps.frozen = true; 13610 weFroze = true; 13611 } else { 13612 weFroze = false; 13613 } 13614 } 13615 13616 try { 13617 replacePackageDirtyLI(pkg, oldPackage, parseFlags, scanFlags, user, allUsers, 13618 installerPackageName, res); 13619 } finally { 13620 // Regardless of success or failure of upgrade steps above, always 13621 // unfreeze the package if we froze it 13622 if (weFroze) { 13623 unfreezePackage(pkgName); 13624 } 13625 } 13626 } 13627 13628 private void replacePackageDirtyLI(PackageParser.Package pkg, PackageParser.Package oldPackage, 13629 int parseFlags, int scanFlags, UserHandle user, int[] allUsers, 13630 String installerPackageName, PackageInstalledInfo res) { 13631 // Update what is removed 13632 res.removedInfo = new PackageRemovedInfo(); 13633 res.removedInfo.uid = oldPackage.applicationInfo.uid; 13634 res.removedInfo.removedPackage = oldPackage.packageName; 13635 res.removedInfo.isUpdate = true; 13636 final int childCount = (oldPackage.childPackages != null) 13637 ? oldPackage.childPackages.size() : 0; 13638 for (int i = 0; i < childCount; i++) { 13639 boolean childPackageUpdated = false; 13640 PackageParser.Package childPkg = oldPackage.childPackages.get(i); 13641 if (res.addedChildPackages != null) { 13642 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName); 13643 if (childRes != null) { 13644 childRes.removedInfo.uid = childPkg.applicationInfo.uid; 13645 childRes.removedInfo.removedPackage = childPkg.packageName; 13646 childRes.removedInfo.isUpdate = true; 13647 childPackageUpdated = true; 13648 } 13649 } 13650 if (!childPackageUpdated) { 13651 PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(); 13652 childRemovedRes.removedPackage = childPkg.packageName; 13653 childRemovedRes.isUpdate = false; 13654 childRemovedRes.dataRemoved = true; 13655 synchronized (mPackages) { 13656 PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName); 13657 if (childPs != null) { 13658 childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true); 13659 } 13660 } 13661 if (res.removedInfo.removedChildPackages == null) { 13662 res.removedInfo.removedChildPackages = new ArrayMap<>(); 13663 } 13664 res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes); 13665 } 13666 } 13667 13668 boolean sysPkg = (isSystemApp(oldPackage)); 13669 if (sysPkg) { 13670 replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags, 13671 user, allUsers, installerPackageName, res); 13672 } else { 13673 replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanFlags, 13674 user, allUsers, installerPackageName, res); 13675 } 13676 } 13677 13678 public List<String> getPreviousCodePaths(String packageName) { 13679 final PackageSetting ps = mSettings.mPackages.get(packageName); 13680 final List<String> result = new ArrayList<String>(); 13681 if (ps != null && ps.oldCodePaths != null) { 13682 result.addAll(ps.oldCodePaths); 13683 } 13684 return result; 13685 } 13686 13687 private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage, 13688 PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, 13689 int[] allUsers, String installerPackageName, PackageInstalledInfo res) { 13690 if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old=" 13691 + deletedPackage); 13692 13693 String pkgName = deletedPackage.packageName; 13694 boolean deletedPkg = true; 13695 boolean addedPkg = false; 13696 boolean updatedSettings = false; 13697 final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0; 13698 final int deleteFlags = PackageManager.DELETE_KEEP_DATA 13699 | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP); 13700 13701 final long origUpdateTime = (pkg.mExtras != null) 13702 ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0; 13703 13704 // First delete the existing package while retaining the data directory 13705 if (!deletePackageLI(pkgName, null, true, allUsers, deleteFlags, 13706 res.removedInfo, true, pkg)) { 13707 // If the existing package wasn't successfully deleted 13708 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI"); 13709 deletedPkg = false; 13710 } else { 13711 // Successfully deleted the old package; proceed with replace. 13712 13713 // If deleted package lived in a container, give users a chance to 13714 // relinquish resources before killing. 13715 if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) { 13716 if (DEBUG_INSTALL) { 13717 Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE"); 13718 } 13719 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid }; 13720 final ArrayList<String> pkgList = new ArrayList<String>(1); 13721 pkgList.add(deletedPackage.applicationInfo.packageName); 13722 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null); 13723 } 13724 13725 deleteCodeCacheDirsLI(pkg); 13726 deleteProfilesLI(pkg, /*destroy*/ false); 13727 13728 try { 13729 final PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags, 13730 scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user); 13731 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user); 13732 13733 // Update the in-memory copy of the previous code paths. 13734 PackageSetting ps = mSettings.mPackages.get(pkgName); 13735 if (!killApp) { 13736 if (ps.oldCodePaths == null) { 13737 ps.oldCodePaths = new ArraySet<>(); 13738 } 13739 Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath); 13740 if (deletedPackage.splitCodePaths != null) { 13741 Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths); 13742 } 13743 } else { 13744 ps.oldCodePaths = null; 13745 } 13746 if (ps.childPackageNames != null) { 13747 for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) { 13748 final String childPkgName = ps.childPackageNames.get(i); 13749 final PackageSetting childPs = mSettings.mPackages.get(childPkgName); 13750 childPs.oldCodePaths = ps.oldCodePaths; 13751 } 13752 } 13753 prepareAppDataAfterInstall(newPackage); 13754 addedPkg = true; 13755 } catch (PackageManagerException e) { 13756 res.setError("Package couldn't be installed in " + pkg.codePath, e); 13757 } 13758 } 13759 13760 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 13761 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName); 13762 13763 // Revert all internal state mutations and added folders for the failed install 13764 if (addedPkg) { 13765 deletePackageLI(pkgName, null, true, allUsers, deleteFlags, 13766 res.removedInfo, true, null); 13767 } 13768 13769 // Restore the old package 13770 if (deletedPkg) { 13771 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage); 13772 File restoreFile = new File(deletedPackage.codePath); 13773 // Parse old package 13774 boolean oldExternal = isExternal(deletedPackage); 13775 int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY | 13776 (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) | 13777 (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0); 13778 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME; 13779 try { 13780 scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, 13781 null); 13782 } catch (PackageManagerException e) { 13783 Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: " 13784 + e.getMessage()); 13785 return; 13786 } 13787 13788 synchronized (mPackages) { 13789 // Ensure the installer package name up to date 13790 setInstallerPackageNameLPw(deletedPackage, installerPackageName); 13791 13792 // Update permissions for restored package 13793 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL); 13794 13795 mSettings.writeLPr(); 13796 } 13797 13798 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade"); 13799 } 13800 } else { 13801 synchronized (mPackages) { 13802 PackageSetting ps = mSettings.peekPackageLPr(pkg.packageName); 13803 if (ps != null) { 13804 res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null; 13805 if (res.removedInfo.removedChildPackages != null) { 13806 final int childCount = res.removedInfo.removedChildPackages.size(); 13807 // Iterate in reverse as we may modify the collection 13808 for (int i = childCount - 1; i >= 0; i--) { 13809 String childPackageName = res.removedInfo.removedChildPackages.keyAt(i); 13810 if (res.addedChildPackages.containsKey(childPackageName)) { 13811 res.removedInfo.removedChildPackages.removeAt(i); 13812 } else { 13813 PackageRemovedInfo childInfo = res.removedInfo 13814 .removedChildPackages.valueAt(i); 13815 childInfo.removedForAllUsers = mPackages.get( 13816 childInfo.removedPackage) == null; 13817 } 13818 } 13819 } 13820 } 13821 } 13822 } 13823 } 13824 13825 private void replaceSystemPackageLI(PackageParser.Package deletedPackage, 13826 PackageParser.Package pkg, int parseFlags, int scanFlags, UserHandle user, 13827 int[] allUsers, String installerPackageName, PackageInstalledInfo res) { 13828 if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg 13829 + ", old=" + deletedPackage); 13830 13831 final boolean disabledSystem; 13832 13833 // Set the system/privileged flags as needed 13834 parseFlags |= PackageParser.PARSE_IS_SYSTEM; 13835 if ((deletedPackage.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) 13836 != 0) { 13837 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 13838 } 13839 13840 // Kill package processes including services, providers, etc. 13841 killPackage(deletedPackage, "replace sys pkg"); 13842 13843 // Remove existing system package 13844 removePackageLI(deletedPackage, true); 13845 13846 disabledSystem = disableSystemPackageLPw(deletedPackage, pkg); 13847 if (!disabledSystem) { 13848 // We didn't need to disable the .apk as a current system package, 13849 // which means we are replacing another update that is already 13850 // installed. We need to make sure to delete the older one's .apk. 13851 res.removedInfo.args = createInstallArgsForExisting(0, 13852 deletedPackage.applicationInfo.getCodePath(), 13853 deletedPackage.applicationInfo.getResourcePath(), 13854 getAppDexInstructionSets(deletedPackage.applicationInfo)); 13855 } else { 13856 res.removedInfo.args = null; 13857 } 13858 13859 // Successfully disabled the old package. Now proceed with re-installation 13860 deleteCodeCacheDirsLI(pkg); 13861 deleteProfilesLI(pkg, /*destroy*/ false); 13862 13863 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 13864 pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP, 13865 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP); 13866 13867 PackageParser.Package newPackage = null; 13868 try { 13869 // Add the package to the internal data structures 13870 newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags, 0, user); 13871 13872 // Set the update and install times 13873 PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras; 13874 setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime, 13875 System.currentTimeMillis()); 13876 13877 // Check for shared user id changes 13878 String invalidPackageName = getParentOrChildPackageChangedSharedUser( 13879 deletedPackage, newPackage); 13880 if (invalidPackageName != null) { 13881 res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 13882 "Forbidding shared user change from " + deletedPkgSetting.sharedUser 13883 + " to " + invalidPackageName); 13884 } 13885 13886 // Update the package dynamic state if succeeded 13887 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 13888 // Now that the install succeeded make sure we remove data 13889 // directories for any child package the update removed. 13890 final int deletedChildCount = (deletedPackage.childPackages != null) 13891 ? deletedPackage.childPackages.size() : 0; 13892 final int newChildCount = (newPackage.childPackages != null) 13893 ? newPackage.childPackages.size() : 0; 13894 for (int i = 0; i < deletedChildCount; i++) { 13895 PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i); 13896 boolean childPackageDeleted = true; 13897 for (int j = 0; j < newChildCount; j++) { 13898 PackageParser.Package newChildPkg = newPackage.childPackages.get(j); 13899 if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) { 13900 childPackageDeleted = false; 13901 break; 13902 } 13903 } 13904 if (childPackageDeleted) { 13905 PackageSetting ps = mSettings.getDisabledSystemPkgLPr( 13906 deletedChildPkg.packageName); 13907 if (ps != null && res.removedInfo.removedChildPackages != null) { 13908 PackageRemovedInfo removedChildRes = res.removedInfo 13909 .removedChildPackages.get(deletedChildPkg.packageName); 13910 removePackageDataLI(ps, allUsers, removedChildRes, 0, false); 13911 removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null; 13912 } 13913 } 13914 } 13915 13916 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user); 13917 prepareAppDataAfterInstall(newPackage); 13918 } 13919 } catch (PackageManagerException e) { 13920 res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR); 13921 res.setError("Package couldn't be installed in " + pkg.codePath, e); 13922 } 13923 13924 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 13925 // Re installation failed. Restore old information 13926 // Remove new pkg information 13927 if (newPackage != null) { 13928 removeInstalledPackageLI(newPackage, true); 13929 } 13930 // Add back the old system package 13931 try { 13932 scanPackageTracedLI(deletedPackage, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user); 13933 } catch (PackageManagerException e) { 13934 Slog.e(TAG, "Failed to restore original package: " + e.getMessage()); 13935 } 13936 13937 synchronized (mPackages) { 13938 if (disabledSystem) { 13939 enableSystemPackageLPw(deletedPackage); 13940 } 13941 13942 // Ensure the installer package name up to date 13943 setInstallerPackageNameLPw(deletedPackage, installerPackageName); 13944 13945 // Update permissions for restored package 13946 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL); 13947 13948 mSettings.writeLPr(); 13949 } 13950 13951 Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName 13952 + " after failed upgrade"); 13953 } 13954 } 13955 13956 /** 13957 * Checks whether the parent or any of the child packages have a change shared 13958 * user. For a package to be a valid update the shred users of the parent and 13959 * the children should match. We may later support changing child shared users. 13960 * @param oldPkg The updated package. 13961 * @param newPkg The update package. 13962 * @return The shared user that change between the versions. 13963 */ 13964 private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg, 13965 PackageParser.Package newPkg) { 13966 // Check parent shared user 13967 if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) { 13968 return newPkg.packageName; 13969 } 13970 // Check child shared users 13971 final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0; 13972 final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0; 13973 for (int i = 0; i < newChildCount; i++) { 13974 PackageParser.Package newChildPkg = newPkg.childPackages.get(i); 13975 // If this child was present, did it have the same shared user? 13976 for (int j = 0; j < oldChildCount; j++) { 13977 PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j); 13978 if (newChildPkg.packageName.equals(oldChildPkg.packageName) 13979 && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) { 13980 return newChildPkg.packageName; 13981 } 13982 } 13983 } 13984 return null; 13985 } 13986 13987 private void removeNativeBinariesLI(PackageSetting ps) { 13988 // Remove the lib path for the parent package 13989 if (ps != null) { 13990 NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString); 13991 // Remove the lib path for the child packages 13992 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0; 13993 for (int i = 0; i < childCount; i++) { 13994 PackageSetting childPs = null; 13995 synchronized (mPackages) { 13996 childPs = mSettings.peekPackageLPr(ps.childPackageNames.get(i)); 13997 } 13998 if (childPs != null) { 13999 NativeLibraryHelper.removeNativeBinariesLI(childPs 14000 .legacyNativeLibraryPathString); 14001 } 14002 } 14003 } 14004 } 14005 14006 private void enableSystemPackageLPw(PackageParser.Package pkg) { 14007 // Enable the parent package 14008 mSettings.enableSystemPackageLPw(pkg.packageName); 14009 // Enable the child packages 14010 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 14011 for (int i = 0; i < childCount; i++) { 14012 PackageParser.Package childPkg = pkg.childPackages.get(i); 14013 mSettings.enableSystemPackageLPw(childPkg.packageName); 14014 } 14015 } 14016 14017 private boolean disableSystemPackageLPw(PackageParser.Package oldPkg, 14018 PackageParser.Package newPkg) { 14019 // Disable the parent package (parent always replaced) 14020 boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true); 14021 // Disable the child packages 14022 final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0; 14023 for (int i = 0; i < childCount; i++) { 14024 PackageParser.Package childPkg = oldPkg.childPackages.get(i); 14025 final boolean replace = newPkg.hasChildPackage(childPkg.packageName); 14026 disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace); 14027 } 14028 return disabled; 14029 } 14030 14031 private void setInstallerPackageNameLPw(PackageParser.Package pkg, 14032 String installerPackageName) { 14033 // Enable the parent package 14034 mSettings.setInstallerPackageName(pkg.packageName, installerPackageName); 14035 // Enable the child packages 14036 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 14037 for (int i = 0; i < childCount; i++) { 14038 PackageParser.Package childPkg = pkg.childPackages.get(i); 14039 mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName); 14040 } 14041 } 14042 14043 private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) { 14044 // Collect all used permissions in the UID 14045 ArraySet<String> usedPermissions = new ArraySet<>(); 14046 final int packageCount = su.packages.size(); 14047 for (int i = 0; i < packageCount; i++) { 14048 PackageSetting ps = su.packages.valueAt(i); 14049 if (ps.pkg == null) { 14050 continue; 14051 } 14052 final int requestedPermCount = ps.pkg.requestedPermissions.size(); 14053 for (int j = 0; j < requestedPermCount; j++) { 14054 String permission = ps.pkg.requestedPermissions.get(j); 14055 BasePermission bp = mSettings.mPermissions.get(permission); 14056 if (bp != null) { 14057 usedPermissions.add(permission); 14058 } 14059 } 14060 } 14061 14062 PermissionsState permissionsState = su.getPermissionsState(); 14063 // Prune install permissions 14064 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates(); 14065 final int installPermCount = installPermStates.size(); 14066 for (int i = installPermCount - 1; i >= 0; i--) { 14067 PermissionState permissionState = installPermStates.get(i); 14068 if (!usedPermissions.contains(permissionState.getName())) { 14069 BasePermission bp = mSettings.mPermissions.get(permissionState.getName()); 14070 if (bp != null) { 14071 permissionsState.revokeInstallPermission(bp); 14072 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 14073 PackageManager.MASK_PERMISSION_FLAGS, 0); 14074 } 14075 } 14076 } 14077 14078 int[] runtimePermissionChangedUserIds = EmptyArray.INT; 14079 14080 // Prune runtime permissions 14081 for (int userId : allUserIds) { 14082 List<PermissionState> runtimePermStates = permissionsState 14083 .getRuntimePermissionStates(userId); 14084 final int runtimePermCount = runtimePermStates.size(); 14085 for (int i = runtimePermCount - 1; i >= 0; i--) { 14086 PermissionState permissionState = runtimePermStates.get(i); 14087 if (!usedPermissions.contains(permissionState.getName())) { 14088 BasePermission bp = mSettings.mPermissions.get(permissionState.getName()); 14089 if (bp != null) { 14090 permissionsState.revokeRuntimePermission(bp, userId); 14091 permissionsState.updatePermissionFlags(bp, userId, 14092 PackageManager.MASK_PERMISSION_FLAGS, 0); 14093 runtimePermissionChangedUserIds = ArrayUtils.appendInt( 14094 runtimePermissionChangedUserIds, userId); 14095 } 14096 } 14097 } 14098 } 14099 14100 return runtimePermissionChangedUserIds; 14101 } 14102 14103 private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, 14104 int[] allUsers, PackageInstalledInfo res, UserHandle user) { 14105 // Update the parent package setting 14106 updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers, 14107 res, user); 14108 // Update the child packages setting 14109 final int childCount = (newPackage.childPackages != null) 14110 ? newPackage.childPackages.size() : 0; 14111 for (int i = 0; i < childCount; i++) { 14112 PackageParser.Package childPackage = newPackage.childPackages.get(i); 14113 PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName); 14114 updateSettingsInternalLI(childPackage, installerPackageName, allUsers, 14115 childRes.origUsers, childRes, user); 14116 } 14117 } 14118 14119 private void updateSettingsInternalLI(PackageParser.Package newPackage, 14120 String installerPackageName, int[] allUsers, int[] installedForUsers, 14121 PackageInstalledInfo res, UserHandle user) { 14122 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 14123 14124 String pkgName = newPackage.packageName; 14125 synchronized (mPackages) { 14126 //write settings. the installStatus will be incomplete at this stage. 14127 //note that the new package setting would have already been 14128 //added to mPackages. It hasn't been persisted yet. 14129 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE); 14130 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings"); 14131 mSettings.writeLPr(); 14132 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14133 } 14134 14135 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath); 14136 synchronized (mPackages) { 14137 updatePermissionsLPw(newPackage.packageName, newPackage, 14138 UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0 14139 ? UPDATE_PERMISSIONS_ALL : 0)); 14140 // For system-bundled packages, we assume that installing an upgraded version 14141 // of the package implies that the user actually wants to run that new code, 14142 // so we enable the package. 14143 PackageSetting ps = mSettings.mPackages.get(pkgName); 14144 final int userId = user.getIdentifier(); 14145 if (ps != null) { 14146 if (isSystemApp(newPackage)) { 14147 if (DEBUG_INSTALL) { 14148 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName); 14149 } 14150 // Enable system package for requested users 14151 if (res.origUsers != null) { 14152 for (int origUserId : res.origUsers) { 14153 if (userId == UserHandle.USER_ALL || userId == origUserId) { 14154 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 14155 origUserId, installerPackageName); 14156 } 14157 } 14158 } 14159 // Also convey the prior install/uninstall state 14160 if (allUsers != null && installedForUsers != null) { 14161 for (int currentUserId : allUsers) { 14162 final boolean installed = ArrayUtils.contains( 14163 installedForUsers, currentUserId); 14164 if (DEBUG_INSTALL) { 14165 Slog.d(TAG, " user " + currentUserId + " => " + installed); 14166 } 14167 ps.setInstalled(installed, currentUserId); 14168 } 14169 // these install state changes will be persisted in the 14170 // upcoming call to mSettings.writeLPr(). 14171 } 14172 } 14173 // It's implied that when a user requests installation, they want the app to be 14174 // installed and enabled. 14175 if (userId != UserHandle.USER_ALL) { 14176 ps.setInstalled(true, userId); 14177 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName); 14178 } 14179 } 14180 res.name = pkgName; 14181 res.uid = newPackage.applicationInfo.uid; 14182 res.pkg = newPackage; 14183 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE); 14184 mSettings.setInstallerPackageName(pkgName, installerPackageName); 14185 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 14186 //to update install status 14187 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings"); 14188 mSettings.writeLPr(); 14189 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14190 } 14191 14192 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14193 } 14194 14195 private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) { 14196 try { 14197 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage"); 14198 installPackageLI(args, res); 14199 } finally { 14200 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14201 } 14202 } 14203 14204 private void installPackageLI(InstallArgs args, PackageInstalledInfo res) { 14205 final int installFlags = args.installFlags; 14206 final String installerPackageName = args.installerPackageName; 14207 final String volumeUuid = args.volumeUuid; 14208 final File tmpPackageFile = new File(args.getCodePath()); 14209 final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0); 14210 final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) 14211 || (args.volumeUuid != null)); 14212 final boolean ephemeral = ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0); 14213 boolean replace = false; 14214 int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE; 14215 if (args.move != null) { 14216 // moving a complete application; perform an initial scan on the new install location 14217 scanFlags |= SCAN_INITIAL; 14218 } 14219 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) { 14220 scanFlags |= SCAN_DONT_KILL_APP; 14221 } 14222 14223 // Result object to be returned 14224 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 14225 14226 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile); 14227 14228 // Sanity check 14229 if (ephemeral && (forwardLocked || onExternal)) { 14230 Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked 14231 + " external=" + onExternal); 14232 res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID); 14233 return; 14234 } 14235 14236 // Retrieve PackageSettings and parse package 14237 final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY 14238 | PackageParser.PARSE_ENFORCE_CODE 14239 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) 14240 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0) 14241 | (ephemeral ? PackageParser.PARSE_IS_EPHEMERAL : 0); 14242 PackageParser pp = new PackageParser(); 14243 pp.setSeparateProcesses(mSeparateProcesses); 14244 pp.setDisplayMetrics(mMetrics); 14245 14246 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage"); 14247 final PackageParser.Package pkg; 14248 try { 14249 pkg = pp.parsePackage(tmpPackageFile, parseFlags); 14250 } catch (PackageParserException e) { 14251 res.setError("Failed parse during installPackageLI", e); 14252 return; 14253 } finally { 14254 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14255 } 14256 14257 // If we are installing a clustered package add results for the children 14258 if (pkg.childPackages != null) { 14259 synchronized (mPackages) { 14260 final int childCount = pkg.childPackages.size(); 14261 for (int i = 0; i < childCount; i++) { 14262 PackageParser.Package childPkg = pkg.childPackages.get(i); 14263 PackageInstalledInfo childRes = new PackageInstalledInfo(); 14264 childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 14265 childRes.pkg = childPkg; 14266 childRes.name = childPkg.packageName; 14267 PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName); 14268 if (childPs != null) { 14269 childRes.origUsers = childPs.queryInstalledUsers( 14270 sUserManager.getUserIds(), true); 14271 } 14272 if ((mPackages.containsKey(childPkg.packageName))) { 14273 childRes.removedInfo = new PackageRemovedInfo(); 14274 childRes.removedInfo.removedPackage = childPkg.packageName; 14275 } 14276 if (res.addedChildPackages == null) { 14277 res.addedChildPackages = new ArrayMap<>(); 14278 } 14279 res.addedChildPackages.put(childPkg.packageName, childRes); 14280 } 14281 } 14282 } 14283 14284 // If package doesn't declare API override, mark that we have an install 14285 // time CPU ABI override. 14286 if (TextUtils.isEmpty(pkg.cpuAbiOverride)) { 14287 pkg.cpuAbiOverride = args.abiOverride; 14288 } 14289 14290 String pkgName = res.name = pkg.packageName; 14291 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) { 14292 if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) { 14293 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI"); 14294 return; 14295 } 14296 } 14297 14298 try { 14299 // either use what we've been given or parse directly from the APK 14300 if (args.certificates != null) { 14301 try { 14302 PackageParser.populateCertificates(pkg, args.certificates); 14303 } catch (PackageParserException e) { 14304 // there was something wrong with the certificates we were given; 14305 // try to pull them from the APK 14306 PackageParser.collectCertificates(pkg, parseFlags); 14307 } 14308 } else { 14309 PackageParser.collectCertificates(pkg, parseFlags); 14310 } 14311 } catch (PackageParserException e) { 14312 res.setError("Failed collect during installPackageLI", e); 14313 return; 14314 } 14315 14316 // Get rid of all references to package scan path via parser. 14317 pp = null; 14318 String oldCodePath = null; 14319 boolean systemApp = false; 14320 synchronized (mPackages) { 14321 // Check if installing already existing package 14322 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 14323 String oldName = mSettings.mRenamedPackages.get(pkgName); 14324 if (pkg.mOriginalPackages != null 14325 && pkg.mOriginalPackages.contains(oldName) 14326 && mPackages.containsKey(oldName)) { 14327 // This package is derived from an original package, 14328 // and this device has been updating from that original 14329 // name. We must continue using the original name, so 14330 // rename the new package here. 14331 pkg.setPackageName(oldName); 14332 pkgName = pkg.packageName; 14333 replace = true; 14334 if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName=" 14335 + oldName + " pkgName=" + pkgName); 14336 } else if (mPackages.containsKey(pkgName)) { 14337 // This package, under its official name, already exists 14338 // on the device; we should replace it. 14339 replace = true; 14340 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName); 14341 } 14342 14343 // Child packages are installed through the parent package 14344 if (pkg.parentPackage != null) { 14345 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME, 14346 "Package " + pkg.packageName + " is child of package " 14347 + pkg.parentPackage.parentPackage + ". Child packages " 14348 + "can be updated only through the parent package."); 14349 return; 14350 } 14351 14352 if (replace) { 14353 // Prevent apps opting out from runtime permissions 14354 PackageParser.Package oldPackage = mPackages.get(pkgName); 14355 final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion; 14356 final int newTargetSdk = pkg.applicationInfo.targetSdkVersion; 14357 if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1 14358 && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) { 14359 res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE, 14360 "Package " + pkg.packageName + " new target SDK " + newTargetSdk 14361 + " doesn't support runtime permissions but the old" 14362 + " target SDK " + oldTargetSdk + " does."); 14363 return; 14364 } 14365 14366 // Prevent installing of child packages 14367 if (oldPackage.parentPackage != null) { 14368 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME, 14369 "Package " + pkg.packageName + " is child of package " 14370 + oldPackage.parentPackage + ". Child packages " 14371 + "can be updated only through the parent package."); 14372 return; 14373 } 14374 } 14375 } 14376 14377 PackageSetting ps = mSettings.mPackages.get(pkgName); 14378 if (ps != null) { 14379 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps); 14380 14381 // Quick sanity check that we're signed correctly if updating; 14382 // we'll check this again later when scanning, but we want to 14383 // bail early here before tripping over redefined permissions. 14384 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { 14385 if (!checkUpgradeKeySetLP(ps, pkg)) { 14386 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 14387 + pkg.packageName + " upgrade keys do not match the " 14388 + "previously installed version"); 14389 return; 14390 } 14391 } else { 14392 try { 14393 verifySignaturesLP(ps, pkg); 14394 } catch (PackageManagerException e) { 14395 res.setError(e.error, e.getMessage()); 14396 return; 14397 } 14398 } 14399 14400 oldCodePath = mSettings.mPackages.get(pkgName).codePathString; 14401 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 14402 systemApp = (ps.pkg.applicationInfo.flags & 14403 ApplicationInfo.FLAG_SYSTEM) != 0; 14404 } 14405 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 14406 } 14407 14408 // Check whether the newly-scanned package wants to define an already-defined perm 14409 int N = pkg.permissions.size(); 14410 for (int i = N-1; i >= 0; i--) { 14411 PackageParser.Permission perm = pkg.permissions.get(i); 14412 BasePermission bp = mSettings.mPermissions.get(perm.info.name); 14413 if (bp != null) { 14414 // If the defining package is signed with our cert, it's okay. This 14415 // also includes the "updating the same package" case, of course. 14416 // "updating same package" could also involve key-rotation. 14417 final boolean sigsOk; 14418 if (bp.sourcePackage.equals(pkg.packageName) 14419 && (bp.packageSetting instanceof PackageSetting) 14420 && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting, 14421 scanFlags))) { 14422 sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg); 14423 } else { 14424 sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures, 14425 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 14426 } 14427 if (!sigsOk) { 14428 // If the owning package is the system itself, we log but allow 14429 // install to proceed; we fail the install on all other permission 14430 // redefinitions. 14431 if (!bp.sourcePackage.equals("android")) { 14432 res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package " 14433 + pkg.packageName + " attempting to redeclare permission " 14434 + perm.info.name + " already owned by " + bp.sourcePackage); 14435 res.origPermission = perm.info.name; 14436 res.origPackage = bp.sourcePackage; 14437 return; 14438 } else { 14439 Slog.w(TAG, "Package " + pkg.packageName 14440 + " attempting to redeclare system permission " 14441 + perm.info.name + "; ignoring new declaration"); 14442 pkg.permissions.remove(i); 14443 } 14444 } 14445 } 14446 } 14447 } 14448 14449 if (systemApp) { 14450 if (onExternal) { 14451 // Abort update; system app can't be replaced with app on sdcard 14452 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION, 14453 "Cannot install updates to system apps on sdcard"); 14454 return; 14455 } else if (ephemeral) { 14456 // Abort update; system app can't be replaced with an ephemeral app 14457 res.setError(INSTALL_FAILED_EPHEMERAL_INVALID, 14458 "Cannot update a system app with an ephemeral app"); 14459 return; 14460 } 14461 } 14462 14463 if (args.move != null) { 14464 // We did an in-place move, so dex is ready to roll 14465 scanFlags |= SCAN_NO_DEX; 14466 scanFlags |= SCAN_MOVE; 14467 14468 synchronized (mPackages) { 14469 final PackageSetting ps = mSettings.mPackages.get(pkgName); 14470 if (ps == null) { 14471 res.setError(INSTALL_FAILED_INTERNAL_ERROR, 14472 "Missing settings for moved package " + pkgName); 14473 } 14474 14475 // We moved the entire application as-is, so bring over the 14476 // previously derived ABI information. 14477 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString; 14478 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString; 14479 } 14480 14481 } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) { 14482 // Enable SCAN_NO_DEX flag to skip dexopt at a later stage 14483 scanFlags |= SCAN_NO_DEX; 14484 14485 try { 14486 String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ? 14487 args.abiOverride : pkg.cpuAbiOverride); 14488 derivePackageAbi(pkg, new File(pkg.codePath), abiOverride, 14489 true /* extract libs */); 14490 } catch (PackageManagerException pme) { 14491 Slog.e(TAG, "Error deriving application ABI", pme); 14492 res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI"); 14493 return; 14494 } 14495 14496 14497 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 14498 // Do not run PackageDexOptimizer through the local performDexOpt 14499 // method because `pkg` is not in `mPackages` yet. 14500 int result = mPackageDexOptimizer.performDexOpt(pkg, null /* instructionSets */, 14501 false /* checkProfiles */, getCompilerFilterForReason(REASON_INSTALL)); 14502 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14503 if (result == PackageDexOptimizer.DEX_OPT_FAILED) { 14504 String msg = "Extracking package failed for " + pkgName; 14505 res.setError(INSTALL_FAILED_DEXOPT, msg); 14506 return; 14507 } 14508 } 14509 14510 if (!args.doRename(res.returnCode, pkg, oldCodePath)) { 14511 res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename"); 14512 return; 14513 } 14514 14515 startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg); 14516 14517 if (replace) { 14518 replacePackageLI(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user, 14519 installerPackageName, res); 14520 } else { 14521 installNewPackageLI(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES, 14522 args.user, installerPackageName, volumeUuid, res); 14523 } 14524 synchronized (mPackages) { 14525 final PackageSetting ps = mSettings.mPackages.get(pkgName); 14526 if (ps != null) { 14527 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 14528 } 14529 14530 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 14531 for (int i = 0; i < childCount; i++) { 14532 PackageParser.Package childPkg = pkg.childPackages.get(i); 14533 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName); 14534 PackageSetting childPs = mSettings.peekPackageLPr(childPkg.packageName); 14535 if (childPs != null) { 14536 childRes.newUsers = childPs.queryInstalledUsers( 14537 sUserManager.getUserIds(), true); 14538 } 14539 } 14540 } 14541 } 14542 14543 private void startIntentFilterVerifications(int userId, boolean replacing, 14544 PackageParser.Package pkg) { 14545 if (mIntentFilterVerifierComponent == null) { 14546 Slog.w(TAG, "No IntentFilter verification will not be done as " 14547 + "there is no IntentFilterVerifier available!"); 14548 return; 14549 } 14550 14551 final int verifierUid = getPackageUid( 14552 mIntentFilterVerifierComponent.getPackageName(), 14553 MATCH_DEBUG_TRIAGED_MISSING, 14554 (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId); 14555 14556 Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 14557 msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid); 14558 mHandler.sendMessage(msg); 14559 14560 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 14561 for (int i = 0; i < childCount; i++) { 14562 PackageParser.Package childPkg = pkg.childPackages.get(i); 14563 msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 14564 msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid); 14565 mHandler.sendMessage(msg); 14566 } 14567 } 14568 14569 private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing, 14570 PackageParser.Package pkg) { 14571 int size = pkg.activities.size(); 14572 if (size == 0) { 14573 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 14574 "No activity, so no need to verify any IntentFilter!"); 14575 return; 14576 } 14577 14578 final boolean hasDomainURLs = hasDomainURLs(pkg); 14579 if (!hasDomainURLs) { 14580 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 14581 "No domain URLs, so no need to verify any IntentFilter!"); 14582 return; 14583 } 14584 14585 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId 14586 + " if any IntentFilter from the " + size 14587 + " Activities needs verification ..."); 14588 14589 int count = 0; 14590 final String packageName = pkg.packageName; 14591 14592 synchronized (mPackages) { 14593 // If this is a new install and we see that we've already run verification for this 14594 // package, we have nothing to do: it means the state was restored from backup. 14595 if (!replacing) { 14596 IntentFilterVerificationInfo ivi = 14597 mSettings.getIntentFilterVerificationLPr(packageName); 14598 if (ivi != null) { 14599 if (DEBUG_DOMAIN_VERIFICATION) { 14600 Slog.i(TAG, "Package " + packageName+ " already verified: status=" 14601 + ivi.getStatusString()); 14602 } 14603 return; 14604 } 14605 } 14606 14607 // If any filters need to be verified, then all need to be. 14608 boolean needToVerify = false; 14609 for (PackageParser.Activity a : pkg.activities) { 14610 for (ActivityIntentInfo filter : a.intents) { 14611 if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) { 14612 if (DEBUG_DOMAIN_VERIFICATION) { 14613 Slog.d(TAG, "Intent filter needs verification, so processing all filters"); 14614 } 14615 needToVerify = true; 14616 break; 14617 } 14618 } 14619 } 14620 14621 if (needToVerify) { 14622 final int verificationId = mIntentFilterVerificationToken++; 14623 for (PackageParser.Activity a : pkg.activities) { 14624 for (ActivityIntentInfo filter : a.intents) { 14625 if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) { 14626 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 14627 "Verification needed for IntentFilter:" + filter.toString()); 14628 mIntentFilterVerifier.addOneIntentFilterVerification( 14629 verifierUid, userId, verificationId, filter, packageName); 14630 count++; 14631 } 14632 } 14633 } 14634 } 14635 } 14636 14637 if (count > 0) { 14638 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count 14639 + " IntentFilter verification" + (count > 1 ? "s" : "") 14640 + " for userId:" + userId); 14641 mIntentFilterVerifier.startVerifications(userId); 14642 } else { 14643 if (DEBUG_DOMAIN_VERIFICATION) { 14644 Slog.d(TAG, "No filters or not all autoVerify for " + packageName); 14645 } 14646 } 14647 } 14648 14649 private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) { 14650 final ComponentName cn = filter.activity.getComponentName(); 14651 final String packageName = cn.getPackageName(); 14652 14653 IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr( 14654 packageName); 14655 if (ivi == null) { 14656 return true; 14657 } 14658 int status = ivi.getStatus(); 14659 switch (status) { 14660 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 14661 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 14662 return true; 14663 14664 default: 14665 // Nothing to do 14666 return false; 14667 } 14668 } 14669 14670 private static boolean isMultiArch(ApplicationInfo info) { 14671 return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0; 14672 } 14673 14674 private static boolean isExternal(PackageParser.Package pkg) { 14675 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 14676 } 14677 14678 private static boolean isExternal(PackageSetting ps) { 14679 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 14680 } 14681 14682 private static boolean isEphemeral(PackageParser.Package pkg) { 14683 return pkg.applicationInfo.isEphemeralApp(); 14684 } 14685 14686 private static boolean isEphemeral(PackageSetting ps) { 14687 return ps.pkg != null && isEphemeral(ps.pkg); 14688 } 14689 14690 private static boolean isSystemApp(PackageParser.Package pkg) { 14691 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 14692 } 14693 14694 private static boolean isPrivilegedApp(PackageParser.Package pkg) { 14695 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; 14696 } 14697 14698 private static boolean hasDomainURLs(PackageParser.Package pkg) { 14699 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0; 14700 } 14701 14702 private static boolean isSystemApp(PackageSetting ps) { 14703 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0; 14704 } 14705 14706 private static boolean isUpdatedSystemApp(PackageSetting ps) { 14707 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; 14708 } 14709 14710 private int packageFlagsToInstallFlags(PackageSetting ps) { 14711 int installFlags = 0; 14712 if (isEphemeral(ps)) { 14713 installFlags |= PackageManager.INSTALL_EPHEMERAL; 14714 } 14715 if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) { 14716 // This existing package was an external ASEC install when we have 14717 // the external flag without a UUID 14718 installFlags |= PackageManager.INSTALL_EXTERNAL; 14719 } 14720 if (ps.isForwardLocked()) { 14721 installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 14722 } 14723 return installFlags; 14724 } 14725 14726 private String getVolumeUuidForPackage(PackageParser.Package pkg) { 14727 if (isExternal(pkg)) { 14728 if (TextUtils.isEmpty(pkg.volumeUuid)) { 14729 return StorageManager.UUID_PRIMARY_PHYSICAL; 14730 } else { 14731 return pkg.volumeUuid; 14732 } 14733 } else { 14734 return StorageManager.UUID_PRIVATE_INTERNAL; 14735 } 14736 } 14737 14738 private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) { 14739 if (isExternal(pkg)) { 14740 if (TextUtils.isEmpty(pkg.volumeUuid)) { 14741 return mSettings.getExternalVersion(); 14742 } else { 14743 return mSettings.findOrCreateVersion(pkg.volumeUuid); 14744 } 14745 } else { 14746 return mSettings.getInternalVersion(); 14747 } 14748 } 14749 14750 private void deleteTempPackageFiles() { 14751 final FilenameFilter filter = new FilenameFilter() { 14752 public boolean accept(File dir, String name) { 14753 return name.startsWith("vmdl") && name.endsWith(".tmp"); 14754 } 14755 }; 14756 for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) { 14757 file.delete(); 14758 } 14759 } 14760 14761 @Override 14762 public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId, 14763 int flags) { 14764 deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId, 14765 flags); 14766 } 14767 14768 @Override 14769 public void deletePackage(final String packageName, 14770 final IPackageDeleteObserver2 observer, final int userId, final int flags) { 14771 mContext.enforceCallingOrSelfPermission( 14772 android.Manifest.permission.DELETE_PACKAGES, null); 14773 Preconditions.checkNotNull(packageName); 14774 Preconditions.checkNotNull(observer); 14775 final int uid = Binder.getCallingUid(); 14776 final boolean deleteAllUsers = (flags & PackageManager.DELETE_ALL_USERS) != 0; 14777 final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId }; 14778 if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) { 14779 mContext.enforceCallingOrSelfPermission( 14780 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 14781 "deletePackage for user " + userId); 14782 } 14783 14784 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) { 14785 try { 14786 observer.onPackageDeleted(packageName, 14787 PackageManager.DELETE_FAILED_USER_RESTRICTED, null); 14788 } catch (RemoteException re) { 14789 } 14790 return; 14791 } 14792 14793 if (!deleteAllUsers && getBlockUninstallForUser(packageName, userId)) { 14794 try { 14795 observer.onPackageDeleted(packageName, 14796 PackageManager.DELETE_FAILED_OWNER_BLOCKED, null); 14797 } catch (RemoteException re) { 14798 } 14799 return; 14800 } 14801 14802 if (DEBUG_REMOVE) { 14803 Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId 14804 + " deleteAllUsers: " + deleteAllUsers ); 14805 } 14806 // Queue up an async operation since the package deletion may take a little while. 14807 mHandler.post(new Runnable() { 14808 public void run() { 14809 mHandler.removeCallbacks(this); 14810 int returnCode; 14811 if (!deleteAllUsers) { 14812 returnCode = deletePackageX(packageName, userId, flags); 14813 } else { 14814 int[] blockUninstallUserIds = getBlockUninstallForUsers(packageName, users); 14815 // If nobody is blocking uninstall, proceed with delete for all users 14816 if (ArrayUtils.isEmpty(blockUninstallUserIds)) { 14817 returnCode = deletePackageX(packageName, userId, flags); 14818 } else { 14819 // Otherwise uninstall individually for users with blockUninstalls=false 14820 final int userFlags = flags & ~PackageManager.DELETE_ALL_USERS; 14821 for (int userId : users) { 14822 if (!ArrayUtils.contains(blockUninstallUserIds, userId)) { 14823 returnCode = deletePackageX(packageName, userId, userFlags); 14824 if (returnCode != PackageManager.DELETE_SUCCEEDED) { 14825 Slog.w(TAG, "Package delete failed for user " + userId 14826 + ", returnCode " + returnCode); 14827 } 14828 } 14829 } 14830 // The app has only been marked uninstalled for certain users. 14831 // We still need to report that delete was blocked 14832 returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED; 14833 } 14834 } 14835 try { 14836 observer.onPackageDeleted(packageName, returnCode, null); 14837 } catch (RemoteException e) { 14838 Log.i(TAG, "Observer no longer exists."); 14839 } //end catch 14840 } //end run 14841 }); 14842 } 14843 14844 private int[] getBlockUninstallForUsers(String packageName, int[] userIds) { 14845 int[] result = EMPTY_INT_ARRAY; 14846 for (int userId : userIds) { 14847 if (getBlockUninstallForUser(packageName, userId)) { 14848 result = ArrayUtils.appendInt(result, userId); 14849 } 14850 } 14851 return result; 14852 } 14853 14854 @Override 14855 public boolean isPackageDeviceAdminOnAnyUser(String packageName) { 14856 return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL); 14857 } 14858 14859 private boolean isPackageDeviceAdmin(String packageName, int userId) { 14860 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface( 14861 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); 14862 try { 14863 if (dpm != null) { 14864 final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent( 14865 /* callingUserOnly =*/ false); 14866 final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null 14867 : deviceOwnerComponentName.getPackageName(); 14868 // Does the package contains the device owner? 14869 // TODO Do we have to do it even if userId != UserHandle.USER_ALL? Otherwise, 14870 // this check is probably not needed, since DO should be registered as a device 14871 // admin on some user too. (Original bug for this: b/17657954) 14872 if (packageName.equals(deviceOwnerPackageName)) { 14873 return true; 14874 } 14875 // Does it contain a device admin for any user? 14876 int[] users; 14877 if (userId == UserHandle.USER_ALL) { 14878 users = sUserManager.getUserIds(); 14879 } else { 14880 users = new int[]{userId}; 14881 } 14882 for (int i = 0; i < users.length; ++i) { 14883 if (dpm.packageHasActiveAdmins(packageName, users[i])) { 14884 return true; 14885 } 14886 } 14887 } 14888 } catch (RemoteException e) { 14889 } 14890 return false; 14891 } 14892 14893 private boolean shouldKeepUninstalledPackageLPr(String packageName) { 14894 return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName); 14895 } 14896 14897 /** 14898 * This method is an internal method that could be get invoked either 14899 * to delete an installed package or to clean up a failed installation. 14900 * After deleting an installed package, a broadcast is sent to notify any 14901 * listeners that the package has been removed. For cleaning up a failed 14902 * installation, the broadcast is not necessary since the package's 14903 * installation wouldn't have sent the initial broadcast either 14904 * The key steps in deleting a package are 14905 * deleting the package information in internal structures like mPackages, 14906 * deleting the packages base directories through installd 14907 * updating mSettings to reflect current status 14908 * persisting settings for later use 14909 * sending a broadcast if necessary 14910 */ 14911 private int deletePackageX(String packageName, int userId, int flags) { 14912 final PackageRemovedInfo info = new PackageRemovedInfo(); 14913 final boolean res; 14914 14915 final UserHandle removeForUser = (flags & PackageManager.DELETE_ALL_USERS) != 0 14916 ? UserHandle.ALL : new UserHandle(userId); 14917 14918 if (isPackageDeviceAdmin(packageName, removeForUser.getIdentifier())) { 14919 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin"); 14920 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER; 14921 } 14922 14923 PackageSetting uninstalledPs = null; 14924 14925 // for the uninstall-updates case and restricted profiles, remember the per- 14926 // user handle installed state 14927 int[] allUsers; 14928 synchronized (mPackages) { 14929 uninstalledPs = mSettings.mPackages.get(packageName); 14930 if (uninstalledPs == null) { 14931 Slog.w(TAG, "Not removing non-existent package " + packageName); 14932 return PackageManager.DELETE_FAILED_INTERNAL_ERROR; 14933 } 14934 allUsers = sUserManager.getUserIds(); 14935 info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true); 14936 } 14937 14938 synchronized (mInstallLock) { 14939 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId); 14940 res = deletePackageLI(packageName, removeForUser, true, allUsers, 14941 flags | REMOVE_CHATTY, info, true, null); 14942 synchronized (mPackages) { 14943 if (res) { 14944 mEphemeralApplicationRegistry.onPackageUninstalledLPw(uninstalledPs.pkg); 14945 } 14946 } 14947 } 14948 14949 if (res) { 14950 final boolean killApp = (flags & PackageManager.INSTALL_DONT_KILL_APP) == 0; 14951 info.sendPackageRemovedBroadcasts(killApp); 14952 info.sendSystemPackageUpdatedBroadcasts(); 14953 info.sendSystemPackageAppearedBroadcasts(); 14954 } 14955 // Force a gc here. 14956 Runtime.getRuntime().gc(); 14957 // Delete the resources here after sending the broadcast to let 14958 // other processes clean up before deleting resources. 14959 if (info.args != null) { 14960 synchronized (mInstallLock) { 14961 info.args.doPostDeleteLI(true); 14962 } 14963 } 14964 14965 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR; 14966 } 14967 14968 class PackageRemovedInfo { 14969 String removedPackage; 14970 int uid = -1; 14971 int removedAppId = -1; 14972 int[] origUsers; 14973 int[] removedUsers = null; 14974 boolean isRemovedPackageSystemUpdate = false; 14975 boolean isUpdate; 14976 boolean dataRemoved; 14977 boolean removedForAllUsers; 14978 // Clean up resources deleted packages. 14979 InstallArgs args = null; 14980 ArrayMap<String, PackageRemovedInfo> removedChildPackages; 14981 ArrayMap<String, PackageInstalledInfo> appearedChildPackages; 14982 14983 void sendPackageRemovedBroadcasts(boolean killApp) { 14984 sendPackageRemovedBroadcastInternal(killApp); 14985 final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0; 14986 for (int i = 0; i < childCount; i++) { 14987 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i); 14988 childInfo.sendPackageRemovedBroadcastInternal(killApp); 14989 } 14990 } 14991 14992 void sendSystemPackageUpdatedBroadcasts() { 14993 if (isRemovedPackageSystemUpdate) { 14994 sendSystemPackageUpdatedBroadcastsInternal(); 14995 final int childCount = (removedChildPackages != null) 14996 ? removedChildPackages.size() : 0; 14997 for (int i = 0; i < childCount; i++) { 14998 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i); 14999 if (childInfo.isRemovedPackageSystemUpdate) { 15000 childInfo.sendSystemPackageUpdatedBroadcastsInternal(); 15001 } 15002 } 15003 } 15004 } 15005 15006 void sendSystemPackageAppearedBroadcasts() { 15007 final int packageCount = (appearedChildPackages != null) 15008 ? appearedChildPackages.size() : 0; 15009 for (int i = 0; i < packageCount; i++) { 15010 PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i); 15011 for (int userId : installedInfo.newUsers) { 15012 sendPackageAddedForUser(installedInfo.name, true, 15013 UserHandle.getAppId(installedInfo.uid), userId); 15014 } 15015 } 15016 } 15017 15018 private void sendSystemPackageUpdatedBroadcastsInternal() { 15019 Bundle extras = new Bundle(2); 15020 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 15021 extras.putBoolean(Intent.EXTRA_REPLACING, true); 15022 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, removedPackage, 15023 extras, 0, null, null, null); 15024 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, removedPackage, 15025 extras, 0, null, null, null); 15026 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null, 15027 null, 0, removedPackage, null, null); 15028 } 15029 15030 private void sendPackageRemovedBroadcastInternal(boolean killApp) { 15031 Bundle extras = new Bundle(2); 15032 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 15033 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved); 15034 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp); 15035 if (isUpdate || isRemovedPackageSystemUpdate) { 15036 extras.putBoolean(Intent.EXTRA_REPLACING, true); 15037 } 15038 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers); 15039 if (removedPackage != null) { 15040 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, 15041 extras, 0, null, null, removedUsers); 15042 if (dataRemoved && !isRemovedPackageSystemUpdate) { 15043 sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, 15044 removedPackage, extras, 0, null, null, removedUsers); 15045 } 15046 } 15047 if (removedAppId >= 0) { 15048 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, 0, null, null, 15049 removedUsers); 15050 } 15051 } 15052 } 15053 15054 /* 15055 * This method deletes the package from internal data structures. If the DONT_DELETE_DATA 15056 * flag is not set, the data directory is removed as well. 15057 * make sure this flag is set for partially installed apps. If not its meaningless to 15058 * delete a partially installed application. 15059 */ 15060 private void removePackageDataLI(PackageSetting ps, int[] allUserHandles, 15061 PackageRemovedInfo outInfo, int flags, boolean writeSettings) { 15062 String packageName = ps.name; 15063 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps); 15064 removePackageLI(ps, (flags&REMOVE_CHATTY) != 0); 15065 // Retrieve object to delete permissions for shared user later on 15066 final PackageSetting deletedPs; 15067 // reader 15068 synchronized (mPackages) { 15069 deletedPs = mSettings.mPackages.get(packageName); 15070 if (outInfo != null) { 15071 outInfo.removedPackage = packageName; 15072 outInfo.removedUsers = deletedPs != null 15073 ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true) 15074 : null; 15075 } 15076 } 15077 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 15078 removeDataDirsLI(ps.volumeUuid, packageName); 15079 if (outInfo != null) { 15080 outInfo.dataRemoved = true; 15081 } 15082 schedulePackageCleaning(packageName, UserHandle.USER_ALL, true); 15083 } 15084 // writer 15085 synchronized (mPackages) { 15086 if (deletedPs != null) { 15087 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 15088 clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL); 15089 clearDefaultBrowserIfNeeded(packageName); 15090 if (outInfo != null) { 15091 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName); 15092 outInfo.removedAppId = mSettings.removePackageLPw(packageName); 15093 } 15094 updatePermissionsLPw(deletedPs.name, null, 0); 15095 if (deletedPs.sharedUser != null) { 15096 // Remove permissions associated with package. Since runtime 15097 // permissions are per user we have to kill the removed package 15098 // or packages running under the shared user of the removed 15099 // package if revoking the permissions requested only by the removed 15100 // package is successful and this causes a change in gids. 15101 for (int userId : UserManagerService.getInstance().getUserIds()) { 15102 final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs, 15103 userId); 15104 if (userIdToKill == UserHandle.USER_ALL 15105 || userIdToKill >= UserHandle.USER_SYSTEM) { 15106 // If gids changed for this user, kill all affected packages. 15107 mHandler.post(new Runnable() { 15108 @Override 15109 public void run() { 15110 // This has to happen with no lock held. 15111 killApplication(deletedPs.name, deletedPs.appId, 15112 KILL_APP_REASON_GIDS_CHANGED); 15113 } 15114 }); 15115 break; 15116 } 15117 } 15118 } 15119 clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL); 15120 } 15121 // make sure to preserve per-user disabled state if this removal was just 15122 // a downgrade of a system app to the factory package 15123 if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) { 15124 if (DEBUG_REMOVE) { 15125 Slog.d(TAG, "Propagating install state across downgrade"); 15126 } 15127 for (int userId : allUserHandles) { 15128 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId); 15129 if (DEBUG_REMOVE) { 15130 Slog.d(TAG, " user " + userId + " => " + installed); 15131 } 15132 ps.setInstalled(installed, userId); 15133 } 15134 } 15135 } 15136 // can downgrade to reader 15137 if (writeSettings) { 15138 // Save settings now 15139 mSettings.writeLPr(); 15140 } 15141 } 15142 if (outInfo != null) { 15143 // A user ID was deleted here. Go through all users and remove it 15144 // from KeyStore. 15145 removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId); 15146 } 15147 } 15148 15149 static boolean locationIsPrivileged(File path) { 15150 try { 15151 final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app") 15152 .getCanonicalPath(); 15153 return path.getCanonicalPath().startsWith(privilegedAppDir); 15154 } catch (IOException e) { 15155 Slog.e(TAG, "Unable to access code path " + path); 15156 } 15157 return false; 15158 } 15159 15160 /* 15161 * Tries to delete system package. 15162 */ 15163 private boolean deleteSystemPackageLI(PackageParser.Package deletedPkg, 15164 PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo, 15165 boolean writeSettings) { 15166 if (deletedPs.parentPackageName != null) { 15167 Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName); 15168 return false; 15169 } 15170 15171 final boolean applyUserRestrictions 15172 = (allUserHandles != null) && (outInfo.origUsers != null); 15173 final PackageSetting disabledPs; 15174 // Confirm if the system package has been updated 15175 // An updated system app can be deleted. This will also have to restore 15176 // the system pkg from system partition 15177 // reader 15178 synchronized (mPackages) { 15179 disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name); 15180 } 15181 15182 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName 15183 + " disabledPs=" + disabledPs); 15184 15185 if (disabledPs == null) { 15186 Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName); 15187 return false; 15188 } else if (DEBUG_REMOVE) { 15189 Slog.d(TAG, "Deleting system pkg from data partition"); 15190 } 15191 15192 if (DEBUG_REMOVE) { 15193 if (applyUserRestrictions) { 15194 Slog.d(TAG, "Remembering install states:"); 15195 for (int userId : allUserHandles) { 15196 final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId); 15197 Slog.d(TAG, " u=" + userId + " inst=" + finstalled); 15198 } 15199 } 15200 } 15201 15202 // Delete the updated package 15203 outInfo.isRemovedPackageSystemUpdate = true; 15204 if (outInfo.removedChildPackages != null) { 15205 final int childCount = (deletedPs.childPackageNames != null) 15206 ? deletedPs.childPackageNames.size() : 0; 15207 for (int i = 0; i < childCount; i++) { 15208 String childPackageName = deletedPs.childPackageNames.get(i); 15209 if (disabledPs.childPackageNames != null && disabledPs.childPackageNames 15210 .contains(childPackageName)) { 15211 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get( 15212 childPackageName); 15213 if (childInfo != null) { 15214 childInfo.isRemovedPackageSystemUpdate = true; 15215 } 15216 } 15217 } 15218 } 15219 15220 if (disabledPs.versionCode < deletedPs.versionCode) { 15221 // Delete data for downgrades 15222 flags &= ~PackageManager.DELETE_KEEP_DATA; 15223 } else { 15224 // Preserve data by setting flag 15225 flags |= PackageManager.DELETE_KEEP_DATA; 15226 } 15227 15228 boolean ret = deleteInstalledPackageLI(deletedPs, true, flags, allUserHandles, 15229 outInfo, writeSettings, disabledPs.pkg); 15230 if (!ret) { 15231 return false; 15232 } 15233 15234 // writer 15235 synchronized (mPackages) { 15236 // Reinstate the old system package 15237 enableSystemPackageLPw(disabledPs.pkg); 15238 // Remove any native libraries from the upgraded package. 15239 removeNativeBinariesLI(deletedPs); 15240 } 15241 15242 // Install the system package 15243 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs); 15244 int parseFlags = PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM; 15245 if (locationIsPrivileged(disabledPs.codePath)) { 15246 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 15247 } 15248 15249 final PackageParser.Package newPkg; 15250 try { 15251 newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null); 15252 } catch (PackageManagerException e) { 15253 Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": " 15254 + e.getMessage()); 15255 return false; 15256 } 15257 15258 prepareAppDataAfterInstall(newPkg); 15259 15260 // writer 15261 synchronized (mPackages) { 15262 PackageSetting ps = mSettings.mPackages.get(newPkg.packageName); 15263 15264 // Propagate the permissions state as we do not want to drop on the floor 15265 // runtime permissions. The update permissions method below will take 15266 // care of removing obsolete permissions and grant install permissions. 15267 ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState()); 15268 updatePermissionsLPw(newPkg.packageName, newPkg, 15269 UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG); 15270 15271 if (applyUserRestrictions) { 15272 if (DEBUG_REMOVE) { 15273 Slog.d(TAG, "Propagating install state across reinstall"); 15274 } 15275 for (int userId : allUserHandles) { 15276 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId); 15277 if (DEBUG_REMOVE) { 15278 Slog.d(TAG, " user " + userId + " => " + installed); 15279 } 15280 ps.setInstalled(installed, userId); 15281 15282 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 15283 } 15284 // Regardless of writeSettings we need to ensure that this restriction 15285 // state propagation is persisted 15286 mSettings.writeAllUsersPackageRestrictionsLPr(); 15287 } 15288 // can downgrade to reader here 15289 if (writeSettings) { 15290 mSettings.writeLPr(); 15291 } 15292 } 15293 return true; 15294 } 15295 15296 private boolean deleteInstalledPackageLI(PackageSetting ps, 15297 boolean deleteCodeAndResources, int flags, int[] allUserHandles, 15298 PackageRemovedInfo outInfo, boolean writeSettings, 15299 PackageParser.Package replacingPackage) { 15300 synchronized (mPackages) { 15301 if (outInfo != null) { 15302 outInfo.uid = ps.appId; 15303 } 15304 15305 if (outInfo != null && outInfo.removedChildPackages != null) { 15306 final int childCount = (ps.childPackageNames != null) 15307 ? ps.childPackageNames.size() : 0; 15308 for (int i = 0; i < childCount; i++) { 15309 String childPackageName = ps.childPackageNames.get(i); 15310 PackageSetting childPs = mSettings.mPackages.get(childPackageName); 15311 if (childPs == null) { 15312 return false; 15313 } 15314 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get( 15315 childPackageName); 15316 if (childInfo != null) { 15317 childInfo.uid = childPs.appId; 15318 } 15319 } 15320 } 15321 } 15322 15323 // Delete package data from internal structures and also remove data if flag is set 15324 removePackageDataLI(ps, allUserHandles, outInfo, flags, writeSettings); 15325 15326 // Delete the child packages data 15327 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0; 15328 for (int i = 0; i < childCount; i++) { 15329 PackageSetting childPs; 15330 synchronized (mPackages) { 15331 childPs = mSettings.peekPackageLPr(ps.childPackageNames.get(i)); 15332 } 15333 if (childPs != null) { 15334 PackageRemovedInfo childOutInfo = (outInfo != null 15335 && outInfo.removedChildPackages != null) 15336 ? outInfo.removedChildPackages.get(childPs.name) : null; 15337 final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0 15338 && (replacingPackage != null 15339 && !replacingPackage.hasChildPackage(childPs.name)) 15340 ? flags & ~DELETE_KEEP_DATA : flags; 15341 removePackageDataLI(childPs, allUserHandles, childOutInfo, 15342 deleteFlags, writeSettings); 15343 } 15344 } 15345 15346 // Delete application code and resources only for parent packages 15347 if (ps.parentPackageName == null) { 15348 if (deleteCodeAndResources && (outInfo != null)) { 15349 outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 15350 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 15351 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args); 15352 } 15353 } 15354 15355 return true; 15356 } 15357 15358 @Override 15359 public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall, 15360 int userId) { 15361 mContext.enforceCallingOrSelfPermission( 15362 android.Manifest.permission.DELETE_PACKAGES, null); 15363 synchronized (mPackages) { 15364 PackageSetting ps = mSettings.mPackages.get(packageName); 15365 if (ps == null) { 15366 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName); 15367 return false; 15368 } 15369 if (!ps.getInstalled(userId)) { 15370 // Can't block uninstall for an app that is not installed or enabled. 15371 Log.i(TAG, "Package not installed in set block uninstall " + packageName); 15372 return false; 15373 } 15374 ps.setBlockUninstall(blockUninstall, userId); 15375 mSettings.writePackageRestrictionsLPr(userId); 15376 } 15377 return true; 15378 } 15379 15380 @Override 15381 public boolean getBlockUninstallForUser(String packageName, int userId) { 15382 synchronized (mPackages) { 15383 PackageSetting ps = mSettings.mPackages.get(packageName); 15384 if (ps == null) { 15385 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName); 15386 return false; 15387 } 15388 return ps.getBlockUninstall(userId); 15389 } 15390 } 15391 15392 @Override 15393 public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) { 15394 int callingUid = Binder.getCallingUid(); 15395 if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) { 15396 throw new SecurityException( 15397 "setRequiredForSystemUser can only be run by the system or root"); 15398 } 15399 synchronized (mPackages) { 15400 PackageSetting ps = mSettings.mPackages.get(packageName); 15401 if (ps == null) { 15402 Log.w(TAG, "Package doesn't exist: " + packageName); 15403 return false; 15404 } 15405 if (systemUserApp) { 15406 ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER; 15407 } else { 15408 ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER; 15409 } 15410 mSettings.writeLPr(); 15411 } 15412 return true; 15413 } 15414 15415 /* 15416 * This method handles package deletion in general 15417 */ 15418 private boolean deletePackageLI(String packageName, UserHandle user, 15419 boolean deleteCodeAndResources, int[] allUserHandles, int flags, 15420 PackageRemovedInfo outInfo, boolean writeSettings, 15421 PackageParser.Package replacingPackage) { 15422 if (packageName == null) { 15423 Slog.w(TAG, "Attempt to delete null packageName."); 15424 return false; 15425 } 15426 15427 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user); 15428 15429 PackageSetting ps; 15430 15431 synchronized (mPackages) { 15432 ps = mSettings.mPackages.get(packageName); 15433 if (ps == null) { 15434 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 15435 return false; 15436 } 15437 15438 if (ps.parentPackageName != null && (!isSystemApp(ps) 15439 || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) { 15440 if (DEBUG_REMOVE) { 15441 Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:" 15442 + ((user == null) ? UserHandle.USER_ALL : user)); 15443 } 15444 final int removedUserId = (user != null) ? user.getIdentifier() 15445 : UserHandle.USER_ALL; 15446 if (!clearPackageStateForUser(ps, removedUserId, outInfo)) { 15447 return false; 15448 } 15449 markPackageUninstalledForUserLPw(ps, user); 15450 scheduleWritePackageRestrictionsLocked(user); 15451 return true; 15452 } 15453 } 15454 15455 if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null 15456 && user.getIdentifier() != UserHandle.USER_ALL)) { 15457 // The caller is asking that the package only be deleted for a single 15458 // user. To do this, we just mark its uninstalled state and delete 15459 // its data. If this is a system app, we only allow this to happen if 15460 // they have set the special DELETE_SYSTEM_APP which requests different 15461 // semantics than normal for uninstalling system apps. 15462 markPackageUninstalledForUserLPw(ps, user); 15463 15464 if (!isSystemApp(ps)) { 15465 // Do not uninstall the APK if an app should be cached 15466 boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName); 15467 if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) { 15468 // Other user still have this package installed, so all 15469 // we need to do is clear this user's data and save that 15470 // it is uninstalled. 15471 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users"); 15472 if (!clearPackageStateForUser(ps, user.getIdentifier(), outInfo)) { 15473 return false; 15474 } 15475 scheduleWritePackageRestrictionsLocked(user); 15476 return true; 15477 } else { 15478 // We need to set it back to 'installed' so the uninstall 15479 // broadcasts will be sent correctly. 15480 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete"); 15481 ps.setInstalled(true, user.getIdentifier()); 15482 } 15483 } else { 15484 // This is a system app, so we assume that the 15485 // other users still have this package installed, so all 15486 // we need to do is clear this user's data and save that 15487 // it is uninstalled. 15488 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app"); 15489 if (!clearPackageStateForUser(ps, user.getIdentifier(), outInfo)) { 15490 return false; 15491 } 15492 scheduleWritePackageRestrictionsLocked(user); 15493 return true; 15494 } 15495 } 15496 15497 // If we are deleting a composite package for all users, keep track 15498 // of result for each child. 15499 if (ps.childPackageNames != null && outInfo != null) { 15500 synchronized (mPackages) { 15501 final int childCount = ps.childPackageNames.size(); 15502 outInfo.removedChildPackages = new ArrayMap<>(childCount); 15503 for (int i = 0; i < childCount; i++) { 15504 String childPackageName = ps.childPackageNames.get(i); 15505 PackageRemovedInfo childInfo = new PackageRemovedInfo(); 15506 childInfo.removedPackage = childPackageName; 15507 outInfo.removedChildPackages.put(childPackageName, childInfo); 15508 PackageSetting childPs = mSettings.peekPackageLPr(childPackageName); 15509 if (childPs != null) { 15510 childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true); 15511 } 15512 } 15513 } 15514 } 15515 15516 boolean ret = false; 15517 if (isSystemApp(ps)) { 15518 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name); 15519 // When an updated system application is deleted we delete the existing resources 15520 // as well and fall back to existing code in system partition 15521 ret = deleteSystemPackageLI(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings); 15522 } else { 15523 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name); 15524 // Kill application pre-emptively especially for apps on sd. 15525 final boolean killApp = (flags & PackageManager.DELETE_DONT_KILL_APP) == 0; 15526 if (killApp) { 15527 killApplication(packageName, ps.appId, "uninstall pkg"); 15528 } 15529 ret = deleteInstalledPackageLI(ps, deleteCodeAndResources, flags, allUserHandles, 15530 outInfo, writeSettings, replacingPackage); 15531 } 15532 15533 // Take a note whether we deleted the package for all users 15534 if (outInfo != null) { 15535 outInfo.removedForAllUsers = mPackages.get(ps.name) == null; 15536 if (outInfo.removedChildPackages != null) { 15537 synchronized (mPackages) { 15538 final int childCount = outInfo.removedChildPackages.size(); 15539 for (int i = 0; i < childCount; i++) { 15540 PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i); 15541 if (childInfo != null) { 15542 childInfo.removedForAllUsers = mPackages.get( 15543 childInfo.removedPackage) == null; 15544 } 15545 } 15546 } 15547 } 15548 // If we uninstalled an update to a system app there may be some 15549 // child packages that appeared as they are declared in the system 15550 // app but were not declared in the update. 15551 if (isSystemApp(ps)) { 15552 synchronized (mPackages) { 15553 PackageSetting updatedPs = mSettings.peekPackageLPr(ps.name); 15554 final int childCount = (updatedPs.childPackageNames != null) 15555 ? updatedPs.childPackageNames.size() : 0; 15556 for (int i = 0; i < childCount; i++) { 15557 String childPackageName = updatedPs.childPackageNames.get(i); 15558 if (outInfo.removedChildPackages == null 15559 || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) { 15560 PackageSetting childPs = mSettings.peekPackageLPr(childPackageName); 15561 if (childPs == null) { 15562 continue; 15563 } 15564 PackageInstalledInfo installRes = new PackageInstalledInfo(); 15565 installRes.name = childPackageName; 15566 installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true); 15567 installRes.pkg = mPackages.get(childPackageName); 15568 installRes.uid = childPs.pkg.applicationInfo.uid; 15569 if (outInfo.appearedChildPackages == null) { 15570 outInfo.appearedChildPackages = new ArrayMap<>(); 15571 } 15572 outInfo.appearedChildPackages.put(childPackageName, installRes); 15573 } 15574 } 15575 } 15576 } 15577 } 15578 15579 return ret; 15580 } 15581 15582 private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) { 15583 final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL) 15584 ? sUserManager.getUserIds() : new int[] {user.getIdentifier()}; 15585 for (int nextUserId : userIds) { 15586 if (DEBUG_REMOVE) { 15587 Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId); 15588 } 15589 ps.setUserState(nextUserId, COMPONENT_ENABLED_STATE_DEFAULT, 15590 false /*installed*/, true /*stopped*/, true /*notLaunched*/, 15591 false /*hidden*/, false /*suspended*/, null, null, null, 15592 false /*blockUninstall*/, 15593 ps.readUserState(nextUserId).domainVerificationStatus, 0); 15594 } 15595 } 15596 15597 private boolean clearPackageStateForUser(PackageSetting ps, int userId, 15598 PackageRemovedInfo outInfo) { 15599 final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() 15600 : new int[] {userId}; 15601 for (int nextUserId : userIds) { 15602 if (DEBUG_REMOVE) { 15603 Slog.d(TAG, "Updating package:" + ps.name + " install state for user:" 15604 + nextUserId); 15605 } 15606 final int flags = StorageManager.FLAG_STORAGE_CE| StorageManager.FLAG_STORAGE_DE; 15607 try { 15608 mInstaller.destroyAppData(ps.volumeUuid, ps.name, nextUserId, flags); 15609 } catch (InstallerException e) { 15610 Slog.w(TAG, "Couldn't remove cache files for package " + ps.name, e); 15611 return false; 15612 } 15613 removeKeystoreDataIfNeeded(nextUserId, ps.appId); 15614 schedulePackageCleaning(ps.name, nextUserId, false); 15615 synchronized (mPackages) { 15616 if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) { 15617 scheduleWritePackageRestrictionsLocked(nextUserId); 15618 } 15619 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId); 15620 } 15621 } 15622 15623 if (outInfo != null) { 15624 outInfo.removedPackage = ps.name; 15625 outInfo.removedAppId = ps.appId; 15626 outInfo.removedUsers = userIds; 15627 } 15628 15629 return true; 15630 } 15631 15632 private final class ClearStorageConnection implements ServiceConnection { 15633 IMediaContainerService mContainerService; 15634 15635 @Override 15636 public void onServiceConnected(ComponentName name, IBinder service) { 15637 synchronized (this) { 15638 mContainerService = IMediaContainerService.Stub.asInterface(service); 15639 notifyAll(); 15640 } 15641 } 15642 15643 @Override 15644 public void onServiceDisconnected(ComponentName name) { 15645 } 15646 } 15647 15648 private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) { 15649 final boolean mounted; 15650 if (Environment.isExternalStorageEmulated()) { 15651 mounted = true; 15652 } else { 15653 final String status = Environment.getExternalStorageState(); 15654 15655 mounted = status.equals(Environment.MEDIA_MOUNTED) 15656 || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY); 15657 } 15658 15659 if (!mounted) { 15660 return; 15661 } 15662 15663 final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 15664 int[] users; 15665 if (userId == UserHandle.USER_ALL) { 15666 users = sUserManager.getUserIds(); 15667 } else { 15668 users = new int[] { userId }; 15669 } 15670 final ClearStorageConnection conn = new ClearStorageConnection(); 15671 if (mContext.bindServiceAsUser( 15672 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) { 15673 try { 15674 for (int curUser : users) { 15675 long timeout = SystemClock.uptimeMillis() + 5000; 15676 synchronized (conn) { 15677 long now = SystemClock.uptimeMillis(); 15678 while (conn.mContainerService == null && now < timeout) { 15679 try { 15680 conn.wait(timeout - now); 15681 } catch (InterruptedException e) { 15682 } 15683 } 15684 } 15685 if (conn.mContainerService == null) { 15686 return; 15687 } 15688 15689 final UserEnvironment userEnv = new UserEnvironment(curUser); 15690 clearDirectory(conn.mContainerService, 15691 userEnv.buildExternalStorageAppCacheDirs(packageName)); 15692 if (allData) { 15693 clearDirectory(conn.mContainerService, 15694 userEnv.buildExternalStorageAppDataDirs(packageName)); 15695 clearDirectory(conn.mContainerService, 15696 userEnv.buildExternalStorageAppMediaDirs(packageName)); 15697 } 15698 } 15699 } finally { 15700 mContext.unbindService(conn); 15701 } 15702 } 15703 } 15704 15705 @Override 15706 public void clearApplicationProfileData(String packageName) { 15707 enforceSystemOrRoot("Only the system can clear all profile data"); 15708 try { 15709 mInstaller.clearAppProfiles(packageName); 15710 } catch (InstallerException ex) { 15711 Log.e(TAG, "Could not clear profile data of package " + packageName); 15712 } 15713 } 15714 15715 @Override 15716 public void clearApplicationUserData(final String packageName, 15717 final IPackageDataObserver observer, final int userId) { 15718 mContext.enforceCallingOrSelfPermission( 15719 android.Manifest.permission.CLEAR_APP_USER_DATA, null); 15720 15721 enforceCrossUserPermission(Binder.getCallingUid(), userId, 15722 true /* requireFullPermission */, false /* checkShell */, "clear application data"); 15723 15724 final DevicePolicyManagerInternal dpmi = LocalServices 15725 .getService(DevicePolicyManagerInternal.class); 15726 if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) { 15727 throw new SecurityException("Cannot clear data for a device owner or a profile owner"); 15728 } 15729 // Queue up an async operation since the package deletion may take a little while. 15730 mHandler.post(new Runnable() { 15731 public void run() { 15732 mHandler.removeCallbacks(this); 15733 final boolean succeeded; 15734 synchronized (mInstallLock) { 15735 succeeded = clearApplicationUserDataLI(packageName, userId); 15736 } 15737 clearExternalStorageDataSync(packageName, userId, true); 15738 if (succeeded) { 15739 // invoke DeviceStorageMonitor's update method to clear any notifications 15740 DeviceStorageMonitorInternal dsm = LocalServices 15741 .getService(DeviceStorageMonitorInternal.class); 15742 if (dsm != null) { 15743 dsm.checkMemory(); 15744 } 15745 } 15746 if(observer != null) { 15747 try { 15748 observer.onRemoveCompleted(packageName, succeeded); 15749 } catch (RemoteException e) { 15750 Log.i(TAG, "Observer no longer exists."); 15751 } 15752 } //end if observer 15753 } //end run 15754 }); 15755 } 15756 15757 private boolean clearApplicationUserDataLI(String packageName, int userId) { 15758 if (packageName == null) { 15759 Slog.w(TAG, "Attempt to delete null packageName."); 15760 return false; 15761 } 15762 15763 // Try finding details about the requested package 15764 PackageParser.Package pkg; 15765 synchronized (mPackages) { 15766 pkg = mPackages.get(packageName); 15767 if (pkg == null) { 15768 final PackageSetting ps = mSettings.mPackages.get(packageName); 15769 if (ps != null) { 15770 pkg = ps.pkg; 15771 } 15772 } 15773 15774 if (pkg == null) { 15775 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 15776 return false; 15777 } 15778 15779 PackageSetting ps = (PackageSetting) pkg.mExtras; 15780 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 15781 } 15782 15783 // Always delete data directories for package, even if we found no other 15784 // record of app. This helps users recover from UID mismatches without 15785 // resorting to a full data wipe. 15786 // TODO: triage flags as part of 26466827 15787 final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE; 15788 try { 15789 mInstaller.clearAppData(pkg.volumeUuid, packageName, userId, flags); 15790 } catch (InstallerException e) { 15791 Slog.w(TAG, "Couldn't remove cache files for package " + packageName, e); 15792 return false; 15793 } 15794 15795 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); 15796 removeKeystoreDataIfNeeded(userId, appId); 15797 15798 // Create a native library symlink only if we have native libraries 15799 // and if the native libraries are 32 bit libraries. We do not provide 15800 // this symlink for 64 bit libraries. 15801 if (pkg.applicationInfo.primaryCpuAbi != null && 15802 !VMRuntime.is64BitAbi(pkg.applicationInfo.primaryCpuAbi)) { 15803 final String nativeLibPath = pkg.applicationInfo.nativeLibraryDir; 15804 try { 15805 mInstaller.linkNativeLibraryDirectory(pkg.volumeUuid, pkg.packageName, 15806 nativeLibPath, userId); 15807 } catch (InstallerException e) { 15808 Slog.w(TAG, "Failed linking native library dir", e); 15809 return false; 15810 } 15811 } 15812 15813 return true; 15814 } 15815 15816 /** 15817 * Reverts user permission state changes (permissions and flags) in 15818 * all packages for a given user. 15819 * 15820 * @param userId The device user for which to do a reset. 15821 */ 15822 private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) { 15823 final int packageCount = mPackages.size(); 15824 for (int i = 0; i < packageCount; i++) { 15825 PackageParser.Package pkg = mPackages.valueAt(i); 15826 PackageSetting ps = (PackageSetting) pkg.mExtras; 15827 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 15828 } 15829 } 15830 15831 /** 15832 * Reverts user permission state changes (permissions and flags). 15833 * 15834 * @param ps The package for which to reset. 15835 * @param userId The device user for which to do a reset. 15836 */ 15837 private void resetUserChangesToRuntimePermissionsAndFlagsLPw( 15838 final PackageSetting ps, final int userId) { 15839 if (ps.pkg == null) { 15840 return; 15841 } 15842 15843 // These are flags that can change base on user actions. 15844 final int userSettableMask = FLAG_PERMISSION_USER_SET 15845 | FLAG_PERMISSION_USER_FIXED 15846 | FLAG_PERMISSION_REVOKE_ON_UPGRADE 15847 | FLAG_PERMISSION_REVIEW_REQUIRED; 15848 15849 final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED 15850 | FLAG_PERMISSION_POLICY_FIXED; 15851 15852 boolean writeInstallPermissions = false; 15853 boolean writeRuntimePermissions = false; 15854 15855 final int permissionCount = ps.pkg.requestedPermissions.size(); 15856 for (int i = 0; i < permissionCount; i++) { 15857 String permission = ps.pkg.requestedPermissions.get(i); 15858 15859 BasePermission bp = mSettings.mPermissions.get(permission); 15860 if (bp == null) { 15861 continue; 15862 } 15863 15864 // If shared user we just reset the state to which only this app contributed. 15865 if (ps.sharedUser != null) { 15866 boolean used = false; 15867 final int packageCount = ps.sharedUser.packages.size(); 15868 for (int j = 0; j < packageCount; j++) { 15869 PackageSetting pkg = ps.sharedUser.packages.valueAt(j); 15870 if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName) 15871 && pkg.pkg.requestedPermissions.contains(permission)) { 15872 used = true; 15873 break; 15874 } 15875 } 15876 if (used) { 15877 continue; 15878 } 15879 } 15880 15881 PermissionsState permissionsState = ps.getPermissionsState(); 15882 15883 final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId); 15884 15885 // Always clear the user settable flags. 15886 final boolean hasInstallState = permissionsState.getInstallPermissionState( 15887 bp.name) != null; 15888 // If permission review is enabled and this is a legacy app, mark the 15889 // permission as requiring a review as this is the initial state. 15890 int flags = 0; 15891 if (Build.PERMISSIONS_REVIEW_REQUIRED 15892 && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 15893 flags |= FLAG_PERMISSION_REVIEW_REQUIRED; 15894 } 15895 if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) { 15896 if (hasInstallState) { 15897 writeInstallPermissions = true; 15898 } else { 15899 writeRuntimePermissions = true; 15900 } 15901 } 15902 15903 // Below is only runtime permission handling. 15904 if (!bp.isRuntime()) { 15905 continue; 15906 } 15907 15908 // Never clobber system or policy. 15909 if ((oldFlags & policyOrSystemFlags) != 0) { 15910 continue; 15911 } 15912 15913 // If this permission was granted by default, make sure it is. 15914 if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) { 15915 if (permissionsState.grantRuntimePermission(bp, userId) 15916 != PERMISSION_OPERATION_FAILURE) { 15917 writeRuntimePermissions = true; 15918 } 15919 // If permission review is enabled the permissions for a legacy apps 15920 // are represented as constantly granted runtime ones, so don't revoke. 15921 } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) { 15922 // Otherwise, reset the permission. 15923 final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId); 15924 switch (revokeResult) { 15925 case PERMISSION_OPERATION_SUCCESS: 15926 case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 15927 writeRuntimePermissions = true; 15928 final int appId = ps.appId; 15929 mHandler.post(new Runnable() { 15930 @Override 15931 public void run() { 15932 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED); 15933 } 15934 }); 15935 } break; 15936 } 15937 } 15938 } 15939 15940 // Synchronously write as we are taking permissions away. 15941 if (writeRuntimePermissions) { 15942 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 15943 } 15944 15945 // Synchronously write as we are taking permissions away. 15946 if (writeInstallPermissions) { 15947 mSettings.writeLPr(); 15948 } 15949 } 15950 15951 /** 15952 * Remove entries from the keystore daemon. Will only remove it if the 15953 * {@code appId} is valid. 15954 */ 15955 private static void removeKeystoreDataIfNeeded(int userId, int appId) { 15956 if (appId < 0) { 15957 return; 15958 } 15959 15960 final KeyStore keyStore = KeyStore.getInstance(); 15961 if (keyStore != null) { 15962 if (userId == UserHandle.USER_ALL) { 15963 for (final int individual : sUserManager.getUserIds()) { 15964 keyStore.clearUid(UserHandle.getUid(individual, appId)); 15965 } 15966 } else { 15967 keyStore.clearUid(UserHandle.getUid(userId, appId)); 15968 } 15969 } else { 15970 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId); 15971 } 15972 } 15973 15974 @Override 15975 public void deleteApplicationCacheFiles(final String packageName, 15976 final IPackageDataObserver observer) { 15977 mContext.enforceCallingOrSelfPermission( 15978 android.Manifest.permission.DELETE_CACHE_FILES, null); 15979 // Queue up an async operation since the package deletion may take a little while. 15980 final int userId = UserHandle.getCallingUserId(); 15981 mHandler.post(new Runnable() { 15982 public void run() { 15983 mHandler.removeCallbacks(this); 15984 final boolean succeded; 15985 synchronized (mInstallLock) { 15986 succeded = deleteApplicationCacheFilesLI(packageName, userId); 15987 } 15988 clearExternalStorageDataSync(packageName, userId, false); 15989 if (observer != null) { 15990 try { 15991 observer.onRemoveCompleted(packageName, succeded); 15992 } catch (RemoteException e) { 15993 Log.i(TAG, "Observer no longer exists."); 15994 } 15995 } //end if observer 15996 } //end run 15997 }); 15998 } 15999 16000 private boolean deleteApplicationCacheFilesLI(String packageName, int userId) { 16001 if (packageName == null) { 16002 Slog.w(TAG, "Attempt to delete null packageName."); 16003 return false; 16004 } 16005 PackageParser.Package p; 16006 synchronized (mPackages) { 16007 p = mPackages.get(packageName); 16008 } 16009 if (p == null) { 16010 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 16011 return false; 16012 } 16013 final ApplicationInfo applicationInfo = p.applicationInfo; 16014 if (applicationInfo == null) { 16015 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 16016 return false; 16017 } 16018 // TODO: triage flags as part of 26466827 16019 final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE; 16020 try { 16021 mInstaller.clearAppData(p.volumeUuid, packageName, userId, 16022 flags | Installer.FLAG_CLEAR_CACHE_ONLY); 16023 } catch (InstallerException e) { 16024 Slog.w(TAG, "Couldn't remove cache files for package " 16025 + packageName + " u" + userId, e); 16026 return false; 16027 } 16028 return true; 16029 } 16030 16031 @Override 16032 public void getPackageSizeInfo(final String packageName, int userHandle, 16033 final IPackageStatsObserver observer) { 16034 mContext.enforceCallingOrSelfPermission( 16035 android.Manifest.permission.GET_PACKAGE_SIZE, null); 16036 if (packageName == null) { 16037 throw new IllegalArgumentException("Attempt to get size of null packageName"); 16038 } 16039 16040 PackageStats stats = new PackageStats(packageName, userHandle); 16041 16042 /* 16043 * Queue up an async operation since the package measurement may take a 16044 * little while. 16045 */ 16046 Message msg = mHandler.obtainMessage(INIT_COPY); 16047 msg.obj = new MeasureParams(stats, observer); 16048 mHandler.sendMessage(msg); 16049 } 16050 16051 private boolean getPackageSizeInfoLI(String packageName, int userHandle, 16052 PackageStats pStats) { 16053 if (packageName == null) { 16054 Slog.w(TAG, "Attempt to get size of null packageName."); 16055 return false; 16056 } 16057 PackageParser.Package p; 16058 boolean dataOnly = false; 16059 String libDirRoot = null; 16060 String asecPath = null; 16061 PackageSetting ps = null; 16062 synchronized (mPackages) { 16063 p = mPackages.get(packageName); 16064 ps = mSettings.mPackages.get(packageName); 16065 if(p == null) { 16066 dataOnly = true; 16067 if((ps == null) || (ps.pkg == null)) { 16068 Slog.w(TAG, "Package named '" + packageName +"' doesn't exist."); 16069 return false; 16070 } 16071 p = ps.pkg; 16072 } 16073 if (ps != null) { 16074 libDirRoot = ps.legacyNativeLibraryPathString; 16075 } 16076 if (p != null && (p.isForwardLocked() || p.applicationInfo.isExternalAsec())) { 16077 final long token = Binder.clearCallingIdentity(); 16078 try { 16079 String secureContainerId = cidFromCodePath(p.applicationInfo.getBaseCodePath()); 16080 if (secureContainerId != null) { 16081 asecPath = PackageHelper.getSdFilesystem(secureContainerId); 16082 } 16083 } finally { 16084 Binder.restoreCallingIdentity(token); 16085 } 16086 } 16087 } 16088 String publicSrcDir = null; 16089 if(!dataOnly) { 16090 final ApplicationInfo applicationInfo = p.applicationInfo; 16091 if (applicationInfo == null) { 16092 Slog.w(TAG, "Package " + packageName + " has no applicationInfo."); 16093 return false; 16094 } 16095 if (p.isForwardLocked()) { 16096 publicSrcDir = applicationInfo.getBaseResourcePath(); 16097 } 16098 } 16099 // TODO: extend to measure size of split APKs 16100 // TODO(multiArch): Extend getSizeInfo to look at the full subdirectory tree, 16101 // not just the first level. 16102 // TODO(multiArch): Extend getSizeInfo to look at *all* instruction sets, not 16103 // just the primary. 16104 String[] dexCodeInstructionSets = getDexCodeInstructionSets(getAppDexInstructionSets(ps)); 16105 16106 String apkPath; 16107 File packageDir = new File(p.codePath); 16108 16109 if (packageDir.isDirectory() && p.canHaveOatDir()) { 16110 apkPath = packageDir.getAbsolutePath(); 16111 // If libDirRoot is inside a package dir, set it to null to avoid it being counted twice 16112 if (libDirRoot != null && libDirRoot.startsWith(apkPath)) { 16113 libDirRoot = null; 16114 } 16115 } else { 16116 apkPath = p.baseCodePath; 16117 } 16118 16119 // TODO: triage flags as part of 26466827 16120 final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE; 16121 try { 16122 mInstaller.getAppSize(p.volumeUuid, packageName, userHandle, flags, apkPath, 16123 libDirRoot, publicSrcDir, asecPath, dexCodeInstructionSets, pStats); 16124 } catch (InstallerException e) { 16125 return false; 16126 } 16127 16128 // Fix-up for forward-locked applications in ASEC containers. 16129 if (!isExternal(p)) { 16130 pStats.codeSize += pStats.externalCodeSize; 16131 pStats.externalCodeSize = 0L; 16132 } 16133 16134 return true; 16135 } 16136 16137 private int getUidTargetSdkVersionLockedLPr(int uid) { 16138 Object obj = mSettings.getUserIdLPr(uid); 16139 if (obj instanceof SharedUserSetting) { 16140 final SharedUserSetting sus = (SharedUserSetting) obj; 16141 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT; 16142 final Iterator<PackageSetting> it = sus.packages.iterator(); 16143 while (it.hasNext()) { 16144 final PackageSetting ps = it.next(); 16145 if (ps.pkg != null) { 16146 int v = ps.pkg.applicationInfo.targetSdkVersion; 16147 if (v < vers) vers = v; 16148 } 16149 } 16150 return vers; 16151 } else if (obj instanceof PackageSetting) { 16152 final PackageSetting ps = (PackageSetting) obj; 16153 if (ps.pkg != null) { 16154 return ps.pkg.applicationInfo.targetSdkVersion; 16155 } 16156 } 16157 return Build.VERSION_CODES.CUR_DEVELOPMENT; 16158 } 16159 16160 @Override 16161 public void addPreferredActivity(IntentFilter filter, int match, 16162 ComponentName[] set, ComponentName activity, int userId) { 16163 addPreferredActivityInternal(filter, match, set, activity, true, userId, 16164 "Adding preferred"); 16165 } 16166 16167 private void addPreferredActivityInternal(IntentFilter filter, int match, 16168 ComponentName[] set, ComponentName activity, boolean always, int userId, 16169 String opname) { 16170 // writer 16171 int callingUid = Binder.getCallingUid(); 16172 enforceCrossUserPermission(callingUid, userId, 16173 true /* requireFullPermission */, false /* checkShell */, "add preferred activity"); 16174 if (filter.countActions() == 0) { 16175 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 16176 return; 16177 } 16178 synchronized (mPackages) { 16179 if (mContext.checkCallingOrSelfPermission( 16180 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 16181 != PackageManager.PERMISSION_GRANTED) { 16182 if (getUidTargetSdkVersionLockedLPr(callingUid) 16183 < Build.VERSION_CODES.FROYO) { 16184 Slog.w(TAG, "Ignoring addPreferredActivity() from uid " 16185 + callingUid); 16186 return; 16187 } 16188 mContext.enforceCallingOrSelfPermission( 16189 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 16190 } 16191 16192 PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId); 16193 Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user " 16194 + userId + ":"); 16195 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 16196 pir.addFilter(new PreferredActivity(filter, match, set, activity, always)); 16197 scheduleWritePackageRestrictionsLocked(userId); 16198 } 16199 } 16200 16201 @Override 16202 public void replacePreferredActivity(IntentFilter filter, int match, 16203 ComponentName[] set, ComponentName activity, int userId) { 16204 if (filter.countActions() != 1) { 16205 throw new IllegalArgumentException( 16206 "replacePreferredActivity expects filter to have only 1 action."); 16207 } 16208 if (filter.countDataAuthorities() != 0 16209 || filter.countDataPaths() != 0 16210 || filter.countDataSchemes() > 1 16211 || filter.countDataTypes() != 0) { 16212 throw new IllegalArgumentException( 16213 "replacePreferredActivity expects filter to have no data authorities, " + 16214 "paths, or types; and at most one scheme."); 16215 } 16216 16217 final int callingUid = Binder.getCallingUid(); 16218 enforceCrossUserPermission(callingUid, userId, 16219 true /* requireFullPermission */, false /* checkShell */, 16220 "replace preferred activity"); 16221 synchronized (mPackages) { 16222 if (mContext.checkCallingOrSelfPermission( 16223 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 16224 != PackageManager.PERMISSION_GRANTED) { 16225 if (getUidTargetSdkVersionLockedLPr(callingUid) 16226 < Build.VERSION_CODES.FROYO) { 16227 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid " 16228 + Binder.getCallingUid()); 16229 return; 16230 } 16231 mContext.enforceCallingOrSelfPermission( 16232 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 16233 } 16234 16235 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 16236 if (pir != null) { 16237 // Get all of the existing entries that exactly match this filter. 16238 ArrayList<PreferredActivity> existing = pir.findFilters(filter); 16239 if (existing != null && existing.size() == 1) { 16240 PreferredActivity cur = existing.get(0); 16241 if (DEBUG_PREFERRED) { 16242 Slog.i(TAG, "Checking replace of preferred:"); 16243 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 16244 if (!cur.mPref.mAlways) { 16245 Slog.i(TAG, " -- CUR; not mAlways!"); 16246 } else { 16247 Slog.i(TAG, " -- CUR: mMatch=" + cur.mPref.mMatch); 16248 Slog.i(TAG, " -- CUR: mSet=" 16249 + Arrays.toString(cur.mPref.mSetComponents)); 16250 Slog.i(TAG, " -- CUR: mComponent=" + cur.mPref.mShortComponent); 16251 Slog.i(TAG, " -- NEW: mMatch=" 16252 + (match&IntentFilter.MATCH_CATEGORY_MASK)); 16253 Slog.i(TAG, " -- CUR: mSet=" + Arrays.toString(set)); 16254 Slog.i(TAG, " -- CUR: mComponent=" + activity.flattenToShortString()); 16255 } 16256 } 16257 if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity) 16258 && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK) 16259 && cur.mPref.sameSet(set)) { 16260 // Setting the preferred activity to what it happens to be already 16261 if (DEBUG_PREFERRED) { 16262 Slog.i(TAG, "Replacing with same preferred activity " 16263 + cur.mPref.mShortComponent + " for user " 16264 + userId + ":"); 16265 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 16266 } 16267 return; 16268 } 16269 } 16270 16271 if (existing != null) { 16272 if (DEBUG_PREFERRED) { 16273 Slog.i(TAG, existing.size() + " existing preferred matches for:"); 16274 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 16275 } 16276 for (int i = 0; i < existing.size(); i++) { 16277 PreferredActivity pa = existing.get(i); 16278 if (DEBUG_PREFERRED) { 16279 Slog.i(TAG, "Removing existing preferred activity " 16280 + pa.mPref.mComponent + ":"); 16281 pa.dump(new LogPrinter(Log.INFO, TAG), " "); 16282 } 16283 pir.removeFilter(pa); 16284 } 16285 } 16286 } 16287 addPreferredActivityInternal(filter, match, set, activity, true, userId, 16288 "Replacing preferred"); 16289 } 16290 } 16291 16292 @Override 16293 public void clearPackagePreferredActivities(String packageName) { 16294 final int uid = Binder.getCallingUid(); 16295 // writer 16296 synchronized (mPackages) { 16297 PackageParser.Package pkg = mPackages.get(packageName); 16298 if (pkg == null || pkg.applicationInfo.uid != uid) { 16299 if (mContext.checkCallingOrSelfPermission( 16300 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 16301 != PackageManager.PERMISSION_GRANTED) { 16302 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid()) 16303 < Build.VERSION_CODES.FROYO) { 16304 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid " 16305 + Binder.getCallingUid()); 16306 return; 16307 } 16308 mContext.enforceCallingOrSelfPermission( 16309 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 16310 } 16311 } 16312 16313 int user = UserHandle.getCallingUserId(); 16314 if (clearPackagePreferredActivitiesLPw(packageName, user)) { 16315 scheduleWritePackageRestrictionsLocked(user); 16316 } 16317 } 16318 } 16319 16320 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 16321 boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) { 16322 ArrayList<PreferredActivity> removed = null; 16323 boolean changed = false; 16324 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 16325 final int thisUserId = mSettings.mPreferredActivities.keyAt(i); 16326 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 16327 if (userId != UserHandle.USER_ALL && userId != thisUserId) { 16328 continue; 16329 } 16330 Iterator<PreferredActivity> it = pir.filterIterator(); 16331 while (it.hasNext()) { 16332 PreferredActivity pa = it.next(); 16333 // Mark entry for removal only if it matches the package name 16334 // and the entry is of type "always". 16335 if (packageName == null || 16336 (pa.mPref.mComponent.getPackageName().equals(packageName) 16337 && pa.mPref.mAlways)) { 16338 if (removed == null) { 16339 removed = new ArrayList<PreferredActivity>(); 16340 } 16341 removed.add(pa); 16342 } 16343 } 16344 if (removed != null) { 16345 for (int j=0; j<removed.size(); j++) { 16346 PreferredActivity pa = removed.get(j); 16347 pir.removeFilter(pa); 16348 } 16349 changed = true; 16350 } 16351 } 16352 return changed; 16353 } 16354 16355 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 16356 private void clearIntentFilterVerificationsLPw(int userId) { 16357 final int packageCount = mPackages.size(); 16358 for (int i = 0; i < packageCount; i++) { 16359 PackageParser.Package pkg = mPackages.valueAt(i); 16360 clearIntentFilterVerificationsLPw(pkg.packageName, userId); 16361 } 16362 } 16363 16364 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 16365 void clearIntentFilterVerificationsLPw(String packageName, int userId) { 16366 if (userId == UserHandle.USER_ALL) { 16367 if (mSettings.removeIntentFilterVerificationLPw(packageName, 16368 sUserManager.getUserIds())) { 16369 for (int oneUserId : sUserManager.getUserIds()) { 16370 scheduleWritePackageRestrictionsLocked(oneUserId); 16371 } 16372 } 16373 } else { 16374 if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) { 16375 scheduleWritePackageRestrictionsLocked(userId); 16376 } 16377 } 16378 } 16379 16380 void clearDefaultBrowserIfNeeded(String packageName) { 16381 for (int oneUserId : sUserManager.getUserIds()) { 16382 String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId); 16383 if (TextUtils.isEmpty(defaultBrowserPackageName)) continue; 16384 if (packageName.equals(defaultBrowserPackageName)) { 16385 setDefaultBrowserPackageName(null, oneUserId); 16386 } 16387 } 16388 } 16389 16390 @Override 16391 public void resetApplicationPreferences(int userId) { 16392 mContext.enforceCallingOrSelfPermission( 16393 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 16394 // writer 16395 synchronized (mPackages) { 16396 final long identity = Binder.clearCallingIdentity(); 16397 try { 16398 clearPackagePreferredActivitiesLPw(null, userId); 16399 mSettings.applyDefaultPreferredAppsLPw(this, userId); 16400 // TODO: We have to reset the default SMS and Phone. This requires 16401 // significant refactoring to keep all default apps in the package 16402 // manager (cleaner but more work) or have the services provide 16403 // callbacks to the package manager to request a default app reset. 16404 applyFactoryDefaultBrowserLPw(userId); 16405 clearIntentFilterVerificationsLPw(userId); 16406 primeDomainVerificationsLPw(userId); 16407 resetUserChangesToRuntimePermissionsAndFlagsLPw(userId); 16408 scheduleWritePackageRestrictionsLocked(userId); 16409 } finally { 16410 Binder.restoreCallingIdentity(identity); 16411 } 16412 } 16413 } 16414 16415 @Override 16416 public int getPreferredActivities(List<IntentFilter> outFilters, 16417 List<ComponentName> outActivities, String packageName) { 16418 16419 int num = 0; 16420 final int userId = UserHandle.getCallingUserId(); 16421 // reader 16422 synchronized (mPackages) { 16423 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 16424 if (pir != null) { 16425 final Iterator<PreferredActivity> it = pir.filterIterator(); 16426 while (it.hasNext()) { 16427 final PreferredActivity pa = it.next(); 16428 if (packageName == null 16429 || (pa.mPref.mComponent.getPackageName().equals(packageName) 16430 && pa.mPref.mAlways)) { 16431 if (outFilters != null) { 16432 outFilters.add(new IntentFilter(pa)); 16433 } 16434 if (outActivities != null) { 16435 outActivities.add(pa.mPref.mComponent); 16436 } 16437 } 16438 } 16439 } 16440 } 16441 16442 return num; 16443 } 16444 16445 @Override 16446 public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity, 16447 int userId) { 16448 int callingUid = Binder.getCallingUid(); 16449 if (callingUid != Process.SYSTEM_UID) { 16450 throw new SecurityException( 16451 "addPersistentPreferredActivity can only be run by the system"); 16452 } 16453 if (filter.countActions() == 0) { 16454 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 16455 return; 16456 } 16457 synchronized (mPackages) { 16458 Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId + 16459 ":"); 16460 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 16461 mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter( 16462 new PersistentPreferredActivity(filter, activity)); 16463 scheduleWritePackageRestrictionsLocked(userId); 16464 } 16465 } 16466 16467 @Override 16468 public void clearPackagePersistentPreferredActivities(String packageName, int userId) { 16469 int callingUid = Binder.getCallingUid(); 16470 if (callingUid != Process.SYSTEM_UID) { 16471 throw new SecurityException( 16472 "clearPackagePersistentPreferredActivities can only be run by the system"); 16473 } 16474 ArrayList<PersistentPreferredActivity> removed = null; 16475 boolean changed = false; 16476 synchronized (mPackages) { 16477 for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) { 16478 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i); 16479 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 16480 .valueAt(i); 16481 if (userId != thisUserId) { 16482 continue; 16483 } 16484 Iterator<PersistentPreferredActivity> it = ppir.filterIterator(); 16485 while (it.hasNext()) { 16486 PersistentPreferredActivity ppa = it.next(); 16487 // Mark entry for removal only if it matches the package name. 16488 if (ppa.mComponent.getPackageName().equals(packageName)) { 16489 if (removed == null) { 16490 removed = new ArrayList<PersistentPreferredActivity>(); 16491 } 16492 removed.add(ppa); 16493 } 16494 } 16495 if (removed != null) { 16496 for (int j=0; j<removed.size(); j++) { 16497 PersistentPreferredActivity ppa = removed.get(j); 16498 ppir.removeFilter(ppa); 16499 } 16500 changed = true; 16501 } 16502 } 16503 16504 if (changed) { 16505 scheduleWritePackageRestrictionsLocked(userId); 16506 } 16507 } 16508 } 16509 16510 /** 16511 * Common machinery for picking apart a restored XML blob and passing 16512 * it to a caller-supplied functor to be applied to the running system. 16513 */ 16514 private void restoreFromXml(XmlPullParser parser, int userId, 16515 String expectedStartTag, BlobXmlRestorer functor) 16516 throws IOException, XmlPullParserException { 16517 int type; 16518 while ((type = parser.next()) != XmlPullParser.START_TAG 16519 && type != XmlPullParser.END_DOCUMENT) { 16520 } 16521 if (type != XmlPullParser.START_TAG) { 16522 // oops didn't find a start tag?! 16523 if (DEBUG_BACKUP) { 16524 Slog.e(TAG, "Didn't find start tag during restore"); 16525 } 16526 return; 16527 } 16528Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName()); 16529 // this is supposed to be TAG_PREFERRED_BACKUP 16530 if (!expectedStartTag.equals(parser.getName())) { 16531 if (DEBUG_BACKUP) { 16532 Slog.e(TAG, "Found unexpected tag " + parser.getName()); 16533 } 16534 return; 16535 } 16536 16537 // skip interfering stuff, then we're aligned with the backing implementation 16538 while ((type = parser.next()) == XmlPullParser.TEXT) { } 16539Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); 16540 functor.apply(parser, userId); 16541 } 16542 16543 private interface BlobXmlRestorer { 16544 public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException; 16545 } 16546 16547 /** 16548 * Non-Binder method, support for the backup/restore mechanism: write the 16549 * full set of preferred activities in its canonical XML format. Returns the 16550 * XML output as a byte array, or null if there is none. 16551 */ 16552 @Override 16553 public byte[] getPreferredActivityBackup(int userId) { 16554 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16555 throw new SecurityException("Only the system may call getPreferredActivityBackup()"); 16556 } 16557 16558 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 16559 try { 16560 final XmlSerializer serializer = new FastXmlSerializer(); 16561 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 16562 serializer.startDocument(null, true); 16563 serializer.startTag(null, TAG_PREFERRED_BACKUP); 16564 16565 synchronized (mPackages) { 16566 mSettings.writePreferredActivitiesLPr(serializer, userId, true); 16567 } 16568 16569 serializer.endTag(null, TAG_PREFERRED_BACKUP); 16570 serializer.endDocument(); 16571 serializer.flush(); 16572 } catch (Exception e) { 16573 if (DEBUG_BACKUP) { 16574 Slog.e(TAG, "Unable to write preferred activities for backup", e); 16575 } 16576 return null; 16577 } 16578 16579 return dataStream.toByteArray(); 16580 } 16581 16582 @Override 16583 public void restorePreferredActivities(byte[] backup, int userId) { 16584 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16585 throw new SecurityException("Only the system may call restorePreferredActivities()"); 16586 } 16587 16588 try { 16589 final XmlPullParser parser = Xml.newPullParser(); 16590 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 16591 restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP, 16592 new BlobXmlRestorer() { 16593 @Override 16594 public void apply(XmlPullParser parser, int userId) 16595 throws XmlPullParserException, IOException { 16596 synchronized (mPackages) { 16597 mSettings.readPreferredActivitiesLPw(parser, userId); 16598 } 16599 } 16600 } ); 16601 } catch (Exception e) { 16602 if (DEBUG_BACKUP) { 16603 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 16604 } 16605 } 16606 } 16607 16608 /** 16609 * Non-Binder method, support for the backup/restore mechanism: write the 16610 * default browser (etc) settings in its canonical XML format. Returns the default 16611 * browser XML representation as a byte array, or null if there is none. 16612 */ 16613 @Override 16614 public byte[] getDefaultAppsBackup(int userId) { 16615 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16616 throw new SecurityException("Only the system may call getDefaultAppsBackup()"); 16617 } 16618 16619 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 16620 try { 16621 final XmlSerializer serializer = new FastXmlSerializer(); 16622 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 16623 serializer.startDocument(null, true); 16624 serializer.startTag(null, TAG_DEFAULT_APPS); 16625 16626 synchronized (mPackages) { 16627 mSettings.writeDefaultAppsLPr(serializer, userId); 16628 } 16629 16630 serializer.endTag(null, TAG_DEFAULT_APPS); 16631 serializer.endDocument(); 16632 serializer.flush(); 16633 } catch (Exception e) { 16634 if (DEBUG_BACKUP) { 16635 Slog.e(TAG, "Unable to write default apps for backup", e); 16636 } 16637 return null; 16638 } 16639 16640 return dataStream.toByteArray(); 16641 } 16642 16643 @Override 16644 public void restoreDefaultApps(byte[] backup, int userId) { 16645 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16646 throw new SecurityException("Only the system may call restoreDefaultApps()"); 16647 } 16648 16649 try { 16650 final XmlPullParser parser = Xml.newPullParser(); 16651 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 16652 restoreFromXml(parser, userId, TAG_DEFAULT_APPS, 16653 new BlobXmlRestorer() { 16654 @Override 16655 public void apply(XmlPullParser parser, int userId) 16656 throws XmlPullParserException, IOException { 16657 synchronized (mPackages) { 16658 mSettings.readDefaultAppsLPw(parser, userId); 16659 } 16660 } 16661 } ); 16662 } catch (Exception e) { 16663 if (DEBUG_BACKUP) { 16664 Slog.e(TAG, "Exception restoring default apps: " + e.getMessage()); 16665 } 16666 } 16667 } 16668 16669 @Override 16670 public byte[] getIntentFilterVerificationBackup(int userId) { 16671 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16672 throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()"); 16673 } 16674 16675 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 16676 try { 16677 final XmlSerializer serializer = new FastXmlSerializer(); 16678 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 16679 serializer.startDocument(null, true); 16680 serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION); 16681 16682 synchronized (mPackages) { 16683 mSettings.writeAllDomainVerificationsLPr(serializer, userId); 16684 } 16685 16686 serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION); 16687 serializer.endDocument(); 16688 serializer.flush(); 16689 } catch (Exception e) { 16690 if (DEBUG_BACKUP) { 16691 Slog.e(TAG, "Unable to write default apps for backup", e); 16692 } 16693 return null; 16694 } 16695 16696 return dataStream.toByteArray(); 16697 } 16698 16699 @Override 16700 public void restoreIntentFilterVerification(byte[] backup, int userId) { 16701 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16702 throw new SecurityException("Only the system may call restorePreferredActivities()"); 16703 } 16704 16705 try { 16706 final XmlPullParser parser = Xml.newPullParser(); 16707 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 16708 restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION, 16709 new BlobXmlRestorer() { 16710 @Override 16711 public void apply(XmlPullParser parser, int userId) 16712 throws XmlPullParserException, IOException { 16713 synchronized (mPackages) { 16714 mSettings.readAllDomainVerificationsLPr(parser, userId); 16715 mSettings.writeLPr(); 16716 } 16717 } 16718 } ); 16719 } catch (Exception e) { 16720 if (DEBUG_BACKUP) { 16721 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 16722 } 16723 } 16724 } 16725 16726 @Override 16727 public byte[] getPermissionGrantBackup(int userId) { 16728 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16729 throw new SecurityException("Only the system may call getPermissionGrantBackup()"); 16730 } 16731 16732 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 16733 try { 16734 final XmlSerializer serializer = new FastXmlSerializer(); 16735 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 16736 serializer.startDocument(null, true); 16737 serializer.startTag(null, TAG_PERMISSION_BACKUP); 16738 16739 synchronized (mPackages) { 16740 serializeRuntimePermissionGrantsLPr(serializer, userId); 16741 } 16742 16743 serializer.endTag(null, TAG_PERMISSION_BACKUP); 16744 serializer.endDocument(); 16745 serializer.flush(); 16746 } catch (Exception e) { 16747 if (DEBUG_BACKUP) { 16748 Slog.e(TAG, "Unable to write default apps for backup", e); 16749 } 16750 return null; 16751 } 16752 16753 return dataStream.toByteArray(); 16754 } 16755 16756 @Override 16757 public void restorePermissionGrants(byte[] backup, int userId) { 16758 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 16759 throw new SecurityException("Only the system may call restorePermissionGrants()"); 16760 } 16761 16762 try { 16763 final XmlPullParser parser = Xml.newPullParser(); 16764 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 16765 restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP, 16766 new BlobXmlRestorer() { 16767 @Override 16768 public void apply(XmlPullParser parser, int userId) 16769 throws XmlPullParserException, IOException { 16770 synchronized (mPackages) { 16771 processRestoredPermissionGrantsLPr(parser, userId); 16772 } 16773 } 16774 } ); 16775 } catch (Exception e) { 16776 if (DEBUG_BACKUP) { 16777 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 16778 } 16779 } 16780 } 16781 16782 private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId) 16783 throws IOException { 16784 serializer.startTag(null, TAG_ALL_GRANTS); 16785 16786 final int N = mSettings.mPackages.size(); 16787 for (int i = 0; i < N; i++) { 16788 final PackageSetting ps = mSettings.mPackages.valueAt(i); 16789 boolean pkgGrantsKnown = false; 16790 16791 PermissionsState packagePerms = ps.getPermissionsState(); 16792 16793 for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) { 16794 final int grantFlags = state.getFlags(); 16795 // only look at grants that are not system/policy fixed 16796 if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) { 16797 final boolean isGranted = state.isGranted(); 16798 // And only back up the user-twiddled state bits 16799 if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) { 16800 final String packageName = mSettings.mPackages.keyAt(i); 16801 if (!pkgGrantsKnown) { 16802 serializer.startTag(null, TAG_GRANT); 16803 serializer.attribute(null, ATTR_PACKAGE_NAME, packageName); 16804 pkgGrantsKnown = true; 16805 } 16806 16807 final boolean userSet = 16808 (grantFlags & FLAG_PERMISSION_USER_SET) != 0; 16809 final boolean userFixed = 16810 (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0; 16811 final boolean revoke = 16812 (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0; 16813 16814 serializer.startTag(null, TAG_PERMISSION); 16815 serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName()); 16816 if (isGranted) { 16817 serializer.attribute(null, ATTR_IS_GRANTED, "true"); 16818 } 16819 if (userSet) { 16820 serializer.attribute(null, ATTR_USER_SET, "true"); 16821 } 16822 if (userFixed) { 16823 serializer.attribute(null, ATTR_USER_FIXED, "true"); 16824 } 16825 if (revoke) { 16826 serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true"); 16827 } 16828 serializer.endTag(null, TAG_PERMISSION); 16829 } 16830 } 16831 } 16832 16833 if (pkgGrantsKnown) { 16834 serializer.endTag(null, TAG_GRANT); 16835 } 16836 } 16837 16838 serializer.endTag(null, TAG_ALL_GRANTS); 16839 } 16840 16841 private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId) 16842 throws XmlPullParserException, IOException { 16843 String pkgName = null; 16844 int outerDepth = parser.getDepth(); 16845 int type; 16846 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 16847 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 16848 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 16849 continue; 16850 } 16851 16852 final String tagName = parser.getName(); 16853 if (tagName.equals(TAG_GRANT)) { 16854 pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME); 16855 if (DEBUG_BACKUP) { 16856 Slog.v(TAG, "+++ Restoring grants for package " + pkgName); 16857 } 16858 } else if (tagName.equals(TAG_PERMISSION)) { 16859 16860 final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED)); 16861 final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME); 16862 16863 int newFlagSet = 0; 16864 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) { 16865 newFlagSet |= FLAG_PERMISSION_USER_SET; 16866 } 16867 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) { 16868 newFlagSet |= FLAG_PERMISSION_USER_FIXED; 16869 } 16870 if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) { 16871 newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE; 16872 } 16873 if (DEBUG_BACKUP) { 16874 Slog.v(TAG, " + Restoring grant: pkg=" + pkgName + " perm=" + permName 16875 + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet)); 16876 } 16877 final PackageSetting ps = mSettings.mPackages.get(pkgName); 16878 if (ps != null) { 16879 // Already installed so we apply the grant immediately 16880 if (DEBUG_BACKUP) { 16881 Slog.v(TAG, " + already installed; applying"); 16882 } 16883 PermissionsState perms = ps.getPermissionsState(); 16884 BasePermission bp = mSettings.mPermissions.get(permName); 16885 if (bp != null) { 16886 if (isGranted) { 16887 perms.grantRuntimePermission(bp, userId); 16888 } 16889 if (newFlagSet != 0) { 16890 perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet); 16891 } 16892 } 16893 } else { 16894 // Need to wait for post-restore install to apply the grant 16895 if (DEBUG_BACKUP) { 16896 Slog.v(TAG, " - not yet installed; saving for later"); 16897 } 16898 mSettings.processRestoredPermissionGrantLPr(pkgName, permName, 16899 isGranted, newFlagSet, userId); 16900 } 16901 } else { 16902 PackageManagerService.reportSettingsProblem(Log.WARN, 16903 "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName); 16904 XmlUtils.skipCurrentTag(parser); 16905 } 16906 } 16907 16908 scheduleWriteSettingsLocked(); 16909 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 16910 } 16911 16912 @Override 16913 public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage, 16914 int sourceUserId, int targetUserId, int flags) { 16915 mContext.enforceCallingOrSelfPermission( 16916 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 16917 int callingUid = Binder.getCallingUid(); 16918 enforceOwnerRights(ownerPackage, callingUid); 16919 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 16920 if (intentFilter.countActions() == 0) { 16921 Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions"); 16922 return; 16923 } 16924 synchronized (mPackages) { 16925 CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter, 16926 ownerPackage, targetUserId, flags); 16927 CrossProfileIntentResolver resolver = 16928 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 16929 ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter); 16930 // We have all those whose filter is equal. Now checking if the rest is equal as well. 16931 if (existing != null) { 16932 int size = existing.size(); 16933 for (int i = 0; i < size; i++) { 16934 if (newFilter.equalsIgnoreFilter(existing.get(i))) { 16935 return; 16936 } 16937 } 16938 } 16939 resolver.addFilter(newFilter); 16940 scheduleWritePackageRestrictionsLocked(sourceUserId); 16941 } 16942 } 16943 16944 @Override 16945 public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) { 16946 mContext.enforceCallingOrSelfPermission( 16947 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 16948 int callingUid = Binder.getCallingUid(); 16949 enforceOwnerRights(ownerPackage, callingUid); 16950 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 16951 synchronized (mPackages) { 16952 CrossProfileIntentResolver resolver = 16953 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 16954 ArraySet<CrossProfileIntentFilter> set = 16955 new ArraySet<CrossProfileIntentFilter>(resolver.filterSet()); 16956 for (CrossProfileIntentFilter filter : set) { 16957 if (filter.getOwnerPackage().equals(ownerPackage)) { 16958 resolver.removeFilter(filter); 16959 } 16960 } 16961 scheduleWritePackageRestrictionsLocked(sourceUserId); 16962 } 16963 } 16964 16965 // Enforcing that callingUid is owning pkg on userId 16966 private void enforceOwnerRights(String pkg, int callingUid) { 16967 // The system owns everything. 16968 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) { 16969 return; 16970 } 16971 int callingUserId = UserHandle.getUserId(callingUid); 16972 PackageInfo pi = getPackageInfo(pkg, 0, callingUserId); 16973 if (pi == null) { 16974 throw new IllegalArgumentException("Unknown package " + pkg + " on user " 16975 + callingUserId); 16976 } 16977 if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) { 16978 throw new SecurityException("Calling uid " + callingUid 16979 + " does not own package " + pkg); 16980 } 16981 } 16982 16983 @Override 16984 public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) { 16985 return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId()); 16986 } 16987 16988 private Intent getHomeIntent() { 16989 Intent intent = new Intent(Intent.ACTION_MAIN); 16990 intent.addCategory(Intent.CATEGORY_HOME); 16991 return intent; 16992 } 16993 16994 private IntentFilter getHomeFilter() { 16995 IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN); 16996 filter.addCategory(Intent.CATEGORY_HOME); 16997 filter.addCategory(Intent.CATEGORY_DEFAULT); 16998 return filter; 16999 } 17000 17001 ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, 17002 int userId) { 17003 Intent intent = getHomeIntent(); 17004 List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null, 17005 PackageManager.GET_META_DATA, userId); 17006 ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0, 17007 true, false, false, userId); 17008 17009 allHomeCandidates.clear(); 17010 if (list != null) { 17011 for (ResolveInfo ri : list) { 17012 allHomeCandidates.add(ri); 17013 } 17014 } 17015 return (preferred == null || preferred.activityInfo == null) 17016 ? null 17017 : new ComponentName(preferred.activityInfo.packageName, 17018 preferred.activityInfo.name); 17019 } 17020 17021 @Override 17022 public void setHomeActivity(ComponentName comp, int userId) { 17023 ArrayList<ResolveInfo> homeActivities = new ArrayList<>(); 17024 getHomeActivitiesAsUser(homeActivities, userId); 17025 17026 boolean found = false; 17027 17028 final int size = homeActivities.size(); 17029 final ComponentName[] set = new ComponentName[size]; 17030 for (int i = 0; i < size; i++) { 17031 final ResolveInfo candidate = homeActivities.get(i); 17032 final ActivityInfo info = candidate.activityInfo; 17033 final ComponentName activityName = new ComponentName(info.packageName, info.name); 17034 set[i] = activityName; 17035 if (!found && activityName.equals(comp)) { 17036 found = true; 17037 } 17038 } 17039 if (!found) { 17040 throw new IllegalArgumentException("Component " + comp + " cannot be home on user " 17041 + userId); 17042 } 17043 replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY, 17044 set, comp, userId); 17045 } 17046 17047 private @Nullable String getSetupWizardPackageName() { 17048 final Intent intent = new Intent(Intent.ACTION_MAIN); 17049 intent.addCategory(Intent.CATEGORY_SETUP_WIZARD); 17050 17051 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, 17052 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE 17053 | MATCH_DISABLED_COMPONENTS, 17054 UserHandle.myUserId()); 17055 if (matches.size() == 1) { 17056 return matches.get(0).getComponentInfo().packageName; 17057 } else { 17058 Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size() 17059 + ": matches=" + matches); 17060 return null; 17061 } 17062 } 17063 17064 @Override 17065 public void setApplicationEnabledSetting(String appPackageName, 17066 int newState, int flags, int userId, String callingPackage) { 17067 if (!sUserManager.exists(userId)) return; 17068 if (callingPackage == null) { 17069 callingPackage = Integer.toString(Binder.getCallingUid()); 17070 } 17071 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage); 17072 } 17073 17074 @Override 17075 public void setComponentEnabledSetting(ComponentName componentName, 17076 int newState, int flags, int userId) { 17077 if (!sUserManager.exists(userId)) return; 17078 setEnabledSetting(componentName.getPackageName(), 17079 componentName.getClassName(), newState, flags, userId, null); 17080 } 17081 17082 private void setEnabledSetting(final String packageName, String className, int newState, 17083 final int flags, int userId, String callingPackage) { 17084 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT 17085 || newState == COMPONENT_ENABLED_STATE_ENABLED 17086 || newState == COMPONENT_ENABLED_STATE_DISABLED 17087 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER 17088 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) { 17089 throw new IllegalArgumentException("Invalid new component state: " 17090 + newState); 17091 } 17092 PackageSetting pkgSetting; 17093 final int uid = Binder.getCallingUid(); 17094 final int permission = mContext.checkCallingOrSelfPermission( 17095 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 17096 enforceCrossUserPermission(uid, userId, 17097 false /* requireFullPermission */, true /* checkShell */, "set enabled"); 17098 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 17099 boolean sendNow = false; 17100 boolean isApp = (className == null); 17101 String componentName = isApp ? packageName : className; 17102 int packageUid = -1; 17103 ArrayList<String> components; 17104 17105 // writer 17106 synchronized (mPackages) { 17107 pkgSetting = mSettings.mPackages.get(packageName); 17108 if (pkgSetting == null) { 17109 if (className == null) { 17110 throw new IllegalArgumentException("Unknown package: " + packageName); 17111 } 17112 throw new IllegalArgumentException( 17113 "Unknown component: " + packageName + "/" + className); 17114 } 17115 // Allow root and verify that userId is not being specified by a different user 17116 if (!allowedByPermission && !UserHandle.isSameApp(uid, pkgSetting.appId)) { 17117 throw new SecurityException( 17118 "Permission Denial: attempt to change component state from pid=" 17119 + Binder.getCallingPid() 17120 + ", uid=" + uid + ", package uid=" + pkgSetting.appId); 17121 } 17122 if (className == null) { 17123 // We're dealing with an application/package level state change 17124 if (pkgSetting.getEnabled(userId) == newState) { 17125 // Nothing to do 17126 return; 17127 } 17128 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT 17129 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { 17130 // Don't care about who enables an app. 17131 callingPackage = null; 17132 } 17133 pkgSetting.setEnabled(newState, userId, callingPackage); 17134 // pkgSetting.pkg.mSetEnabled = newState; 17135 } else { 17136 // We're dealing with a component level state change 17137 // First, verify that this is a valid class name. 17138 PackageParser.Package pkg = pkgSetting.pkg; 17139 if (pkg == null || !pkg.hasComponentClassName(className)) { 17140 if (pkg != null && 17141 pkg.applicationInfo.targetSdkVersion >= 17142 Build.VERSION_CODES.JELLY_BEAN) { 17143 throw new IllegalArgumentException("Component class " + className 17144 + " does not exist in " + packageName); 17145 } else { 17146 Slog.w(TAG, "Failed setComponentEnabledSetting: component class " 17147 + className + " does not exist in " + packageName); 17148 } 17149 } 17150 switch (newState) { 17151 case COMPONENT_ENABLED_STATE_ENABLED: 17152 if (!pkgSetting.enableComponentLPw(className, userId)) { 17153 return; 17154 } 17155 break; 17156 case COMPONENT_ENABLED_STATE_DISABLED: 17157 if (!pkgSetting.disableComponentLPw(className, userId)) { 17158 return; 17159 } 17160 break; 17161 case COMPONENT_ENABLED_STATE_DEFAULT: 17162 if (!pkgSetting.restoreComponentLPw(className, userId)) { 17163 return; 17164 } 17165 break; 17166 default: 17167 Slog.e(TAG, "Invalid new component state: " + newState); 17168 return; 17169 } 17170 } 17171 scheduleWritePackageRestrictionsLocked(userId); 17172 components = mPendingBroadcasts.get(userId, packageName); 17173 final boolean newPackage = components == null; 17174 if (newPackage) { 17175 components = new ArrayList<String>(); 17176 } 17177 if (!components.contains(componentName)) { 17178 components.add(componentName); 17179 } 17180 if ((flags&PackageManager.DONT_KILL_APP) == 0) { 17181 sendNow = true; 17182 // Purge entry from pending broadcast list if another one exists already 17183 // since we are sending one right away. 17184 mPendingBroadcasts.remove(userId, packageName); 17185 } else { 17186 if (newPackage) { 17187 mPendingBroadcasts.put(userId, packageName, components); 17188 } 17189 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) { 17190 // Schedule a message 17191 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY); 17192 } 17193 } 17194 } 17195 17196 long callingId = Binder.clearCallingIdentity(); 17197 try { 17198 if (sendNow) { 17199 packageUid = UserHandle.getUid(userId, pkgSetting.appId); 17200 sendPackageChangedBroadcast(packageName, 17201 (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid); 17202 } 17203 } finally { 17204 Binder.restoreCallingIdentity(callingId); 17205 } 17206 } 17207 17208 @Override 17209 public void flushPackageRestrictionsAsUser(int userId) { 17210 if (!sUserManager.exists(userId)) { 17211 return; 17212 } 17213 enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/, 17214 false /* checkShell */, "flushPackageRestrictions"); 17215 synchronized (mPackages) { 17216 mSettings.writePackageRestrictionsLPr(userId); 17217 mDirtyUsers.remove(userId); 17218 if (mDirtyUsers.isEmpty()) { 17219 mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS); 17220 } 17221 } 17222 } 17223 17224 private void sendPackageChangedBroadcast(String packageName, 17225 boolean killFlag, ArrayList<String> componentNames, int packageUid) { 17226 if (DEBUG_INSTALL) 17227 Log.v(TAG, "Sending package changed: package=" + packageName + " components=" 17228 + componentNames); 17229 Bundle extras = new Bundle(4); 17230 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0)); 17231 String nameList[] = new String[componentNames.size()]; 17232 componentNames.toArray(nameList); 17233 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList); 17234 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag); 17235 extras.putInt(Intent.EXTRA_UID, packageUid); 17236 // If this is not reporting a change of the overall package, then only send it 17237 // to registered receivers. We don't want to launch a swath of apps for every 17238 // little component state change. 17239 final int flags = !componentNames.contains(packageName) 17240 ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0; 17241 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, flags, null, null, 17242 new int[] {UserHandle.getUserId(packageUid)}); 17243 } 17244 17245 @Override 17246 public void setPackageStoppedState(String packageName, boolean stopped, int userId) { 17247 if (!sUserManager.exists(userId)) return; 17248 final int uid = Binder.getCallingUid(); 17249 final int permission = mContext.checkCallingOrSelfPermission( 17250 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 17251 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 17252 enforceCrossUserPermission(uid, userId, 17253 true /* requireFullPermission */, true /* checkShell */, "stop package"); 17254 // writer 17255 synchronized (mPackages) { 17256 if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped, 17257 allowedByPermission, uid, userId)) { 17258 scheduleWritePackageRestrictionsLocked(userId); 17259 } 17260 } 17261 } 17262 17263 @Override 17264 public String getInstallerPackageName(String packageName) { 17265 // reader 17266 synchronized (mPackages) { 17267 return mSettings.getInstallerPackageNameLPr(packageName); 17268 } 17269 } 17270 17271 @Override 17272 public int getApplicationEnabledSetting(String packageName, int userId) { 17273 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 17274 int uid = Binder.getCallingUid(); 17275 enforceCrossUserPermission(uid, userId, 17276 false /* requireFullPermission */, false /* checkShell */, "get enabled"); 17277 // reader 17278 synchronized (mPackages) { 17279 return mSettings.getApplicationEnabledSettingLPr(packageName, userId); 17280 } 17281 } 17282 17283 @Override 17284 public int getComponentEnabledSetting(ComponentName componentName, int userId) { 17285 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 17286 int uid = Binder.getCallingUid(); 17287 enforceCrossUserPermission(uid, userId, 17288 false /* requireFullPermission */, false /* checkShell */, "get component enabled"); 17289 // reader 17290 synchronized (mPackages) { 17291 return mSettings.getComponentEnabledSettingLPr(componentName, userId); 17292 } 17293 } 17294 17295 @Override 17296 public void enterSafeMode() { 17297 enforceSystemOrRoot("Only the system can request entering safe mode"); 17298 17299 if (!mSystemReady) { 17300 mSafeMode = true; 17301 } 17302 } 17303 17304 @Override 17305 public void systemReady() { 17306 mSystemReady = true; 17307 17308 // Read the compatibilty setting when the system is ready. 17309 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt( 17310 mContext.getContentResolver(), 17311 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1; 17312 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled); 17313 if (DEBUG_SETTINGS) { 17314 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled); 17315 } 17316 17317 int[] grantPermissionsUserIds = EMPTY_INT_ARRAY; 17318 17319 synchronized (mPackages) { 17320 // Verify that all of the preferred activity components actually 17321 // exist. It is possible for applications to be updated and at 17322 // that point remove a previously declared activity component that 17323 // had been set as a preferred activity. We try to clean this up 17324 // the next time we encounter that preferred activity, but it is 17325 // possible for the user flow to never be able to return to that 17326 // situation so here we do a sanity check to make sure we haven't 17327 // left any junk around. 17328 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>(); 17329 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 17330 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 17331 removed.clear(); 17332 for (PreferredActivity pa : pir.filterSet()) { 17333 if (mActivities.mActivities.get(pa.mPref.mComponent) == null) { 17334 removed.add(pa); 17335 } 17336 } 17337 if (removed.size() > 0) { 17338 for (int r=0; r<removed.size(); r++) { 17339 PreferredActivity pa = removed.get(r); 17340 Slog.w(TAG, "Removing dangling preferred activity: " 17341 + pa.mPref.mComponent); 17342 pir.removeFilter(pa); 17343 } 17344 mSettings.writePackageRestrictionsLPr( 17345 mSettings.mPreferredActivities.keyAt(i)); 17346 } 17347 } 17348 17349 for (int userId : UserManagerService.getInstance().getUserIds()) { 17350 if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) { 17351 grantPermissionsUserIds = ArrayUtils.appendInt( 17352 grantPermissionsUserIds, userId); 17353 } 17354 } 17355 } 17356 sUserManager.systemReady(); 17357 17358 // If we upgraded grant all default permissions before kicking off. 17359 for (int userId : grantPermissionsUserIds) { 17360 mDefaultPermissionPolicy.grantDefaultPermissions(userId); 17361 } 17362 17363 // Kick off any messages waiting for system ready 17364 if (mPostSystemReadyMessages != null) { 17365 for (Message msg : mPostSystemReadyMessages) { 17366 msg.sendToTarget(); 17367 } 17368 mPostSystemReadyMessages = null; 17369 } 17370 17371 // Watch for external volumes that come and go over time 17372 final StorageManager storage = mContext.getSystemService(StorageManager.class); 17373 storage.registerListener(mStorageListener); 17374 17375 mInstallerService.systemReady(); 17376 mPackageDexOptimizer.systemReady(); 17377 17378 MountServiceInternal mountServiceInternal = LocalServices.getService( 17379 MountServiceInternal.class); 17380 mountServiceInternal.addExternalStoragePolicy( 17381 new MountServiceInternal.ExternalStorageMountPolicy() { 17382 @Override 17383 public int getMountMode(int uid, String packageName) { 17384 if (Process.isIsolated(uid)) { 17385 return Zygote.MOUNT_EXTERNAL_NONE; 17386 } 17387 if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) { 17388 return Zygote.MOUNT_EXTERNAL_DEFAULT; 17389 } 17390 if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { 17391 return Zygote.MOUNT_EXTERNAL_DEFAULT; 17392 } 17393 if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { 17394 return Zygote.MOUNT_EXTERNAL_READ; 17395 } 17396 return Zygote.MOUNT_EXTERNAL_WRITE; 17397 } 17398 17399 @Override 17400 public boolean hasExternalStorage(int uid, String packageName) { 17401 return true; 17402 } 17403 }); 17404 } 17405 17406 @Override 17407 public boolean isSafeMode() { 17408 return mSafeMode; 17409 } 17410 17411 @Override 17412 public boolean hasSystemUidErrors() { 17413 return mHasSystemUidErrors; 17414 } 17415 17416 static String arrayToString(int[] array) { 17417 StringBuffer buf = new StringBuffer(128); 17418 buf.append('['); 17419 if (array != null) { 17420 for (int i=0; i<array.length; i++) { 17421 if (i > 0) buf.append(", "); 17422 buf.append(array[i]); 17423 } 17424 } 17425 buf.append(']'); 17426 return buf.toString(); 17427 } 17428 17429 static class DumpState { 17430 public static final int DUMP_LIBS = 1 << 0; 17431 public static final int DUMP_FEATURES = 1 << 1; 17432 public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2; 17433 public static final int DUMP_SERVICE_RESOLVERS = 1 << 3; 17434 public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4; 17435 public static final int DUMP_CONTENT_RESOLVERS = 1 << 5; 17436 public static final int DUMP_PERMISSIONS = 1 << 6; 17437 public static final int DUMP_PACKAGES = 1 << 7; 17438 public static final int DUMP_SHARED_USERS = 1 << 8; 17439 public static final int DUMP_MESSAGES = 1 << 9; 17440 public static final int DUMP_PROVIDERS = 1 << 10; 17441 public static final int DUMP_VERIFIERS = 1 << 11; 17442 public static final int DUMP_PREFERRED = 1 << 12; 17443 public static final int DUMP_PREFERRED_XML = 1 << 13; 17444 public static final int DUMP_KEYSETS = 1 << 14; 17445 public static final int DUMP_VERSION = 1 << 15; 17446 public static final int DUMP_INSTALLS = 1 << 16; 17447 public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17; 17448 public static final int DUMP_DOMAIN_PREFERRED = 1 << 18; 17449 17450 public static final int OPTION_SHOW_FILTERS = 1 << 0; 17451 17452 private int mTypes; 17453 17454 private int mOptions; 17455 17456 private boolean mTitlePrinted; 17457 17458 private SharedUserSetting mSharedUser; 17459 17460 public boolean isDumping(int type) { 17461 if (mTypes == 0 && type != DUMP_PREFERRED_XML) { 17462 return true; 17463 } 17464 17465 return (mTypes & type) != 0; 17466 } 17467 17468 public void setDump(int type) { 17469 mTypes |= type; 17470 } 17471 17472 public boolean isOptionEnabled(int option) { 17473 return (mOptions & option) != 0; 17474 } 17475 17476 public void setOptionEnabled(int option) { 17477 mOptions |= option; 17478 } 17479 17480 public boolean onTitlePrinted() { 17481 final boolean printed = mTitlePrinted; 17482 mTitlePrinted = true; 17483 return printed; 17484 } 17485 17486 public boolean getTitlePrinted() { 17487 return mTitlePrinted; 17488 } 17489 17490 public void setTitlePrinted(boolean enabled) { 17491 mTitlePrinted = enabled; 17492 } 17493 17494 public SharedUserSetting getSharedUser() { 17495 return mSharedUser; 17496 } 17497 17498 public void setSharedUser(SharedUserSetting user) { 17499 mSharedUser = user; 17500 } 17501 } 17502 17503 @Override 17504 public void onShellCommand(FileDescriptor in, FileDescriptor out, 17505 FileDescriptor err, String[] args, ResultReceiver resultReceiver) { 17506 (new PackageManagerShellCommand(this)).exec( 17507 this, in, out, err, args, resultReceiver); 17508 } 17509 17510 @Override 17511 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 17512 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 17513 != PackageManager.PERMISSION_GRANTED) { 17514 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 17515 + Binder.getCallingPid() 17516 + ", uid=" + Binder.getCallingUid() 17517 + " without permission " 17518 + android.Manifest.permission.DUMP); 17519 return; 17520 } 17521 17522 DumpState dumpState = new DumpState(); 17523 boolean fullPreferred = false; 17524 boolean checkin = false; 17525 17526 String packageName = null; 17527 ArraySet<String> permissionNames = null; 17528 17529 int opti = 0; 17530 while (opti < args.length) { 17531 String opt = args[opti]; 17532 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 17533 break; 17534 } 17535 opti++; 17536 17537 if ("-a".equals(opt)) { 17538 // Right now we only know how to print all. 17539 } else if ("-h".equals(opt)) { 17540 pw.println("Package manager dump options:"); 17541 pw.println(" [-h] [-f] [--checkin] [cmd] ..."); 17542 pw.println(" --checkin: dump for a checkin"); 17543 pw.println(" -f: print details of intent filters"); 17544 pw.println(" -h: print this help"); 17545 pw.println(" cmd may be one of:"); 17546 pw.println(" l[ibraries]: list known shared libraries"); 17547 pw.println(" f[eatures]: list device features"); 17548 pw.println(" k[eysets]: print known keysets"); 17549 pw.println(" r[esolvers] [activity|service|receiver|content]: dump intent resolvers"); 17550 pw.println(" perm[issions]: dump permissions"); 17551 pw.println(" permission [name ...]: dump declaration and use of given permission"); 17552 pw.println(" pref[erred]: print preferred package settings"); 17553 pw.println(" preferred-xml [--full]: print preferred package settings as xml"); 17554 pw.println(" prov[iders]: dump content providers"); 17555 pw.println(" p[ackages]: dump installed packages"); 17556 pw.println(" s[hared-users]: dump shared user IDs"); 17557 pw.println(" m[essages]: print collected runtime messages"); 17558 pw.println(" v[erifiers]: print package verifier info"); 17559 pw.println(" d[omain-preferred-apps]: print domains preferred apps"); 17560 pw.println(" i[ntent-filter-verifiers]|ifv: print intent filter verifier info"); 17561 pw.println(" version: print database version info"); 17562 pw.println(" write: write current settings now"); 17563 pw.println(" installs: details about install sessions"); 17564 pw.println(" check-permission <permission> <package> [<user>]: does pkg hold perm?"); 17565 pw.println(" <package.name>: info about given package"); 17566 return; 17567 } else if ("--checkin".equals(opt)) { 17568 checkin = true; 17569 } else if ("-f".equals(opt)) { 17570 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 17571 } else { 17572 pw.println("Unknown argument: " + opt + "; use -h for help"); 17573 } 17574 } 17575 17576 // Is the caller requesting to dump a particular piece of data? 17577 if (opti < args.length) { 17578 String cmd = args[opti]; 17579 opti++; 17580 // Is this a package name? 17581 if ("android".equals(cmd) || cmd.contains(".")) { 17582 packageName = cmd; 17583 // When dumping a single package, we always dump all of its 17584 // filter information since the amount of data will be reasonable. 17585 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 17586 } else if ("check-permission".equals(cmd)) { 17587 if (opti >= args.length) { 17588 pw.println("Error: check-permission missing permission argument"); 17589 return; 17590 } 17591 String perm = args[opti]; 17592 opti++; 17593 if (opti >= args.length) { 17594 pw.println("Error: check-permission missing package argument"); 17595 return; 17596 } 17597 String pkg = args[opti]; 17598 opti++; 17599 int user = UserHandle.getUserId(Binder.getCallingUid()); 17600 if (opti < args.length) { 17601 try { 17602 user = Integer.parseInt(args[opti]); 17603 } catch (NumberFormatException e) { 17604 pw.println("Error: check-permission user argument is not a number: " 17605 + args[opti]); 17606 return; 17607 } 17608 } 17609 pw.println(checkPermission(perm, pkg, user)); 17610 return; 17611 } else if ("l".equals(cmd) || "libraries".equals(cmd)) { 17612 dumpState.setDump(DumpState.DUMP_LIBS); 17613 } else if ("f".equals(cmd) || "features".equals(cmd)) { 17614 dumpState.setDump(DumpState.DUMP_FEATURES); 17615 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) { 17616 if (opti >= args.length) { 17617 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS 17618 | DumpState.DUMP_SERVICE_RESOLVERS 17619 | DumpState.DUMP_RECEIVER_RESOLVERS 17620 | DumpState.DUMP_CONTENT_RESOLVERS); 17621 } else { 17622 while (opti < args.length) { 17623 String name = args[opti]; 17624 if ("a".equals(name) || "activity".equals(name)) { 17625 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS); 17626 } else if ("s".equals(name) || "service".equals(name)) { 17627 dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS); 17628 } else if ("r".equals(name) || "receiver".equals(name)) { 17629 dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS); 17630 } else if ("c".equals(name) || "content".equals(name)) { 17631 dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS); 17632 } else { 17633 pw.println("Error: unknown resolver table type: " + name); 17634 return; 17635 } 17636 opti++; 17637 } 17638 } 17639 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) { 17640 dumpState.setDump(DumpState.DUMP_PERMISSIONS); 17641 } else if ("permission".equals(cmd)) { 17642 if (opti >= args.length) { 17643 pw.println("Error: permission requires permission name"); 17644 return; 17645 } 17646 permissionNames = new ArraySet<>(); 17647 while (opti < args.length) { 17648 permissionNames.add(args[opti]); 17649 opti++; 17650 } 17651 dumpState.setDump(DumpState.DUMP_PERMISSIONS 17652 | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS); 17653 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) { 17654 dumpState.setDump(DumpState.DUMP_PREFERRED); 17655 } else if ("preferred-xml".equals(cmd)) { 17656 dumpState.setDump(DumpState.DUMP_PREFERRED_XML); 17657 if (opti < args.length && "--full".equals(args[opti])) { 17658 fullPreferred = true; 17659 opti++; 17660 } 17661 } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) { 17662 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED); 17663 } else if ("p".equals(cmd) || "packages".equals(cmd)) { 17664 dumpState.setDump(DumpState.DUMP_PACKAGES); 17665 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) { 17666 dumpState.setDump(DumpState.DUMP_SHARED_USERS); 17667 } else if ("prov".equals(cmd) || "providers".equals(cmd)) { 17668 dumpState.setDump(DumpState.DUMP_PROVIDERS); 17669 } else if ("m".equals(cmd) || "messages".equals(cmd)) { 17670 dumpState.setDump(DumpState.DUMP_MESSAGES); 17671 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) { 17672 dumpState.setDump(DumpState.DUMP_VERIFIERS); 17673 } else if ("i".equals(cmd) || "ifv".equals(cmd) 17674 || "intent-filter-verifiers".equals(cmd)) { 17675 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS); 17676 } else if ("version".equals(cmd)) { 17677 dumpState.setDump(DumpState.DUMP_VERSION); 17678 } else if ("k".equals(cmd) || "keysets".equals(cmd)) { 17679 dumpState.setDump(DumpState.DUMP_KEYSETS); 17680 } else if ("installs".equals(cmd)) { 17681 dumpState.setDump(DumpState.DUMP_INSTALLS); 17682 } else if ("write".equals(cmd)) { 17683 synchronized (mPackages) { 17684 mSettings.writeLPr(); 17685 pw.println("Settings written."); 17686 return; 17687 } 17688 } 17689 } 17690 17691 if (checkin) { 17692 pw.println("vers,1"); 17693 } 17694 17695 // reader 17696 synchronized (mPackages) { 17697 if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) { 17698 if (!checkin) { 17699 if (dumpState.onTitlePrinted()) 17700 pw.println(); 17701 pw.println("Database versions:"); 17702 mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, " ")); 17703 } 17704 } 17705 17706 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) { 17707 if (!checkin) { 17708 if (dumpState.onTitlePrinted()) 17709 pw.println(); 17710 pw.println("Verifiers:"); 17711 pw.print(" Required: "); 17712 pw.print(mRequiredVerifierPackage); 17713 pw.print(" (uid="); 17714 pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 17715 UserHandle.USER_SYSTEM)); 17716 pw.println(")"); 17717 } else if (mRequiredVerifierPackage != null) { 17718 pw.print("vrfy,"); pw.print(mRequiredVerifierPackage); 17719 pw.print(","); 17720 pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 17721 UserHandle.USER_SYSTEM)); 17722 } 17723 } 17724 17725 if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) && 17726 packageName == null) { 17727 if (mIntentFilterVerifierComponent != null) { 17728 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName(); 17729 if (!checkin) { 17730 if (dumpState.onTitlePrinted()) 17731 pw.println(); 17732 pw.println("Intent Filter Verifier:"); 17733 pw.print(" Using: "); 17734 pw.print(verifierPackageName); 17735 pw.print(" (uid="); 17736 pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING, 17737 UserHandle.USER_SYSTEM)); 17738 pw.println(")"); 17739 } else if (verifierPackageName != null) { 17740 pw.print("ifv,"); pw.print(verifierPackageName); 17741 pw.print(","); 17742 pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING, 17743 UserHandle.USER_SYSTEM)); 17744 } 17745 } else { 17746 pw.println(); 17747 pw.println("No Intent Filter Verifier available!"); 17748 } 17749 } 17750 17751 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) { 17752 boolean printedHeader = false; 17753 final Iterator<String> it = mSharedLibraries.keySet().iterator(); 17754 while (it.hasNext()) { 17755 String name = it.next(); 17756 SharedLibraryEntry ent = mSharedLibraries.get(name); 17757 if (!checkin) { 17758 if (!printedHeader) { 17759 if (dumpState.onTitlePrinted()) 17760 pw.println(); 17761 pw.println("Libraries:"); 17762 printedHeader = true; 17763 } 17764 pw.print(" "); 17765 } else { 17766 pw.print("lib,"); 17767 } 17768 pw.print(name); 17769 if (!checkin) { 17770 pw.print(" -> "); 17771 } 17772 if (ent.path != null) { 17773 if (!checkin) { 17774 pw.print("(jar) "); 17775 pw.print(ent.path); 17776 } else { 17777 pw.print(",jar,"); 17778 pw.print(ent.path); 17779 } 17780 } else { 17781 if (!checkin) { 17782 pw.print("(apk) "); 17783 pw.print(ent.apk); 17784 } else { 17785 pw.print(",apk,"); 17786 pw.print(ent.apk); 17787 } 17788 } 17789 pw.println(); 17790 } 17791 } 17792 17793 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) { 17794 if (dumpState.onTitlePrinted()) 17795 pw.println(); 17796 if (!checkin) { 17797 pw.println("Features:"); 17798 } 17799 17800 for (FeatureInfo feat : mAvailableFeatures.values()) { 17801 if (checkin) { 17802 pw.print("feat,"); 17803 pw.print(feat.name); 17804 pw.print(","); 17805 pw.println(feat.version); 17806 } else { 17807 pw.print(" "); 17808 pw.print(feat.name); 17809 if (feat.version > 0) { 17810 pw.print(" version="); 17811 pw.print(feat.version); 17812 } 17813 pw.println(); 17814 } 17815 } 17816 } 17817 17818 if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) { 17819 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:" 17820 : "Activity Resolver Table:", " ", packageName, 17821 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 17822 dumpState.setTitlePrinted(true); 17823 } 17824 } 17825 if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) { 17826 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:" 17827 : "Receiver Resolver Table:", " ", packageName, 17828 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 17829 dumpState.setTitlePrinted(true); 17830 } 17831 } 17832 if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) { 17833 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:" 17834 : "Service Resolver Table:", " ", packageName, 17835 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 17836 dumpState.setTitlePrinted(true); 17837 } 17838 } 17839 if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) { 17840 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:" 17841 : "Provider Resolver Table:", " ", packageName, 17842 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 17843 dumpState.setTitlePrinted(true); 17844 } 17845 } 17846 17847 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) { 17848 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 17849 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 17850 int user = mSettings.mPreferredActivities.keyAt(i); 17851 if (pir.dump(pw, 17852 dumpState.getTitlePrinted() 17853 ? "\nPreferred Activities User " + user + ":" 17854 : "Preferred Activities User " + user + ":", " ", 17855 packageName, true, false)) { 17856 dumpState.setTitlePrinted(true); 17857 } 17858 } 17859 } 17860 17861 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) { 17862 pw.flush(); 17863 FileOutputStream fout = new FileOutputStream(fd); 17864 BufferedOutputStream str = new BufferedOutputStream(fout); 17865 XmlSerializer serializer = new FastXmlSerializer(); 17866 try { 17867 serializer.setOutput(str, StandardCharsets.UTF_8.name()); 17868 serializer.startDocument(null, true); 17869 serializer.setFeature( 17870 "http://xmlpull.org/v1/doc/features.html#indent-output", true); 17871 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred); 17872 serializer.endDocument(); 17873 serializer.flush(); 17874 } catch (IllegalArgumentException e) { 17875 pw.println("Failed writing: " + e); 17876 } catch (IllegalStateException e) { 17877 pw.println("Failed writing: " + e); 17878 } catch (IOException e) { 17879 pw.println("Failed writing: " + e); 17880 } 17881 } 17882 17883 if (!checkin 17884 && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED) 17885 && packageName == null) { 17886 pw.println(); 17887 int count = mSettings.mPackages.size(); 17888 if (count == 0) { 17889 pw.println("No applications!"); 17890 pw.println(); 17891 } else { 17892 final String prefix = " "; 17893 Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values(); 17894 if (allPackageSettings.size() == 0) { 17895 pw.println("No domain preferred apps!"); 17896 pw.println(); 17897 } else { 17898 pw.println("App verification status:"); 17899 pw.println(); 17900 count = 0; 17901 for (PackageSetting ps : allPackageSettings) { 17902 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo(); 17903 if (ivi == null || ivi.getPackageName() == null) continue; 17904 pw.println(prefix + "Package: " + ivi.getPackageName()); 17905 pw.println(prefix + "Domains: " + ivi.getDomainsString()); 17906 pw.println(prefix + "Status: " + ivi.getStatusString()); 17907 pw.println(); 17908 count++; 17909 } 17910 if (count == 0) { 17911 pw.println(prefix + "No app verification established."); 17912 pw.println(); 17913 } 17914 for (int userId : sUserManager.getUserIds()) { 17915 pw.println("App linkages for user " + userId + ":"); 17916 pw.println(); 17917 count = 0; 17918 for (PackageSetting ps : allPackageSettings) { 17919 final long status = ps.getDomainVerificationStatusForUser(userId); 17920 if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 17921 continue; 17922 } 17923 pw.println(prefix + "Package: " + ps.name); 17924 pw.println(prefix + "Domains: " + dumpDomainString(ps.name)); 17925 String statusStr = IntentFilterVerificationInfo. 17926 getStatusStringFromValue(status); 17927 pw.println(prefix + "Status: " + statusStr); 17928 pw.println(); 17929 count++; 17930 } 17931 if (count == 0) { 17932 pw.println(prefix + "No configured app linkages."); 17933 pw.println(); 17934 } 17935 } 17936 } 17937 } 17938 } 17939 17940 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) { 17941 mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState); 17942 if (packageName == null && permissionNames == null) { 17943 for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) { 17944 if (iperm == 0) { 17945 if (dumpState.onTitlePrinted()) 17946 pw.println(); 17947 pw.println("AppOp Permissions:"); 17948 } 17949 pw.print(" AppOp Permission "); 17950 pw.print(mAppOpPermissionPackages.keyAt(iperm)); 17951 pw.println(":"); 17952 ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm); 17953 for (int ipkg=0; ipkg<pkgs.size(); ipkg++) { 17954 pw.print(" "); pw.println(pkgs.valueAt(ipkg)); 17955 } 17956 } 17957 } 17958 } 17959 17960 if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) { 17961 boolean printedSomething = false; 17962 for (PackageParser.Provider p : mProviders.mProviders.values()) { 17963 if (packageName != null && !packageName.equals(p.info.packageName)) { 17964 continue; 17965 } 17966 if (!printedSomething) { 17967 if (dumpState.onTitlePrinted()) 17968 pw.println(); 17969 pw.println("Registered ContentProviders:"); 17970 printedSomething = true; 17971 } 17972 pw.print(" "); p.printComponentShortName(pw); pw.println(":"); 17973 pw.print(" "); pw.println(p.toString()); 17974 } 17975 printedSomething = false; 17976 for (Map.Entry<String, PackageParser.Provider> entry : 17977 mProvidersByAuthority.entrySet()) { 17978 PackageParser.Provider p = entry.getValue(); 17979 if (packageName != null && !packageName.equals(p.info.packageName)) { 17980 continue; 17981 } 17982 if (!printedSomething) { 17983 if (dumpState.onTitlePrinted()) 17984 pw.println(); 17985 pw.println("ContentProvider Authorities:"); 17986 printedSomething = true; 17987 } 17988 pw.print(" ["); pw.print(entry.getKey()); pw.println("]:"); 17989 pw.print(" "); pw.println(p.toString()); 17990 if (p.info != null && p.info.applicationInfo != null) { 17991 final String appInfo = p.info.applicationInfo.toString(); 17992 pw.print(" applicationInfo="); pw.println(appInfo); 17993 } 17994 } 17995 } 17996 17997 if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) { 17998 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState); 17999 } 18000 18001 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) { 18002 mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin); 18003 } 18004 18005 if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) { 18006 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin); 18007 } 18008 18009 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) { 18010 mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState); 18011 } 18012 18013 if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) { 18014 // XXX should handle packageName != null by dumping only install data that 18015 // the given package is involved with. 18016 if (dumpState.onTitlePrinted()) pw.println(); 18017 mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120)); 18018 } 18019 18020 if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) { 18021 if (dumpState.onTitlePrinted()) pw.println(); 18022 mSettings.dumpReadMessagesLPr(pw, dumpState); 18023 18024 pw.println(); 18025 pw.println("Package warning messages:"); 18026 BufferedReader in = null; 18027 String line = null; 18028 try { 18029 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 18030 while ((line = in.readLine()) != null) { 18031 if (line.contains("ignored: updated version")) continue; 18032 pw.println(line); 18033 } 18034 } catch (IOException ignored) { 18035 } finally { 18036 IoUtils.closeQuietly(in); 18037 } 18038 } 18039 18040 if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) { 18041 BufferedReader in = null; 18042 String line = null; 18043 try { 18044 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 18045 while ((line = in.readLine()) != null) { 18046 if (line.contains("ignored: updated version")) continue; 18047 pw.print("msg,"); 18048 pw.println(line); 18049 } 18050 } catch (IOException ignored) { 18051 } finally { 18052 IoUtils.closeQuietly(in); 18053 } 18054 } 18055 } 18056 } 18057 18058 private String dumpDomainString(String packageName) { 18059 List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName) 18060 .getList(); 18061 List<IntentFilter> filters = getAllIntentFilters(packageName).getList(); 18062 18063 ArraySet<String> result = new ArraySet<>(); 18064 if (iviList.size() > 0) { 18065 for (IntentFilterVerificationInfo ivi : iviList) { 18066 for (String host : ivi.getDomains()) { 18067 result.add(host); 18068 } 18069 } 18070 } 18071 if (filters != null && filters.size() > 0) { 18072 for (IntentFilter filter : filters) { 18073 if (filter.hasCategory(Intent.CATEGORY_BROWSABLE) 18074 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 18075 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) { 18076 result.addAll(filter.getHostsList()); 18077 } 18078 } 18079 } 18080 18081 StringBuilder sb = new StringBuilder(result.size() * 16); 18082 for (String domain : result) { 18083 if (sb.length() > 0) sb.append(" "); 18084 sb.append(domain); 18085 } 18086 return sb.toString(); 18087 } 18088 18089 // ------- apps on sdcard specific code ------- 18090 static final boolean DEBUG_SD_INSTALL = false; 18091 18092 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD"; 18093 18094 private static final String SD_ENCRYPTION_ALGORITHM = "AES"; 18095 18096 private boolean mMediaMounted = false; 18097 18098 static String getEncryptKey() { 18099 try { 18100 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString( 18101 SD_ENCRYPTION_KEYSTORE_NAME); 18102 if (sdEncKey == null) { 18103 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128, 18104 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME); 18105 if (sdEncKey == null) { 18106 Slog.e(TAG, "Failed to create encryption keys"); 18107 return null; 18108 } 18109 } 18110 return sdEncKey; 18111 } catch (NoSuchAlgorithmException nsae) { 18112 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae); 18113 return null; 18114 } catch (IOException ioe) { 18115 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe); 18116 return null; 18117 } 18118 } 18119 18120 /* 18121 * Update media status on PackageManager. 18122 */ 18123 @Override 18124 public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) { 18125 int callingUid = Binder.getCallingUid(); 18126 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 18127 throw new SecurityException("Media status can only be updated by the system"); 18128 } 18129 // reader; this apparently protects mMediaMounted, but should probably 18130 // be a different lock in that case. 18131 synchronized (mPackages) { 18132 Log.i(TAG, "Updating external media status from " 18133 + (mMediaMounted ? "mounted" : "unmounted") + " to " 18134 + (mediaStatus ? "mounted" : "unmounted")); 18135 if (DEBUG_SD_INSTALL) 18136 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus 18137 + ", mMediaMounted=" + mMediaMounted); 18138 if (mediaStatus == mMediaMounted) { 18139 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 18140 : 0, -1); 18141 mHandler.sendMessage(msg); 18142 return; 18143 } 18144 mMediaMounted = mediaStatus; 18145 } 18146 // Queue up an async operation since the package installation may take a 18147 // little while. 18148 mHandler.post(new Runnable() { 18149 public void run() { 18150 updateExternalMediaStatusInner(mediaStatus, reportStatus, true); 18151 } 18152 }); 18153 } 18154 18155 /** 18156 * Called by MountService when the initial ASECs to scan are available. 18157 * Should block until all the ASEC containers are finished being scanned. 18158 */ 18159 public void scanAvailableAsecs() { 18160 updateExternalMediaStatusInner(true, false, false); 18161 } 18162 18163 /* 18164 * Collect information of applications on external media, map them against 18165 * existing containers and update information based on current mount status. 18166 * Please note that we always have to report status if reportStatus has been 18167 * set to true especially when unloading packages. 18168 */ 18169 private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus, 18170 boolean externalStorage) { 18171 ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>(); 18172 int[] uidArr = EmptyArray.INT; 18173 18174 final String[] list = PackageHelper.getSecureContainerList(); 18175 if (ArrayUtils.isEmpty(list)) { 18176 Log.i(TAG, "No secure containers found"); 18177 } else { 18178 // Process list of secure containers and categorize them 18179 // as active or stale based on their package internal state. 18180 18181 // reader 18182 synchronized (mPackages) { 18183 for (String cid : list) { 18184 // Leave stages untouched for now; installer service owns them 18185 if (PackageInstallerService.isStageName(cid)) continue; 18186 18187 if (DEBUG_SD_INSTALL) 18188 Log.i(TAG, "Processing container " + cid); 18189 String pkgName = getAsecPackageName(cid); 18190 if (pkgName == null) { 18191 Slog.i(TAG, "Found stale container " + cid + " with no package name"); 18192 continue; 18193 } 18194 if (DEBUG_SD_INSTALL) 18195 Log.i(TAG, "Looking for pkg : " + pkgName); 18196 18197 final PackageSetting ps = mSettings.mPackages.get(pkgName); 18198 if (ps == null) { 18199 Slog.i(TAG, "Found stale container " + cid + " with no matching settings"); 18200 continue; 18201 } 18202 18203 /* 18204 * Skip packages that are not external if we're unmounting 18205 * external storage. 18206 */ 18207 if (externalStorage && !isMounted && !isExternal(ps)) { 18208 continue; 18209 } 18210 18211 final AsecInstallArgs args = new AsecInstallArgs(cid, 18212 getAppDexInstructionSets(ps), ps.isForwardLocked()); 18213 // The package status is changed only if the code path 18214 // matches between settings and the container id. 18215 if (ps.codePathString != null 18216 && ps.codePathString.startsWith(args.getCodePath())) { 18217 if (DEBUG_SD_INSTALL) { 18218 Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName 18219 + " at code path: " + ps.codePathString); 18220 } 18221 18222 // We do have a valid package installed on sdcard 18223 processCids.put(args, ps.codePathString); 18224 final int uid = ps.appId; 18225 if (uid != -1) { 18226 uidArr = ArrayUtils.appendInt(uidArr, uid); 18227 } 18228 } else { 18229 Slog.i(TAG, "Found stale container " + cid + ": expected codePath=" 18230 + ps.codePathString); 18231 } 18232 } 18233 } 18234 18235 Arrays.sort(uidArr); 18236 } 18237 18238 // Process packages with valid entries. 18239 if (isMounted) { 18240 if (DEBUG_SD_INSTALL) 18241 Log.i(TAG, "Loading packages"); 18242 loadMediaPackages(processCids, uidArr, externalStorage); 18243 startCleaningPackages(); 18244 mInstallerService.onSecureContainersAvailable(); 18245 } else { 18246 if (DEBUG_SD_INSTALL) 18247 Log.i(TAG, "Unloading packages"); 18248 unloadMediaPackages(processCids, uidArr, reportStatus); 18249 } 18250 } 18251 18252 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 18253 ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) { 18254 final int size = infos.size(); 18255 final String[] packageNames = new String[size]; 18256 final int[] packageUids = new int[size]; 18257 for (int i = 0; i < size; i++) { 18258 final ApplicationInfo info = infos.get(i); 18259 packageNames[i] = info.packageName; 18260 packageUids[i] = info.uid; 18261 } 18262 sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids, 18263 finishedReceiver); 18264 } 18265 18266 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 18267 ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 18268 sendResourcesChangedBroadcast(mediaStatus, replacing, 18269 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver); 18270 } 18271 18272 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 18273 String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 18274 int size = pkgList.length; 18275 if (size > 0) { 18276 // Send broadcasts here 18277 Bundle extras = new Bundle(); 18278 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 18279 if (uidArr != null) { 18280 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr); 18281 } 18282 if (replacing) { 18283 extras.putBoolean(Intent.EXTRA_REPLACING, replacing); 18284 } 18285 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE 18286 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE; 18287 sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null); 18288 } 18289 } 18290 18291 /* 18292 * Look at potentially valid container ids from processCids If package 18293 * information doesn't match the one on record or package scanning fails, 18294 * the cid is added to list of removeCids. We currently don't delete stale 18295 * containers. 18296 */ 18297 private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr, 18298 boolean externalStorage) { 18299 ArrayList<String> pkgList = new ArrayList<String>(); 18300 Set<AsecInstallArgs> keys = processCids.keySet(); 18301 18302 for (AsecInstallArgs args : keys) { 18303 String codePath = processCids.get(args); 18304 if (DEBUG_SD_INSTALL) 18305 Log.i(TAG, "Loading container : " + args.cid); 18306 int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 18307 try { 18308 // Make sure there are no container errors first. 18309 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) { 18310 Slog.e(TAG, "Failed to mount cid : " + args.cid 18311 + " when installing from sdcard"); 18312 continue; 18313 } 18314 // Check code path here. 18315 if (codePath == null || !codePath.startsWith(args.getCodePath())) { 18316 Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath() 18317 + " does not match one in settings " + codePath); 18318 continue; 18319 } 18320 // Parse package 18321 int parseFlags = mDefParseFlags; 18322 if (args.isExternalAsec()) { 18323 parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE; 18324 } 18325 if (args.isFwdLocked()) { 18326 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 18327 } 18328 18329 synchronized (mInstallLock) { 18330 PackageParser.Package pkg = null; 18331 try { 18332 pkg = scanPackageTracedLI(new File(codePath), parseFlags, 0, 0, null); 18333 } catch (PackageManagerException e) { 18334 Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage()); 18335 } 18336 // Scan the package 18337 if (pkg != null) { 18338 /* 18339 * TODO why is the lock being held? doPostInstall is 18340 * called in other places without the lock. This needs 18341 * to be straightened out. 18342 */ 18343 // writer 18344 synchronized (mPackages) { 18345 retCode = PackageManager.INSTALL_SUCCEEDED; 18346 pkgList.add(pkg.packageName); 18347 // Post process args 18348 args.doPostInstall(PackageManager.INSTALL_SUCCEEDED, 18349 pkg.applicationInfo.uid); 18350 } 18351 } else { 18352 Slog.i(TAG, "Failed to install pkg from " + codePath + " from sdcard"); 18353 } 18354 } 18355 18356 } finally { 18357 if (retCode != PackageManager.INSTALL_SUCCEEDED) { 18358 Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode); 18359 } 18360 } 18361 } 18362 // writer 18363 synchronized (mPackages) { 18364 // If the platform SDK has changed since the last time we booted, 18365 // we need to re-grant app permission to catch any new ones that 18366 // appear. This is really a hack, and means that apps can in some 18367 // cases get permissions that the user didn't initially explicitly 18368 // allow... it would be nice to have some better way to handle 18369 // this situation. 18370 final VersionInfo ver = externalStorage ? mSettings.getExternalVersion() 18371 : mSettings.getInternalVersion(); 18372 final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL 18373 : StorageManager.UUID_PRIVATE_INTERNAL; 18374 18375 int updateFlags = UPDATE_PERMISSIONS_ALL; 18376 if (ver.sdkVersion != mSdkVersion) { 18377 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " 18378 + mSdkVersion + "; regranting permissions for external"); 18379 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 18380 } 18381 updatePermissionsLPw(null, null, volumeUuid, updateFlags); 18382 18383 // Yay, everything is now upgraded 18384 ver.forceCurrent(); 18385 18386 // can downgrade to reader 18387 // Persist settings 18388 mSettings.writeLPr(); 18389 } 18390 // Send a broadcast to let everyone know we are done processing 18391 if (pkgList.size() > 0) { 18392 sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null); 18393 } 18394 } 18395 18396 /* 18397 * Utility method to unload a list of specified containers 18398 */ 18399 private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) { 18400 // Just unmount all valid containers. 18401 for (AsecInstallArgs arg : cidArgs) { 18402 synchronized (mInstallLock) { 18403 arg.doPostDeleteLI(false); 18404 } 18405 } 18406 } 18407 18408 /* 18409 * Unload packages mounted on external media. This involves deleting package 18410 * data from internal structures, sending broadcasts about disabled packages, 18411 * gc'ing to free up references, unmounting all secure containers 18412 * corresponding to packages on external media, and posting a 18413 * UPDATED_MEDIA_STATUS message if status has been requested. Please note 18414 * that we always have to post this message if status has been requested no 18415 * matter what. 18416 */ 18417 private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[], 18418 final boolean reportStatus) { 18419 if (DEBUG_SD_INSTALL) 18420 Log.i(TAG, "unloading media packages"); 18421 ArrayList<String> pkgList = new ArrayList<String>(); 18422 ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>(); 18423 final Set<AsecInstallArgs> keys = processCids.keySet(); 18424 for (AsecInstallArgs args : keys) { 18425 String pkgName = args.getPackageName(); 18426 if (DEBUG_SD_INSTALL) 18427 Log.i(TAG, "Trying to unload pkg : " + pkgName); 18428 // Delete package internally 18429 PackageRemovedInfo outInfo = new PackageRemovedInfo(); 18430 synchronized (mInstallLock) { 18431 boolean res = deletePackageLI(pkgName, null, false, null, 18432 PackageManager.DELETE_KEEP_DATA, outInfo, false, null); 18433 if (res) { 18434 pkgList.add(pkgName); 18435 } else { 18436 Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName); 18437 failedList.add(args); 18438 } 18439 } 18440 } 18441 18442 // reader 18443 synchronized (mPackages) { 18444 // We didn't update the settings after removing each package; 18445 // write them now for all packages. 18446 mSettings.writeLPr(); 18447 } 18448 18449 // We have to absolutely send UPDATED_MEDIA_STATUS only 18450 // after confirming that all the receivers processed the ordered 18451 // broadcast when packages get disabled, force a gc to clean things up. 18452 // and unload all the containers. 18453 if (pkgList.size() > 0) { 18454 sendResourcesChangedBroadcast(false, false, pkgList, uidArr, 18455 new IIntentReceiver.Stub() { 18456 public void performReceive(Intent intent, int resultCode, String data, 18457 Bundle extras, boolean ordered, boolean sticky, 18458 int sendingUser) throws RemoteException { 18459 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, 18460 reportStatus ? 1 : 0, 1, keys); 18461 mHandler.sendMessage(msg); 18462 } 18463 }); 18464 } else { 18465 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1, 18466 keys); 18467 mHandler.sendMessage(msg); 18468 } 18469 } 18470 18471 private void loadPrivatePackages(final VolumeInfo vol) { 18472 mHandler.post(new Runnable() { 18473 @Override 18474 public void run() { 18475 loadPrivatePackagesInner(vol); 18476 } 18477 }); 18478 } 18479 18480 private void loadPrivatePackagesInner(VolumeInfo vol) { 18481 final String volumeUuid = vol.fsUuid; 18482 if (TextUtils.isEmpty(volumeUuid)) { 18483 Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring"); 18484 return; 18485 } 18486 18487 final ArrayList<ApplicationInfo> loaded = new ArrayList<>(); 18488 final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE; 18489 18490 final VersionInfo ver; 18491 final List<PackageSetting> packages; 18492 synchronized (mPackages) { 18493 ver = mSettings.findOrCreateVersion(volumeUuid); 18494 packages = mSettings.getVolumePackagesLPr(volumeUuid); 18495 } 18496 18497 // TODO: introduce a new concept similar to "frozen" to prevent these 18498 // apps from being launched until after data has been fully reconciled 18499 for (PackageSetting ps : packages) { 18500 synchronized (mInstallLock) { 18501 final PackageParser.Package pkg; 18502 try { 18503 pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null); 18504 loaded.add(pkg.applicationInfo); 18505 18506 } catch (PackageManagerException e) { 18507 Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage()); 18508 } 18509 18510 if (!Build.FINGERPRINT.equals(ver.fingerprint)) { 18511 deleteCodeCacheDirsLI(ps.volumeUuid, ps.name); 18512 } 18513 } 18514 } 18515 18516 // Reconcile app data for all started/unlocked users 18517 final StorageManager sm = mContext.getSystemService(StorageManager.class); 18518 final UserManager um = mContext.getSystemService(UserManager.class); 18519 for (UserInfo user : um.getUsers()) { 18520 final int flags; 18521 if (um.isUserUnlocked(user.id)) { 18522 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 18523 } else if (um.isUserRunning(user.id)) { 18524 flags = StorageManager.FLAG_STORAGE_DE; 18525 } else { 18526 continue; 18527 } 18528 18529 sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags); 18530 reconcileAppsData(volumeUuid, user.id, flags); 18531 } 18532 18533 synchronized (mPackages) { 18534 int updateFlags = UPDATE_PERMISSIONS_ALL; 18535 if (ver.sdkVersion != mSdkVersion) { 18536 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " 18537 + mSdkVersion + "; regranting permissions for " + volumeUuid); 18538 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 18539 } 18540 updatePermissionsLPw(null, null, volumeUuid, updateFlags); 18541 18542 // Yay, everything is now upgraded 18543 ver.forceCurrent(); 18544 18545 mSettings.writeLPr(); 18546 } 18547 18548 if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded); 18549 sendResourcesChangedBroadcast(true, false, loaded, null); 18550 } 18551 18552 private void unloadPrivatePackages(final VolumeInfo vol) { 18553 mHandler.post(new Runnable() { 18554 @Override 18555 public void run() { 18556 unloadPrivatePackagesInner(vol); 18557 } 18558 }); 18559 } 18560 18561 private void unloadPrivatePackagesInner(VolumeInfo vol) { 18562 final String volumeUuid = vol.fsUuid; 18563 if (TextUtils.isEmpty(volumeUuid)) { 18564 Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring"); 18565 return; 18566 } 18567 18568 final ArrayList<ApplicationInfo> unloaded = new ArrayList<>(); 18569 synchronized (mInstallLock) { 18570 synchronized (mPackages) { 18571 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid); 18572 for (PackageSetting ps : packages) { 18573 if (ps.pkg == null) continue; 18574 18575 final ApplicationInfo info = ps.pkg.applicationInfo; 18576 final PackageRemovedInfo outInfo = new PackageRemovedInfo(); 18577 if (deletePackageLI(ps.name, null, false, null, 18578 PackageManager.DELETE_KEEP_DATA, outInfo, false, null)) { 18579 unloaded.add(info); 18580 } else { 18581 Slog.w(TAG, "Failed to unload " + ps.codePath); 18582 } 18583 } 18584 18585 mSettings.writeLPr(); 18586 } 18587 } 18588 18589 if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded); 18590 sendResourcesChangedBroadcast(false, false, unloaded, null); 18591 } 18592 18593 /** 18594 * Examine all users present on given mounted volume, and destroy data 18595 * belonging to users that are no longer valid, or whose user ID has been 18596 * recycled. 18597 */ 18598 private void reconcileUsers(String volumeUuid) { 18599 // TODO: also reconcile DE directories 18600 final File[] files = FileUtils 18601 .listFilesOrEmpty(Environment.getDataUserCeDirectory(volumeUuid)); 18602 for (File file : files) { 18603 if (!file.isDirectory()) continue; 18604 18605 final int userId; 18606 final UserInfo info; 18607 try { 18608 userId = Integer.parseInt(file.getName()); 18609 info = sUserManager.getUserInfo(userId); 18610 } catch (NumberFormatException e) { 18611 Slog.w(TAG, "Invalid user directory " + file); 18612 continue; 18613 } 18614 18615 boolean destroyUser = false; 18616 if (info == null) { 18617 logCriticalInfo(Log.WARN, "Destroying user directory " + file 18618 + " because no matching user was found"); 18619 destroyUser = true; 18620 } else { 18621 try { 18622 UserManagerService.enforceSerialNumber(file, info.serialNumber); 18623 } catch (IOException e) { 18624 logCriticalInfo(Log.WARN, "Destroying user directory " + file 18625 + " because we failed to enforce serial number: " + e); 18626 destroyUser = true; 18627 } 18628 } 18629 18630 if (destroyUser) { 18631 synchronized (mInstallLock) { 18632 try { 18633 mInstaller.removeUserDataDirs(volumeUuid, userId); 18634 } catch (InstallerException e) { 18635 Slog.w(TAG, "Failed to clean up user dirs", e); 18636 } 18637 } 18638 } 18639 } 18640 } 18641 18642 private void assertPackageKnown(String volumeUuid, String packageName) 18643 throws PackageManagerException { 18644 synchronized (mPackages) { 18645 final PackageSetting ps = mSettings.mPackages.get(packageName); 18646 if (ps == null) { 18647 throw new PackageManagerException("Package " + packageName + " is unknown"); 18648 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) { 18649 throw new PackageManagerException( 18650 "Package " + packageName + " found on unknown volume " + volumeUuid 18651 + "; expected volume " + ps.volumeUuid); 18652 } 18653 } 18654 } 18655 18656 private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId) 18657 throws PackageManagerException { 18658 synchronized (mPackages) { 18659 final PackageSetting ps = mSettings.mPackages.get(packageName); 18660 if (ps == null) { 18661 throw new PackageManagerException("Package " + packageName + " is unknown"); 18662 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) { 18663 throw new PackageManagerException( 18664 "Package " + packageName + " found on unknown volume " + volumeUuid 18665 + "; expected volume " + ps.volumeUuid); 18666 } else if (!ps.getInstalled(userId)) { 18667 throw new PackageManagerException( 18668 "Package " + packageName + " not installed for user " + userId); 18669 } 18670 } 18671 } 18672 18673 /** 18674 * Examine all apps present on given mounted volume, and destroy apps that 18675 * aren't expected, either due to uninstallation or reinstallation on 18676 * another volume. 18677 */ 18678 private void reconcileApps(String volumeUuid) { 18679 final File[] files = FileUtils 18680 .listFilesOrEmpty(Environment.getDataAppDirectory(volumeUuid)); 18681 for (File file : files) { 18682 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 18683 && !PackageInstallerService.isStageName(file.getName()); 18684 if (!isPackage) { 18685 // Ignore entries which are not packages 18686 continue; 18687 } 18688 18689 try { 18690 final PackageLite pkg = PackageParser.parsePackageLite(file, 18691 PackageParser.PARSE_MUST_BE_APK); 18692 assertPackageKnown(volumeUuid, pkg.packageName); 18693 18694 } catch (PackageParserException | PackageManagerException e) { 18695 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 18696 synchronized (mInstallLock) { 18697 removeCodePathLI(file); 18698 } 18699 } 18700 } 18701 } 18702 18703 /** 18704 * Reconcile all app data for the given user. 18705 * <p> 18706 * Verifies that directories exist and that ownership and labeling is 18707 * correct for all installed apps on all mounted volumes. 18708 */ 18709 void reconcileAppsData(int userId, int flags) { 18710 final StorageManager storage = mContext.getSystemService(StorageManager.class); 18711 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 18712 final String volumeUuid = vol.getFsUuid(); 18713 reconcileAppsData(volumeUuid, userId, flags); 18714 } 18715 } 18716 18717 /** 18718 * Reconcile all app data on given mounted volume. 18719 * <p> 18720 * Destroys app data that isn't expected, either due to uninstallation or 18721 * reinstallation on another volume. 18722 * <p> 18723 * Verifies that directories exist and that ownership and labeling is 18724 * correct for all installed apps. 18725 */ 18726 private void reconcileAppsData(String volumeUuid, int userId, int flags) { 18727 Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x" 18728 + Integer.toHexString(flags)); 18729 18730 final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId); 18731 final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId); 18732 18733 boolean restoreconNeeded = false; 18734 18735 // First look for stale data that doesn't belong, and check if things 18736 // have changed since we did our last restorecon 18737 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 18738 if (!isUserKeyUnlocked(userId)) { 18739 throw new RuntimeException( 18740 "Yikes, someone asked us to reconcile CE storage while " + userId 18741 + " was still locked; this would have caused massive data loss!"); 18742 } 18743 18744 restoreconNeeded |= SELinuxMMAC.isRestoreconNeeded(ceDir); 18745 18746 final File[] files = FileUtils.listFilesOrEmpty(ceDir); 18747 for (File file : files) { 18748 final String packageName = file.getName(); 18749 try { 18750 assertPackageKnownAndInstalled(volumeUuid, packageName, userId); 18751 } catch (PackageManagerException e) { 18752 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 18753 synchronized (mInstallLock) { 18754 destroyAppDataLI(volumeUuid, packageName, userId, 18755 StorageManager.FLAG_STORAGE_CE); 18756 } 18757 } 18758 } 18759 } 18760 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) { 18761 restoreconNeeded |= SELinuxMMAC.isRestoreconNeeded(deDir); 18762 18763 final File[] files = FileUtils.listFilesOrEmpty(deDir); 18764 for (File file : files) { 18765 final String packageName = file.getName(); 18766 try { 18767 assertPackageKnownAndInstalled(volumeUuid, packageName, userId); 18768 } catch (PackageManagerException e) { 18769 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 18770 synchronized (mInstallLock) { 18771 destroyAppDataLI(volumeUuid, packageName, userId, 18772 StorageManager.FLAG_STORAGE_DE); 18773 } 18774 } 18775 } 18776 } 18777 18778 // Ensure that data directories are ready to roll for all packages 18779 // installed for this volume and user 18780 final List<PackageSetting> packages; 18781 synchronized (mPackages) { 18782 packages = mSettings.getVolumePackagesLPr(volumeUuid); 18783 } 18784 int preparedCount = 0; 18785 for (PackageSetting ps : packages) { 18786 final String packageName = ps.name; 18787 if (ps.pkg == null) { 18788 Slog.w(TAG, "Odd, missing scanned package " + packageName); 18789 // TODO: might be due to legacy ASEC apps; we should circle back 18790 // and reconcile again once they're scanned 18791 continue; 18792 } 18793 18794 if (ps.getInstalled(userId)) { 18795 prepareAppData(volumeUuid, userId, flags, ps.pkg, restoreconNeeded); 18796 18797 if (maybeMigrateAppData(volumeUuid, userId, ps.pkg)) { 18798 // We may have just shuffled around app data directories, so 18799 // prepare them one more time 18800 prepareAppData(volumeUuid, userId, flags, ps.pkg, restoreconNeeded); 18801 } 18802 18803 preparedCount++; 18804 } 18805 } 18806 18807 if (restoreconNeeded) { 18808 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 18809 SELinuxMMAC.setRestoreconDone(ceDir); 18810 } 18811 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) { 18812 SELinuxMMAC.setRestoreconDone(deDir); 18813 } 18814 } 18815 18816 Slog.v(TAG, "reconcileAppsData finished " + preparedCount 18817 + " packages; restoreconNeeded was " + restoreconNeeded); 18818 } 18819 18820 /** 18821 * Prepare app data for the given app just after it was installed or 18822 * upgraded. This method carefully only touches users that it's installed 18823 * for, and it forces a restorecon to handle any seinfo changes. 18824 * <p> 18825 * Verifies that directories exist and that ownership and labeling is 18826 * correct for all installed apps. If there is an ownership mismatch, it 18827 * will try recovering system apps by wiping data; third-party app data is 18828 * left intact. 18829 * <p> 18830 * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em> 18831 */ 18832 private void prepareAppDataAfterInstall(PackageParser.Package pkg) { 18833 prepareAppDataAfterInstallInternal(pkg); 18834 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 18835 for (int i = 0; i < childCount; i++) { 18836 PackageParser.Package childPackage = pkg.childPackages.get(i); 18837 prepareAppDataAfterInstallInternal(childPackage); 18838 } 18839 } 18840 18841 private void prepareAppDataAfterInstallInternal(PackageParser.Package pkg) { 18842 final PackageSetting ps; 18843 synchronized (mPackages) { 18844 ps = mSettings.mPackages.get(pkg.packageName); 18845 mSettings.writeKernelMappingLPr(ps); 18846 } 18847 18848 final UserManager um = mContext.getSystemService(UserManager.class); 18849 for (UserInfo user : um.getUsers()) { 18850 final int flags; 18851 if (um.isUserUnlocked(user.id)) { 18852 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 18853 } else if (um.isUserRunning(user.id)) { 18854 flags = StorageManager.FLAG_STORAGE_DE; 18855 } else { 18856 continue; 18857 } 18858 18859 if (ps.getInstalled(user.id)) { 18860 // Whenever an app changes, force a restorecon of its data 18861 // TODO: when user data is locked, mark that we're still dirty 18862 prepareAppData(pkg.volumeUuid, user.id, flags, pkg, true); 18863 } 18864 } 18865 } 18866 18867 /** 18868 * Prepare app data for the given app. 18869 * <p> 18870 * Verifies that directories exist and that ownership and labeling is 18871 * correct for all installed apps. If there is an ownership mismatch, this 18872 * will try recovering system apps by wiping data; third-party app data is 18873 * left intact. 18874 */ 18875 private void prepareAppData(String volumeUuid, int userId, int flags, 18876 PackageParser.Package pkg, boolean restoreconNeeded) { 18877 if (DEBUG_APP_DATA) { 18878 Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x" 18879 + Integer.toHexString(flags) + (restoreconNeeded ? " restoreconNeeded" : "")); 18880 } 18881 18882 final String packageName = pkg.packageName; 18883 final ApplicationInfo app = pkg.applicationInfo; 18884 final int appId = UserHandle.getAppId(app.uid); 18885 18886 Preconditions.checkNotNull(app.seinfo); 18887 18888 synchronized (mInstallLock) { 18889 try { 18890 mInstaller.createAppData(volumeUuid, packageName, userId, flags, 18891 appId, app.seinfo, app.targetSdkVersion); 18892 } catch (InstallerException e) { 18893 if (app.isSystemApp()) { 18894 logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName 18895 + ", but trying to recover: " + e); 18896 destroyAppDataLI(volumeUuid, packageName, userId, flags); 18897 try { 18898 mInstaller.createAppData(volumeUuid, packageName, userId, flags, 18899 appId, app.seinfo, app.targetSdkVersion); 18900 logCriticalInfo(Log.DEBUG, "Recovery succeeded!"); 18901 } catch (InstallerException e2) { 18902 logCriticalInfo(Log.DEBUG, "Recovery failed!"); 18903 } 18904 } else { 18905 Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e); 18906 } 18907 } 18908 18909 if (restoreconNeeded) { 18910 restoreconAppDataLI(volumeUuid, packageName, userId, flags, appId, app.seinfo); 18911 } 18912 18913 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 18914 // Create a native library symlink only if we have native libraries 18915 // and if the native libraries are 32 bit libraries. We do not provide 18916 // this symlink for 64 bit libraries. 18917 if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) { 18918 final String nativeLibPath = app.nativeLibraryDir; 18919 try { 18920 mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName, 18921 nativeLibPath, userId); 18922 } catch (InstallerException e) { 18923 Slog.e(TAG, "Failed to link native for " + packageName + ": " + e); 18924 } 18925 } 18926 } 18927 } 18928 } 18929 18930 /** 18931 * For system apps on non-FBE devices, this method migrates any existing 18932 * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag 18933 * requested by the app. 18934 */ 18935 private boolean maybeMigrateAppData(String volumeUuid, int userId, PackageParser.Package pkg) { 18936 if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated() 18937 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) { 18938 final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage() 18939 ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE; 18940 synchronized (mInstallLock) { 18941 try { 18942 mInstaller.migrateAppData(volumeUuid, pkg.packageName, userId, storageTarget); 18943 } catch (InstallerException e) { 18944 logCriticalInfo(Log.WARN, 18945 "Failed to migrate " + pkg.packageName + ": " + e.getMessage()); 18946 } 18947 } 18948 return true; 18949 } else { 18950 return false; 18951 } 18952 } 18953 18954 private void unfreezePackage(String packageName) { 18955 synchronized (mPackages) { 18956 final PackageSetting ps = mSettings.mPackages.get(packageName); 18957 if (ps != null) { 18958 ps.frozen = false; 18959 } 18960 } 18961 } 18962 18963 @Override 18964 public int movePackage(final String packageName, final String volumeUuid) { 18965 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 18966 18967 final int moveId = mNextMoveId.getAndIncrement(); 18968 mHandler.post(new Runnable() { 18969 @Override 18970 public void run() { 18971 try { 18972 movePackageInternal(packageName, volumeUuid, moveId); 18973 } catch (PackageManagerException e) { 18974 Slog.w(TAG, "Failed to move " + packageName, e); 18975 mMoveCallbacks.notifyStatusChanged(moveId, 18976 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 18977 } 18978 } 18979 }); 18980 return moveId; 18981 } 18982 18983 private void movePackageInternal(final String packageName, final String volumeUuid, 18984 final int moveId) throws PackageManagerException { 18985 final UserHandle user = new UserHandle(UserHandle.getCallingUserId()); 18986 final StorageManager storage = mContext.getSystemService(StorageManager.class); 18987 final PackageManager pm = mContext.getPackageManager(); 18988 18989 final boolean currentAsec; 18990 final String currentVolumeUuid; 18991 final File codeFile; 18992 final String installerPackageName; 18993 final String packageAbiOverride; 18994 final int appId; 18995 final String seinfo; 18996 final String label; 18997 final int targetSdkVersion; 18998 18999 // reader 19000 synchronized (mPackages) { 19001 final PackageParser.Package pkg = mPackages.get(packageName); 19002 final PackageSetting ps = mSettings.mPackages.get(packageName); 19003 if (pkg == null || ps == null) { 19004 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package"); 19005 } 19006 19007 if (pkg.applicationInfo.isSystemApp()) { 19008 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE, 19009 "Cannot move system application"); 19010 } 19011 19012 if (pkg.applicationInfo.isExternalAsec()) { 19013 currentAsec = true; 19014 currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL; 19015 } else if (pkg.applicationInfo.isForwardLocked()) { 19016 currentAsec = true; 19017 currentVolumeUuid = "forward_locked"; 19018 } else { 19019 currentAsec = false; 19020 currentVolumeUuid = ps.volumeUuid; 19021 19022 final File probe = new File(pkg.codePath); 19023 final File probeOat = new File(probe, "oat"); 19024 if (!probe.isDirectory() || !probeOat.isDirectory()) { 19025 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 19026 "Move only supported for modern cluster style installs"); 19027 } 19028 } 19029 19030 if (Objects.equals(currentVolumeUuid, volumeUuid)) { 19031 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 19032 "Package already moved to " + volumeUuid); 19033 } 19034 if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) { 19035 throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN, 19036 "Device admin cannot be moved"); 19037 } 19038 19039 if (ps.frozen) { 19040 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING, 19041 "Failed to move already frozen package"); 19042 } 19043 ps.frozen = true; 19044 19045 codeFile = new File(pkg.codePath); 19046 installerPackageName = ps.installerPackageName; 19047 packageAbiOverride = ps.cpuAbiOverrideString; 19048 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 19049 seinfo = pkg.applicationInfo.seinfo; 19050 label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo)); 19051 targetSdkVersion = pkg.applicationInfo.targetSdkVersion; 19052 } 19053 19054 // Now that we're guarded by frozen state, kill app during move 19055 final long token = Binder.clearCallingIdentity(); 19056 try { 19057 killApplication(packageName, appId, "move pkg"); 19058 } finally { 19059 Binder.restoreCallingIdentity(token); 19060 } 19061 19062 final Bundle extras = new Bundle(); 19063 extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName); 19064 extras.putString(Intent.EXTRA_TITLE, label); 19065 mMoveCallbacks.notifyCreated(moveId, extras); 19066 19067 int installFlags; 19068 final boolean moveCompleteApp; 19069 final File measurePath; 19070 19071 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) { 19072 installFlags = INSTALL_INTERNAL; 19073 moveCompleteApp = !currentAsec; 19074 measurePath = Environment.getDataAppDirectory(volumeUuid); 19075 } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) { 19076 installFlags = INSTALL_EXTERNAL; 19077 moveCompleteApp = false; 19078 measurePath = storage.getPrimaryPhysicalVolume().getPath(); 19079 } else { 19080 final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid); 19081 if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE 19082 || !volume.isMountedWritable()) { 19083 unfreezePackage(packageName); 19084 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 19085 "Move location not mounted private volume"); 19086 } 19087 19088 Preconditions.checkState(!currentAsec); 19089 19090 installFlags = INSTALL_INTERNAL; 19091 moveCompleteApp = true; 19092 measurePath = Environment.getDataAppDirectory(volumeUuid); 19093 } 19094 19095 final PackageStats stats = new PackageStats(null, -1); 19096 synchronized (mInstaller) { 19097 if (!getPackageSizeInfoLI(packageName, -1, stats)) { 19098 unfreezePackage(packageName); 19099 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 19100 "Failed to measure package size"); 19101 } 19102 } 19103 19104 if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size " 19105 + stats.dataSize); 19106 19107 final long startFreeBytes = measurePath.getFreeSpace(); 19108 final long sizeBytes; 19109 if (moveCompleteApp) { 19110 sizeBytes = stats.codeSize + stats.dataSize; 19111 } else { 19112 sizeBytes = stats.codeSize; 19113 } 19114 19115 if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) { 19116 unfreezePackage(packageName); 19117 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 19118 "Not enough free space to move"); 19119 } 19120 19121 mMoveCallbacks.notifyStatusChanged(moveId, 10); 19122 19123 final CountDownLatch installedLatch = new CountDownLatch(1); 19124 final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() { 19125 @Override 19126 public void onUserActionRequired(Intent intent) throws RemoteException { 19127 throw new IllegalStateException(); 19128 } 19129 19130 @Override 19131 public void onPackageInstalled(String basePackageName, int returnCode, String msg, 19132 Bundle extras) throws RemoteException { 19133 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: " 19134 + PackageManager.installStatusToString(returnCode, msg)); 19135 19136 installedLatch.countDown(); 19137 19138 // Regardless of success or failure of the move operation, 19139 // always unfreeze the package 19140 unfreezePackage(packageName); 19141 19142 final int status = PackageManager.installStatusToPublicStatus(returnCode); 19143 switch (status) { 19144 case PackageInstaller.STATUS_SUCCESS: 19145 mMoveCallbacks.notifyStatusChanged(moveId, 19146 PackageManager.MOVE_SUCCEEDED); 19147 break; 19148 case PackageInstaller.STATUS_FAILURE_STORAGE: 19149 mMoveCallbacks.notifyStatusChanged(moveId, 19150 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE); 19151 break; 19152 default: 19153 mMoveCallbacks.notifyStatusChanged(moveId, 19154 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 19155 break; 19156 } 19157 } 19158 }; 19159 19160 final MoveInfo move; 19161 if (moveCompleteApp) { 19162 // Kick off a thread to report progress estimates 19163 new Thread() { 19164 @Override 19165 public void run() { 19166 while (true) { 19167 try { 19168 if (installedLatch.await(1, TimeUnit.SECONDS)) { 19169 break; 19170 } 19171 } catch (InterruptedException ignored) { 19172 } 19173 19174 final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace(); 19175 final int progress = 10 + (int) MathUtils.constrain( 19176 ((deltaFreeBytes * 80) / sizeBytes), 0, 80); 19177 mMoveCallbacks.notifyStatusChanged(moveId, progress); 19178 } 19179 } 19180 }.start(); 19181 19182 final String dataAppName = codeFile.getName(); 19183 move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName, 19184 dataAppName, appId, seinfo, targetSdkVersion); 19185 } else { 19186 move = null; 19187 } 19188 19189 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 19190 19191 final Message msg = mHandler.obtainMessage(INIT_COPY); 19192 final OriginInfo origin = OriginInfo.fromExistingFile(codeFile); 19193 final InstallParams params = new InstallParams(origin, move, installObserver, installFlags, 19194 installerPackageName, volumeUuid, null /*verificationInfo*/, user, 19195 packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/); 19196 params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params)); 19197 msg.obj = params; 19198 19199 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage", 19200 System.identityHashCode(msg.obj)); 19201 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 19202 System.identityHashCode(msg.obj)); 19203 19204 mHandler.sendMessage(msg); 19205 } 19206 19207 @Override 19208 public int movePrimaryStorage(String volumeUuid) throws RemoteException { 19209 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 19210 19211 final int realMoveId = mNextMoveId.getAndIncrement(); 19212 final Bundle extras = new Bundle(); 19213 extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid); 19214 mMoveCallbacks.notifyCreated(realMoveId, extras); 19215 19216 final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() { 19217 @Override 19218 public void onCreated(int moveId, Bundle extras) { 19219 // Ignored 19220 } 19221 19222 @Override 19223 public void onStatusChanged(int moveId, int status, long estMillis) { 19224 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis); 19225 } 19226 }; 19227 19228 final StorageManager storage = mContext.getSystemService(StorageManager.class); 19229 storage.setPrimaryStorageUuid(volumeUuid, callback); 19230 return realMoveId; 19231 } 19232 19233 @Override 19234 public int getMoveStatus(int moveId) { 19235 mContext.enforceCallingOrSelfPermission( 19236 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 19237 return mMoveCallbacks.mLastStatus.get(moveId); 19238 } 19239 19240 @Override 19241 public void registerMoveCallback(IPackageMoveObserver callback) { 19242 mContext.enforceCallingOrSelfPermission( 19243 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 19244 mMoveCallbacks.register(callback); 19245 } 19246 19247 @Override 19248 public void unregisterMoveCallback(IPackageMoveObserver callback) { 19249 mContext.enforceCallingOrSelfPermission( 19250 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 19251 mMoveCallbacks.unregister(callback); 19252 } 19253 19254 @Override 19255 public boolean setInstallLocation(int loc) { 19256 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, 19257 null); 19258 if (getInstallLocation() == loc) { 19259 return true; 19260 } 19261 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL 19262 || loc == PackageHelper.APP_INSTALL_EXTERNAL) { 19263 android.provider.Settings.Global.putInt(mContext.getContentResolver(), 19264 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc); 19265 return true; 19266 } 19267 return false; 19268 } 19269 19270 @Override 19271 public int getInstallLocation() { 19272 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 19273 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, 19274 PackageHelper.APP_INSTALL_AUTO); 19275 } 19276 19277 /** Called by UserManagerService */ 19278 void cleanUpUser(UserManagerService userManager, int userHandle) { 19279 synchronized (mPackages) { 19280 mDirtyUsers.remove(userHandle); 19281 mUserNeedsBadging.delete(userHandle); 19282 mSettings.removeUserLPw(userHandle); 19283 mPendingBroadcasts.remove(userHandle); 19284 mEphemeralApplicationRegistry.onUserRemovedLPw(userHandle); 19285 } 19286 synchronized (mInstallLock) { 19287 final StorageManager storage = mContext.getSystemService(StorageManager.class); 19288 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 19289 final String volumeUuid = vol.getFsUuid(); 19290 if (DEBUG_INSTALL) Slog.d(TAG, "Removing user data on volume " + volumeUuid); 19291 try { 19292 mInstaller.removeUserDataDirs(volumeUuid, userHandle); 19293 } catch (InstallerException e) { 19294 Slog.w(TAG, "Failed to remove user data", e); 19295 } 19296 } 19297 synchronized (mPackages) { 19298 removeUnusedPackagesLILPw(userManager, userHandle); 19299 } 19300 } 19301 } 19302 19303 /** 19304 * We're removing userHandle and would like to remove any downloaded packages 19305 * that are no longer in use by any other user. 19306 * @param userHandle the user being removed 19307 */ 19308 private void removeUnusedPackagesLILPw(UserManagerService userManager, final int userHandle) { 19309 final boolean DEBUG_CLEAN_APKS = false; 19310 int [] users = userManager.getUserIds(); 19311 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 19312 while (psit.hasNext()) { 19313 PackageSetting ps = psit.next(); 19314 if (ps.pkg == null) { 19315 continue; 19316 } 19317 final String packageName = ps.pkg.packageName; 19318 // Skip over if system app 19319 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) { 19320 continue; 19321 } 19322 if (DEBUG_CLEAN_APKS) { 19323 Slog.i(TAG, "Checking package " + packageName); 19324 } 19325 boolean keep = shouldKeepUninstalledPackageLPr(packageName); 19326 if (keep) { 19327 if (DEBUG_CLEAN_APKS) { 19328 Slog.i(TAG, " Keeping package " + packageName + " - requested by DO"); 19329 } 19330 } else { 19331 for (int i = 0; i < users.length; i++) { 19332 if (users[i] != userHandle && ps.getInstalled(users[i])) { 19333 keep = true; 19334 if (DEBUG_CLEAN_APKS) { 19335 Slog.i(TAG, " Keeping package " + packageName + " for user " 19336 + users[i]); 19337 } 19338 break; 19339 } 19340 } 19341 } 19342 if (!keep) { 19343 if (DEBUG_CLEAN_APKS) { 19344 Slog.i(TAG, " Removing package " + packageName); 19345 } 19346 mHandler.post(new Runnable() { 19347 public void run() { 19348 deletePackageX(packageName, userHandle, 0); 19349 } //end run 19350 }); 19351 } 19352 } 19353 } 19354 19355 /** Called by UserManagerService */ 19356 void createNewUser(int userHandle) { 19357 synchronized (mInstallLock) { 19358 try { 19359 mInstaller.createUserConfig(userHandle); 19360 } catch (InstallerException e) { 19361 Slog.w(TAG, "Failed to create user config", e); 19362 } 19363 mSettings.createNewUserLI(this, mInstaller, userHandle); 19364 } 19365 synchronized (mPackages) { 19366 applyFactoryDefaultBrowserLPw(userHandle); 19367 primeDomainVerificationsLPw(userHandle); 19368 } 19369 } 19370 19371 void newUserCreated(final int userHandle) { 19372 mDefaultPermissionPolicy.grantDefaultPermissions(userHandle); 19373 // If permission review for legacy apps is required, we represent 19374 // dagerous permissions for such apps as always granted runtime 19375 // permissions to keep per user flag state whether review is needed. 19376 // Hence, if a new user is added we have to propagate dangerous 19377 // permission grants for these legacy apps. 19378 if (Build.PERMISSIONS_REVIEW_REQUIRED) { 19379 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL 19380 | UPDATE_PERMISSIONS_REPLACE_ALL); 19381 } 19382 } 19383 19384 @Override 19385 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException { 19386 mContext.enforceCallingOrSelfPermission( 19387 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 19388 "Only package verification agents can read the verifier device identity"); 19389 19390 synchronized (mPackages) { 19391 return mSettings.getVerifierDeviceIdentityLPw(); 19392 } 19393 } 19394 19395 @Override 19396 public void setPermissionEnforced(String permission, boolean enforced) { 19397 // TODO: Now that we no longer change GID for storage, this should to away. 19398 mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 19399 "setPermissionEnforced"); 19400 if (READ_EXTERNAL_STORAGE.equals(permission)) { 19401 synchronized (mPackages) { 19402 if (mSettings.mReadExternalStorageEnforced == null 19403 || mSettings.mReadExternalStorageEnforced != enforced) { 19404 mSettings.mReadExternalStorageEnforced = enforced; 19405 mSettings.writeLPr(); 19406 } 19407 } 19408 // kill any non-foreground processes so we restart them and 19409 // grant/revoke the GID. 19410 final IActivityManager am = ActivityManagerNative.getDefault(); 19411 if (am != null) { 19412 final long token = Binder.clearCallingIdentity(); 19413 try { 19414 am.killProcessesBelowForeground("setPermissionEnforcement"); 19415 } catch (RemoteException e) { 19416 } finally { 19417 Binder.restoreCallingIdentity(token); 19418 } 19419 } 19420 } else { 19421 throw new IllegalArgumentException("No selective enforcement for " + permission); 19422 } 19423 } 19424 19425 @Override 19426 @Deprecated 19427 public boolean isPermissionEnforced(String permission) { 19428 return true; 19429 } 19430 19431 @Override 19432 public boolean isStorageLow() { 19433 final long token = Binder.clearCallingIdentity(); 19434 try { 19435 final DeviceStorageMonitorInternal 19436 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 19437 if (dsm != null) { 19438 return dsm.isMemoryLow(); 19439 } else { 19440 return false; 19441 } 19442 } finally { 19443 Binder.restoreCallingIdentity(token); 19444 } 19445 } 19446 19447 @Override 19448 public IPackageInstaller getPackageInstaller() { 19449 return mInstallerService; 19450 } 19451 19452 private boolean userNeedsBadging(int userId) { 19453 int index = mUserNeedsBadging.indexOfKey(userId); 19454 if (index < 0) { 19455 final UserInfo userInfo; 19456 final long token = Binder.clearCallingIdentity(); 19457 try { 19458 userInfo = sUserManager.getUserInfo(userId); 19459 } finally { 19460 Binder.restoreCallingIdentity(token); 19461 } 19462 final boolean b; 19463 if (userInfo != null && userInfo.isManagedProfile()) { 19464 b = true; 19465 } else { 19466 b = false; 19467 } 19468 mUserNeedsBadging.put(userId, b); 19469 return b; 19470 } 19471 return mUserNeedsBadging.valueAt(index); 19472 } 19473 19474 @Override 19475 public KeySet getKeySetByAlias(String packageName, String alias) { 19476 if (packageName == null || alias == null) { 19477 return null; 19478 } 19479 synchronized(mPackages) { 19480 final PackageParser.Package pkg = mPackages.get(packageName); 19481 if (pkg == null) { 19482 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 19483 throw new IllegalArgumentException("Unknown package: " + packageName); 19484 } 19485 KeySetManagerService ksms = mSettings.mKeySetManagerService; 19486 return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias)); 19487 } 19488 } 19489 19490 @Override 19491 public KeySet getSigningKeySet(String packageName) { 19492 if (packageName == null) { 19493 return null; 19494 } 19495 synchronized(mPackages) { 19496 final PackageParser.Package pkg = mPackages.get(packageName); 19497 if (pkg == null) { 19498 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 19499 throw new IllegalArgumentException("Unknown package: " + packageName); 19500 } 19501 if (pkg.applicationInfo.uid != Binder.getCallingUid() 19502 && Process.SYSTEM_UID != Binder.getCallingUid()) { 19503 throw new SecurityException("May not access signing KeySet of other apps."); 19504 } 19505 KeySetManagerService ksms = mSettings.mKeySetManagerService; 19506 return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName)); 19507 } 19508 } 19509 19510 @Override 19511 public boolean isPackageSignedByKeySet(String packageName, KeySet ks) { 19512 if (packageName == null || ks == null) { 19513 return false; 19514 } 19515 synchronized(mPackages) { 19516 final PackageParser.Package pkg = mPackages.get(packageName); 19517 if (pkg == null) { 19518 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 19519 throw new IllegalArgumentException("Unknown package: " + packageName); 19520 } 19521 IBinder ksh = ks.getToken(); 19522 if (ksh instanceof KeySetHandle) { 19523 KeySetManagerService ksms = mSettings.mKeySetManagerService; 19524 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh); 19525 } 19526 return false; 19527 } 19528 } 19529 19530 @Override 19531 public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) { 19532 if (packageName == null || ks == null) { 19533 return false; 19534 } 19535 synchronized(mPackages) { 19536 final PackageParser.Package pkg = mPackages.get(packageName); 19537 if (pkg == null) { 19538 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 19539 throw new IllegalArgumentException("Unknown package: " + packageName); 19540 } 19541 IBinder ksh = ks.getToken(); 19542 if (ksh instanceof KeySetHandle) { 19543 KeySetManagerService ksms = mSettings.mKeySetManagerService; 19544 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh); 19545 } 19546 return false; 19547 } 19548 } 19549 19550 private void deletePackageIfUnusedLPr(final String packageName) { 19551 PackageSetting ps = mSettings.mPackages.get(packageName); 19552 if (ps == null) { 19553 return; 19554 } 19555 if (!ps.isAnyInstalled(sUserManager.getUserIds())) { 19556 // TODO Implement atomic delete if package is unused 19557 // It is currently possible that the package will be deleted even if it is installed 19558 // after this method returns. 19559 mHandler.post(new Runnable() { 19560 public void run() { 19561 deletePackageX(packageName, 0, PackageManager.DELETE_ALL_USERS); 19562 } 19563 }); 19564 } 19565 } 19566 19567 /** 19568 * Check and throw if the given before/after packages would be considered a 19569 * downgrade. 19570 */ 19571 private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after) 19572 throws PackageManagerException { 19573 if (after.versionCode < before.mVersionCode) { 19574 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 19575 "Update version code " + after.versionCode + " is older than current " 19576 + before.mVersionCode); 19577 } else if (after.versionCode == before.mVersionCode) { 19578 if (after.baseRevisionCode < before.baseRevisionCode) { 19579 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 19580 "Update base revision code " + after.baseRevisionCode 19581 + " is older than current " + before.baseRevisionCode); 19582 } 19583 19584 if (!ArrayUtils.isEmpty(after.splitNames)) { 19585 for (int i = 0; i < after.splitNames.length; i++) { 19586 final String splitName = after.splitNames[i]; 19587 final int j = ArrayUtils.indexOf(before.splitNames, splitName); 19588 if (j != -1) { 19589 if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) { 19590 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 19591 "Update split " + splitName + " revision code " 19592 + after.splitRevisionCodes[i] + " is older than current " 19593 + before.splitRevisionCodes[j]); 19594 } 19595 } 19596 } 19597 } 19598 } 19599 } 19600 19601 private static class MoveCallbacks extends Handler { 19602 private static final int MSG_CREATED = 1; 19603 private static final int MSG_STATUS_CHANGED = 2; 19604 19605 private final RemoteCallbackList<IPackageMoveObserver> 19606 mCallbacks = new RemoteCallbackList<>(); 19607 19608 private final SparseIntArray mLastStatus = new SparseIntArray(); 19609 19610 public MoveCallbacks(Looper looper) { 19611 super(looper); 19612 } 19613 19614 public void register(IPackageMoveObserver callback) { 19615 mCallbacks.register(callback); 19616 } 19617 19618 public void unregister(IPackageMoveObserver callback) { 19619 mCallbacks.unregister(callback); 19620 } 19621 19622 @Override 19623 public void handleMessage(Message msg) { 19624 final SomeArgs args = (SomeArgs) msg.obj; 19625 final int n = mCallbacks.beginBroadcast(); 19626 for (int i = 0; i < n; i++) { 19627 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i); 19628 try { 19629 invokeCallback(callback, msg.what, args); 19630 } catch (RemoteException ignored) { 19631 } 19632 } 19633 mCallbacks.finishBroadcast(); 19634 args.recycle(); 19635 } 19636 19637 private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args) 19638 throws RemoteException { 19639 switch (what) { 19640 case MSG_CREATED: { 19641 callback.onCreated(args.argi1, (Bundle) args.arg2); 19642 break; 19643 } 19644 case MSG_STATUS_CHANGED: { 19645 callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3); 19646 break; 19647 } 19648 } 19649 } 19650 19651 private void notifyCreated(int moveId, Bundle extras) { 19652 Slog.v(TAG, "Move " + moveId + " created " + extras.toString()); 19653 19654 final SomeArgs args = SomeArgs.obtain(); 19655 args.argi1 = moveId; 19656 args.arg2 = extras; 19657 obtainMessage(MSG_CREATED, args).sendToTarget(); 19658 } 19659 19660 private void notifyStatusChanged(int moveId, int status) { 19661 notifyStatusChanged(moveId, status, -1); 19662 } 19663 19664 private void notifyStatusChanged(int moveId, int status, long estMillis) { 19665 Slog.v(TAG, "Move " + moveId + " status " + status); 19666 19667 final SomeArgs args = SomeArgs.obtain(); 19668 args.argi1 = moveId; 19669 args.argi2 = status; 19670 args.arg3 = estMillis; 19671 obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget(); 19672 19673 synchronized (mLastStatus) { 19674 mLastStatus.put(moveId, status); 19675 } 19676 } 19677 } 19678 19679 private final static class OnPermissionChangeListeners extends Handler { 19680 private static final int MSG_ON_PERMISSIONS_CHANGED = 1; 19681 19682 private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners = 19683 new RemoteCallbackList<>(); 19684 19685 public OnPermissionChangeListeners(Looper looper) { 19686 super(looper); 19687 } 19688 19689 @Override 19690 public void handleMessage(Message msg) { 19691 switch (msg.what) { 19692 case MSG_ON_PERMISSIONS_CHANGED: { 19693 final int uid = msg.arg1; 19694 handleOnPermissionsChanged(uid); 19695 } break; 19696 } 19697 } 19698 19699 public void addListenerLocked(IOnPermissionsChangeListener listener) { 19700 mPermissionListeners.register(listener); 19701 19702 } 19703 19704 public void removeListenerLocked(IOnPermissionsChangeListener listener) { 19705 mPermissionListeners.unregister(listener); 19706 } 19707 19708 public void onPermissionsChanged(int uid) { 19709 if (mPermissionListeners.getRegisteredCallbackCount() > 0) { 19710 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget(); 19711 } 19712 } 19713 19714 private void handleOnPermissionsChanged(int uid) { 19715 final int count = mPermissionListeners.beginBroadcast(); 19716 try { 19717 for (int i = 0; i < count; i++) { 19718 IOnPermissionsChangeListener callback = mPermissionListeners 19719 .getBroadcastItem(i); 19720 try { 19721 callback.onPermissionsChanged(uid); 19722 } catch (RemoteException e) { 19723 Log.e(TAG, "Permission listener is dead", e); 19724 } 19725 } 19726 } finally { 19727 mPermissionListeners.finishBroadcast(); 19728 } 19729 } 19730 } 19731 19732 private class PackageManagerInternalImpl extends PackageManagerInternal { 19733 @Override 19734 public void setLocationPackagesProvider(PackagesProvider provider) { 19735 synchronized (mPackages) { 19736 mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider); 19737 } 19738 } 19739 19740 @Override 19741 public void setVoiceInteractionPackagesProvider(PackagesProvider provider) { 19742 synchronized (mPackages) { 19743 mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider); 19744 } 19745 } 19746 19747 @Override 19748 public void setSmsAppPackagesProvider(PackagesProvider provider) { 19749 synchronized (mPackages) { 19750 mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider); 19751 } 19752 } 19753 19754 @Override 19755 public void setDialerAppPackagesProvider(PackagesProvider provider) { 19756 synchronized (mPackages) { 19757 mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider); 19758 } 19759 } 19760 19761 @Override 19762 public void setSimCallManagerPackagesProvider(PackagesProvider provider) { 19763 synchronized (mPackages) { 19764 mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider); 19765 } 19766 } 19767 19768 @Override 19769 public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) { 19770 synchronized (mPackages) { 19771 mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider); 19772 } 19773 } 19774 19775 @Override 19776 public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) { 19777 synchronized (mPackages) { 19778 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr( 19779 packageName, userId); 19780 } 19781 } 19782 19783 @Override 19784 public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) { 19785 synchronized (mPackages) { 19786 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr( 19787 packageName, userId); 19788 } 19789 } 19790 19791 @Override 19792 public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) { 19793 synchronized (mPackages) { 19794 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr( 19795 packageName, userId); 19796 } 19797 } 19798 19799 @Override 19800 public void setKeepUninstalledPackages(final List<String> packageList) { 19801 Preconditions.checkNotNull(packageList); 19802 List<String> removedFromList = null; 19803 synchronized (mPackages) { 19804 if (mKeepUninstalledPackages != null) { 19805 final int packagesCount = mKeepUninstalledPackages.size(); 19806 for (int i = 0; i < packagesCount; i++) { 19807 String oldPackage = mKeepUninstalledPackages.get(i); 19808 if (packageList != null && packageList.contains(oldPackage)) { 19809 continue; 19810 } 19811 if (removedFromList == null) { 19812 removedFromList = new ArrayList<>(); 19813 } 19814 removedFromList.add(oldPackage); 19815 } 19816 } 19817 mKeepUninstalledPackages = new ArrayList<>(packageList); 19818 if (removedFromList != null) { 19819 final int removedCount = removedFromList.size(); 19820 for (int i = 0; i < removedCount; i++) { 19821 deletePackageIfUnusedLPr(removedFromList.get(i)); 19822 } 19823 } 19824 } 19825 } 19826 19827 @Override 19828 public boolean isPermissionsReviewRequired(String packageName, int userId) { 19829 synchronized (mPackages) { 19830 // If we do not support permission review, done. 19831 if (!Build.PERMISSIONS_REVIEW_REQUIRED) { 19832 return false; 19833 } 19834 19835 PackageSetting packageSetting = mSettings.mPackages.get(packageName); 19836 if (packageSetting == null) { 19837 return false; 19838 } 19839 19840 // Permission review applies only to apps not supporting the new permission model. 19841 if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) { 19842 return false; 19843 } 19844 19845 // Legacy apps have the permission and get user consent on launch. 19846 PermissionsState permissionsState = packageSetting.getPermissionsState(); 19847 return permissionsState.isPermissionReviewRequired(userId); 19848 } 19849 } 19850 19851 @Override 19852 public ApplicationInfo getApplicationInfo(String packageName, int userId) { 19853 return PackageManagerService.this.getApplicationInfo(packageName, 0 /*flags*/, userId); 19854 } 19855 19856 @Override 19857 public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, 19858 int userId) { 19859 return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId); 19860 } 19861 } 19862 19863 @Override 19864 public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) { 19865 enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps"); 19866 synchronized (mPackages) { 19867 final long identity = Binder.clearCallingIdentity(); 19868 try { 19869 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr( 19870 packageNames, userId); 19871 } finally { 19872 Binder.restoreCallingIdentity(identity); 19873 } 19874 } 19875 } 19876 19877 private static void enforceSystemOrPhoneCaller(String tag) { 19878 int callingUid = Binder.getCallingUid(); 19879 if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) { 19880 throw new SecurityException( 19881 "Cannot call " + tag + " from UID " + callingUid); 19882 } 19883 } 19884 19885 boolean isHistoricalPackageUsageAvailable() { 19886 return mPackageUsage.isHistoricalPackageUsageAvailable(); 19887 } 19888 19889 /** 19890 * Return a <b>copy</b> of the collection of packages known to the package manager. 19891 * @return A copy of the values of mPackages. 19892 */ 19893 Collection<PackageParser.Package> getPackages() { 19894 synchronized (mPackages) { 19895 return new ArrayList<>(mPackages.values()); 19896 } 19897 } 19898 19899 /** 19900 * Logs process start information (including base APK hash) to the security log. 19901 * @hide 19902 */ 19903 public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo, 19904 String apkFile, int pid) { 19905 if (!SecurityLog.isLoggingEnabled()) { 19906 return; 19907 } 19908 Bundle data = new Bundle(); 19909 data.putLong("startTimestamp", System.currentTimeMillis()); 19910 data.putString("processName", processName); 19911 data.putInt("uid", uid); 19912 data.putString("seinfo", seinfo); 19913 data.putString("apkFile", apkFile); 19914 data.putInt("pid", pid); 19915 Message msg = mProcessLoggingHandler.obtainMessage( 19916 ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG); 19917 msg.setData(data); 19918 mProcessLoggingHandler.sendMessage(msg); 19919 } 19920} 19921