PackageManagerService.java revision 13810374a47f783e89092a5232f0ac5da21da403
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_DUPLICATE_PACKAGE; 39import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION; 40import static android.content.pm.PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID; 41import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 42import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 43import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK; 44import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 45import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY; 46import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED; 47import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE; 48import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE; 49import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY; 50import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE; 51import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED; 52import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 53import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK; 54import static android.content.pm.PackageManager.INSTALL_INTERNAL; 55import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES; 56import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 57import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK; 58import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 59import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER; 60import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 61import static android.content.pm.PackageManager.MATCH_ALL; 62import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING; 63import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE; 64import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE; 65import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS; 66import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY; 67import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY; 68import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES; 69import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN; 70import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST; 71import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR; 72import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING; 73import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE; 74import static android.content.pm.PackageManager.PERMISSION_DENIED; 75import static android.content.pm.PackageManager.PERMISSION_GRANTED; 76import static android.content.pm.PackageParser.PARSE_IS_PRIVILEGED; 77import static android.content.pm.PackageParser.isApkFile; 78import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; 79import static android.system.OsConstants.O_CREAT; 80import static android.system.OsConstants.O_RDWR; 81 82import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE; 83import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT; 84import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME; 85import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME; 86import static com.android.internal.util.ArrayUtils.appendInt; 87import static com.android.server.pm.Installer.DEXOPT_PUBLIC; 88import static com.android.server.pm.InstructionSets.getAppDexInstructionSets; 89import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet; 90import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets; 91import static com.android.server.pm.InstructionSets.getPreferredInstructionSet; 92import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet; 93import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason; 94import static com.android.server.pm.PackageManagerServiceCompilerMapping.getFullCompilerFilter; 95import static com.android.server.pm.PackageManagerServiceCompilerMapping.getNonProfileGuidedCompilerFilter; 96import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE; 97import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS; 98import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED; 99 100import android.Manifest; 101import android.annotation.NonNull; 102import android.annotation.Nullable; 103import android.app.ActivityManager; 104import android.app.ActivityManagerNative; 105import android.app.IActivityManager; 106import android.app.ResourcesManager; 107import android.app.admin.IDevicePolicyManager; 108import android.app.admin.SecurityLog; 109import android.app.backup.IBackupManager; 110import android.content.BroadcastReceiver; 111import android.content.ComponentName; 112import android.content.ContentResolver; 113import android.content.Context; 114import android.content.IIntentReceiver; 115import android.content.Intent; 116import android.content.IntentFilter; 117import android.content.IntentSender; 118import android.content.IntentSender.SendIntentException; 119import android.content.ServiceConnection; 120import android.content.pm.ActivityInfo; 121import android.content.pm.ApplicationInfo; 122import android.content.pm.AppsQueryHelper; 123import android.content.pm.ComponentInfo; 124import android.content.pm.EphemeralApplicationInfo; 125import android.content.pm.EphemeralResolveInfo; 126import android.content.pm.EphemeralResolveInfo.EphemeralDigest; 127import android.content.pm.EphemeralResolveInfo.EphemeralResolveIntentInfo; 128import android.content.pm.FeatureInfo; 129import android.content.pm.IOnPermissionsChangeListener; 130import android.content.pm.IPackageDataObserver; 131import android.content.pm.IPackageDeleteObserver; 132import android.content.pm.IPackageDeleteObserver2; 133import android.content.pm.IPackageInstallObserver2; 134import android.content.pm.IPackageInstaller; 135import android.content.pm.IPackageManager; 136import android.content.pm.IPackageMoveObserver; 137import android.content.pm.IPackageStatsObserver; 138import android.content.pm.InstrumentationInfo; 139import android.content.pm.IntentFilterVerificationInfo; 140import android.content.pm.KeySet; 141import android.content.pm.PackageCleanItem; 142import android.content.pm.PackageInfo; 143import android.content.pm.PackageInfoLite; 144import android.content.pm.PackageInstaller; 145import android.content.pm.PackageManager; 146import android.content.pm.PackageManager.LegacyPackageDeleteObserver; 147import android.content.pm.PackageManagerInternal; 148import android.content.pm.PackageParser; 149import android.content.pm.PackageParser.ActivityIntentInfo; 150import android.content.pm.PackageParser.PackageLite; 151import android.content.pm.PackageParser.PackageParserException; 152import android.content.pm.PackageStats; 153import android.content.pm.PackageUserState; 154import android.content.pm.ParceledListSlice; 155import android.content.pm.PermissionGroupInfo; 156import android.content.pm.PermissionInfo; 157import android.content.pm.ProviderInfo; 158import android.content.pm.ResolveInfo; 159import android.content.pm.ServiceInfo; 160import android.content.pm.Signature; 161import android.content.pm.UserInfo; 162import android.content.pm.VerifierDeviceIdentity; 163import android.content.pm.VerifierInfo; 164import android.content.res.Resources; 165import android.graphics.Bitmap; 166import android.hardware.display.DisplayManager; 167import android.net.Uri; 168import android.os.Binder; 169import android.os.Build; 170import android.os.Bundle; 171import android.os.Debug; 172import android.os.Environment; 173import android.os.Environment.UserEnvironment; 174import android.os.FileUtils; 175import android.os.Handler; 176import android.os.IBinder; 177import android.os.Looper; 178import android.os.Message; 179import android.os.Parcel; 180import android.os.ParcelFileDescriptor; 181import android.os.PatternMatcher; 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.ShellCallback; 189import android.os.SystemClock; 190import android.os.SystemProperties; 191import android.os.Trace; 192import android.os.UserHandle; 193import android.os.UserManager; 194import android.os.UserManagerInternal; 195import android.os.storage.IMountService; 196import android.os.storage.MountServiceInternal; 197import android.os.storage.StorageEventListener; 198import android.os.storage.StorageManager; 199import android.os.storage.VolumeInfo; 200import android.os.storage.VolumeRecord; 201import android.provider.Settings.Global; 202import android.provider.Settings.Secure; 203import android.security.KeyStore; 204import android.security.SystemKeyStore; 205import android.system.ErrnoException; 206import android.system.Os; 207import android.text.TextUtils; 208import android.text.format.DateUtils; 209import android.util.ArrayMap; 210import android.util.ArraySet; 211import android.util.DisplayMetrics; 212import android.util.EventLog; 213import android.util.ExceptionUtils; 214import android.util.Log; 215import android.util.LogPrinter; 216import android.util.MathUtils; 217import android.util.Pair; 218import android.util.PrintStreamPrinter; 219import android.util.Slog; 220import android.util.SparseArray; 221import android.util.SparseBooleanArray; 222import android.util.SparseIntArray; 223import android.util.Xml; 224import android.util.jar.StrictJarFile; 225import android.view.Display; 226 227import com.android.internal.R; 228import com.android.internal.annotations.GuardedBy; 229import com.android.internal.app.IMediaContainerService; 230import com.android.internal.app.ResolverActivity; 231import com.android.internal.content.NativeLibraryHelper; 232import com.android.internal.content.PackageHelper; 233import com.android.internal.logging.MetricsLogger; 234import com.android.internal.os.IParcelFileDescriptorFactory; 235import com.android.internal.os.InstallerConnection.InstallerException; 236import com.android.internal.os.SomeArgs; 237import com.android.internal.os.Zygote; 238import com.android.internal.telephony.CarrierAppUtils; 239import com.android.internal.util.ArrayUtils; 240import com.android.internal.util.FastPrintWriter; 241import com.android.internal.util.FastXmlSerializer; 242import com.android.internal.util.IndentingPrintWriter; 243import com.android.internal.util.Preconditions; 244import com.android.internal.util.XmlUtils; 245import com.android.server.AttributeCache; 246import com.android.server.EventLogTags; 247import com.android.server.FgThread; 248import com.android.server.IntentResolver; 249import com.android.server.LocalServices; 250import com.android.server.ServiceThread; 251import com.android.server.SystemConfig; 252import com.android.server.Watchdog; 253import com.android.server.net.NetworkPolicyManagerInternal; 254import com.android.server.pm.PermissionsState.PermissionState; 255import com.android.server.pm.Settings.DatabaseVersion; 256import com.android.server.pm.Settings.VersionInfo; 257import com.android.server.storage.DeviceStorageMonitorInternal; 258 259import dalvik.system.CloseGuard; 260import dalvik.system.DexFile; 261import dalvik.system.VMRuntime; 262 263import libcore.io.IoUtils; 264import libcore.util.EmptyArray; 265 266import org.xmlpull.v1.XmlPullParser; 267import org.xmlpull.v1.XmlPullParserException; 268import org.xmlpull.v1.XmlSerializer; 269 270import java.io.BufferedOutputStream; 271import java.io.BufferedReader; 272import java.io.ByteArrayInputStream; 273import java.io.ByteArrayOutputStream; 274import java.io.File; 275import java.io.FileDescriptor; 276import java.io.FileInputStream; 277import java.io.FileNotFoundException; 278import java.io.FileOutputStream; 279import java.io.FileReader; 280import java.io.FilenameFilter; 281import java.io.IOException; 282import java.io.PrintWriter; 283import java.nio.charset.StandardCharsets; 284import java.security.DigestInputStream; 285import java.security.MessageDigest; 286import java.security.NoSuchAlgorithmException; 287import java.security.PublicKey; 288import java.security.cert.Certificate; 289import java.security.cert.CertificateEncodingException; 290import java.security.cert.CertificateException; 291import java.text.SimpleDateFormat; 292import java.util.ArrayList; 293import java.util.Arrays; 294import java.util.Collection; 295import java.util.Collections; 296import java.util.Comparator; 297import java.util.Date; 298import java.util.HashSet; 299import java.util.Iterator; 300import java.util.List; 301import java.util.Map; 302import java.util.Objects; 303import java.util.Set; 304import java.util.concurrent.CountDownLatch; 305import java.util.concurrent.TimeUnit; 306import java.util.concurrent.atomic.AtomicBoolean; 307import java.util.concurrent.atomic.AtomicInteger; 308 309/** 310 * Keep track of all those APKs everywhere. 311 * <p> 312 * Internally there are two important locks: 313 * <ul> 314 * <li>{@link #mPackages} is used to guard all in-memory parsed package details 315 * and other related state. It is a fine-grained lock that should only be held 316 * momentarily, as it's one of the most contended locks in the system. 317 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose 318 * operations typically involve heavy lifting of application data on disk. Since 319 * {@code installd} is single-threaded, and it's operations can often be slow, 320 * this lock should never be acquired while already holding {@link #mPackages}. 321 * Conversely, it's safe to acquire {@link #mPackages} momentarily while already 322 * holding {@link #mInstallLock}. 323 * </ul> 324 * Many internal methods rely on the caller to hold the appropriate locks, and 325 * this contract is expressed through method name suffixes: 326 * <ul> 327 * <li>fooLI(): the caller must hold {@link #mInstallLock} 328 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package 329 * being modified must be frozen 330 * <li>fooLPr(): the caller must hold {@link #mPackages} for reading 331 * <li>fooLPw(): the caller must hold {@link #mPackages} for writing 332 * </ul> 333 * <p> 334 * Because this class is very central to the platform's security; please run all 335 * CTS and unit tests whenever making modifications: 336 * 337 * <pre> 338 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core 339 * $ cts-tradefed run commandAndExit cts -m AppSecurityTests 340 * </pre> 341 */ 342public class PackageManagerService extends IPackageManager.Stub { 343 static final String TAG = "PackageManager"; 344 static final boolean DEBUG_SETTINGS = false; 345 static final boolean DEBUG_PREFERRED = false; 346 static final boolean DEBUG_UPGRADE = false; 347 static final boolean DEBUG_DOMAIN_VERIFICATION = false; 348 private static final boolean DEBUG_BACKUP = false; 349 private static final boolean DEBUG_INSTALL = false; 350 private static final boolean DEBUG_REMOVE = false; 351 private static final boolean DEBUG_BROADCASTS = false; 352 private static final boolean DEBUG_SHOW_INFO = false; 353 private static final boolean DEBUG_PACKAGE_INFO = false; 354 private static final boolean DEBUG_INTENT_MATCHING = false; 355 private static final boolean DEBUG_PACKAGE_SCANNING = false; 356 private static final boolean DEBUG_VERIFY = false; 357 private static final boolean DEBUG_FILTERS = false; 358 359 // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService 360 // and PackageDexOptimizer. All these classes have their own flag to allow switching a single 361 // user, but by default initialize to this. 362 static final boolean DEBUG_DEXOPT = false; 363 364 private static final boolean DEBUG_ABI_SELECTION = false; 365 private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE; 366 private static final boolean DEBUG_TRIAGED_MISSING = false; 367 private static final boolean DEBUG_APP_DATA = false; 368 369 /** REMOVE. According to Svet, this was only used to reset permissions during development. */ 370 static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false; 371 372 private static final boolean DISABLE_EPHEMERAL_APPS = false; 373 private static final boolean HIDE_EPHEMERAL_APIS = true; 374 375 private static final int RADIO_UID = Process.PHONE_UID; 376 private static final int LOG_UID = Process.LOG_UID; 377 private static final int NFC_UID = Process.NFC_UID; 378 private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID; 379 private static final int SHELL_UID = Process.SHELL_UID; 380 381 // Cap the size of permission trees that 3rd party apps can define 382 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768; // characters of text 383 384 // Suffix used during package installation when copying/moving 385 // package apks to install directory. 386 private static final String INSTALL_PACKAGE_SUFFIX = "-"; 387 388 static final int SCAN_NO_DEX = 1<<1; 389 static final int SCAN_FORCE_DEX = 1<<2; 390 static final int SCAN_UPDATE_SIGNATURE = 1<<3; 391 static final int SCAN_NEW_INSTALL = 1<<4; 392 static final int SCAN_NO_PATHS = 1<<5; 393 static final int SCAN_UPDATE_TIME = 1<<6; 394 static final int SCAN_DEFER_DEX = 1<<7; 395 static final int SCAN_BOOTING = 1<<8; 396 static final int SCAN_TRUSTED_OVERLAY = 1<<9; 397 static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10; 398 static final int SCAN_REPLACING = 1<<11; 399 static final int SCAN_REQUIRE_KNOWN = 1<<12; 400 static final int SCAN_MOVE = 1<<13; 401 static final int SCAN_INITIAL = 1<<14; 402 static final int SCAN_CHECK_ONLY = 1<<15; 403 static final int SCAN_DONT_KILL_APP = 1<<17; 404 static final int SCAN_IGNORE_FROZEN = 1<<18; 405 406 static final int REMOVE_CHATTY = 1<<16; 407 408 private static final int[] EMPTY_INT_ARRAY = new int[0]; 409 410 /** 411 * Timeout (in milliseconds) after which the watchdog should declare that 412 * our handler thread is wedged. The usual default for such things is one 413 * minute but we sometimes do very lengthy I/O operations on this thread, 414 * such as installing multi-gigabyte applications, so ours needs to be longer. 415 */ 416 private static final long WATCHDOG_TIMEOUT = 1000*60*10; // ten minutes 417 418 /** 419 * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim 420 * be run on this device. We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL 421 * settings entry if available, otherwise we use the hardcoded default. If it's been 422 * more than this long since the last fstrim, we force one during the boot sequence. 423 * 424 * This backstops other fstrim scheduling: if the device is alive at midnight+idle, 425 * one gets run at the next available charging+idle time. This final mandatory 426 * no-fstrim check kicks in only of the other scheduling criteria is never met. 427 */ 428 private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS; 429 430 /** 431 * Whether verification is enabled by default. 432 */ 433 private static final boolean DEFAULT_VERIFY_ENABLE = true; 434 435 /** 436 * The default maximum time to wait for the verification agent to return in 437 * milliseconds. 438 */ 439 private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000; 440 441 /** 442 * The default response for package verification timeout. 443 * 444 * This can be either PackageManager.VERIFICATION_ALLOW or 445 * PackageManager.VERIFICATION_REJECT. 446 */ 447 private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW; 448 449 static final String PLATFORM_PACKAGE_NAME = "android"; 450 451 static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer"; 452 453 static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName( 454 DEFAULT_CONTAINER_PACKAGE, 455 "com.android.defcontainer.DefaultContainerService"); 456 457 private static final String KILL_APP_REASON_GIDS_CHANGED = 458 "permission grant or revoke changed gids"; 459 460 private static final String KILL_APP_REASON_PERMISSIONS_REVOKED = 461 "permissions revoked"; 462 463 private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive"; 464 465 private static final String PACKAGE_SCHEME = "package"; 466 467 private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay"; 468 /** 469 * If VENDOR_OVERLAY_THEME_PROPERTY is set, search for runtime resource overlay APKs also in 470 * VENDOR_OVERLAY_DIR/<value of VENDOR_OVERLAY_THEME_PROPERTY> in addition to 471 * VENDOR_OVERLAY_DIR. 472 */ 473 private static final String VENDOR_OVERLAY_THEME_PROPERTY = "ro.boot.vendor.overlay.theme"; 474 475 private static int DEFAULT_EPHEMERAL_HASH_PREFIX_MASK = 0xFFFFF000; 476 private static int DEFAULT_EPHEMERAL_HASH_PREFIX_COUNT = 5; 477 478 /** Permission grant: not grant the permission. */ 479 private static final int GRANT_DENIED = 1; 480 481 /** Permission grant: grant the permission as an install permission. */ 482 private static final int GRANT_INSTALL = 2; 483 484 /** Permission grant: grant the permission as a runtime one. */ 485 private static final int GRANT_RUNTIME = 3; 486 487 /** Permission grant: grant as runtime a permission that was granted as an install time one. */ 488 private static final int GRANT_UPGRADE = 4; 489 490 /** Canonical intent used to identify what counts as a "web browser" app */ 491 private static final Intent sBrowserIntent; 492 static { 493 sBrowserIntent = new Intent(); 494 sBrowserIntent.setAction(Intent.ACTION_VIEW); 495 sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE); 496 sBrowserIntent.setData(Uri.parse("http:")); 497 } 498 499 /** 500 * The set of all protected actions [i.e. those actions for which a high priority 501 * intent filter is disallowed]. 502 */ 503 private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>(); 504 static { 505 PROTECTED_ACTIONS.add(Intent.ACTION_SEND); 506 PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO); 507 PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE); 508 PROTECTED_ACTIONS.add(Intent.ACTION_VIEW); 509 } 510 511 // Compilation reasons. 512 public static final int REASON_FIRST_BOOT = 0; 513 public static final int REASON_BOOT = 1; 514 public static final int REASON_INSTALL = 2; 515 public static final int REASON_BACKGROUND_DEXOPT = 3; 516 public static final int REASON_AB_OTA = 4; 517 public static final int REASON_NON_SYSTEM_LIBRARY = 5; 518 public static final int REASON_SHARED_APK = 6; 519 public static final int REASON_FORCED_DEXOPT = 7; 520 public static final int REASON_CORE_APP = 8; 521 522 public static final int REASON_LAST = REASON_CORE_APP; 523 524 /** Special library name that skips shared libraries check during compilation. */ 525 private static final String SKIP_SHARED_LIBRARY_CHECK = "&"; 526 527 final ServiceThread mHandlerThread; 528 529 final PackageHandler mHandler; 530 531 private final ProcessLoggingHandler mProcessLoggingHandler; 532 533 /** 534 * Messages for {@link #mHandler} that need to wait for system ready before 535 * being dispatched. 536 */ 537 private ArrayList<Message> mPostSystemReadyMessages; 538 539 final int mSdkVersion = Build.VERSION.SDK_INT; 540 541 final Context mContext; 542 final boolean mFactoryTest; 543 final boolean mOnlyCore; 544 final DisplayMetrics mMetrics; 545 final int mDefParseFlags; 546 final String[] mSeparateProcesses; 547 final boolean mIsUpgrade; 548 final boolean mIsPreNUpgrade; 549 final boolean mIsPreNMR1Upgrade; 550 551 @GuardedBy("mPackages") 552 private boolean mDexOptDialogShown; 553 554 /** The location for ASEC container files on internal storage. */ 555 final String mAsecInternalPath; 556 557 // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages 558 // LOCK HELD. Can be called with mInstallLock held. 559 @GuardedBy("mInstallLock") 560 final Installer mInstaller; 561 562 /** Directory where installed third-party apps stored */ 563 final File mAppInstallDir; 564 final File mEphemeralInstallDir; 565 566 /** 567 * Directory to which applications installed internally have their 568 * 32 bit native libraries copied. 569 */ 570 private File mAppLib32InstallDir; 571 572 // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked 573 // apps. 574 final File mDrmAppPrivateInstallDir; 575 576 // ---------------------------------------------------------------- 577 578 // Lock for state used when installing and doing other long running 579 // operations. Methods that must be called with this lock held have 580 // the suffix "LI". 581 final Object mInstallLock = new Object(); 582 583 // ---------------------------------------------------------------- 584 585 // Keys are String (package name), values are Package. This also serves 586 // as the lock for the global state. Methods that must be called with 587 // this lock held have the prefix "LP". 588 @GuardedBy("mPackages") 589 final ArrayMap<String, PackageParser.Package> mPackages = 590 new ArrayMap<String, PackageParser.Package>(); 591 592 final ArrayMap<String, Set<String>> mKnownCodebase = 593 new ArrayMap<String, Set<String>>(); 594 595 // Tracks available target package names -> overlay package paths. 596 final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays = 597 new ArrayMap<String, ArrayMap<String, PackageParser.Package>>(); 598 599 /** 600 * Tracks new system packages [received in an OTA] that we expect to 601 * find updated user-installed versions. Keys are package name, values 602 * are package location. 603 */ 604 final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>(); 605 /** 606 * Tracks high priority intent filters for protected actions. During boot, certain 607 * filter actions are protected and should never be allowed to have a high priority 608 * intent filter for them. However, there is one, and only one exception -- the 609 * setup wizard. It must be able to define a high priority intent filter for these 610 * actions to ensure there are no escapes from the wizard. We need to delay processing 611 * of these during boot as we need to look at all of the system packages in order 612 * to know which component is the setup wizard. 613 */ 614 private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>(); 615 /** 616 * Whether or not processing protected filters should be deferred. 617 */ 618 private boolean mDeferProtectedFilters = true; 619 620 /** 621 * Tracks existing system packages prior to receiving an OTA. Keys are package name. 622 */ 623 final private ArraySet<String> mExistingSystemPackages = new ArraySet<>(); 624 /** 625 * Whether or not system app permissions should be promoted from install to runtime. 626 */ 627 boolean mPromoteSystemApps; 628 629 @GuardedBy("mPackages") 630 final Settings mSettings; 631 632 /** 633 * Set of package names that are currently "frozen", which means active 634 * surgery is being done on the code/data for that package. The platform 635 * will refuse to launch frozen packages to avoid race conditions. 636 * 637 * @see PackageFreezer 638 */ 639 @GuardedBy("mPackages") 640 final ArraySet<String> mFrozenPackages = new ArraySet<>(); 641 642 final ProtectedPackages mProtectedPackages; 643 644 boolean mFirstBoot; 645 646 // System configuration read by SystemConfig. 647 final int[] mGlobalGids; 648 final SparseArray<ArraySet<String>> mSystemPermissions; 649 final ArrayMap<String, FeatureInfo> mAvailableFeatures; 650 651 // If mac_permissions.xml was found for seinfo labeling. 652 boolean mFoundPolicyFile; 653 654 private final EphemeralApplicationRegistry mEphemeralApplicationRegistry; 655 656 public static final class SharedLibraryEntry { 657 public final String path; 658 public final String apk; 659 660 SharedLibraryEntry(String _path, String _apk) { 661 path = _path; 662 apk = _apk; 663 } 664 } 665 666 // Currently known shared libraries. 667 final ArrayMap<String, SharedLibraryEntry> mSharedLibraries = 668 new ArrayMap<String, SharedLibraryEntry>(); 669 670 // All available activities, for your resolving pleasure. 671 final ActivityIntentResolver mActivities = 672 new ActivityIntentResolver(); 673 674 // All available receivers, for your resolving pleasure. 675 final ActivityIntentResolver mReceivers = 676 new ActivityIntentResolver(); 677 678 // All available services, for your resolving pleasure. 679 final ServiceIntentResolver mServices = new ServiceIntentResolver(); 680 681 // All available providers, for your resolving pleasure. 682 final ProviderIntentResolver mProviders = new ProviderIntentResolver(); 683 684 // Mapping from provider base names (first directory in content URI codePath) 685 // to the provider information. 686 final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority = 687 new ArrayMap<String, PackageParser.Provider>(); 688 689 // Mapping from instrumentation class names to info about them. 690 final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation = 691 new ArrayMap<ComponentName, PackageParser.Instrumentation>(); 692 693 // Mapping from permission names to info about them. 694 final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups = 695 new ArrayMap<String, PackageParser.PermissionGroup>(); 696 697 // Packages whose data we have transfered into another package, thus 698 // should no longer exist. 699 final ArraySet<String> mTransferedPackages = new ArraySet<String>(); 700 701 // Broadcast actions that are only available to the system. 702 final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>(); 703 704 /** List of packages waiting for verification. */ 705 final SparseArray<PackageVerificationState> mPendingVerification 706 = new SparseArray<PackageVerificationState>(); 707 708 /** Set of packages associated with each app op permission. */ 709 final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>(); 710 711 final PackageInstallerService mInstallerService; 712 713 private final PackageDexOptimizer mPackageDexOptimizer; 714 715 private AtomicInteger mNextMoveId = new AtomicInteger(); 716 private final MoveCallbacks mMoveCallbacks; 717 718 private final OnPermissionChangeListeners mOnPermissionChangeListeners; 719 720 // Cache of users who need badging. 721 SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray(); 722 723 /** Token for keys in mPendingVerification. */ 724 private int mPendingVerificationToken = 0; 725 726 volatile boolean mSystemReady; 727 volatile boolean mSafeMode; 728 volatile boolean mHasSystemUidErrors; 729 730 ApplicationInfo mAndroidApplication; 731 final ActivityInfo mResolveActivity = new ActivityInfo(); 732 final ResolveInfo mResolveInfo = new ResolveInfo(); 733 ComponentName mResolveComponentName; 734 PackageParser.Package mPlatformPackage; 735 ComponentName mCustomResolverComponentName; 736 737 boolean mResolverReplaced = false; 738 739 private final @Nullable ComponentName mIntentFilterVerifierComponent; 740 private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier; 741 742 private int mIntentFilterVerificationToken = 0; 743 744 /** Component that knows whether or not an ephemeral application exists */ 745 final ComponentName mEphemeralResolverComponent; 746 /** The service connection to the ephemeral resolver */ 747 final EphemeralResolverConnection mEphemeralResolverConnection; 748 749 /** Component used to install ephemeral applications */ 750 final ComponentName mEphemeralInstallerComponent; 751 final ActivityInfo mEphemeralInstallerActivity = new ActivityInfo(); 752 final ResolveInfo mEphemeralInstallerInfo = new ResolveInfo(); 753 754 final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates 755 = new SparseArray<IntentFilterVerificationState>(); 756 757 final DefaultPermissionGrantPolicy mDefaultPermissionPolicy; 758 759 // List of packages names to keep cached, even if they are uninstalled for all users 760 private List<String> mKeepUninstalledPackages; 761 762 private UserManagerInternal mUserManagerInternal; 763 764 private static class IFVerificationParams { 765 PackageParser.Package pkg; 766 boolean replacing; 767 int userId; 768 int verifierUid; 769 770 public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing, 771 int _userId, int _verifierUid) { 772 pkg = _pkg; 773 replacing = _replacing; 774 userId = _userId; 775 replacing = _replacing; 776 verifierUid = _verifierUid; 777 } 778 } 779 780 private interface IntentFilterVerifier<T extends IntentFilter> { 781 boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId, 782 T filter, String packageName); 783 void startVerifications(int userId); 784 void receiveVerificationResponse(int verificationId); 785 } 786 787 private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> { 788 private Context mContext; 789 private ComponentName mIntentFilterVerifierComponent; 790 private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>(); 791 792 public IntentVerifierProxy(Context context, ComponentName verifierComponent) { 793 mContext = context; 794 mIntentFilterVerifierComponent = verifierComponent; 795 } 796 797 private String getDefaultScheme() { 798 return IntentFilter.SCHEME_HTTPS; 799 } 800 801 @Override 802 public void startVerifications(int userId) { 803 // Launch verifications requests 804 int count = mCurrentIntentFilterVerifications.size(); 805 for (int n=0; n<count; n++) { 806 int verificationId = mCurrentIntentFilterVerifications.get(n); 807 final IntentFilterVerificationState ivs = 808 mIntentFilterVerificationStates.get(verificationId); 809 810 String packageName = ivs.getPackageName(); 811 812 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 813 final int filterCount = filters.size(); 814 ArraySet<String> domainsSet = new ArraySet<>(); 815 for (int m=0; m<filterCount; m++) { 816 PackageParser.ActivityIntentInfo filter = filters.get(m); 817 domainsSet.addAll(filter.getHostsList()); 818 } 819 synchronized (mPackages) { 820 if (mSettings.createIntentFilterVerificationIfNeededLPw( 821 packageName, domainsSet) != null) { 822 scheduleWriteSettingsLocked(); 823 } 824 } 825 sendVerificationRequest(userId, verificationId, ivs); 826 } 827 mCurrentIntentFilterVerifications.clear(); 828 } 829 830 private void sendVerificationRequest(int userId, int verificationId, 831 IntentFilterVerificationState ivs) { 832 833 Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 834 verificationIntent.putExtra( 835 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID, 836 verificationId); 837 verificationIntent.putExtra( 838 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME, 839 getDefaultScheme()); 840 verificationIntent.putExtra( 841 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS, 842 ivs.getHostsString()); 843 verificationIntent.putExtra( 844 PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME, 845 ivs.getPackageName()); 846 verificationIntent.setComponent(mIntentFilterVerifierComponent); 847 verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 848 849 UserHandle user = new UserHandle(userId); 850 mContext.sendBroadcastAsUser(verificationIntent, user); 851 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 852 "Sending IntentFilter verification broadcast"); 853 } 854 855 public void receiveVerificationResponse(int verificationId) { 856 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 857 858 final boolean verified = ivs.isVerified(); 859 860 ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); 861 final int count = filters.size(); 862 if (DEBUG_DOMAIN_VERIFICATION) { 863 Slog.i(TAG, "Received verification response " + verificationId 864 + " for " + count + " filters, verified=" + verified); 865 } 866 for (int n=0; n<count; n++) { 867 PackageParser.ActivityIntentInfo filter = filters.get(n); 868 filter.setVerified(verified); 869 870 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString() 871 + " verified with result:" + verified + " and hosts:" 872 + ivs.getHostsString()); 873 } 874 875 mIntentFilterVerificationStates.remove(verificationId); 876 877 final String packageName = ivs.getPackageName(); 878 IntentFilterVerificationInfo ivi = null; 879 880 synchronized (mPackages) { 881 ivi = mSettings.getIntentFilterVerificationLPr(packageName); 882 } 883 if (ivi == null) { 884 Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:" 885 + verificationId + " packageName:" + packageName); 886 return; 887 } 888 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 889 "Updating IntentFilterVerificationInfo for package " + packageName 890 +" verificationId:" + verificationId); 891 892 synchronized (mPackages) { 893 if (verified) { 894 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS); 895 } else { 896 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK); 897 } 898 scheduleWriteSettingsLocked(); 899 900 final int userId = ivs.getUserId(); 901 if (userId != UserHandle.USER_ALL) { 902 final int userStatus = 903 mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 904 905 int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 906 boolean needUpdate = false; 907 908 // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have 909 // already been set by the User thru the Disambiguation dialog 910 switch (userStatus) { 911 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 912 if (verified) { 913 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 914 } else { 915 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 916 } 917 needUpdate = true; 918 break; 919 920 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 921 if (verified) { 922 updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 923 needUpdate = true; 924 } 925 break; 926 927 default: 928 // Nothing to do 929 } 930 931 if (needUpdate) { 932 mSettings.updateIntentFilterVerificationStatusLPw( 933 packageName, updatedStatus, userId); 934 scheduleWritePackageRestrictionsLocked(userId); 935 } 936 } 937 } 938 } 939 940 @Override 941 public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId, 942 ActivityIntentInfo filter, String packageName) { 943 if (!hasValidDomains(filter)) { 944 return false; 945 } 946 IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); 947 if (ivs == null) { 948 ivs = createDomainVerificationState(verifierUid, userId, verificationId, 949 packageName); 950 } 951 if (DEBUG_DOMAIN_VERIFICATION) { 952 Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter); 953 } 954 ivs.addFilter(filter); 955 return true; 956 } 957 958 private IntentFilterVerificationState createDomainVerificationState(int verifierUid, 959 int userId, int verificationId, String packageName) { 960 IntentFilterVerificationState ivs = new IntentFilterVerificationState( 961 verifierUid, userId, packageName); 962 ivs.setPendingState(); 963 synchronized (mPackages) { 964 mIntentFilterVerificationStates.append(verificationId, ivs); 965 mCurrentIntentFilterVerifications.add(verificationId); 966 } 967 return ivs; 968 } 969 } 970 971 private static boolean hasValidDomains(ActivityIntentInfo filter) { 972 return filter.hasCategory(Intent.CATEGORY_BROWSABLE) 973 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 974 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS)); 975 } 976 977 // Set of pending broadcasts for aggregating enable/disable of components. 978 static class PendingPackageBroadcasts { 979 // for each user id, a map of <package name -> components within that package> 980 final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap; 981 982 public PendingPackageBroadcasts() { 983 mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2); 984 } 985 986 public ArrayList<String> get(int userId, String packageName) { 987 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 988 return packages.get(packageName); 989 } 990 991 public void put(int userId, String packageName, ArrayList<String> components) { 992 ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); 993 packages.put(packageName, components); 994 } 995 996 public void remove(int userId, String packageName) { 997 ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId); 998 if (packages != null) { 999 packages.remove(packageName); 1000 } 1001 } 1002 1003 public void remove(int userId) { 1004 mUidMap.remove(userId); 1005 } 1006 1007 public int userIdCount() { 1008 return mUidMap.size(); 1009 } 1010 1011 public int userIdAt(int n) { 1012 return mUidMap.keyAt(n); 1013 } 1014 1015 public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) { 1016 return mUidMap.get(userId); 1017 } 1018 1019 public int size() { 1020 // total number of pending broadcast entries across all userIds 1021 int num = 0; 1022 for (int i = 0; i< mUidMap.size(); i++) { 1023 num += mUidMap.valueAt(i).size(); 1024 } 1025 return num; 1026 } 1027 1028 public void clear() { 1029 mUidMap.clear(); 1030 } 1031 1032 private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) { 1033 ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId); 1034 if (map == null) { 1035 map = new ArrayMap<String, ArrayList<String>>(); 1036 mUidMap.put(userId, map); 1037 } 1038 return map; 1039 } 1040 } 1041 final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts(); 1042 1043 // Service Connection to remote media container service to copy 1044 // package uri's from external media onto secure containers 1045 // or internal storage. 1046 private IMediaContainerService mContainerService = null; 1047 1048 static final int SEND_PENDING_BROADCAST = 1; 1049 static final int MCS_BOUND = 3; 1050 static final int END_COPY = 4; 1051 static final int INIT_COPY = 5; 1052 static final int MCS_UNBIND = 6; 1053 static final int START_CLEANING_PACKAGE = 7; 1054 static final int FIND_INSTALL_LOC = 8; 1055 static final int POST_INSTALL = 9; 1056 static final int MCS_RECONNECT = 10; 1057 static final int MCS_GIVE_UP = 11; 1058 static final int UPDATED_MEDIA_STATUS = 12; 1059 static final int WRITE_SETTINGS = 13; 1060 static final int WRITE_PACKAGE_RESTRICTIONS = 14; 1061 static final int PACKAGE_VERIFIED = 15; 1062 static final int CHECK_PENDING_VERIFICATION = 16; 1063 static final int START_INTENT_FILTER_VERIFICATIONS = 17; 1064 static final int INTENT_FILTER_VERIFIED = 18; 1065 static final int WRITE_PACKAGE_LIST = 19; 1066 1067 static final int WRITE_SETTINGS_DELAY = 10*1000; // 10 seconds 1068 1069 // Delay time in millisecs 1070 static final int BROADCAST_DELAY = 10 * 1000; 1071 1072 static UserManagerService sUserManager; 1073 1074 // Stores a list of users whose package restrictions file needs to be updated 1075 private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>(); 1076 1077 final private DefaultContainerConnection mDefContainerConn = 1078 new DefaultContainerConnection(); 1079 class DefaultContainerConnection implements ServiceConnection { 1080 public void onServiceConnected(ComponentName name, IBinder service) { 1081 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected"); 1082 IMediaContainerService imcs = 1083 IMediaContainerService.Stub.asInterface(service); 1084 mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs)); 1085 } 1086 1087 public void onServiceDisconnected(ComponentName name) { 1088 if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected"); 1089 } 1090 } 1091 1092 // Recordkeeping of restore-after-install operations that are currently in flight 1093 // between the Package Manager and the Backup Manager 1094 static class PostInstallData { 1095 public InstallArgs args; 1096 public PackageInstalledInfo res; 1097 1098 PostInstallData(InstallArgs _a, PackageInstalledInfo _r) { 1099 args = _a; 1100 res = _r; 1101 } 1102 } 1103 1104 final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>(); 1105 int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows 1106 1107 // XML tags for backup/restore of various bits of state 1108 private static final String TAG_PREFERRED_BACKUP = "pa"; 1109 private static final String TAG_DEFAULT_APPS = "da"; 1110 private static final String TAG_INTENT_FILTER_VERIFICATION = "iv"; 1111 1112 private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup"; 1113 private static final String TAG_ALL_GRANTS = "rt-grants"; 1114 private static final String TAG_GRANT = "grant"; 1115 private static final String ATTR_PACKAGE_NAME = "pkg"; 1116 1117 private static final String TAG_PERMISSION = "perm"; 1118 private static final String ATTR_PERMISSION_NAME = "name"; 1119 private static final String ATTR_IS_GRANTED = "g"; 1120 private static final String ATTR_USER_SET = "set"; 1121 private static final String ATTR_USER_FIXED = "fixed"; 1122 private static final String ATTR_REVOKE_ON_UPGRADE = "rou"; 1123 1124 // System/policy permission grants are not backed up 1125 private static final int SYSTEM_RUNTIME_GRANT_MASK = 1126 FLAG_PERMISSION_POLICY_FIXED 1127 | FLAG_PERMISSION_SYSTEM_FIXED 1128 | FLAG_PERMISSION_GRANTED_BY_DEFAULT; 1129 1130 // And we back up these user-adjusted states 1131 private static final int USER_RUNTIME_GRANT_MASK = 1132 FLAG_PERMISSION_USER_SET 1133 | FLAG_PERMISSION_USER_FIXED 1134 | FLAG_PERMISSION_REVOKE_ON_UPGRADE; 1135 1136 final @Nullable String mRequiredVerifierPackage; 1137 final @NonNull String mRequiredInstallerPackage; 1138 final @NonNull String mRequiredUninstallerPackage; 1139 final @Nullable String mSetupWizardPackage; 1140 final @Nullable String mStorageManagerPackage; 1141 final @NonNull String mServicesSystemSharedLibraryPackageName; 1142 final @NonNull String mSharedSystemSharedLibraryPackageName; 1143 1144 final boolean mPermissionReviewRequired; 1145 1146 private final PackageUsage mPackageUsage = new PackageUsage(); 1147 private final CompilerStats mCompilerStats = new CompilerStats(); 1148 1149 class PackageHandler extends Handler { 1150 private boolean mBound = false; 1151 final ArrayList<HandlerParams> mPendingInstalls = 1152 new ArrayList<HandlerParams>(); 1153 1154 private boolean connectToService() { 1155 if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" + 1156 " DefaultContainerService"); 1157 Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 1158 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1159 if (mContext.bindServiceAsUser(service, mDefContainerConn, 1160 Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) { 1161 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1162 mBound = true; 1163 return true; 1164 } 1165 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1166 return false; 1167 } 1168 1169 private void disconnectService() { 1170 mContainerService = null; 1171 mBound = false; 1172 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1173 mContext.unbindService(mDefContainerConn); 1174 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1175 } 1176 1177 PackageHandler(Looper looper) { 1178 super(looper); 1179 } 1180 1181 public void handleMessage(Message msg) { 1182 try { 1183 doHandleMessage(msg); 1184 } finally { 1185 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1186 } 1187 } 1188 1189 void doHandleMessage(Message msg) { 1190 switch (msg.what) { 1191 case INIT_COPY: { 1192 HandlerParams params = (HandlerParams) msg.obj; 1193 int idx = mPendingInstalls.size(); 1194 if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params); 1195 // If a bind was already initiated we dont really 1196 // need to do anything. The pending install 1197 // will be processed later on. 1198 if (!mBound) { 1199 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1200 System.identityHashCode(mHandler)); 1201 // If this is the only one pending we might 1202 // have to bind to the service again. 1203 if (!connectToService()) { 1204 Slog.e(TAG, "Failed to bind to media container service"); 1205 params.serviceError(); 1206 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1207 System.identityHashCode(mHandler)); 1208 if (params.traceMethod != null) { 1209 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod, 1210 params.traceCookie); 1211 } 1212 return; 1213 } else { 1214 // Once we bind to the service, the first 1215 // pending request will be processed. 1216 mPendingInstalls.add(idx, params); 1217 } 1218 } else { 1219 mPendingInstalls.add(idx, params); 1220 // Already bound to the service. Just make 1221 // sure we trigger off processing the first request. 1222 if (idx == 0) { 1223 mHandler.sendEmptyMessage(MCS_BOUND); 1224 } 1225 } 1226 break; 1227 } 1228 case MCS_BOUND: { 1229 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound"); 1230 if (msg.obj != null) { 1231 mContainerService = (IMediaContainerService) msg.obj; 1232 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS", 1233 System.identityHashCode(mHandler)); 1234 } 1235 if (mContainerService == null) { 1236 if (!mBound) { 1237 // Something seriously wrong since we are not bound and we are not 1238 // waiting for connection. Bail out. 1239 Slog.e(TAG, "Cannot bind to media container service"); 1240 for (HandlerParams params : mPendingInstalls) { 1241 // Indicate service bind error 1242 params.serviceError(); 1243 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1244 System.identityHashCode(params)); 1245 if (params.traceMethod != null) { 1246 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, 1247 params.traceMethod, params.traceCookie); 1248 } 1249 return; 1250 } 1251 mPendingInstalls.clear(); 1252 } else { 1253 Slog.w(TAG, "Waiting to connect to media container service"); 1254 } 1255 } else if (mPendingInstalls.size() > 0) { 1256 HandlerParams params = mPendingInstalls.get(0); 1257 if (params != null) { 1258 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1259 System.identityHashCode(params)); 1260 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy"); 1261 if (params.startCopy()) { 1262 // We are done... look for more work or to 1263 // go idle. 1264 if (DEBUG_SD_INSTALL) Log.i(TAG, 1265 "Checking for more work or unbind..."); 1266 // Delete pending install 1267 if (mPendingInstalls.size() > 0) { 1268 mPendingInstalls.remove(0); 1269 } 1270 if (mPendingInstalls.size() == 0) { 1271 if (mBound) { 1272 if (DEBUG_SD_INSTALL) Log.i(TAG, 1273 "Posting delayed MCS_UNBIND"); 1274 removeMessages(MCS_UNBIND); 1275 Message ubmsg = obtainMessage(MCS_UNBIND); 1276 // Unbind after a little delay, to avoid 1277 // continual thrashing. 1278 sendMessageDelayed(ubmsg, 10000); 1279 } 1280 } else { 1281 // There are more pending requests in queue. 1282 // Just post MCS_BOUND message to trigger processing 1283 // of next pending install. 1284 if (DEBUG_SD_INSTALL) Log.i(TAG, 1285 "Posting MCS_BOUND for next work"); 1286 mHandler.sendEmptyMessage(MCS_BOUND); 1287 } 1288 } 1289 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 1290 } 1291 } else { 1292 // Should never happen ideally. 1293 Slog.w(TAG, "Empty queue"); 1294 } 1295 break; 1296 } 1297 case MCS_RECONNECT: { 1298 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect"); 1299 if (mPendingInstalls.size() > 0) { 1300 if (mBound) { 1301 disconnectService(); 1302 } 1303 if (!connectToService()) { 1304 Slog.e(TAG, "Failed to bind to media container service"); 1305 for (HandlerParams params : mPendingInstalls) { 1306 // Indicate service bind error 1307 params.serviceError(); 1308 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1309 System.identityHashCode(params)); 1310 } 1311 mPendingInstalls.clear(); 1312 } 1313 } 1314 break; 1315 } 1316 case MCS_UNBIND: { 1317 // If there is no actual work left, then time to unbind. 1318 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind"); 1319 1320 if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) { 1321 if (mBound) { 1322 if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()"); 1323 1324 disconnectService(); 1325 } 1326 } else if (mPendingInstalls.size() > 0) { 1327 // There are more pending requests in queue. 1328 // Just post MCS_BOUND message to trigger processing 1329 // of next pending install. 1330 mHandler.sendEmptyMessage(MCS_BOUND); 1331 } 1332 1333 break; 1334 } 1335 case MCS_GIVE_UP: { 1336 if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries"); 1337 HandlerParams params = mPendingInstalls.remove(0); 1338 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 1339 System.identityHashCode(params)); 1340 break; 1341 } 1342 case SEND_PENDING_BROADCAST: { 1343 String packages[]; 1344 ArrayList<String> components[]; 1345 int size = 0; 1346 int uids[]; 1347 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1348 synchronized (mPackages) { 1349 if (mPendingBroadcasts == null) { 1350 return; 1351 } 1352 size = mPendingBroadcasts.size(); 1353 if (size <= 0) { 1354 // Nothing to be done. Just return 1355 return; 1356 } 1357 packages = new String[size]; 1358 components = new ArrayList[size]; 1359 uids = new int[size]; 1360 int i = 0; // filling out the above arrays 1361 1362 for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) { 1363 int packageUserId = mPendingBroadcasts.userIdAt(n); 1364 Iterator<Map.Entry<String, ArrayList<String>>> it 1365 = mPendingBroadcasts.packagesForUserId(packageUserId) 1366 .entrySet().iterator(); 1367 while (it.hasNext() && i < size) { 1368 Map.Entry<String, ArrayList<String>> ent = it.next(); 1369 packages[i] = ent.getKey(); 1370 components[i] = ent.getValue(); 1371 PackageSetting ps = mSettings.mPackages.get(ent.getKey()); 1372 uids[i] = (ps != null) 1373 ? UserHandle.getUid(packageUserId, ps.appId) 1374 : -1; 1375 i++; 1376 } 1377 } 1378 size = i; 1379 mPendingBroadcasts.clear(); 1380 } 1381 // Send broadcasts 1382 for (int i = 0; i < size; i++) { 1383 sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]); 1384 } 1385 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1386 break; 1387 } 1388 case START_CLEANING_PACKAGE: { 1389 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1390 final String packageName = (String)msg.obj; 1391 final int userId = msg.arg1; 1392 final boolean andCode = msg.arg2 != 0; 1393 synchronized (mPackages) { 1394 if (userId == UserHandle.USER_ALL) { 1395 int[] users = sUserManager.getUserIds(); 1396 for (int user : users) { 1397 mSettings.addPackageToCleanLPw( 1398 new PackageCleanItem(user, packageName, andCode)); 1399 } 1400 } else { 1401 mSettings.addPackageToCleanLPw( 1402 new PackageCleanItem(userId, packageName, andCode)); 1403 } 1404 } 1405 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1406 startCleaningPackages(); 1407 } break; 1408 case POST_INSTALL: { 1409 if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1); 1410 1411 PostInstallData data = mRunningInstalls.get(msg.arg1); 1412 final boolean didRestore = (msg.arg2 != 0); 1413 mRunningInstalls.delete(msg.arg1); 1414 1415 if (data != null) { 1416 InstallArgs args = data.args; 1417 PackageInstalledInfo parentRes = data.res; 1418 1419 final boolean grantPermissions = (args.installFlags 1420 & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0; 1421 final boolean killApp = (args.installFlags 1422 & PackageManager.INSTALL_DONT_KILL_APP) == 0; 1423 final String[] grantedPermissions = args.installGrantPermissions; 1424 1425 // Handle the parent package 1426 handlePackagePostInstall(parentRes, grantPermissions, killApp, 1427 grantedPermissions, didRestore, args.installerPackageName, 1428 args.observer); 1429 1430 // Handle the child packages 1431 final int childCount = (parentRes.addedChildPackages != null) 1432 ? parentRes.addedChildPackages.size() : 0; 1433 for (int i = 0; i < childCount; i++) { 1434 PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i); 1435 handlePackagePostInstall(childRes, grantPermissions, killApp, 1436 grantedPermissions, false, args.installerPackageName, 1437 args.observer); 1438 } 1439 1440 // Log tracing if needed 1441 if (args.traceMethod != null) { 1442 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod, 1443 args.traceCookie); 1444 } 1445 } else { 1446 Slog.e(TAG, "Bogus post-install token " + msg.arg1); 1447 } 1448 1449 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1); 1450 } break; 1451 case UPDATED_MEDIA_STATUS: { 1452 if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS"); 1453 boolean reportStatus = msg.arg1 == 1; 1454 boolean doGc = msg.arg2 == 1; 1455 if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc); 1456 if (doGc) { 1457 // Force a gc to clear up stale containers. 1458 Runtime.getRuntime().gc(); 1459 } 1460 if (msg.obj != null) { 1461 @SuppressWarnings("unchecked") 1462 Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj; 1463 if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers"); 1464 // Unload containers 1465 unloadAllContainers(args); 1466 } 1467 if (reportStatus) { 1468 try { 1469 if (DEBUG_SD_INSTALL) Log.i(TAG, "Invoking MountService call back"); 1470 PackageHelper.getMountService().finishMediaUpdate(); 1471 } catch (RemoteException e) { 1472 Log.e(TAG, "MountService not running?"); 1473 } 1474 } 1475 } break; 1476 case WRITE_SETTINGS: { 1477 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1478 synchronized (mPackages) { 1479 removeMessages(WRITE_SETTINGS); 1480 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1481 mSettings.writeLPr(); 1482 mDirtyUsers.clear(); 1483 } 1484 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1485 } break; 1486 case WRITE_PACKAGE_RESTRICTIONS: { 1487 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1488 synchronized (mPackages) { 1489 removeMessages(WRITE_PACKAGE_RESTRICTIONS); 1490 for (int userId : mDirtyUsers) { 1491 mSettings.writePackageRestrictionsLPr(userId); 1492 } 1493 mDirtyUsers.clear(); 1494 } 1495 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1496 } break; 1497 case WRITE_PACKAGE_LIST: { 1498 Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 1499 synchronized (mPackages) { 1500 removeMessages(WRITE_PACKAGE_LIST); 1501 mSettings.writePackageListLPr(msg.arg1); 1502 } 1503 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1504 } break; 1505 case CHECK_PENDING_VERIFICATION: { 1506 final int verificationId = msg.arg1; 1507 final PackageVerificationState state = mPendingVerification.get(verificationId); 1508 1509 if ((state != null) && !state.timeoutExtended()) { 1510 final InstallArgs args = state.getInstallArgs(); 1511 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1512 1513 Slog.i(TAG, "Verification timed out for " + originUri); 1514 mPendingVerification.remove(verificationId); 1515 1516 int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1517 1518 if (getDefaultVerificationResponse() == PackageManager.VERIFICATION_ALLOW) { 1519 Slog.i(TAG, "Continuing with installation of " + originUri); 1520 state.setVerifierResponse(Binder.getCallingUid(), 1521 PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT); 1522 broadcastPackageVerified(verificationId, originUri, 1523 PackageManager.VERIFICATION_ALLOW, 1524 state.getInstallArgs().getUser()); 1525 try { 1526 ret = args.copyApk(mContainerService, true); 1527 } catch (RemoteException e) { 1528 Slog.e(TAG, "Could not contact the ContainerService"); 1529 } 1530 } else { 1531 broadcastPackageVerified(verificationId, originUri, 1532 PackageManager.VERIFICATION_REJECT, 1533 state.getInstallArgs().getUser()); 1534 } 1535 1536 Trace.asyncTraceEnd( 1537 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 1538 1539 processPendingInstall(args, ret); 1540 mHandler.sendEmptyMessage(MCS_UNBIND); 1541 } 1542 break; 1543 } 1544 case PACKAGE_VERIFIED: { 1545 final int verificationId = msg.arg1; 1546 1547 final PackageVerificationState state = mPendingVerification.get(verificationId); 1548 if (state == null) { 1549 Slog.w(TAG, "Invalid verification token " + verificationId + " received"); 1550 break; 1551 } 1552 1553 final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj; 1554 1555 state.setVerifierResponse(response.callerUid, response.code); 1556 1557 if (state.isVerificationComplete()) { 1558 mPendingVerification.remove(verificationId); 1559 1560 final InstallArgs args = state.getInstallArgs(); 1561 final Uri originUri = Uri.fromFile(args.origin.resolvedFile); 1562 1563 int ret; 1564 if (state.isInstallAllowed()) { 1565 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 1566 broadcastPackageVerified(verificationId, originUri, 1567 response.code, state.getInstallArgs().getUser()); 1568 try { 1569 ret = args.copyApk(mContainerService, true); 1570 } catch (RemoteException e) { 1571 Slog.e(TAG, "Could not contact the ContainerService"); 1572 } 1573 } else { 1574 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 1575 } 1576 1577 Trace.asyncTraceEnd( 1578 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 1579 1580 processPendingInstall(args, ret); 1581 mHandler.sendEmptyMessage(MCS_UNBIND); 1582 } 1583 1584 break; 1585 } 1586 case START_INTENT_FILTER_VERIFICATIONS: { 1587 IFVerificationParams params = (IFVerificationParams) msg.obj; 1588 verifyIntentFiltersIfNeeded(params.userId, params.verifierUid, 1589 params.replacing, params.pkg); 1590 break; 1591 } 1592 case INTENT_FILTER_VERIFIED: { 1593 final int verificationId = msg.arg1; 1594 1595 final IntentFilterVerificationState state = mIntentFilterVerificationStates.get( 1596 verificationId); 1597 if (state == null) { 1598 Slog.w(TAG, "Invalid IntentFilter verification token " 1599 + verificationId + " received"); 1600 break; 1601 } 1602 1603 final int userId = state.getUserId(); 1604 1605 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1606 "Processing IntentFilter verification with token:" 1607 + verificationId + " and userId:" + userId); 1608 1609 final IntentFilterVerificationResponse response = 1610 (IntentFilterVerificationResponse) msg.obj; 1611 1612 state.setVerifierResponse(response.callerUid, response.code); 1613 1614 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1615 "IntentFilter verification with token:" + verificationId 1616 + " and userId:" + userId 1617 + " is settings verifier response with response code:" 1618 + response.code); 1619 1620 if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) { 1621 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: " 1622 + response.getFailedDomainsString()); 1623 } 1624 1625 if (state.isVerificationComplete()) { 1626 mIntentFilterVerifier.receiveVerificationResponse(verificationId); 1627 } else { 1628 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 1629 "IntentFilter verification with token:" + verificationId 1630 + " was not said to be complete"); 1631 } 1632 1633 break; 1634 } 1635 } 1636 } 1637 } 1638 1639 private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions, 1640 boolean killApp, String[] grantedPermissions, 1641 boolean launchedForRestore, String installerPackage, 1642 IPackageInstallObserver2 installObserver) { 1643 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 1644 // Send the removed broadcasts 1645 if (res.removedInfo != null) { 1646 res.removedInfo.sendPackageRemovedBroadcasts(killApp); 1647 } 1648 1649 // Now that we successfully installed the package, grant runtime 1650 // permissions if requested before broadcasting the install. 1651 if (grantPermissions && res.pkg.applicationInfo.targetSdkVersion 1652 >= Build.VERSION_CODES.M) { 1653 grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions); 1654 } 1655 1656 final boolean update = res.removedInfo != null 1657 && res.removedInfo.removedPackage != null; 1658 1659 // If this is the first time we have child packages for a disabled privileged 1660 // app that had no children, we grant requested runtime permissions to the new 1661 // children if the parent on the system image had them already granted. 1662 if (res.pkg.parentPackage != null) { 1663 synchronized (mPackages) { 1664 grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg); 1665 } 1666 } 1667 1668 synchronized (mPackages) { 1669 mEphemeralApplicationRegistry.onPackageInstalledLPw(res.pkg); 1670 } 1671 1672 final String packageName = res.pkg.applicationInfo.packageName; 1673 1674 // Determine the set of users who are adding this package for 1675 // the first time vs. those who are seeing an update. 1676 int[] firstUsers = EMPTY_INT_ARRAY; 1677 int[] updateUsers = EMPTY_INT_ARRAY; 1678 if (res.origUsers == null || res.origUsers.length == 0) { 1679 firstUsers = res.newUsers; 1680 } else { 1681 for (int newUser : res.newUsers) { 1682 boolean isNew = true; 1683 for (int origUser : res.origUsers) { 1684 if (origUser == newUser) { 1685 isNew = false; 1686 break; 1687 } 1688 } 1689 if (isNew) { 1690 firstUsers = ArrayUtils.appendInt(firstUsers, newUser); 1691 } else { 1692 updateUsers = ArrayUtils.appendInt(updateUsers, newUser); 1693 } 1694 } 1695 } 1696 1697 // Send installed broadcasts if the install/update is not ephemeral 1698 if (!isEphemeral(res.pkg)) { 1699 mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath); 1700 1701 // Send added for users that see the package for the first time 1702 // sendPackageAddedForNewUsers also deals with system apps 1703 int appId = UserHandle.getAppId(res.uid); 1704 boolean isSystem = res.pkg.applicationInfo.isSystemApp(); 1705 sendPackageAddedForNewUsers(packageName, isSystem, appId, firstUsers); 1706 1707 // Send added for users that don't see the package for the first time 1708 Bundle extras = new Bundle(1); 1709 extras.putInt(Intent.EXTRA_UID, res.uid); 1710 if (update) { 1711 extras.putBoolean(Intent.EXTRA_REPLACING, true); 1712 } 1713 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName, 1714 extras, 0 /*flags*/, null /*targetPackage*/, 1715 null /*finishedReceiver*/, updateUsers); 1716 1717 // Send replaced for users that don't see the package for the first time 1718 if (update) { 1719 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, 1720 packageName, extras, 0 /*flags*/, 1721 null /*targetPackage*/, null /*finishedReceiver*/, 1722 updateUsers); 1723 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, 1724 null /*package*/, null /*extras*/, 0 /*flags*/, 1725 packageName /*targetPackage*/, 1726 null /*finishedReceiver*/, updateUsers); 1727 } else if (launchedForRestore && !isSystemApp(res.pkg)) { 1728 // First-install and we did a restore, so we're responsible for the 1729 // first-launch broadcast. 1730 if (DEBUG_BACKUP) { 1731 Slog.i(TAG, "Post-restore of " + packageName 1732 + " sending FIRST_LAUNCH in " + Arrays.toString(firstUsers)); 1733 } 1734 sendFirstLaunchBroadcast(packageName, installerPackage, firstUsers); 1735 } 1736 1737 // Send broadcast package appeared if forward locked/external for all users 1738 // treat asec-hosted packages like removable media on upgrade 1739 if (res.pkg.isForwardLocked() || isExternal(res.pkg)) { 1740 if (DEBUG_INSTALL) { 1741 Slog.i(TAG, "upgrading pkg " + res.pkg 1742 + " is ASEC-hosted -> AVAILABLE"); 1743 } 1744 final int[] uidArray = new int[]{res.pkg.applicationInfo.uid}; 1745 ArrayList<String> pkgList = new ArrayList<>(1); 1746 pkgList.add(packageName); 1747 sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null); 1748 } 1749 } 1750 1751 // Work that needs to happen on first install within each user 1752 if (firstUsers != null && firstUsers.length > 0) { 1753 synchronized (mPackages) { 1754 for (int userId : firstUsers) { 1755 // If this app is a browser and it's newly-installed for some 1756 // users, clear any default-browser state in those users. The 1757 // app's nature doesn't depend on the user, so we can just check 1758 // its browser nature in any user and generalize. 1759 if (packageIsBrowser(packageName, userId)) { 1760 mSettings.setDefaultBrowserPackageNameLPw(null, userId); 1761 } 1762 1763 // We may also need to apply pending (restored) runtime 1764 // permission grants within these users. 1765 mSettings.applyPendingPermissionGrantsLPw(packageName, userId); 1766 } 1767 } 1768 } 1769 1770 // Log current value of "unknown sources" setting 1771 EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED, 1772 getUnknownSourcesSettings()); 1773 1774 // Force a gc to clear up things 1775 Runtime.getRuntime().gc(); 1776 1777 // Remove the replaced package's older resources safely now 1778 // We delete after a gc for applications on sdcard. 1779 if (res.removedInfo != null && res.removedInfo.args != null) { 1780 synchronized (mInstallLock) { 1781 res.removedInfo.args.doPostDeleteLI(true); 1782 } 1783 } 1784 } 1785 1786 // If someone is watching installs - notify them 1787 if (installObserver != null) { 1788 try { 1789 Bundle extras = extrasForInstallResult(res); 1790 installObserver.onPackageInstalled(res.name, res.returnCode, 1791 res.returnMsg, extras); 1792 } catch (RemoteException e) { 1793 Slog.i(TAG, "Observer no longer exists."); 1794 } 1795 } 1796 } 1797 1798 private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw( 1799 PackageParser.Package pkg) { 1800 if (pkg.parentPackage == null) { 1801 return; 1802 } 1803 if (pkg.requestedPermissions == null) { 1804 return; 1805 } 1806 final PackageSetting disabledSysParentPs = mSettings 1807 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName); 1808 if (disabledSysParentPs == null || disabledSysParentPs.pkg == null 1809 || !disabledSysParentPs.isPrivileged() 1810 || (disabledSysParentPs.childPackageNames != null 1811 && !disabledSysParentPs.childPackageNames.isEmpty())) { 1812 return; 1813 } 1814 final int[] allUserIds = sUserManager.getUserIds(); 1815 final int permCount = pkg.requestedPermissions.size(); 1816 for (int i = 0; i < permCount; i++) { 1817 String permission = pkg.requestedPermissions.get(i); 1818 BasePermission bp = mSettings.mPermissions.get(permission); 1819 if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) { 1820 continue; 1821 } 1822 for (int userId : allUserIds) { 1823 if (disabledSysParentPs.getPermissionsState().hasRuntimePermission( 1824 permission, userId)) { 1825 grantRuntimePermission(pkg.packageName, permission, userId); 1826 } 1827 } 1828 } 1829 } 1830 1831 private StorageEventListener mStorageListener = new StorageEventListener() { 1832 @Override 1833 public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) { 1834 if (vol.type == VolumeInfo.TYPE_PRIVATE) { 1835 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1836 final String volumeUuid = vol.getFsUuid(); 1837 1838 // Clean up any users or apps that were removed or recreated 1839 // while this volume was missing 1840 reconcileUsers(volumeUuid); 1841 reconcileApps(volumeUuid); 1842 1843 // Clean up any install sessions that expired or were 1844 // cancelled while this volume was missing 1845 mInstallerService.onPrivateVolumeMounted(volumeUuid); 1846 1847 loadPrivatePackages(vol); 1848 1849 } else if (vol.state == VolumeInfo.STATE_EJECTING) { 1850 unloadPrivatePackages(vol); 1851 } 1852 } 1853 1854 if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) { 1855 if (vol.state == VolumeInfo.STATE_MOUNTED) { 1856 updateExternalMediaStatus(true, false); 1857 } else if (vol.state == VolumeInfo.STATE_EJECTING) { 1858 updateExternalMediaStatus(false, false); 1859 } 1860 } 1861 } 1862 1863 @Override 1864 public void onVolumeForgotten(String fsUuid) { 1865 if (TextUtils.isEmpty(fsUuid)) { 1866 Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring"); 1867 return; 1868 } 1869 1870 // Remove any apps installed on the forgotten volume 1871 synchronized (mPackages) { 1872 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid); 1873 for (PackageSetting ps : packages) { 1874 Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten"); 1875 deletePackage(ps.name, new LegacyPackageDeleteObserver(null).getBinder(), 1876 UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS); 1877 } 1878 1879 mSettings.onVolumeForgotten(fsUuid); 1880 mSettings.writeLPr(); 1881 } 1882 } 1883 }; 1884 1885 private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds, 1886 String[] grantedPermissions) { 1887 for (int userId : userIds) { 1888 grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions); 1889 } 1890 1891 // We could have touched GID membership, so flush out packages.list 1892 synchronized (mPackages) { 1893 mSettings.writePackageListLPr(); 1894 } 1895 } 1896 1897 private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId, 1898 String[] grantedPermissions) { 1899 SettingBase sb = (SettingBase) pkg.mExtras; 1900 if (sb == null) { 1901 return; 1902 } 1903 1904 PermissionsState permissionsState = sb.getPermissionsState(); 1905 1906 final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 1907 | PackageManager.FLAG_PERMISSION_POLICY_FIXED; 1908 1909 for (String permission : pkg.requestedPermissions) { 1910 final BasePermission bp; 1911 synchronized (mPackages) { 1912 bp = mSettings.mPermissions.get(permission); 1913 } 1914 if (bp != null && (bp.isRuntime() || bp.isDevelopment()) 1915 && (grantedPermissions == null 1916 || ArrayUtils.contains(grantedPermissions, permission))) { 1917 final int flags = permissionsState.getPermissionFlags(permission, userId); 1918 // Installer cannot change immutable permissions. 1919 if ((flags & immutableFlags) == 0) { 1920 grantRuntimePermission(pkg.packageName, permission, userId); 1921 } 1922 } 1923 } 1924 } 1925 1926 Bundle extrasForInstallResult(PackageInstalledInfo res) { 1927 Bundle extras = null; 1928 switch (res.returnCode) { 1929 case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: { 1930 extras = new Bundle(); 1931 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION, 1932 res.origPermission); 1933 extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE, 1934 res.origPackage); 1935 break; 1936 } 1937 case PackageManager.INSTALL_SUCCEEDED: { 1938 extras = new Bundle(); 1939 extras.putBoolean(Intent.EXTRA_REPLACING, 1940 res.removedInfo != null && res.removedInfo.removedPackage != null); 1941 break; 1942 } 1943 } 1944 return extras; 1945 } 1946 1947 void scheduleWriteSettingsLocked() { 1948 if (!mHandler.hasMessages(WRITE_SETTINGS)) { 1949 mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY); 1950 } 1951 } 1952 1953 void scheduleWritePackageListLocked(int userId) { 1954 if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) { 1955 Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST); 1956 msg.arg1 = userId; 1957 mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY); 1958 } 1959 } 1960 1961 void scheduleWritePackageRestrictionsLocked(UserHandle user) { 1962 final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier(); 1963 scheduleWritePackageRestrictionsLocked(userId); 1964 } 1965 1966 void scheduleWritePackageRestrictionsLocked(int userId) { 1967 final int[] userIds = (userId == UserHandle.USER_ALL) 1968 ? sUserManager.getUserIds() : new int[]{userId}; 1969 for (int nextUserId : userIds) { 1970 if (!sUserManager.exists(nextUserId)) return; 1971 mDirtyUsers.add(nextUserId); 1972 if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) { 1973 mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY); 1974 } 1975 } 1976 } 1977 1978 public static PackageManagerService main(Context context, Installer installer, 1979 boolean factoryTest, boolean onlyCore) { 1980 // Self-check for initial settings. 1981 PackageManagerServiceCompilerMapping.checkProperties(); 1982 1983 PackageManagerService m = new PackageManagerService(context, installer, 1984 factoryTest, onlyCore); 1985 m.enableSystemUserPackages(); 1986 ServiceManager.addService("package", m); 1987 return m; 1988 } 1989 1990 private void enableSystemUserPackages() { 1991 if (!UserManager.isSplitSystemUser()) { 1992 return; 1993 } 1994 // For system user, enable apps based on the following conditions: 1995 // - app is whitelisted or belong to one of these groups: 1996 // -- system app which has no launcher icons 1997 // -- system app which has INTERACT_ACROSS_USERS permission 1998 // -- system IME app 1999 // - app is not in the blacklist 2000 AppsQueryHelper queryHelper = new AppsQueryHelper(this); 2001 Set<String> enableApps = new ArraySet<>(); 2002 enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS 2003 | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM 2004 | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM)); 2005 ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps(); 2006 enableApps.addAll(wlApps); 2007 enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER, 2008 /* systemAppsOnly */ false, UserHandle.SYSTEM)); 2009 ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps(); 2010 enableApps.removeAll(blApps); 2011 Log.i(TAG, "Applications installed for system user: " + enableApps); 2012 List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false, 2013 UserHandle.SYSTEM); 2014 final int allAppsSize = allAps.size(); 2015 synchronized (mPackages) { 2016 for (int i = 0; i < allAppsSize; i++) { 2017 String pName = allAps.get(i); 2018 PackageSetting pkgSetting = mSettings.mPackages.get(pName); 2019 // Should not happen, but we shouldn't be failing if it does 2020 if (pkgSetting == null) { 2021 continue; 2022 } 2023 boolean install = enableApps.contains(pName); 2024 if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) { 2025 Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName 2026 + " for system user"); 2027 pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM); 2028 } 2029 } 2030 } 2031 } 2032 2033 private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) { 2034 DisplayManager displayManager = (DisplayManager) context.getSystemService( 2035 Context.DISPLAY_SERVICE); 2036 displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics); 2037 } 2038 2039 /** 2040 * Requests that files preopted on a secondary system partition be copied to the data partition 2041 * if possible. Note that the actual copying of the files is accomplished by init for security 2042 * reasons. This simply requests that the copy takes place and awaits confirmation of its 2043 * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy. 2044 */ 2045 private static void requestCopyPreoptedFiles() { 2046 final int WAIT_TIME_MS = 100; 2047 final String CP_PREOPT_PROPERTY = "sys.cppreopt"; 2048 if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) { 2049 SystemProperties.set(CP_PREOPT_PROPERTY, "requested"); 2050 // We will wait for up to 100 seconds. 2051 final long timeEnd = SystemClock.uptimeMillis() + 100 * 1000; 2052 while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) { 2053 try { 2054 Thread.sleep(WAIT_TIME_MS); 2055 } catch (InterruptedException e) { 2056 // Do nothing 2057 } 2058 if (SystemClock.uptimeMillis() > timeEnd) { 2059 SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out"); 2060 Slog.wtf(TAG, "cppreopt did not finish!"); 2061 break; 2062 } 2063 } 2064 } 2065 } 2066 2067 public PackageManagerService(Context context, Installer installer, 2068 boolean factoryTest, boolean onlyCore) { 2069 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager"); 2070 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START, 2071 SystemClock.uptimeMillis()); 2072 2073 if (mSdkVersion <= 0) { 2074 Slog.w(TAG, "**** ro.build.version.sdk not set!"); 2075 } 2076 2077 mContext = context; 2078 2079 mPermissionReviewRequired = context.getResources().getBoolean( 2080 R.bool.config_permissionReviewRequired); 2081 2082 mFactoryTest = factoryTest; 2083 mOnlyCore = onlyCore; 2084 mMetrics = new DisplayMetrics(); 2085 mSettings = new Settings(mPackages); 2086 mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID, 2087 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2088 mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID, 2089 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2090 mSettings.addSharedUserLPw("android.uid.log", LOG_UID, 2091 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2092 mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID, 2093 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2094 mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID, 2095 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2096 mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID, 2097 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); 2098 2099 String separateProcesses = SystemProperties.get("debug.separate_processes"); 2100 if (separateProcesses != null && separateProcesses.length() > 0) { 2101 if ("*".equals(separateProcesses)) { 2102 mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES; 2103 mSeparateProcesses = null; 2104 Slog.w(TAG, "Running with debug.separate_processes: * (ALL)"); 2105 } else { 2106 mDefParseFlags = 0; 2107 mSeparateProcesses = separateProcesses.split(","); 2108 Slog.w(TAG, "Running with debug.separate_processes: " 2109 + separateProcesses); 2110 } 2111 } else { 2112 mDefParseFlags = 0; 2113 mSeparateProcesses = null; 2114 } 2115 2116 mInstaller = installer; 2117 mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context, 2118 "*dexopt*"); 2119 mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper()); 2120 2121 mOnPermissionChangeListeners = new OnPermissionChangeListeners( 2122 FgThread.get().getLooper()); 2123 2124 getDefaultDisplayMetrics(context, mMetrics); 2125 2126 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config"); 2127 SystemConfig systemConfig = SystemConfig.getInstance(); 2128 mGlobalGids = systemConfig.getGlobalGids(); 2129 mSystemPermissions = systemConfig.getSystemPermissions(); 2130 mAvailableFeatures = systemConfig.getAvailableFeatures(); 2131 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2132 2133 mProtectedPackages = new ProtectedPackages(mContext); 2134 2135 synchronized (mInstallLock) { 2136 // writer 2137 synchronized (mPackages) { 2138 mHandlerThread = new ServiceThread(TAG, 2139 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/); 2140 mHandlerThread.start(); 2141 mHandler = new PackageHandler(mHandlerThread.getLooper()); 2142 mProcessLoggingHandler = new ProcessLoggingHandler(); 2143 Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT); 2144 2145 mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(this); 2146 2147 File dataDir = Environment.getDataDirectory(); 2148 mAppInstallDir = new File(dataDir, "app"); 2149 mAppLib32InstallDir = new File(dataDir, "app-lib"); 2150 mEphemeralInstallDir = new File(dataDir, "app-ephemeral"); 2151 mAsecInternalPath = new File(dataDir, "app-asec").getPath(); 2152 mDrmAppPrivateInstallDir = new File(dataDir, "app-private"); 2153 2154 sUserManager = new UserManagerService(context, this, mPackages); 2155 2156 // Propagate permission configuration in to package manager. 2157 ArrayMap<String, SystemConfig.PermissionEntry> permConfig 2158 = systemConfig.getPermissions(); 2159 for (int i=0; i<permConfig.size(); i++) { 2160 SystemConfig.PermissionEntry perm = permConfig.valueAt(i); 2161 BasePermission bp = mSettings.mPermissions.get(perm.name); 2162 if (bp == null) { 2163 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN); 2164 mSettings.mPermissions.put(perm.name, bp); 2165 } 2166 if (perm.gids != null) { 2167 bp.setGids(perm.gids, perm.perUser); 2168 } 2169 } 2170 2171 ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries(); 2172 for (int i=0; i<libConfig.size(); i++) { 2173 mSharedLibraries.put(libConfig.keyAt(i), 2174 new SharedLibraryEntry(libConfig.valueAt(i), null)); 2175 } 2176 2177 mFoundPolicyFile = SELinuxMMAC.readInstallPolicy(); 2178 2179 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings"); 2180 mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false)); 2181 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2182 2183 if (mFirstBoot) { 2184 requestCopyPreoptedFiles(); 2185 } 2186 2187 String customResolverActivity = Resources.getSystem().getString( 2188 R.string.config_customResolverActivity); 2189 if (TextUtils.isEmpty(customResolverActivity)) { 2190 customResolverActivity = null; 2191 } else { 2192 mCustomResolverComponentName = ComponentName.unflattenFromString( 2193 customResolverActivity); 2194 } 2195 2196 long startTime = SystemClock.uptimeMillis(); 2197 2198 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START, 2199 startTime); 2200 2201 // Set flag to monitor and not change apk file paths when 2202 // scanning install directories. 2203 final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING | SCAN_INITIAL; 2204 2205 final String bootClassPath = System.getenv("BOOTCLASSPATH"); 2206 final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH"); 2207 2208 if (bootClassPath == null) { 2209 Slog.w(TAG, "No BOOTCLASSPATH found!"); 2210 } 2211 2212 if (systemServerClassPath == null) { 2213 Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!"); 2214 } 2215 2216 final List<String> allInstructionSets = InstructionSets.getAllInstructionSets(); 2217 final String[] dexCodeInstructionSets = 2218 getDexCodeInstructionSets( 2219 allInstructionSets.toArray(new String[allInstructionSets.size()])); 2220 2221 /** 2222 * Ensure all external libraries have had dexopt run on them. 2223 */ 2224 if (mSharedLibraries.size() > 0) { 2225 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 2226 // NOTE: For now, we're compiling these system "shared libraries" 2227 // (and framework jars) into all available architectures. It's possible 2228 // to compile them only when we come across an app that uses them (there's 2229 // already logic for that in scanPackageLI) but that adds some complexity. 2230 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 2231 for (SharedLibraryEntry libEntry : mSharedLibraries.values()) { 2232 final String lib = libEntry.path; 2233 if (lib == null) { 2234 continue; 2235 } 2236 2237 try { 2238 // Shared libraries do not have profiles so we perform a full 2239 // AOT compilation (if needed). 2240 int dexoptNeeded = DexFile.getDexOptNeeded( 2241 lib, dexCodeInstructionSet, 2242 getCompilerFilterForReason(REASON_SHARED_APK), 2243 false /* newProfile */); 2244 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { 2245 mInstaller.dexopt(lib, Process.SYSTEM_UID, dexCodeInstructionSet, 2246 dexoptNeeded, DEXOPT_PUBLIC /*dexFlags*/, 2247 getCompilerFilterForReason(REASON_SHARED_APK), 2248 StorageManager.UUID_PRIVATE_INTERNAL, 2249 SKIP_SHARED_LIBRARY_CHECK); 2250 } 2251 } catch (FileNotFoundException e) { 2252 Slog.w(TAG, "Library not found: " + lib); 2253 } catch (IOException | InstallerException e) { 2254 Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? " 2255 + e.getMessage()); 2256 } 2257 } 2258 } 2259 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2260 } 2261 2262 File frameworkDir = new File(Environment.getRootDirectory(), "framework"); 2263 2264 final VersionInfo ver = mSettings.getInternalVersion(); 2265 mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint); 2266 2267 // when upgrading from pre-M, promote system app permissions from install to runtime 2268 mPromoteSystemApps = 2269 mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1; 2270 2271 // When upgrading from pre-N, we need to handle package extraction like first boot, 2272 // as there is no profiling data available. 2273 mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N; 2274 2275 mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1; 2276 2277 // save off the names of pre-existing system packages prior to scanning; we don't 2278 // want to automatically grant runtime permissions for new system apps 2279 if (mPromoteSystemApps) { 2280 Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator(); 2281 while (pkgSettingIter.hasNext()) { 2282 PackageSetting ps = pkgSettingIter.next(); 2283 if (isSystemApp(ps)) { 2284 mExistingSystemPackages.add(ps.name); 2285 } 2286 } 2287 } 2288 2289 // Collect vendor overlay packages. (Do this before scanning any apps.) 2290 // For security and version matching reason, only consider 2291 // overlay packages if they reside in the right directory. 2292 String overlayThemeDir = SystemProperties.get(VENDOR_OVERLAY_THEME_PROPERTY); 2293 if (!overlayThemeDir.isEmpty()) { 2294 scanDirTracedLI(new File(VENDOR_OVERLAY_DIR, overlayThemeDir), mDefParseFlags 2295 | PackageParser.PARSE_IS_SYSTEM 2296 | PackageParser.PARSE_IS_SYSTEM_DIR 2297 | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0); 2298 } 2299 scanDirTracedLI(new File(VENDOR_OVERLAY_DIR), mDefParseFlags 2300 | PackageParser.PARSE_IS_SYSTEM 2301 | PackageParser.PARSE_IS_SYSTEM_DIR 2302 | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0); 2303 2304 // Find base frameworks (resource packages without code). 2305 scanDirTracedLI(frameworkDir, mDefParseFlags 2306 | PackageParser.PARSE_IS_SYSTEM 2307 | PackageParser.PARSE_IS_SYSTEM_DIR 2308 | PackageParser.PARSE_IS_PRIVILEGED, 2309 scanFlags | SCAN_NO_DEX, 0); 2310 2311 // Collected privileged system packages. 2312 final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app"); 2313 scanDirTracedLI(privilegedAppDir, mDefParseFlags 2314 | PackageParser.PARSE_IS_SYSTEM 2315 | PackageParser.PARSE_IS_SYSTEM_DIR 2316 | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0); 2317 2318 // Collect ordinary system packages. 2319 final File systemAppDir = new File(Environment.getRootDirectory(), "app"); 2320 scanDirTracedLI(systemAppDir, mDefParseFlags 2321 | PackageParser.PARSE_IS_SYSTEM 2322 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2323 2324 // Collect all vendor packages. 2325 File vendorAppDir = new File("/vendor/app"); 2326 try { 2327 vendorAppDir = vendorAppDir.getCanonicalFile(); 2328 } catch (IOException e) { 2329 // failed to look up canonical path, continue with original one 2330 } 2331 scanDirTracedLI(vendorAppDir, mDefParseFlags 2332 | PackageParser.PARSE_IS_SYSTEM 2333 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2334 2335 // Collect all OEM packages. 2336 final File oemAppDir = new File(Environment.getOemDirectory(), "app"); 2337 scanDirTracedLI(oemAppDir, mDefParseFlags 2338 | PackageParser.PARSE_IS_SYSTEM 2339 | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0); 2340 2341 // Prune any system packages that no longer exist. 2342 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>(); 2343 if (!mOnlyCore) { 2344 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 2345 while (psit.hasNext()) { 2346 PackageSetting ps = psit.next(); 2347 2348 /* 2349 * If this is not a system app, it can't be a 2350 * disable system app. 2351 */ 2352 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) { 2353 continue; 2354 } 2355 2356 /* 2357 * If the package is scanned, it's not erased. 2358 */ 2359 final PackageParser.Package scannedPkg = mPackages.get(ps.name); 2360 if (scannedPkg != null) { 2361 /* 2362 * If the system app is both scanned and in the 2363 * disabled packages list, then it must have been 2364 * added via OTA. Remove it from the currently 2365 * scanned package so the previously user-installed 2366 * application can be scanned. 2367 */ 2368 if (mSettings.isDisabledSystemPackageLPr(ps.name)) { 2369 logCriticalInfo(Log.WARN, "Expecting better updated system app for " 2370 + ps.name + "; removing system app. Last known codePath=" 2371 + ps.codePathString + ", installStatus=" + ps.installStatus 2372 + ", versionCode=" + ps.versionCode + "; scanned versionCode=" 2373 + scannedPkg.mVersionCode); 2374 removePackageLI(scannedPkg, true); 2375 mExpectingBetter.put(ps.name, ps.codePath); 2376 } 2377 2378 continue; 2379 } 2380 2381 if (!mSettings.isDisabledSystemPackageLPr(ps.name)) { 2382 psit.remove(); 2383 logCriticalInfo(Log.WARN, "System package " + ps.name 2384 + " no longer exists; it's data will be wiped"); 2385 // Actual deletion of code and data will be handled by later 2386 // reconciliation step 2387 } else { 2388 final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name); 2389 if (disabledPs.codePath == null || !disabledPs.codePath.exists()) { 2390 possiblyDeletedUpdatedSystemApps.add(ps.name); 2391 } 2392 } 2393 } 2394 } 2395 2396 //look for any incomplete package installations 2397 ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr(); 2398 for (int i = 0; i < deletePkgsList.size(); i++) { 2399 // Actual deletion of code and data will be handled by later 2400 // reconciliation step 2401 final String packageName = deletePkgsList.get(i).name; 2402 logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName); 2403 synchronized (mPackages) { 2404 mSettings.removePackageLPw(packageName); 2405 } 2406 } 2407 2408 //delete tmp files 2409 deleteTempPackageFiles(); 2410 2411 // Remove any shared userIDs that have no associated packages 2412 mSettings.pruneSharedUsersLPw(); 2413 2414 if (!mOnlyCore) { 2415 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START, 2416 SystemClock.uptimeMillis()); 2417 scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0); 2418 2419 scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags 2420 | PackageParser.PARSE_FORWARD_LOCK, 2421 scanFlags | SCAN_REQUIRE_KNOWN, 0); 2422 2423 scanDirLI(mEphemeralInstallDir, mDefParseFlags 2424 | PackageParser.PARSE_IS_EPHEMERAL, 2425 scanFlags | SCAN_REQUIRE_KNOWN, 0); 2426 2427 /** 2428 * Remove disable package settings for any updated system 2429 * apps that were removed via an OTA. If they're not a 2430 * previously-updated app, remove them completely. 2431 * Otherwise, just revoke their system-level permissions. 2432 */ 2433 for (String deletedAppName : possiblyDeletedUpdatedSystemApps) { 2434 PackageParser.Package deletedPkg = mPackages.get(deletedAppName); 2435 mSettings.removeDisabledSystemPackageLPw(deletedAppName); 2436 2437 String msg; 2438 if (deletedPkg == null) { 2439 msg = "Updated system package " + deletedAppName 2440 + " no longer exists; it's data will be wiped"; 2441 // Actual deletion of code and data will be handled by later 2442 // reconciliation step 2443 } else { 2444 msg = "Updated system app + " + deletedAppName 2445 + " no longer present; removing system privileges for " 2446 + deletedAppName; 2447 2448 deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM; 2449 2450 PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName); 2451 deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM; 2452 } 2453 logCriticalInfo(Log.WARN, msg); 2454 } 2455 2456 /** 2457 * Make sure all system apps that we expected to appear on 2458 * the userdata partition actually showed up. If they never 2459 * appeared, crawl back and revive the system version. 2460 */ 2461 for (int i = 0; i < mExpectingBetter.size(); i++) { 2462 final String packageName = mExpectingBetter.keyAt(i); 2463 if (!mPackages.containsKey(packageName)) { 2464 final File scanFile = mExpectingBetter.valueAt(i); 2465 2466 logCriticalInfo(Log.WARN, "Expected better " + packageName 2467 + " but never showed up; reverting to system"); 2468 2469 int reparseFlags = mDefParseFlags; 2470 if (FileUtils.contains(privilegedAppDir, scanFile)) { 2471 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2472 | PackageParser.PARSE_IS_SYSTEM_DIR 2473 | PackageParser.PARSE_IS_PRIVILEGED; 2474 } else if (FileUtils.contains(systemAppDir, scanFile)) { 2475 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2476 | PackageParser.PARSE_IS_SYSTEM_DIR; 2477 } else if (FileUtils.contains(vendorAppDir, scanFile)) { 2478 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2479 | PackageParser.PARSE_IS_SYSTEM_DIR; 2480 } else if (FileUtils.contains(oemAppDir, scanFile)) { 2481 reparseFlags = PackageParser.PARSE_IS_SYSTEM 2482 | PackageParser.PARSE_IS_SYSTEM_DIR; 2483 } else { 2484 Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile); 2485 continue; 2486 } 2487 2488 mSettings.enableSystemPackageLPw(packageName); 2489 2490 try { 2491 scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null); 2492 } catch (PackageManagerException e) { 2493 Slog.e(TAG, "Failed to parse original system package: " 2494 + e.getMessage()); 2495 } 2496 } 2497 } 2498 } 2499 mExpectingBetter.clear(); 2500 2501 // Resolve the storage manager. 2502 mStorageManagerPackage = getStorageManagerPackageName(); 2503 2504 // Resolve protected action filters. Only the setup wizard is allowed to 2505 // have a high priority filter for these actions. 2506 mSetupWizardPackage = getSetupWizardPackageName(); 2507 if (mProtectedFilters.size() > 0) { 2508 if (DEBUG_FILTERS && mSetupWizardPackage == null) { 2509 Slog.i(TAG, "No setup wizard;" 2510 + " All protected intents capped to priority 0"); 2511 } 2512 for (ActivityIntentInfo filter : mProtectedFilters) { 2513 if (filter.activity.info.packageName.equals(mSetupWizardPackage)) { 2514 if (DEBUG_FILTERS) { 2515 Slog.i(TAG, "Found setup wizard;" 2516 + " allow priority " + filter.getPriority() + ";" 2517 + " package: " + filter.activity.info.packageName 2518 + " activity: " + filter.activity.className 2519 + " priority: " + filter.getPriority()); 2520 } 2521 // skip setup wizard; allow it to keep the high priority filter 2522 continue; 2523 } 2524 Slog.w(TAG, "Protected action; cap priority to 0;" 2525 + " package: " + filter.activity.info.packageName 2526 + " activity: " + filter.activity.className 2527 + " origPrio: " + filter.getPriority()); 2528 filter.setPriority(0); 2529 } 2530 } 2531 mDeferProtectedFilters = false; 2532 mProtectedFilters.clear(); 2533 2534 // Now that we know all of the shared libraries, update all clients to have 2535 // the correct library paths. 2536 updateAllSharedLibrariesLPw(); 2537 2538 for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) { 2539 // NOTE: We ignore potential failures here during a system scan (like 2540 // the rest of the commands above) because there's precious little we 2541 // can do about it. A settings error is reported, though. 2542 adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/); 2543 } 2544 2545 // Now that we know all the packages we are keeping, 2546 // read and update their last usage times. 2547 mPackageUsage.read(mPackages); 2548 mCompilerStats.read(); 2549 2550 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END, 2551 SystemClock.uptimeMillis()); 2552 Slog.i(TAG, "Time to scan packages: " 2553 + ((SystemClock.uptimeMillis()-startTime)/1000f) 2554 + " seconds"); 2555 2556 // If the platform SDK has changed since the last time we booted, 2557 // we need to re-grant app permission to catch any new ones that 2558 // appear. This is really a hack, and means that apps can in some 2559 // cases get permissions that the user didn't initially explicitly 2560 // allow... it would be nice to have some better way to handle 2561 // this situation. 2562 int updateFlags = UPDATE_PERMISSIONS_ALL; 2563 if (ver.sdkVersion != mSdkVersion) { 2564 Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to " 2565 + mSdkVersion + "; regranting permissions for internal storage"); 2566 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 2567 } 2568 updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags); 2569 ver.sdkVersion = mSdkVersion; 2570 2571 // If this is the first boot or an update from pre-M, and it is a normal 2572 // boot, then we need to initialize the default preferred apps across 2573 // all defined users. 2574 if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) { 2575 for (UserInfo user : sUserManager.getUsers(true)) { 2576 mSettings.applyDefaultPreferredAppsLPw(this, user.id); 2577 applyFactoryDefaultBrowserLPw(user.id); 2578 primeDomainVerificationsLPw(user.id); 2579 } 2580 } 2581 2582 // Prepare storage for system user really early during boot, 2583 // since core system apps like SettingsProvider and SystemUI 2584 // can't wait for user to start 2585 final int storageFlags; 2586 if (StorageManager.isFileEncryptedNativeOrEmulated()) { 2587 storageFlags = StorageManager.FLAG_STORAGE_DE; 2588 } else { 2589 storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 2590 } 2591 reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL, UserHandle.USER_SYSTEM, 2592 storageFlags, true /* migrateAppData */); 2593 2594 // If this is first boot after an OTA, and a normal boot, then 2595 // we need to clear code cache directories. 2596 // Note that we do *not* clear the application profiles. These remain valid 2597 // across OTAs and are used to drive profile verification (post OTA) and 2598 // profile compilation (without waiting to collect a fresh set of profiles). 2599 if (mIsUpgrade && !onlyCore) { 2600 Slog.i(TAG, "Build fingerprint changed; clearing code caches"); 2601 for (int i = 0; i < mSettings.mPackages.size(); i++) { 2602 final PackageSetting ps = mSettings.mPackages.valueAt(i); 2603 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) { 2604 // No apps are running this early, so no need to freeze 2605 clearAppDataLIF(ps.pkg, UserHandle.USER_ALL, 2606 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE 2607 | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 2608 } 2609 } 2610 ver.fingerprint = Build.FINGERPRINT; 2611 } 2612 2613 checkDefaultBrowser(); 2614 2615 // clear only after permissions and other defaults have been updated 2616 mExistingSystemPackages.clear(); 2617 mPromoteSystemApps = false; 2618 2619 // All the changes are done during package scanning. 2620 ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION; 2621 2622 // can downgrade to reader 2623 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings"); 2624 mSettings.writeLPr(); 2625 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2626 2627 // Perform dexopt on all apps that mark themselves as coreApps. We do this pretty 2628 // early on (before the package manager declares itself as early) because other 2629 // components in the system server might ask for package contexts for these apps. 2630 // 2631 // Note that "onlyCore" in this context means the system is encrypted or encrypting 2632 // (i.e, that the data partition is unavailable). 2633 if ((isFirstBoot() || isUpgrade() || VMRuntime.didPruneDalvikCache()) && !onlyCore) { 2634 long start = System.nanoTime(); 2635 List<PackageParser.Package> coreApps = new ArrayList<>(); 2636 for (PackageParser.Package pkg : mPackages.values()) { 2637 if (pkg.coreApp) { 2638 coreApps.add(pkg); 2639 } 2640 } 2641 2642 int[] stats = performDexOptUpgrade(coreApps, false, 2643 getCompilerFilterForReason(REASON_CORE_APP)); 2644 2645 final int elapsedTimeSeconds = 2646 (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start); 2647 MetricsLogger.histogram(mContext, "opt_coreapps_time_s", elapsedTimeSeconds); 2648 2649 if (DEBUG_DEXOPT) { 2650 Slog.i(TAG, "Dex-opt core apps took : " + elapsedTimeSeconds + " seconds (" + 2651 stats[0] + ", " + stats[1] + ", " + stats[2] + ")"); 2652 } 2653 2654 2655 // TODO: Should we log these stats to tron too ? 2656 // MetricsLogger.histogram(mContext, "opt_coreapps_num_dexopted", stats[0]); 2657 // MetricsLogger.histogram(mContext, "opt_coreapps_num_skipped", stats[1]); 2658 // MetricsLogger.histogram(mContext, "opt_coreapps_num_failed", stats[2]); 2659 // MetricsLogger.histogram(mContext, "opt_coreapps_num_total", coreApps.size()); 2660 } 2661 2662 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY, 2663 SystemClock.uptimeMillis()); 2664 2665 if (!mOnlyCore) { 2666 mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr(); 2667 mRequiredInstallerPackage = getRequiredInstallerLPr(); 2668 mRequiredUninstallerPackage = getRequiredUninstallerLPr(); 2669 mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr(); 2670 mIntentFilterVerifier = new IntentVerifierProxy(mContext, 2671 mIntentFilterVerifierComponent); 2672 mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr( 2673 PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES); 2674 mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr( 2675 PackageManager.SYSTEM_SHARED_LIBRARY_SHARED); 2676 } else { 2677 mRequiredVerifierPackage = null; 2678 mRequiredInstallerPackage = null; 2679 mRequiredUninstallerPackage = null; 2680 mIntentFilterVerifierComponent = null; 2681 mIntentFilterVerifier = null; 2682 mServicesSystemSharedLibraryPackageName = null; 2683 mSharedSystemSharedLibraryPackageName = null; 2684 } 2685 2686 mInstallerService = new PackageInstallerService(context, this); 2687 2688 final ComponentName ephemeralResolverComponent = getEphemeralResolverLPr(); 2689 final ComponentName ephemeralInstallerComponent = getEphemeralInstallerLPr(); 2690 // both the installer and resolver must be present to enable ephemeral 2691 if (ephemeralInstallerComponent != null && ephemeralResolverComponent != null) { 2692 if (DEBUG_EPHEMERAL) { 2693 Slog.i(TAG, "Ephemeral activated; resolver: " + ephemeralResolverComponent 2694 + " installer:" + ephemeralInstallerComponent); 2695 } 2696 mEphemeralResolverComponent = ephemeralResolverComponent; 2697 mEphemeralInstallerComponent = ephemeralInstallerComponent; 2698 setUpEphemeralInstallerActivityLP(mEphemeralInstallerComponent); 2699 mEphemeralResolverConnection = 2700 new EphemeralResolverConnection(mContext, mEphemeralResolverComponent); 2701 } else { 2702 if (DEBUG_EPHEMERAL) { 2703 final String missingComponent = 2704 (ephemeralResolverComponent == null) 2705 ? (ephemeralInstallerComponent == null) 2706 ? "resolver and installer" 2707 : "resolver" 2708 : "installer"; 2709 Slog.i(TAG, "Ephemeral deactivated; missing " + missingComponent); 2710 } 2711 mEphemeralResolverComponent = null; 2712 mEphemeralInstallerComponent = null; 2713 mEphemeralResolverConnection = null; 2714 } 2715 2716 mEphemeralApplicationRegistry = new EphemeralApplicationRegistry(this); 2717 } // synchronized (mPackages) 2718 } // synchronized (mInstallLock) 2719 2720 // Now after opening every single application zip, make sure they 2721 // are all flushed. Not really needed, but keeps things nice and 2722 // tidy. 2723 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC"); 2724 Runtime.getRuntime().gc(); 2725 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2726 2727 // The initial scanning above does many calls into installd while 2728 // holding the mPackages lock, but we're mostly interested in yelling 2729 // once we have a booted system. 2730 mInstaller.setWarnIfHeld(mPackages); 2731 2732 // Expose private service for system components to use. 2733 LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl()); 2734 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 2735 } 2736 2737 @Override 2738 public boolean isFirstBoot() { 2739 return mFirstBoot; 2740 } 2741 2742 @Override 2743 public boolean isOnlyCoreApps() { 2744 return mOnlyCore; 2745 } 2746 2747 @Override 2748 public boolean isUpgrade() { 2749 return mIsUpgrade; 2750 } 2751 2752 private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() { 2753 final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 2754 2755 final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE, 2756 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 2757 UserHandle.USER_SYSTEM); 2758 if (matches.size() == 1) { 2759 return matches.get(0).getComponentInfo().packageName; 2760 } else if (matches.size() == 0) { 2761 Log.e(TAG, "There should probably be a verifier, but, none were found"); 2762 return null; 2763 } 2764 throw new RuntimeException("There must be exactly one verifier; found " + matches); 2765 } 2766 2767 private @NonNull String getRequiredSharedLibraryLPr(String libraryName) { 2768 synchronized (mPackages) { 2769 SharedLibraryEntry libraryEntry = mSharedLibraries.get(libraryName); 2770 if (libraryEntry == null) { 2771 throw new IllegalStateException("Missing required shared library:" + libraryName); 2772 } 2773 return libraryEntry.apk; 2774 } 2775 } 2776 2777 private @NonNull String getRequiredInstallerLPr() { 2778 final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE); 2779 intent.addCategory(Intent.CATEGORY_DEFAULT); 2780 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE); 2781 2782 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE, 2783 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 2784 UserHandle.USER_SYSTEM); 2785 if (matches.size() == 1) { 2786 ResolveInfo resolveInfo = matches.get(0); 2787 if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) { 2788 throw new RuntimeException("The installer must be a privileged app"); 2789 } 2790 return matches.get(0).getComponentInfo().packageName; 2791 } else { 2792 throw new RuntimeException("There must be exactly one installer; found " + matches); 2793 } 2794 } 2795 2796 private @NonNull String getRequiredUninstallerLPr() { 2797 final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE); 2798 intent.addCategory(Intent.CATEGORY_DEFAULT); 2799 intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null)); 2800 2801 final ResolveInfo resolveInfo = resolveIntent(intent, null, 2802 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 2803 UserHandle.USER_SYSTEM); 2804 if (resolveInfo == null || 2805 mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) { 2806 throw new RuntimeException("There must be exactly one uninstaller; found " 2807 + resolveInfo); 2808 } 2809 return resolveInfo.getComponentInfo().packageName; 2810 } 2811 2812 private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() { 2813 final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION); 2814 2815 final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE, 2816 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 2817 UserHandle.USER_SYSTEM); 2818 ResolveInfo best = null; 2819 final int N = matches.size(); 2820 for (int i = 0; i < N; i++) { 2821 final ResolveInfo cur = matches.get(i); 2822 final String packageName = cur.getComponentInfo().packageName; 2823 if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 2824 packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) { 2825 continue; 2826 } 2827 2828 if (best == null || cur.priority > best.priority) { 2829 best = cur; 2830 } 2831 } 2832 2833 if (best != null) { 2834 return best.getComponentInfo().getComponentName(); 2835 } else { 2836 throw new RuntimeException("There must be at least one intent filter verifier"); 2837 } 2838 } 2839 2840 private @Nullable ComponentName getEphemeralResolverLPr() { 2841 final String[] packageArray = 2842 mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage); 2843 if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) { 2844 if (DEBUG_EPHEMERAL) { 2845 Slog.d(TAG, "Ephemeral resolver NOT found; empty package list"); 2846 } 2847 return null; 2848 } 2849 2850 final int resolveFlags = 2851 MATCH_DIRECT_BOOT_AWARE 2852 | MATCH_DIRECT_BOOT_UNAWARE 2853 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0); 2854 final Intent resolverIntent = new Intent(Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE); 2855 final List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null, 2856 resolveFlags, UserHandle.USER_SYSTEM); 2857 2858 final int N = resolvers.size(); 2859 if (N == 0) { 2860 if (DEBUG_EPHEMERAL) { 2861 Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters"); 2862 } 2863 return null; 2864 } 2865 2866 final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray)); 2867 for (int i = 0; i < N; i++) { 2868 final ResolveInfo info = resolvers.get(i); 2869 2870 if (info.serviceInfo == null) { 2871 continue; 2872 } 2873 2874 final String packageName = info.serviceInfo.packageName; 2875 if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) { 2876 if (DEBUG_EPHEMERAL) { 2877 Slog.d(TAG, "Ephemeral resolver not in allowed package list;" 2878 + " pkg: " + packageName + ", info:" + info); 2879 } 2880 continue; 2881 } 2882 2883 if (DEBUG_EPHEMERAL) { 2884 Slog.v(TAG, "Ephemeral resolver found;" 2885 + " pkg: " + packageName + ", info:" + info); 2886 } 2887 return new ComponentName(packageName, info.serviceInfo.name); 2888 } 2889 if (DEBUG_EPHEMERAL) { 2890 Slog.v(TAG, "Ephemeral resolver NOT found"); 2891 } 2892 return null; 2893 } 2894 2895 private @Nullable ComponentName getEphemeralInstallerLPr() { 2896 final Intent intent = new Intent(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE); 2897 intent.addCategory(Intent.CATEGORY_DEFAULT); 2898 intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE); 2899 2900 final int resolveFlags = 2901 MATCH_DIRECT_BOOT_AWARE 2902 | MATCH_DIRECT_BOOT_UNAWARE 2903 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0); 2904 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE, 2905 resolveFlags, UserHandle.USER_SYSTEM); 2906 if (matches.size() == 0) { 2907 return null; 2908 } else if (matches.size() == 1) { 2909 return matches.get(0).getComponentInfo().getComponentName(); 2910 } else { 2911 throw new RuntimeException( 2912 "There must be at most one ephemeral installer; found " + matches); 2913 } 2914 } 2915 2916 private void primeDomainVerificationsLPw(int userId) { 2917 if (DEBUG_DOMAIN_VERIFICATION) { 2918 Slog.d(TAG, "Priming domain verifications in user " + userId); 2919 } 2920 2921 SystemConfig systemConfig = SystemConfig.getInstance(); 2922 ArraySet<String> packages = systemConfig.getLinkedApps(); 2923 2924 for (String packageName : packages) { 2925 PackageParser.Package pkg = mPackages.get(packageName); 2926 if (pkg != null) { 2927 if (!pkg.isSystemApp()) { 2928 Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>"); 2929 continue; 2930 } 2931 2932 ArraySet<String> domains = null; 2933 for (PackageParser.Activity a : pkg.activities) { 2934 for (ActivityIntentInfo filter : a.intents) { 2935 if (hasValidDomains(filter)) { 2936 if (domains == null) { 2937 domains = new ArraySet<String>(); 2938 } 2939 domains.addAll(filter.getHostsList()); 2940 } 2941 } 2942 } 2943 2944 if (domains != null && domains.size() > 0) { 2945 if (DEBUG_DOMAIN_VERIFICATION) { 2946 Slog.v(TAG, " + " + packageName); 2947 } 2948 // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual 2949 // state w.r.t. the formal app-linkage "no verification attempted" state; 2950 // and then 'always' in the per-user state actually used for intent resolution. 2951 final IntentFilterVerificationInfo ivi; 2952 ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains); 2953 ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED); 2954 mSettings.updateIntentFilterVerificationStatusLPw(packageName, 2955 INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId); 2956 } else { 2957 Slog.w(TAG, "Sysconfig <app-link> package '" + packageName 2958 + "' does not handle web links"); 2959 } 2960 } else { 2961 Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>"); 2962 } 2963 } 2964 2965 scheduleWritePackageRestrictionsLocked(userId); 2966 scheduleWriteSettingsLocked(); 2967 } 2968 2969 private void applyFactoryDefaultBrowserLPw(int userId) { 2970 // The default browser app's package name is stored in a string resource, 2971 // with a product-specific overlay used for vendor customization. 2972 String browserPkg = mContext.getResources().getString( 2973 com.android.internal.R.string.default_browser); 2974 if (!TextUtils.isEmpty(browserPkg)) { 2975 // non-empty string => required to be a known package 2976 PackageSetting ps = mSettings.mPackages.get(browserPkg); 2977 if (ps == null) { 2978 Slog.e(TAG, "Product default browser app does not exist: " + browserPkg); 2979 browserPkg = null; 2980 } else { 2981 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId); 2982 } 2983 } 2984 2985 // Nothing valid explicitly set? Make the factory-installed browser the explicit 2986 // default. If there's more than one, just leave everything alone. 2987 if (browserPkg == null) { 2988 calculateDefaultBrowserLPw(userId); 2989 } 2990 } 2991 2992 private void calculateDefaultBrowserLPw(int userId) { 2993 List<String> allBrowsers = resolveAllBrowserApps(userId); 2994 final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null; 2995 mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId); 2996 } 2997 2998 private List<String> resolveAllBrowserApps(int userId) { 2999 // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set 3000 List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null, 3001 PackageManager.MATCH_ALL, userId); 3002 3003 final int count = list.size(); 3004 List<String> result = new ArrayList<String>(count); 3005 for (int i=0; i<count; i++) { 3006 ResolveInfo info = list.get(i); 3007 if (info.activityInfo == null 3008 || !info.handleAllWebDataURI 3009 || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0 3010 || result.contains(info.activityInfo.packageName)) { 3011 continue; 3012 } 3013 result.add(info.activityInfo.packageName); 3014 } 3015 3016 return result; 3017 } 3018 3019 private boolean packageIsBrowser(String packageName, int userId) { 3020 List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null, 3021 PackageManager.MATCH_ALL, userId); 3022 final int N = list.size(); 3023 for (int i = 0; i < N; i++) { 3024 ResolveInfo info = list.get(i); 3025 if (packageName.equals(info.activityInfo.packageName)) { 3026 return true; 3027 } 3028 } 3029 return false; 3030 } 3031 3032 private void checkDefaultBrowser() { 3033 final int myUserId = UserHandle.myUserId(); 3034 final String packageName = getDefaultBrowserPackageName(myUserId); 3035 if (packageName != null) { 3036 PackageInfo info = getPackageInfo(packageName, 0, myUserId); 3037 if (info == null) { 3038 Slog.w(TAG, "Default browser no longer installed: " + packageName); 3039 synchronized (mPackages) { 3040 applyFactoryDefaultBrowserLPw(myUserId); // leaves ambiguous when > 1 3041 } 3042 } 3043 } 3044 } 3045 3046 @Override 3047 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 3048 throws RemoteException { 3049 try { 3050 return super.onTransact(code, data, reply, flags); 3051 } catch (RuntimeException e) { 3052 if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) { 3053 Slog.wtf(TAG, "Package Manager Crash", e); 3054 } 3055 throw e; 3056 } 3057 } 3058 3059 static int[] appendInts(int[] cur, int[] add) { 3060 if (add == null) return cur; 3061 if (cur == null) return add; 3062 final int N = add.length; 3063 for (int i=0; i<N; i++) { 3064 cur = appendInt(cur, add[i]); 3065 } 3066 return cur; 3067 } 3068 3069 private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) { 3070 if (!sUserManager.exists(userId)) return null; 3071 if (ps == null) { 3072 return null; 3073 } 3074 final PackageParser.Package p = ps.pkg; 3075 if (p == null) { 3076 return null; 3077 } 3078 3079 final PermissionsState permissionsState = ps.getPermissionsState(); 3080 3081 // Compute GIDs only if requested 3082 final int[] gids = (flags & PackageManager.GET_GIDS) == 0 3083 ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId); 3084 // Compute granted permissions only if package has requested permissions 3085 final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions) 3086 ? Collections.<String>emptySet() : permissionsState.getPermissions(userId); 3087 final PackageUserState state = ps.readUserState(userId); 3088 3089 return PackageParser.generatePackageInfo(p, gids, flags, 3090 ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId); 3091 } 3092 3093 @Override 3094 public void checkPackageStartable(String packageName, int userId) { 3095 final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId); 3096 3097 synchronized (mPackages) { 3098 final PackageSetting ps = mSettings.mPackages.get(packageName); 3099 if (ps == null) { 3100 throw new SecurityException("Package " + packageName + " was not found!"); 3101 } 3102 3103 if (!ps.getInstalled(userId)) { 3104 throw new SecurityException( 3105 "Package " + packageName + " was not installed for user " + userId + "!"); 3106 } 3107 3108 if (mSafeMode && !ps.isSystem()) { 3109 throw new SecurityException("Package " + packageName + " not a system app!"); 3110 } 3111 3112 if (mFrozenPackages.contains(packageName)) { 3113 throw new SecurityException("Package " + packageName + " is currently frozen!"); 3114 } 3115 3116 if (!userKeyUnlocked && !(ps.pkg.applicationInfo.isDirectBootAware() 3117 || ps.pkg.applicationInfo.isPartiallyDirectBootAware())) { 3118 throw new SecurityException("Package " + packageName + " is not encryption aware!"); 3119 } 3120 } 3121 } 3122 3123 @Override 3124 public boolean isPackageAvailable(String packageName, int userId) { 3125 if (!sUserManager.exists(userId)) return false; 3126 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3127 false /* requireFullPermission */, false /* checkShell */, "is package available"); 3128 synchronized (mPackages) { 3129 PackageParser.Package p = mPackages.get(packageName); 3130 if (p != null) { 3131 final PackageSetting ps = (PackageSetting) p.mExtras; 3132 if (ps != null) { 3133 final PackageUserState state = ps.readUserState(userId); 3134 if (state != null) { 3135 return PackageParser.isAvailable(state); 3136 } 3137 } 3138 } 3139 } 3140 return false; 3141 } 3142 3143 @Override 3144 public PackageInfo getPackageInfo(String packageName, int flags, int userId) { 3145 if (!sUserManager.exists(userId)) return null; 3146 flags = updateFlagsForPackage(flags, userId, packageName); 3147 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3148 false /* requireFullPermission */, false /* checkShell */, "get package info"); 3149 // reader 3150 synchronized (mPackages) { 3151 final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0; 3152 PackageParser.Package p = null; 3153 if (matchFactoryOnly) { 3154 final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName); 3155 if (ps != null) { 3156 return generatePackageInfo(ps, flags, userId); 3157 } 3158 } 3159 if (p == null) { 3160 p = mPackages.get(packageName); 3161 if (matchFactoryOnly && p != null && !isSystemApp(p)) { 3162 return null; 3163 } 3164 } 3165 if (DEBUG_PACKAGE_INFO) 3166 Log.v(TAG, "getPackageInfo " + packageName + ": " + p); 3167 if (p != null) { 3168 return generatePackageInfo((PackageSetting)p.mExtras, flags, userId); 3169 } 3170 if (!matchFactoryOnly && (flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 3171 final PackageSetting ps = mSettings.mPackages.get(packageName); 3172 return generatePackageInfo(ps, flags, userId); 3173 } 3174 } 3175 return null; 3176 } 3177 3178 @Override 3179 public String[] currentToCanonicalPackageNames(String[] names) { 3180 String[] out = new String[names.length]; 3181 // reader 3182 synchronized (mPackages) { 3183 for (int i=names.length-1; i>=0; i--) { 3184 PackageSetting ps = mSettings.mPackages.get(names[i]); 3185 out[i] = ps != null && ps.realName != null ? ps.realName : names[i]; 3186 } 3187 } 3188 return out; 3189 } 3190 3191 @Override 3192 public String[] canonicalToCurrentPackageNames(String[] names) { 3193 String[] out = new String[names.length]; 3194 // reader 3195 synchronized (mPackages) { 3196 for (int i=names.length-1; i>=0; i--) { 3197 String cur = mSettings.getRenamedPackageLPr(names[i]); 3198 out[i] = cur != null ? cur : names[i]; 3199 } 3200 } 3201 return out; 3202 } 3203 3204 @Override 3205 public int getPackageUid(String packageName, int flags, int userId) { 3206 if (!sUserManager.exists(userId)) return -1; 3207 flags = updateFlagsForPackage(flags, userId, packageName); 3208 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3209 false /* requireFullPermission */, false /* checkShell */, "get package uid"); 3210 3211 // reader 3212 synchronized (mPackages) { 3213 final PackageParser.Package p = mPackages.get(packageName); 3214 if (p != null && p.isMatch(flags)) { 3215 return UserHandle.getUid(userId, p.applicationInfo.uid); 3216 } 3217 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 3218 final PackageSetting ps = mSettings.mPackages.get(packageName); 3219 if (ps != null && ps.isMatch(flags)) { 3220 return UserHandle.getUid(userId, ps.appId); 3221 } 3222 } 3223 } 3224 3225 return -1; 3226 } 3227 3228 @Override 3229 public int[] getPackageGids(String packageName, int flags, int userId) { 3230 if (!sUserManager.exists(userId)) return null; 3231 flags = updateFlagsForPackage(flags, userId, packageName); 3232 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3233 false /* requireFullPermission */, false /* checkShell */, 3234 "getPackageGids"); 3235 3236 // reader 3237 synchronized (mPackages) { 3238 final PackageParser.Package p = mPackages.get(packageName); 3239 if (p != null && p.isMatch(flags)) { 3240 PackageSetting ps = (PackageSetting) p.mExtras; 3241 return ps.getPermissionsState().computeGids(userId); 3242 } 3243 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 3244 final PackageSetting ps = mSettings.mPackages.get(packageName); 3245 if (ps != null && ps.isMatch(flags)) { 3246 return ps.getPermissionsState().computeGids(userId); 3247 } 3248 } 3249 } 3250 3251 return null; 3252 } 3253 3254 static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) { 3255 if (bp.perm != null) { 3256 return PackageParser.generatePermissionInfo(bp.perm, flags); 3257 } 3258 PermissionInfo pi = new PermissionInfo(); 3259 pi.name = bp.name; 3260 pi.packageName = bp.sourcePackage; 3261 pi.nonLocalizedLabel = bp.name; 3262 pi.protectionLevel = bp.protectionLevel; 3263 return pi; 3264 } 3265 3266 @Override 3267 public PermissionInfo getPermissionInfo(String name, int flags) { 3268 // reader 3269 synchronized (mPackages) { 3270 final BasePermission p = mSettings.mPermissions.get(name); 3271 if (p != null) { 3272 return generatePermissionInfo(p, flags); 3273 } 3274 return null; 3275 } 3276 } 3277 3278 @Override 3279 public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group, 3280 int flags) { 3281 // reader 3282 synchronized (mPackages) { 3283 if (group != null && !mPermissionGroups.containsKey(group)) { 3284 // This is thrown as NameNotFoundException 3285 return null; 3286 } 3287 3288 ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10); 3289 for (BasePermission p : mSettings.mPermissions.values()) { 3290 if (group == null) { 3291 if (p.perm == null || p.perm.info.group == null) { 3292 out.add(generatePermissionInfo(p, flags)); 3293 } 3294 } else { 3295 if (p.perm != null && group.equals(p.perm.info.group)) { 3296 out.add(PackageParser.generatePermissionInfo(p.perm, flags)); 3297 } 3298 } 3299 } 3300 return new ParceledListSlice<>(out); 3301 } 3302 } 3303 3304 @Override 3305 public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) { 3306 // reader 3307 synchronized (mPackages) { 3308 return PackageParser.generatePermissionGroupInfo( 3309 mPermissionGroups.get(name), flags); 3310 } 3311 } 3312 3313 @Override 3314 public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) { 3315 // reader 3316 synchronized (mPackages) { 3317 final int N = mPermissionGroups.size(); 3318 ArrayList<PermissionGroupInfo> out 3319 = new ArrayList<PermissionGroupInfo>(N); 3320 for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) { 3321 out.add(PackageParser.generatePermissionGroupInfo(pg, flags)); 3322 } 3323 return new ParceledListSlice<>(out); 3324 } 3325 } 3326 3327 private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags, 3328 int userId) { 3329 if (!sUserManager.exists(userId)) return null; 3330 PackageSetting ps = mSettings.mPackages.get(packageName); 3331 if (ps != null) { 3332 if (ps.pkg == null) { 3333 final PackageInfo pInfo = generatePackageInfo(ps, flags, userId); 3334 if (pInfo != null) { 3335 return pInfo.applicationInfo; 3336 } 3337 return null; 3338 } 3339 return PackageParser.generateApplicationInfo(ps.pkg, flags, 3340 ps.readUserState(userId), userId); 3341 } 3342 return null; 3343 } 3344 3345 @Override 3346 public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) { 3347 if (!sUserManager.exists(userId)) return null; 3348 flags = updateFlagsForApplication(flags, userId, packageName); 3349 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3350 false /* requireFullPermission */, false /* checkShell */, "get application info"); 3351 // writer 3352 synchronized (mPackages) { 3353 PackageParser.Package p = mPackages.get(packageName); 3354 if (DEBUG_PACKAGE_INFO) Log.v( 3355 TAG, "getApplicationInfo " + packageName 3356 + ": " + p); 3357 if (p != null) { 3358 PackageSetting ps = mSettings.mPackages.get(packageName); 3359 if (ps == null) return null; 3360 // Note: isEnabledLP() does not apply here - always return info 3361 return PackageParser.generateApplicationInfo( 3362 p, flags, ps.readUserState(userId), userId); 3363 } 3364 if ("android".equals(packageName)||"system".equals(packageName)) { 3365 return mAndroidApplication; 3366 } 3367 if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) { 3368 return generateApplicationInfoFromSettingsLPw(packageName, flags, userId); 3369 } 3370 } 3371 return null; 3372 } 3373 3374 @Override 3375 public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize, 3376 final IPackageDataObserver observer) { 3377 mContext.enforceCallingOrSelfPermission( 3378 android.Manifest.permission.CLEAR_APP_CACHE, null); 3379 // Queue up an async operation since clearing cache may take a little while. 3380 mHandler.post(new Runnable() { 3381 public void run() { 3382 mHandler.removeCallbacks(this); 3383 boolean success = true; 3384 synchronized (mInstallLock) { 3385 try { 3386 mInstaller.freeCache(volumeUuid, freeStorageSize); 3387 } catch (InstallerException e) { 3388 Slog.w(TAG, "Couldn't clear application caches: " + e); 3389 success = false; 3390 } 3391 } 3392 if (observer != null) { 3393 try { 3394 observer.onRemoveCompleted(null, success); 3395 } catch (RemoteException e) { 3396 Slog.w(TAG, "RemoveException when invoking call back"); 3397 } 3398 } 3399 } 3400 }); 3401 } 3402 3403 @Override 3404 public void freeStorage(final String volumeUuid, final long freeStorageSize, 3405 final IntentSender pi) { 3406 mContext.enforceCallingOrSelfPermission( 3407 android.Manifest.permission.CLEAR_APP_CACHE, null); 3408 // Queue up an async operation since clearing cache may take a little while. 3409 mHandler.post(new Runnable() { 3410 public void run() { 3411 mHandler.removeCallbacks(this); 3412 boolean success = true; 3413 synchronized (mInstallLock) { 3414 try { 3415 mInstaller.freeCache(volumeUuid, freeStorageSize); 3416 } catch (InstallerException e) { 3417 Slog.w(TAG, "Couldn't clear application caches: " + e); 3418 success = false; 3419 } 3420 } 3421 if(pi != null) { 3422 try { 3423 // Callback via pending intent 3424 int code = success ? 1 : 0; 3425 pi.sendIntent(null, code, null, 3426 null, null); 3427 } catch (SendIntentException e1) { 3428 Slog.i(TAG, "Failed to send pending intent"); 3429 } 3430 } 3431 } 3432 }); 3433 } 3434 3435 void freeStorage(String volumeUuid, long freeStorageSize) throws IOException { 3436 synchronized (mInstallLock) { 3437 try { 3438 mInstaller.freeCache(volumeUuid, freeStorageSize); 3439 } catch (InstallerException e) { 3440 throw new IOException("Failed to free enough space", e); 3441 } 3442 } 3443 } 3444 3445 /** 3446 * Update given flags based on encryption status of current user. 3447 */ 3448 private int updateFlags(int flags, int userId) { 3449 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE 3450 | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) { 3451 // Caller expressed an explicit opinion about what encryption 3452 // aware/unaware components they want to see, so fall through and 3453 // give them what they want 3454 } else { 3455 // Caller expressed no opinion, so match based on user state 3456 if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) { 3457 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE; 3458 } else { 3459 flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE; 3460 } 3461 } 3462 return flags; 3463 } 3464 3465 private UserManagerInternal getUserManagerInternal() { 3466 if (mUserManagerInternal == null) { 3467 mUserManagerInternal = LocalServices.getService(UserManagerInternal.class); 3468 } 3469 return mUserManagerInternal; 3470 } 3471 3472 /** 3473 * Update given flags when being used to request {@link PackageInfo}. 3474 */ 3475 private int updateFlagsForPackage(int flags, int userId, Object cookie) { 3476 boolean triaged = true; 3477 if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS 3478 | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) { 3479 // Caller is asking for component details, so they'd better be 3480 // asking for specific encryption matching behavior, or be triaged 3481 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE 3482 | PackageManager.MATCH_DIRECT_BOOT_AWARE 3483 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3484 triaged = false; 3485 } 3486 } 3487 if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES 3488 | PackageManager.MATCH_SYSTEM_ONLY 3489 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3490 triaged = false; 3491 } 3492 if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) { 3493 Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie 3494 + " with flags 0x" + Integer.toHexString(flags), new Throwable()); 3495 } 3496 return updateFlags(flags, userId); 3497 } 3498 3499 /** 3500 * Update given flags when being used to request {@link ApplicationInfo}. 3501 */ 3502 private int updateFlagsForApplication(int flags, int userId, Object cookie) { 3503 return updateFlagsForPackage(flags, userId, cookie); 3504 } 3505 3506 /** 3507 * Update given flags when being used to request {@link ComponentInfo}. 3508 */ 3509 private int updateFlagsForComponent(int flags, int userId, Object cookie) { 3510 if (cookie instanceof Intent) { 3511 if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) { 3512 flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING; 3513 } 3514 } 3515 3516 boolean triaged = true; 3517 // Caller is asking for component details, so they'd better be 3518 // asking for specific encryption matching behavior, or be triaged 3519 if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE 3520 | PackageManager.MATCH_DIRECT_BOOT_AWARE 3521 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) { 3522 triaged = false; 3523 } 3524 if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) { 3525 Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie 3526 + " with flags 0x" + Integer.toHexString(flags), new Throwable()); 3527 } 3528 3529 return updateFlags(flags, userId); 3530 } 3531 3532 /** 3533 * Update given flags when being used to request {@link ResolveInfo}. 3534 */ 3535 int updateFlagsForResolve(int flags, int userId, Object cookie) { 3536 // Safe mode means we shouldn't match any third-party components 3537 if (mSafeMode) { 3538 flags |= PackageManager.MATCH_SYSTEM_ONLY; 3539 } 3540 3541 return updateFlagsForComponent(flags, userId, cookie); 3542 } 3543 3544 @Override 3545 public ActivityInfo getActivityInfo(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 activity info"); 3550 synchronized (mPackages) { 3551 PackageParser.Activity a = mActivities.mActivities.get(component); 3552 3553 if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a); 3554 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) { 3555 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3556 if (ps == null) return null; 3557 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 3558 userId); 3559 } 3560 if (mResolveComponentName.equals(component)) { 3561 return PackageParser.generateActivityInfo(mResolveActivity, flags, 3562 new PackageUserState(), userId); 3563 } 3564 } 3565 return null; 3566 } 3567 3568 @Override 3569 public boolean activitySupportsIntent(ComponentName component, Intent intent, 3570 String resolvedType) { 3571 synchronized (mPackages) { 3572 if (component.equals(mResolveComponentName)) { 3573 // The resolver supports EVERYTHING! 3574 return true; 3575 } 3576 PackageParser.Activity a = mActivities.mActivities.get(component); 3577 if (a == null) { 3578 return false; 3579 } 3580 for (int i=0; i<a.intents.size(); i++) { 3581 if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(), 3582 intent.getData(), intent.getCategories(), TAG) >= 0) { 3583 return true; 3584 } 3585 } 3586 return false; 3587 } 3588 } 3589 3590 @Override 3591 public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) { 3592 if (!sUserManager.exists(userId)) return null; 3593 flags = updateFlagsForComponent(flags, userId, component); 3594 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3595 false /* requireFullPermission */, false /* checkShell */, "get receiver info"); 3596 synchronized (mPackages) { 3597 PackageParser.Activity a = mReceivers.mActivities.get(component); 3598 if (DEBUG_PACKAGE_INFO) Log.v( 3599 TAG, "getReceiverInfo " + component + ": " + a); 3600 if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) { 3601 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3602 if (ps == null) return null; 3603 return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), 3604 userId); 3605 } 3606 } 3607 return null; 3608 } 3609 3610 @Override 3611 public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) { 3612 if (!sUserManager.exists(userId)) return null; 3613 flags = updateFlagsForComponent(flags, userId, component); 3614 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3615 false /* requireFullPermission */, false /* checkShell */, "get service info"); 3616 synchronized (mPackages) { 3617 PackageParser.Service s = mServices.mServices.get(component); 3618 if (DEBUG_PACKAGE_INFO) Log.v( 3619 TAG, "getServiceInfo " + component + ": " + s); 3620 if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) { 3621 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3622 if (ps == null) return null; 3623 return PackageParser.generateServiceInfo(s, flags, ps.readUserState(userId), 3624 userId); 3625 } 3626 } 3627 return null; 3628 } 3629 3630 @Override 3631 public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) { 3632 if (!sUserManager.exists(userId)) return null; 3633 flags = updateFlagsForComponent(flags, userId, component); 3634 enforceCrossUserPermission(Binder.getCallingUid(), userId, 3635 false /* requireFullPermission */, false /* checkShell */, "get provider info"); 3636 synchronized (mPackages) { 3637 PackageParser.Provider p = mProviders.mProviders.get(component); 3638 if (DEBUG_PACKAGE_INFO) Log.v( 3639 TAG, "getProviderInfo " + component + ": " + p); 3640 if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) { 3641 PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); 3642 if (ps == null) return null; 3643 return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId), 3644 userId); 3645 } 3646 } 3647 return null; 3648 } 3649 3650 @Override 3651 public String[] getSystemSharedLibraryNames() { 3652 Set<String> libSet; 3653 synchronized (mPackages) { 3654 libSet = mSharedLibraries.keySet(); 3655 int size = libSet.size(); 3656 if (size > 0) { 3657 String[] libs = new String[size]; 3658 libSet.toArray(libs); 3659 return libs; 3660 } 3661 } 3662 return null; 3663 } 3664 3665 @Override 3666 public @NonNull String getServicesSystemSharedLibraryPackageName() { 3667 synchronized (mPackages) { 3668 return mServicesSystemSharedLibraryPackageName; 3669 } 3670 } 3671 3672 @Override 3673 public @NonNull String getSharedSystemSharedLibraryPackageName() { 3674 synchronized (mPackages) { 3675 return mSharedSystemSharedLibraryPackageName; 3676 } 3677 } 3678 3679 @Override 3680 public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() { 3681 synchronized (mPackages) { 3682 final ArrayList<FeatureInfo> res = new ArrayList<>(mAvailableFeatures.values()); 3683 3684 final FeatureInfo fi = new FeatureInfo(); 3685 fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version", 3686 FeatureInfo.GL_ES_VERSION_UNDEFINED); 3687 res.add(fi); 3688 3689 return new ParceledListSlice<>(res); 3690 } 3691 } 3692 3693 @Override 3694 public boolean hasSystemFeature(String name, int version) { 3695 synchronized (mPackages) { 3696 final FeatureInfo feat = mAvailableFeatures.get(name); 3697 if (feat == null) { 3698 return false; 3699 } else { 3700 return feat.version >= version; 3701 } 3702 } 3703 } 3704 3705 @Override 3706 public int checkPermission(String permName, String pkgName, int userId) { 3707 if (!sUserManager.exists(userId)) { 3708 return PackageManager.PERMISSION_DENIED; 3709 } 3710 3711 synchronized (mPackages) { 3712 final PackageParser.Package p = mPackages.get(pkgName); 3713 if (p != null && p.mExtras != null) { 3714 final PackageSetting ps = (PackageSetting) p.mExtras; 3715 final PermissionsState permissionsState = ps.getPermissionsState(); 3716 if (permissionsState.hasPermission(permName, userId)) { 3717 return PackageManager.PERMISSION_GRANTED; 3718 } 3719 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION 3720 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState 3721 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { 3722 return PackageManager.PERMISSION_GRANTED; 3723 } 3724 } 3725 } 3726 3727 return PackageManager.PERMISSION_DENIED; 3728 } 3729 3730 @Override 3731 public int checkUidPermission(String permName, int uid) { 3732 final int userId = UserHandle.getUserId(uid); 3733 3734 if (!sUserManager.exists(userId)) { 3735 return PackageManager.PERMISSION_DENIED; 3736 } 3737 3738 synchronized (mPackages) { 3739 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 3740 if (obj != null) { 3741 final SettingBase ps = (SettingBase) obj; 3742 final PermissionsState permissionsState = ps.getPermissionsState(); 3743 if (permissionsState.hasPermission(permName, userId)) { 3744 return PackageManager.PERMISSION_GRANTED; 3745 } 3746 // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION 3747 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState 3748 .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) { 3749 return PackageManager.PERMISSION_GRANTED; 3750 } 3751 } else { 3752 ArraySet<String> perms = mSystemPermissions.get(uid); 3753 if (perms != null) { 3754 if (perms.contains(permName)) { 3755 return PackageManager.PERMISSION_GRANTED; 3756 } 3757 if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms 3758 .contains(Manifest.permission.ACCESS_FINE_LOCATION)) { 3759 return PackageManager.PERMISSION_GRANTED; 3760 } 3761 } 3762 } 3763 } 3764 3765 return PackageManager.PERMISSION_DENIED; 3766 } 3767 3768 @Override 3769 public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) { 3770 if (UserHandle.getCallingUserId() != userId) { 3771 mContext.enforceCallingPermission( 3772 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 3773 "isPermissionRevokedByPolicy for user " + userId); 3774 } 3775 3776 if (checkPermission(permission, packageName, userId) 3777 == PackageManager.PERMISSION_GRANTED) { 3778 return false; 3779 } 3780 3781 final long identity = Binder.clearCallingIdentity(); 3782 try { 3783 final int flags = getPermissionFlags(permission, packageName, userId); 3784 return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0; 3785 } finally { 3786 Binder.restoreCallingIdentity(identity); 3787 } 3788 } 3789 3790 @Override 3791 public String getPermissionControllerPackageName() { 3792 synchronized (mPackages) { 3793 return mRequiredInstallerPackage; 3794 } 3795 } 3796 3797 /** 3798 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS 3799 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller. 3800 * @param checkShell whether to prevent shell from access if there's a debugging restriction 3801 * @param message the message to log on security exception 3802 */ 3803 void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission, 3804 boolean checkShell, String message) { 3805 if (userId < 0) { 3806 throw new IllegalArgumentException("Invalid userId " + userId); 3807 } 3808 if (checkShell) { 3809 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); 3810 } 3811 if (userId == UserHandle.getUserId(callingUid)) return; 3812 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 3813 if (requireFullPermission) { 3814 mContext.enforceCallingOrSelfPermission( 3815 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 3816 } else { 3817 try { 3818 mContext.enforceCallingOrSelfPermission( 3819 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message); 3820 } catch (SecurityException se) { 3821 mContext.enforceCallingOrSelfPermission( 3822 android.Manifest.permission.INTERACT_ACROSS_USERS, message); 3823 } 3824 } 3825 } 3826 } 3827 3828 void enforceShellRestriction(String restriction, int callingUid, int userHandle) { 3829 if (callingUid == Process.SHELL_UID) { 3830 if (userHandle >= 0 3831 && sUserManager.hasUserRestriction(restriction, userHandle)) { 3832 throw new SecurityException("Shell does not have permission to access user " 3833 + userHandle); 3834 } else if (userHandle < 0) { 3835 Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t" 3836 + Debug.getCallers(3)); 3837 } 3838 } 3839 } 3840 3841 private BasePermission findPermissionTreeLP(String permName) { 3842 for(BasePermission bp : mSettings.mPermissionTrees.values()) { 3843 if (permName.startsWith(bp.name) && 3844 permName.length() > bp.name.length() && 3845 permName.charAt(bp.name.length()) == '.') { 3846 return bp; 3847 } 3848 } 3849 return null; 3850 } 3851 3852 private BasePermission checkPermissionTreeLP(String permName) { 3853 if (permName != null) { 3854 BasePermission bp = findPermissionTreeLP(permName); 3855 if (bp != null) { 3856 if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) { 3857 return bp; 3858 } 3859 throw new SecurityException("Calling uid " 3860 + Binder.getCallingUid() 3861 + " is not allowed to add to permission tree " 3862 + bp.name + " owned by uid " + bp.uid); 3863 } 3864 } 3865 throw new SecurityException("No permission tree found for " + permName); 3866 } 3867 3868 static boolean compareStrings(CharSequence s1, CharSequence s2) { 3869 if (s1 == null) { 3870 return s2 == null; 3871 } 3872 if (s2 == null) { 3873 return false; 3874 } 3875 if (s1.getClass() != s2.getClass()) { 3876 return false; 3877 } 3878 return s1.equals(s2); 3879 } 3880 3881 static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) { 3882 if (pi1.icon != pi2.icon) return false; 3883 if (pi1.logo != pi2.logo) return false; 3884 if (pi1.protectionLevel != pi2.protectionLevel) return false; 3885 if (!compareStrings(pi1.name, pi2.name)) return false; 3886 if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false; 3887 // We'll take care of setting this one. 3888 if (!compareStrings(pi1.packageName, pi2.packageName)) return false; 3889 // These are not currently stored in settings. 3890 //if (!compareStrings(pi1.group, pi2.group)) return false; 3891 //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false; 3892 //if (pi1.labelRes != pi2.labelRes) return false; 3893 //if (pi1.descriptionRes != pi2.descriptionRes) return false; 3894 return true; 3895 } 3896 3897 int permissionInfoFootprint(PermissionInfo info) { 3898 int size = info.name.length(); 3899 if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length(); 3900 if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length(); 3901 return size; 3902 } 3903 3904 int calculateCurrentPermissionFootprintLocked(BasePermission tree) { 3905 int size = 0; 3906 for (BasePermission perm : mSettings.mPermissions.values()) { 3907 if (perm.uid == tree.uid) { 3908 size += perm.name.length() + permissionInfoFootprint(perm.perm.info); 3909 } 3910 } 3911 return size; 3912 } 3913 3914 void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) { 3915 // We calculate the max size of permissions defined by this uid and throw 3916 // if that plus the size of 'info' would exceed our stated maximum. 3917 if (tree.uid != Process.SYSTEM_UID) { 3918 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree); 3919 if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) { 3920 throw new SecurityException("Permission tree size cap exceeded"); 3921 } 3922 } 3923 } 3924 3925 boolean addPermissionLocked(PermissionInfo info, boolean async) { 3926 if (info.labelRes == 0 && info.nonLocalizedLabel == null) { 3927 throw new SecurityException("Label must be specified in permission"); 3928 } 3929 BasePermission tree = checkPermissionTreeLP(info.name); 3930 BasePermission bp = mSettings.mPermissions.get(info.name); 3931 boolean added = bp == null; 3932 boolean changed = true; 3933 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel); 3934 if (added) { 3935 enforcePermissionCapLocked(info, tree); 3936 bp = new BasePermission(info.name, tree.sourcePackage, 3937 BasePermission.TYPE_DYNAMIC); 3938 } else if (bp.type != BasePermission.TYPE_DYNAMIC) { 3939 throw new SecurityException( 3940 "Not allowed to modify non-dynamic permission " 3941 + info.name); 3942 } else { 3943 if (bp.protectionLevel == fixedLevel 3944 && bp.perm.owner.equals(tree.perm.owner) 3945 && bp.uid == tree.uid 3946 && comparePermissionInfos(bp.perm.info, info)) { 3947 changed = false; 3948 } 3949 } 3950 bp.protectionLevel = fixedLevel; 3951 info = new PermissionInfo(info); 3952 info.protectionLevel = fixedLevel; 3953 bp.perm = new PackageParser.Permission(tree.perm.owner, info); 3954 bp.perm.info.packageName = tree.perm.info.packageName; 3955 bp.uid = tree.uid; 3956 if (added) { 3957 mSettings.mPermissions.put(info.name, bp); 3958 } 3959 if (changed) { 3960 if (!async) { 3961 mSettings.writeLPr(); 3962 } else { 3963 scheduleWriteSettingsLocked(); 3964 } 3965 } 3966 return added; 3967 } 3968 3969 @Override 3970 public boolean addPermission(PermissionInfo info) { 3971 synchronized (mPackages) { 3972 return addPermissionLocked(info, false); 3973 } 3974 } 3975 3976 @Override 3977 public boolean addPermissionAsync(PermissionInfo info) { 3978 synchronized (mPackages) { 3979 return addPermissionLocked(info, true); 3980 } 3981 } 3982 3983 @Override 3984 public void removePermission(String name) { 3985 synchronized (mPackages) { 3986 checkPermissionTreeLP(name); 3987 BasePermission bp = mSettings.mPermissions.get(name); 3988 if (bp != null) { 3989 if (bp.type != BasePermission.TYPE_DYNAMIC) { 3990 throw new SecurityException( 3991 "Not allowed to modify non-dynamic permission " 3992 + name); 3993 } 3994 mSettings.mPermissions.remove(name); 3995 mSettings.writeLPr(); 3996 } 3997 } 3998 } 3999 4000 private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg, 4001 BasePermission bp) { 4002 int index = pkg.requestedPermissions.indexOf(bp.name); 4003 if (index == -1) { 4004 throw new SecurityException("Package " + pkg.packageName 4005 + " has not requested permission " + bp.name); 4006 } 4007 if (!bp.isRuntime() && !bp.isDevelopment()) { 4008 throw new SecurityException("Permission " + bp.name 4009 + " is not a changeable permission type"); 4010 } 4011 } 4012 4013 @Override 4014 public void grantRuntimePermission(String packageName, String name, final int userId) { 4015 grantRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */); 4016 } 4017 4018 private void grantRuntimePermission(String packageName, String name, final int userId, 4019 boolean overridePolicy) { 4020 if (!sUserManager.exists(userId)) { 4021 Log.e(TAG, "No such user:" + userId); 4022 return; 4023 } 4024 4025 mContext.enforceCallingOrSelfPermission( 4026 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 4027 "grantRuntimePermission"); 4028 4029 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4030 true /* requireFullPermission */, true /* checkShell */, 4031 "grantRuntimePermission"); 4032 4033 final int uid; 4034 final SettingBase sb; 4035 4036 synchronized (mPackages) { 4037 final PackageParser.Package pkg = mPackages.get(packageName); 4038 if (pkg == null) { 4039 throw new IllegalArgumentException("Unknown package: " + packageName); 4040 } 4041 4042 final BasePermission bp = mSettings.mPermissions.get(name); 4043 if (bp == null) { 4044 throw new IllegalArgumentException("Unknown permission: " + name); 4045 } 4046 4047 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp); 4048 4049 // If a permission review is required for legacy apps we represent 4050 // their permissions as always granted runtime ones since we need 4051 // to keep the review required permission flag per user while an 4052 // install permission's state is shared across all users. 4053 if (mPermissionReviewRequired 4054 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M 4055 && bp.isRuntime()) { 4056 return; 4057 } 4058 4059 uid = UserHandle.getUid(userId, pkg.applicationInfo.uid); 4060 sb = (SettingBase) pkg.mExtras; 4061 if (sb == null) { 4062 throw new IllegalArgumentException("Unknown package: " + packageName); 4063 } 4064 4065 final PermissionsState permissionsState = sb.getPermissionsState(); 4066 4067 final int flags = permissionsState.getPermissionFlags(name, userId); 4068 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 4069 throw new SecurityException("Cannot grant system fixed permission " 4070 + name + " for package " + packageName); 4071 } 4072 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) { 4073 throw new SecurityException("Cannot grant policy fixed permission " 4074 + name + " for package " + packageName); 4075 } 4076 4077 if (bp.isDevelopment()) { 4078 // Development permissions must be handled specially, since they are not 4079 // normal runtime permissions. For now they apply to all users. 4080 if (permissionsState.grantInstallPermission(bp) != 4081 PermissionsState.PERMISSION_OPERATION_FAILURE) { 4082 scheduleWriteSettingsLocked(); 4083 } 4084 return; 4085 } 4086 4087 if (pkg.applicationInfo.isEphemeralApp() && !bp.isEphemeral()) { 4088 throw new SecurityException("Cannot grant non-ephemeral permission" 4089 + name + " for package " + packageName); 4090 } 4091 4092 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 4093 Slog.w(TAG, "Cannot grant runtime permission to a legacy app"); 4094 return; 4095 } 4096 4097 final int result = permissionsState.grantRuntimePermission(bp, userId); 4098 switch (result) { 4099 case PermissionsState.PERMISSION_OPERATION_FAILURE: { 4100 return; 4101 } 4102 4103 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 4104 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); 4105 mHandler.post(new Runnable() { 4106 @Override 4107 public void run() { 4108 killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED); 4109 } 4110 }); 4111 } 4112 break; 4113 } 4114 4115 mOnPermissionChangeListeners.onPermissionsChanged(uid); 4116 4117 // Not critical if that is lost - app has to request again. 4118 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 4119 } 4120 4121 // Only need to do this if user is initialized. Otherwise it's a new user 4122 // and there are no processes running as the user yet and there's no need 4123 // to make an expensive call to remount processes for the changed permissions. 4124 if (READ_EXTERNAL_STORAGE.equals(name) 4125 || WRITE_EXTERNAL_STORAGE.equals(name)) { 4126 final long token = Binder.clearCallingIdentity(); 4127 try { 4128 if (sUserManager.isInitialized(userId)) { 4129 MountServiceInternal mountServiceInternal = LocalServices.getService( 4130 MountServiceInternal.class); 4131 mountServiceInternal.onExternalStoragePolicyChanged(uid, packageName); 4132 } 4133 } finally { 4134 Binder.restoreCallingIdentity(token); 4135 } 4136 } 4137 } 4138 4139 @Override 4140 public void revokeRuntimePermission(String packageName, String name, int userId) { 4141 revokeRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */); 4142 } 4143 4144 private void revokeRuntimePermission(String packageName, String name, int userId, 4145 boolean overridePolicy) { 4146 if (!sUserManager.exists(userId)) { 4147 Log.e(TAG, "No such user:" + userId); 4148 return; 4149 } 4150 4151 mContext.enforceCallingOrSelfPermission( 4152 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 4153 "revokeRuntimePermission"); 4154 4155 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4156 true /* requireFullPermission */, true /* checkShell */, 4157 "revokeRuntimePermission"); 4158 4159 final int appId; 4160 4161 synchronized (mPackages) { 4162 final PackageParser.Package pkg = mPackages.get(packageName); 4163 if (pkg == null) { 4164 throw new IllegalArgumentException("Unknown package: " + packageName); 4165 } 4166 4167 final BasePermission bp = mSettings.mPermissions.get(name); 4168 if (bp == null) { 4169 throw new IllegalArgumentException("Unknown permission: " + name); 4170 } 4171 4172 enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp); 4173 4174 // If a permission review is required for legacy apps we represent 4175 // their permissions as always granted runtime ones since we need 4176 // to keep the review required permission flag per user while an 4177 // install permission's state is shared across all users. 4178 if (mPermissionReviewRequired 4179 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M 4180 && bp.isRuntime()) { 4181 return; 4182 } 4183 4184 SettingBase sb = (SettingBase) pkg.mExtras; 4185 if (sb == null) { 4186 throw new IllegalArgumentException("Unknown package: " + packageName); 4187 } 4188 4189 final PermissionsState permissionsState = sb.getPermissionsState(); 4190 4191 final int flags = permissionsState.getPermissionFlags(name, userId); 4192 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) { 4193 throw new SecurityException("Cannot revoke system fixed permission " 4194 + name + " for package " + packageName); 4195 } 4196 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) { 4197 throw new SecurityException("Cannot revoke policy fixed permission " 4198 + name + " for package " + packageName); 4199 } 4200 4201 if (bp.isDevelopment()) { 4202 // Development permissions must be handled specially, since they are not 4203 // normal runtime permissions. For now they apply to all users. 4204 if (permissionsState.revokeInstallPermission(bp) != 4205 PermissionsState.PERMISSION_OPERATION_FAILURE) { 4206 scheduleWriteSettingsLocked(); 4207 } 4208 return; 4209 } 4210 4211 if (permissionsState.revokeRuntimePermission(bp, userId) == 4212 PermissionsState.PERMISSION_OPERATION_FAILURE) { 4213 return; 4214 } 4215 4216 mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid); 4217 4218 // Critical, after this call app should never have the permission. 4219 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 4220 4221 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 4222 } 4223 4224 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED); 4225 } 4226 4227 @Override 4228 public void resetRuntimePermissions() { 4229 mContext.enforceCallingOrSelfPermission( 4230 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, 4231 "revokeRuntimePermission"); 4232 4233 int callingUid = Binder.getCallingUid(); 4234 if (callingUid != Process.SYSTEM_UID && callingUid != 0) { 4235 mContext.enforceCallingOrSelfPermission( 4236 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 4237 "resetRuntimePermissions"); 4238 } 4239 4240 synchronized (mPackages) { 4241 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL); 4242 for (int userId : UserManagerService.getInstance().getUserIds()) { 4243 final int packageCount = mPackages.size(); 4244 for (int i = 0; i < packageCount; i++) { 4245 PackageParser.Package pkg = mPackages.valueAt(i); 4246 if (!(pkg.mExtras instanceof PackageSetting)) { 4247 continue; 4248 } 4249 PackageSetting ps = (PackageSetting) pkg.mExtras; 4250 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 4251 } 4252 } 4253 } 4254 } 4255 4256 @Override 4257 public int getPermissionFlags(String name, String packageName, int userId) { 4258 if (!sUserManager.exists(userId)) { 4259 return 0; 4260 } 4261 4262 enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags"); 4263 4264 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4265 true /* requireFullPermission */, false /* checkShell */, 4266 "getPermissionFlags"); 4267 4268 synchronized (mPackages) { 4269 final PackageParser.Package pkg = mPackages.get(packageName); 4270 if (pkg == null) { 4271 return 0; 4272 } 4273 4274 final BasePermission bp = mSettings.mPermissions.get(name); 4275 if (bp == null) { 4276 return 0; 4277 } 4278 4279 SettingBase sb = (SettingBase) pkg.mExtras; 4280 if (sb == null) { 4281 return 0; 4282 } 4283 4284 PermissionsState permissionsState = sb.getPermissionsState(); 4285 return permissionsState.getPermissionFlags(name, userId); 4286 } 4287 } 4288 4289 @Override 4290 public void updatePermissionFlags(String name, String packageName, int flagMask, 4291 int flagValues, int userId) { 4292 if (!sUserManager.exists(userId)) { 4293 return; 4294 } 4295 4296 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags"); 4297 4298 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4299 true /* requireFullPermission */, true /* checkShell */, 4300 "updatePermissionFlags"); 4301 4302 // Only the system can change these flags and nothing else. 4303 if (getCallingUid() != Process.SYSTEM_UID) { 4304 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4305 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4306 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 4307 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; 4308 flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 4309 } 4310 4311 synchronized (mPackages) { 4312 final PackageParser.Package pkg = mPackages.get(packageName); 4313 if (pkg == null) { 4314 throw new IllegalArgumentException("Unknown package: " + packageName); 4315 } 4316 4317 final BasePermission bp = mSettings.mPermissions.get(name); 4318 if (bp == null) { 4319 throw new IllegalArgumentException("Unknown permission: " + name); 4320 } 4321 4322 SettingBase sb = (SettingBase) pkg.mExtras; 4323 if (sb == null) { 4324 throw new IllegalArgumentException("Unknown package: " + packageName); 4325 } 4326 4327 PermissionsState permissionsState = sb.getPermissionsState(); 4328 4329 boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null; 4330 4331 if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) { 4332 // Install and runtime permissions are stored in different places, 4333 // so figure out what permission changed and persist the change. 4334 if (permissionsState.getInstallPermissionState(name) != null) { 4335 scheduleWriteSettingsLocked(); 4336 } else if (permissionsState.getRuntimePermissionState(name, userId) != null 4337 || hadState) { 4338 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 4339 } 4340 } 4341 } 4342 } 4343 4344 /** 4345 * Update the permission flags for all packages and runtime permissions of a user in order 4346 * to allow device or profile owner to remove POLICY_FIXED. 4347 */ 4348 @Override 4349 public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) { 4350 if (!sUserManager.exists(userId)) { 4351 return; 4352 } 4353 4354 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps"); 4355 4356 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4357 true /* requireFullPermission */, true /* checkShell */, 4358 "updatePermissionFlagsForAllApps"); 4359 4360 // Only the system can change system fixed flags. 4361 if (getCallingUid() != Process.SYSTEM_UID) { 4362 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4363 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; 4364 } 4365 4366 synchronized (mPackages) { 4367 boolean changed = false; 4368 final int packageCount = mPackages.size(); 4369 for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) { 4370 final PackageParser.Package pkg = mPackages.valueAt(pkgIndex); 4371 SettingBase sb = (SettingBase) pkg.mExtras; 4372 if (sb == null) { 4373 continue; 4374 } 4375 PermissionsState permissionsState = sb.getPermissionsState(); 4376 changed |= permissionsState.updatePermissionFlagsForAllPermissions( 4377 userId, flagMask, flagValues); 4378 } 4379 if (changed) { 4380 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 4381 } 4382 } 4383 } 4384 4385 private void enforceGrantRevokeRuntimePermissionPermissions(String message) { 4386 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS) 4387 != PackageManager.PERMISSION_GRANTED 4388 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS) 4389 != PackageManager.PERMISSION_GRANTED) { 4390 throw new SecurityException(message + " requires " 4391 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or " 4392 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS); 4393 } 4394 } 4395 4396 @Override 4397 public boolean shouldShowRequestPermissionRationale(String permissionName, 4398 String packageName, int userId) { 4399 if (UserHandle.getCallingUserId() != userId) { 4400 mContext.enforceCallingPermission( 4401 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 4402 "canShowRequestPermissionRationale for user " + userId); 4403 } 4404 4405 final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId); 4406 if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) { 4407 return false; 4408 } 4409 4410 if (checkPermission(permissionName, packageName, userId) 4411 == PackageManager.PERMISSION_GRANTED) { 4412 return false; 4413 } 4414 4415 final int flags; 4416 4417 final long identity = Binder.clearCallingIdentity(); 4418 try { 4419 flags = getPermissionFlags(permissionName, 4420 packageName, userId); 4421 } finally { 4422 Binder.restoreCallingIdentity(identity); 4423 } 4424 4425 final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED 4426 | PackageManager.FLAG_PERMISSION_POLICY_FIXED 4427 | PackageManager.FLAG_PERMISSION_USER_FIXED; 4428 4429 if ((flags & fixedFlags) != 0) { 4430 return false; 4431 } 4432 4433 return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0; 4434 } 4435 4436 @Override 4437 public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 4438 mContext.enforceCallingOrSelfPermission( 4439 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS, 4440 "addOnPermissionsChangeListener"); 4441 4442 synchronized (mPackages) { 4443 mOnPermissionChangeListeners.addListenerLocked(listener); 4444 } 4445 } 4446 4447 @Override 4448 public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { 4449 synchronized (mPackages) { 4450 mOnPermissionChangeListeners.removeListenerLocked(listener); 4451 } 4452 } 4453 4454 @Override 4455 public boolean isProtectedBroadcast(String actionName) { 4456 synchronized (mPackages) { 4457 if (mProtectedBroadcasts.contains(actionName)) { 4458 return true; 4459 } else if (actionName != null) { 4460 // TODO: remove these terrible hacks 4461 if (actionName.startsWith("android.net.netmon.lingerExpired") 4462 || actionName.startsWith("com.android.server.sip.SipWakeupTimer") 4463 || actionName.startsWith("com.android.internal.telephony.data-reconnect") 4464 || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) { 4465 return true; 4466 } 4467 } 4468 } 4469 return false; 4470 } 4471 4472 @Override 4473 public int checkSignatures(String pkg1, String pkg2) { 4474 synchronized (mPackages) { 4475 final PackageParser.Package p1 = mPackages.get(pkg1); 4476 final PackageParser.Package p2 = mPackages.get(pkg2); 4477 if (p1 == null || p1.mExtras == null 4478 || p2 == null || p2.mExtras == null) { 4479 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4480 } 4481 return compareSignatures(p1.mSignatures, p2.mSignatures); 4482 } 4483 } 4484 4485 @Override 4486 public int checkUidSignatures(int uid1, int uid2) { 4487 // Map to base uids. 4488 uid1 = UserHandle.getAppId(uid1); 4489 uid2 = UserHandle.getAppId(uid2); 4490 // reader 4491 synchronized (mPackages) { 4492 Signature[] s1; 4493 Signature[] s2; 4494 Object obj = mSettings.getUserIdLPr(uid1); 4495 if (obj != null) { 4496 if (obj instanceof SharedUserSetting) { 4497 s1 = ((SharedUserSetting)obj).signatures.mSignatures; 4498 } else if (obj instanceof PackageSetting) { 4499 s1 = ((PackageSetting)obj).signatures.mSignatures; 4500 } else { 4501 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4502 } 4503 } else { 4504 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4505 } 4506 obj = mSettings.getUserIdLPr(uid2); 4507 if (obj != null) { 4508 if (obj instanceof SharedUserSetting) { 4509 s2 = ((SharedUserSetting)obj).signatures.mSignatures; 4510 } else if (obj instanceof PackageSetting) { 4511 s2 = ((PackageSetting)obj).signatures.mSignatures; 4512 } else { 4513 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4514 } 4515 } else { 4516 return PackageManager.SIGNATURE_UNKNOWN_PACKAGE; 4517 } 4518 return compareSignatures(s1, s2); 4519 } 4520 } 4521 4522 /** 4523 * This method should typically only be used when granting or revoking 4524 * permissions, since the app may immediately restart after this call. 4525 * <p> 4526 * If you're doing surgery on app code/data, use {@link PackageFreezer} to 4527 * guard your work against the app being relaunched. 4528 */ 4529 private void killUid(int appId, int userId, String reason) { 4530 final long identity = Binder.clearCallingIdentity(); 4531 try { 4532 IActivityManager am = ActivityManagerNative.getDefault(); 4533 if (am != null) { 4534 try { 4535 am.killUid(appId, userId, reason); 4536 } catch (RemoteException e) { 4537 /* ignore - same process */ 4538 } 4539 } 4540 } finally { 4541 Binder.restoreCallingIdentity(identity); 4542 } 4543 } 4544 4545 /** 4546 * Compares two sets of signatures. Returns: 4547 * <br /> 4548 * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null, 4549 * <br /> 4550 * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null, 4551 * <br /> 4552 * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null, 4553 * <br /> 4554 * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical, 4555 * <br /> 4556 * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ. 4557 */ 4558 static int compareSignatures(Signature[] s1, Signature[] s2) { 4559 if (s1 == null) { 4560 return s2 == null 4561 ? PackageManager.SIGNATURE_NEITHER_SIGNED 4562 : PackageManager.SIGNATURE_FIRST_NOT_SIGNED; 4563 } 4564 4565 if (s2 == null) { 4566 return PackageManager.SIGNATURE_SECOND_NOT_SIGNED; 4567 } 4568 4569 if (s1.length != s2.length) { 4570 return PackageManager.SIGNATURE_NO_MATCH; 4571 } 4572 4573 // Since both signature sets are of size 1, we can compare without HashSets. 4574 if (s1.length == 1) { 4575 return s1[0].equals(s2[0]) ? 4576 PackageManager.SIGNATURE_MATCH : 4577 PackageManager.SIGNATURE_NO_MATCH; 4578 } 4579 4580 ArraySet<Signature> set1 = new ArraySet<Signature>(); 4581 for (Signature sig : s1) { 4582 set1.add(sig); 4583 } 4584 ArraySet<Signature> set2 = new ArraySet<Signature>(); 4585 for (Signature sig : s2) { 4586 set2.add(sig); 4587 } 4588 // Make sure s2 contains all signatures in s1. 4589 if (set1.equals(set2)) { 4590 return PackageManager.SIGNATURE_MATCH; 4591 } 4592 return PackageManager.SIGNATURE_NO_MATCH; 4593 } 4594 4595 /** 4596 * If the database version for this type of package (internal storage or 4597 * external storage) is less than the version where package signatures 4598 * were updated, return true. 4599 */ 4600 private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 4601 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); 4602 return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY; 4603 } 4604 4605 /** 4606 * Used for backward compatibility to make sure any packages with 4607 * certificate chains get upgraded to the new style. {@code existingSigs} 4608 * will be in the old format (since they were stored on disk from before the 4609 * system upgrade) and {@code scannedSigs} will be in the newer format. 4610 */ 4611 private int compareSignaturesCompat(PackageSignatures existingSigs, 4612 PackageParser.Package scannedPkg) { 4613 if (!isCompatSignatureUpdateNeeded(scannedPkg)) { 4614 return PackageManager.SIGNATURE_NO_MATCH; 4615 } 4616 4617 ArraySet<Signature> existingSet = new ArraySet<Signature>(); 4618 for (Signature sig : existingSigs.mSignatures) { 4619 existingSet.add(sig); 4620 } 4621 ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>(); 4622 for (Signature sig : scannedPkg.mSignatures) { 4623 try { 4624 Signature[] chainSignatures = sig.getChainSignatures(); 4625 for (Signature chainSig : chainSignatures) { 4626 scannedCompatSet.add(chainSig); 4627 } 4628 } catch (CertificateEncodingException e) { 4629 scannedCompatSet.add(sig); 4630 } 4631 } 4632 /* 4633 * Make sure the expanded scanned set contains all signatures in the 4634 * existing one. 4635 */ 4636 if (scannedCompatSet.equals(existingSet)) { 4637 // Migrate the old signatures to the new scheme. 4638 existingSigs.assignSignatures(scannedPkg.mSignatures); 4639 // The new KeySets will be re-added later in the scanning process. 4640 synchronized (mPackages) { 4641 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName); 4642 } 4643 return PackageManager.SIGNATURE_MATCH; 4644 } 4645 return PackageManager.SIGNATURE_NO_MATCH; 4646 } 4647 4648 private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) { 4649 final VersionInfo ver = getSettingsVersionForPackage(scannedPkg); 4650 return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER; 4651 } 4652 4653 private int compareSignaturesRecover(PackageSignatures existingSigs, 4654 PackageParser.Package scannedPkg) { 4655 if (!isRecoverSignatureUpdateNeeded(scannedPkg)) { 4656 return PackageManager.SIGNATURE_NO_MATCH; 4657 } 4658 4659 String msg = null; 4660 try { 4661 if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) { 4662 logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for " 4663 + scannedPkg.packageName); 4664 return PackageManager.SIGNATURE_MATCH; 4665 } 4666 } catch (CertificateException e) { 4667 msg = e.getMessage(); 4668 } 4669 4670 logCriticalInfo(Log.INFO, 4671 "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg); 4672 return PackageManager.SIGNATURE_NO_MATCH; 4673 } 4674 4675 @Override 4676 public List<String> getAllPackages() { 4677 synchronized (mPackages) { 4678 return new ArrayList<String>(mPackages.keySet()); 4679 } 4680 } 4681 4682 @Override 4683 public String[] getPackagesForUid(int uid) { 4684 final int userId = UserHandle.getUserId(uid); 4685 uid = UserHandle.getAppId(uid); 4686 // reader 4687 synchronized (mPackages) { 4688 Object obj = mSettings.getUserIdLPr(uid); 4689 if (obj instanceof SharedUserSetting) { 4690 final SharedUserSetting sus = (SharedUserSetting) obj; 4691 final int N = sus.packages.size(); 4692 String[] res = new String[N]; 4693 final Iterator<PackageSetting> it = sus.packages.iterator(); 4694 int i = 0; 4695 while (it.hasNext()) { 4696 PackageSetting ps = it.next(); 4697 if (ps.getInstalled(userId)) { 4698 res[i++] = ps.name; 4699 } else { 4700 res = ArrayUtils.removeElement(String.class, res, res[i]); 4701 } 4702 } 4703 return res; 4704 } else if (obj instanceof PackageSetting) { 4705 final PackageSetting ps = (PackageSetting) obj; 4706 return new String[] { ps.name }; 4707 } 4708 } 4709 return null; 4710 } 4711 4712 @Override 4713 public String getNameForUid(int uid) { 4714 // reader 4715 synchronized (mPackages) { 4716 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4717 if (obj instanceof SharedUserSetting) { 4718 final SharedUserSetting sus = (SharedUserSetting) obj; 4719 return sus.name + ":" + sus.userId; 4720 } else if (obj instanceof PackageSetting) { 4721 final PackageSetting ps = (PackageSetting) obj; 4722 return ps.name; 4723 } 4724 } 4725 return null; 4726 } 4727 4728 @Override 4729 public int getUidForSharedUser(String sharedUserName) { 4730 if(sharedUserName == null) { 4731 return -1; 4732 } 4733 // reader 4734 synchronized (mPackages) { 4735 SharedUserSetting suid; 4736 try { 4737 suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false); 4738 if (suid != null) { 4739 return suid.userId; 4740 } 4741 } catch (PackageManagerException ignore) { 4742 // can't happen, but, still need to catch it 4743 } 4744 return -1; 4745 } 4746 } 4747 4748 @Override 4749 public int getFlagsForUid(int uid) { 4750 synchronized (mPackages) { 4751 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4752 if (obj instanceof SharedUserSetting) { 4753 final SharedUserSetting sus = (SharedUserSetting) obj; 4754 return sus.pkgFlags; 4755 } else if (obj instanceof PackageSetting) { 4756 final PackageSetting ps = (PackageSetting) obj; 4757 return ps.pkgFlags; 4758 } 4759 } 4760 return 0; 4761 } 4762 4763 @Override 4764 public int getPrivateFlagsForUid(int uid) { 4765 synchronized (mPackages) { 4766 Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid)); 4767 if (obj instanceof SharedUserSetting) { 4768 final SharedUserSetting sus = (SharedUserSetting) obj; 4769 return sus.pkgPrivateFlags; 4770 } else if (obj instanceof PackageSetting) { 4771 final PackageSetting ps = (PackageSetting) obj; 4772 return ps.pkgPrivateFlags; 4773 } 4774 } 4775 return 0; 4776 } 4777 4778 @Override 4779 public boolean isUidPrivileged(int uid) { 4780 uid = UserHandle.getAppId(uid); 4781 // reader 4782 synchronized (mPackages) { 4783 Object obj = mSettings.getUserIdLPr(uid); 4784 if (obj instanceof SharedUserSetting) { 4785 final SharedUserSetting sus = (SharedUserSetting) obj; 4786 final Iterator<PackageSetting> it = sus.packages.iterator(); 4787 while (it.hasNext()) { 4788 if (it.next().isPrivileged()) { 4789 return true; 4790 } 4791 } 4792 } else if (obj instanceof PackageSetting) { 4793 final PackageSetting ps = (PackageSetting) obj; 4794 return ps.isPrivileged(); 4795 } 4796 } 4797 return false; 4798 } 4799 4800 @Override 4801 public String[] getAppOpPermissionPackages(String permissionName) { 4802 synchronized (mPackages) { 4803 ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName); 4804 if (pkgs == null) { 4805 return null; 4806 } 4807 return pkgs.toArray(new String[pkgs.size()]); 4808 } 4809 } 4810 4811 @Override 4812 public ResolveInfo resolveIntent(Intent intent, String resolvedType, 4813 int flags, int userId) { 4814 try { 4815 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent"); 4816 4817 if (!sUserManager.exists(userId)) return null; 4818 flags = updateFlagsForResolve(flags, userId, intent); 4819 enforceCrossUserPermission(Binder.getCallingUid(), userId, 4820 false /*requireFullPermission*/, false /*checkShell*/, "resolve intent"); 4821 4822 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities"); 4823 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, 4824 flags, userId); 4825 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 4826 4827 final ResolveInfo bestChoice = 4828 chooseBestActivity(intent, resolvedType, flags, query, userId); 4829 return bestChoice; 4830 } finally { 4831 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 4832 } 4833 } 4834 4835 @Override 4836 public void setLastChosenActivity(Intent intent, String resolvedType, int flags, 4837 IntentFilter filter, int match, ComponentName activity) { 4838 final int userId = UserHandle.getCallingUserId(); 4839 if (DEBUG_PREFERRED) { 4840 Log.v(TAG, "setLastChosenActivity intent=" + intent 4841 + " resolvedType=" + resolvedType 4842 + " flags=" + flags 4843 + " filter=" + filter 4844 + " match=" + match 4845 + " activity=" + activity); 4846 filter.dump(new PrintStreamPrinter(System.out), " "); 4847 } 4848 intent.setComponent(null); 4849 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags, 4850 userId); 4851 // Find any earlier preferred or last chosen entries and nuke them 4852 findPreferredActivity(intent, resolvedType, 4853 flags, query, 0, false, true, false, userId); 4854 // Add the new activity as the last chosen for this filter 4855 addPreferredActivityInternal(filter, match, null, activity, false, userId, 4856 "Setting last chosen"); 4857 } 4858 4859 @Override 4860 public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) { 4861 final int userId = UserHandle.getCallingUserId(); 4862 if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent); 4863 final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags, 4864 userId); 4865 return findPreferredActivity(intent, resolvedType, flags, query, 0, 4866 false, false, false, userId); 4867 } 4868 4869 private boolean isEphemeralDisabled() { 4870 // ephemeral apps have been disabled across the board 4871 if (DISABLE_EPHEMERAL_APPS) { 4872 return true; 4873 } 4874 // system isn't up yet; can't read settings, so, assume no ephemeral apps 4875 if (!mSystemReady) { 4876 return true; 4877 } 4878 // we can't get a content resolver until the system is ready; these checks must happen last 4879 final ContentResolver resolver = mContext.getContentResolver(); 4880 if (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) { 4881 return true; 4882 } 4883 return Secure.getInt(resolver, Secure.WEB_ACTION_ENABLED, 1) == 0; 4884 } 4885 4886 private boolean isEphemeralAllowed( 4887 Intent intent, List<ResolveInfo> resolvedActivities, int userId, 4888 boolean skipPackageCheck) { 4889 // Short circuit and return early if possible. 4890 if (isEphemeralDisabled()) { 4891 return false; 4892 } 4893 final int callingUser = UserHandle.getCallingUserId(); 4894 if (callingUser != UserHandle.USER_SYSTEM) { 4895 return false; 4896 } 4897 if (mEphemeralResolverConnection == null) { 4898 return false; 4899 } 4900 if (intent.getComponent() != null) { 4901 return false; 4902 } 4903 if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) { 4904 return false; 4905 } 4906 if (!skipPackageCheck && intent.getPackage() != null) { 4907 return false; 4908 } 4909 final boolean isWebUri = hasWebURI(intent); 4910 if (!isWebUri || intent.getData().getHost() == null) { 4911 return false; 4912 } 4913 // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution. 4914 synchronized (mPackages) { 4915 final int count = (resolvedActivities == null ? 0 : resolvedActivities.size()); 4916 for (int n = 0; n < count; n++) { 4917 ResolveInfo info = resolvedActivities.get(n); 4918 String packageName = info.activityInfo.packageName; 4919 PackageSetting ps = mSettings.mPackages.get(packageName); 4920 if (ps != null) { 4921 // Try to get the status from User settings first 4922 long packedStatus = getDomainVerificationStatusLPr(ps, userId); 4923 int status = (int) (packedStatus >> 32); 4924 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS 4925 || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) { 4926 if (DEBUG_EPHEMERAL) { 4927 Slog.v(TAG, "DENY ephemeral apps;" 4928 + " pkg: " + packageName + ", status: " + status); 4929 } 4930 return false; 4931 } 4932 } 4933 } 4934 } 4935 // We've exhausted all ways to deny ephemeral application; let the system look for them. 4936 return true; 4937 } 4938 4939 private static EphemeralResolveInfo getEphemeralResolveInfo( 4940 Context context, EphemeralResolverConnection resolverConnection, Intent intent, 4941 String resolvedType, int userId, String packageName) { 4942 final int ephemeralPrefixMask = Global.getInt(context.getContentResolver(), 4943 Global.EPHEMERAL_HASH_PREFIX_MASK, DEFAULT_EPHEMERAL_HASH_PREFIX_MASK); 4944 final int ephemeralPrefixCount = Global.getInt(context.getContentResolver(), 4945 Global.EPHEMERAL_HASH_PREFIX_COUNT, DEFAULT_EPHEMERAL_HASH_PREFIX_COUNT); 4946 final EphemeralDigest digest = new EphemeralDigest(intent.getData(), ephemeralPrefixMask, 4947 ephemeralPrefixCount); 4948 final int[] shaPrefix = digest.getDigestPrefix(); 4949 final byte[][] digestBytes = digest.getDigestBytes(); 4950 final List<EphemeralResolveInfo> ephemeralResolveInfoList = 4951 resolverConnection.getEphemeralResolveInfoList(shaPrefix, ephemeralPrefixMask); 4952 if (ephemeralResolveInfoList == null || ephemeralResolveInfoList.size() == 0) { 4953 // No hash prefix match; there are no ephemeral apps for this domain. 4954 return null; 4955 } 4956 4957 // Go in reverse order so we match the narrowest scope first. 4958 for (int i = shaPrefix.length - 1; i >= 0 ; --i) { 4959 for (EphemeralResolveInfo ephemeralApplication : ephemeralResolveInfoList) { 4960 if (!Arrays.equals(digestBytes[i], ephemeralApplication.getDigestBytes())) { 4961 continue; 4962 } 4963 final List<IntentFilter> filters = ephemeralApplication.getFilters(); 4964 // No filters; this should never happen. 4965 if (filters.isEmpty()) { 4966 continue; 4967 } 4968 if (packageName != null 4969 && !packageName.equals(ephemeralApplication.getPackageName())) { 4970 continue; 4971 } 4972 // We have a domain match; resolve the filters to see if anything matches. 4973 final EphemeralIntentResolver ephemeralResolver = new EphemeralIntentResolver(); 4974 for (int j = filters.size() - 1; j >= 0; --j) { 4975 final EphemeralResolveIntentInfo intentInfo = 4976 new EphemeralResolveIntentInfo(filters.get(j), ephemeralApplication); 4977 ephemeralResolver.addFilter(intentInfo); 4978 } 4979 List<EphemeralResolveInfo> matchedResolveInfoList = ephemeralResolver.queryIntent( 4980 intent, resolvedType, false /*defaultOnly*/, userId); 4981 if (!matchedResolveInfoList.isEmpty()) { 4982 return matchedResolveInfoList.get(0); 4983 } 4984 } 4985 } 4986 // Hash or filter mis-match; no ephemeral apps for this domain. 4987 return null; 4988 } 4989 4990 private ResolveInfo chooseBestActivity(Intent intent, String resolvedType, 4991 int flags, List<ResolveInfo> query, int userId) { 4992 if (query != null) { 4993 final int N = query.size(); 4994 if (N == 1) { 4995 return query.get(0); 4996 } else if (N > 1) { 4997 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 4998 // If there is more than one activity with the same priority, 4999 // then let the user decide between them. 5000 ResolveInfo r0 = query.get(0); 5001 ResolveInfo r1 = query.get(1); 5002 if (DEBUG_INTENT_MATCHING || debug) { 5003 Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs " 5004 + r1.activityInfo.name + "=" + r1.priority); 5005 } 5006 // If the first activity has a higher priority, or a different 5007 // default, then it is always desirable to pick it. 5008 if (r0.priority != r1.priority 5009 || r0.preferredOrder != r1.preferredOrder 5010 || r0.isDefault != r1.isDefault) { 5011 return query.get(0); 5012 } 5013 // If we have saved a preference for a preferred activity for 5014 // this Intent, use that. 5015 ResolveInfo ri = findPreferredActivity(intent, resolvedType, 5016 flags, query, r0.priority, true, false, debug, userId); 5017 if (ri != null) { 5018 return ri; 5019 } 5020 ri = new ResolveInfo(mResolveInfo); 5021 ri.activityInfo = new ActivityInfo(ri.activityInfo); 5022 ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction()); 5023 // If all of the options come from the same package, show the application's 5024 // label and icon instead of the generic resolver's. 5025 // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here 5026 // and then throw away the ResolveInfo itself, meaning that the caller loses 5027 // the resolvePackageName. Therefore the activityInfo.labelRes above provides 5028 // a fallback for this case; we only set the target package's resources on 5029 // the ResolveInfo, not the ActivityInfo. 5030 final String intentPackage = intent.getPackage(); 5031 if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) { 5032 final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo; 5033 ri.resolvePackageName = intentPackage; 5034 if (userNeedsBadging(userId)) { 5035 ri.noResourceId = true; 5036 } else { 5037 ri.icon = appi.icon; 5038 } 5039 ri.iconResourceId = appi.icon; 5040 ri.labelRes = appi.labelRes; 5041 } 5042 ri.activityInfo.applicationInfo = new ApplicationInfo( 5043 ri.activityInfo.applicationInfo); 5044 if (userId != 0) { 5045 ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId, 5046 UserHandle.getAppId(ri.activityInfo.applicationInfo.uid)); 5047 } 5048 // Make sure that the resolver is displayable in car mode 5049 if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle(); 5050 ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true); 5051 return ri; 5052 } 5053 } 5054 return null; 5055 } 5056 5057 /** 5058 * Return true if the given list is not empty and all of its contents have 5059 * an activityInfo with the given package name. 5060 */ 5061 private boolean allHavePackage(List<ResolveInfo> list, String packageName) { 5062 if (ArrayUtils.isEmpty(list)) { 5063 return false; 5064 } 5065 for (int i = 0, N = list.size(); i < N; i++) { 5066 final ResolveInfo ri = list.get(i); 5067 final ActivityInfo ai = ri != null ? ri.activityInfo : null; 5068 if (ai == null || !packageName.equals(ai.packageName)) { 5069 return false; 5070 } 5071 } 5072 return true; 5073 } 5074 5075 private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType, 5076 int flags, List<ResolveInfo> query, boolean debug, int userId) { 5077 final int N = query.size(); 5078 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 5079 .get(userId); 5080 // Get the list of persistent preferred activities that handle the intent 5081 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities..."); 5082 List<PersistentPreferredActivity> pprefs = ppir != null 5083 ? ppir.queryIntent(intent, resolvedType, 5084 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 5085 : null; 5086 if (pprefs != null && pprefs.size() > 0) { 5087 final int M = pprefs.size(); 5088 for (int i=0; i<M; i++) { 5089 final PersistentPreferredActivity ppa = pprefs.get(i); 5090 if (DEBUG_PREFERRED || debug) { 5091 Slog.v(TAG, "Checking PersistentPreferredActivity ds=" 5092 + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>") 5093 + "\n component=" + ppa.mComponent); 5094 ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 5095 } 5096 final ActivityInfo ai = getActivityInfo(ppa.mComponent, 5097 flags | MATCH_DISABLED_COMPONENTS, userId); 5098 if (DEBUG_PREFERRED || debug) { 5099 Slog.v(TAG, "Found persistent preferred activity:"); 5100 if (ai != null) { 5101 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 5102 } else { 5103 Slog.v(TAG, " null"); 5104 } 5105 } 5106 if (ai == null) { 5107 // This previously registered persistent preferred activity 5108 // component is no longer known. Ignore it and do NOT remove it. 5109 continue; 5110 } 5111 for (int j=0; j<N; j++) { 5112 final ResolveInfo ri = query.get(j); 5113 if (!ri.activityInfo.applicationInfo.packageName 5114 .equals(ai.applicationInfo.packageName)) { 5115 continue; 5116 } 5117 if (!ri.activityInfo.name.equals(ai.name)) { 5118 continue; 5119 } 5120 // Found a persistent preference that can handle the intent. 5121 if (DEBUG_PREFERRED || debug) { 5122 Slog.v(TAG, "Returning persistent preferred activity: " + 5123 ri.activityInfo.packageName + "/" + ri.activityInfo.name); 5124 } 5125 return ri; 5126 } 5127 } 5128 } 5129 return null; 5130 } 5131 5132 // TODO: handle preferred activities missing while user has amnesia 5133 ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags, 5134 List<ResolveInfo> query, int priority, boolean always, 5135 boolean removeMatches, boolean debug, int userId) { 5136 if (!sUserManager.exists(userId)) return null; 5137 flags = updateFlagsForResolve(flags, userId, intent); 5138 // writer 5139 synchronized (mPackages) { 5140 if (intent.getSelector() != null) { 5141 intent = intent.getSelector(); 5142 } 5143 if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION); 5144 5145 // Try to find a matching persistent preferred activity. 5146 ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query, 5147 debug, userId); 5148 5149 // If a persistent preferred activity matched, use it. 5150 if (pri != null) { 5151 return pri; 5152 } 5153 5154 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 5155 // Get the list of preferred activities that handle the intent 5156 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities..."); 5157 List<PreferredActivity> prefs = pir != null 5158 ? pir.queryIntent(intent, resolvedType, 5159 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId) 5160 : null; 5161 if (prefs != null && prefs.size() > 0) { 5162 boolean changed = false; 5163 try { 5164 // First figure out how good the original match set is. 5165 // We will only allow preferred activities that came 5166 // from the same match quality. 5167 int match = 0; 5168 5169 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match..."); 5170 5171 final int N = query.size(); 5172 for (int j=0; j<N; j++) { 5173 final ResolveInfo ri = query.get(j); 5174 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo 5175 + ": 0x" + Integer.toHexString(match)); 5176 if (ri.match > match) { 5177 match = ri.match; 5178 } 5179 } 5180 5181 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x" 5182 + Integer.toHexString(match)); 5183 5184 match &= IntentFilter.MATCH_CATEGORY_MASK; 5185 final int M = prefs.size(); 5186 for (int i=0; i<M; i++) { 5187 final PreferredActivity pa = prefs.get(i); 5188 if (DEBUG_PREFERRED || debug) { 5189 Slog.v(TAG, "Checking PreferredActivity ds=" 5190 + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>") 5191 + "\n component=" + pa.mPref.mComponent); 5192 pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 5193 } 5194 if (pa.mPref.mMatch != match) { 5195 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match " 5196 + Integer.toHexString(pa.mPref.mMatch)); 5197 continue; 5198 } 5199 // If it's not an "always" type preferred activity and that's what we're 5200 // looking for, skip it. 5201 if (always && !pa.mPref.mAlways) { 5202 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry"); 5203 continue; 5204 } 5205 final ActivityInfo ai = getActivityInfo( 5206 pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS 5207 | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, 5208 userId); 5209 if (DEBUG_PREFERRED || debug) { 5210 Slog.v(TAG, "Found preferred activity:"); 5211 if (ai != null) { 5212 ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " "); 5213 } else { 5214 Slog.v(TAG, " null"); 5215 } 5216 } 5217 if (ai == null) { 5218 // This previously registered preferred activity 5219 // component is no longer known. Most likely an update 5220 // to the app was installed and in the new version this 5221 // component no longer exists. Clean it up by removing 5222 // it from the preferred activities list, and skip it. 5223 Slog.w(TAG, "Removing dangling preferred activity: " 5224 + pa.mPref.mComponent); 5225 pir.removeFilter(pa); 5226 changed = true; 5227 continue; 5228 } 5229 for (int j=0; j<N; j++) { 5230 final ResolveInfo ri = query.get(j); 5231 if (!ri.activityInfo.applicationInfo.packageName 5232 .equals(ai.applicationInfo.packageName)) { 5233 continue; 5234 } 5235 if (!ri.activityInfo.name.equals(ai.name)) { 5236 continue; 5237 } 5238 5239 if (removeMatches) { 5240 pir.removeFilter(pa); 5241 changed = true; 5242 if (DEBUG_PREFERRED) { 5243 Slog.v(TAG, "Removing match " + pa.mPref.mComponent); 5244 } 5245 break; 5246 } 5247 5248 // Okay we found a previously set preferred or last chosen app. 5249 // If the result set is different from when this 5250 // was created, we need to clear it and re-ask the 5251 // user their preference, if we're looking for an "always" type entry. 5252 if (always && !pa.mPref.sameSet(query)) { 5253 Slog.i(TAG, "Result set changed, dropping preferred activity for " 5254 + intent + " type " + resolvedType); 5255 if (DEBUG_PREFERRED) { 5256 Slog.v(TAG, "Removing preferred activity since set changed " 5257 + pa.mPref.mComponent); 5258 } 5259 pir.removeFilter(pa); 5260 // Re-add the filter as a "last chosen" entry (!always) 5261 PreferredActivity lastChosen = new PreferredActivity( 5262 pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false); 5263 pir.addFilter(lastChosen); 5264 changed = true; 5265 return null; 5266 } 5267 5268 // Yay! Either the set matched or we're looking for the last chosen 5269 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: " 5270 + ri.activityInfo.packageName + "/" + ri.activityInfo.name); 5271 return ri; 5272 } 5273 } 5274 } finally { 5275 if (changed) { 5276 if (DEBUG_PREFERRED) { 5277 Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions"); 5278 } 5279 scheduleWritePackageRestrictionsLocked(userId); 5280 } 5281 } 5282 } 5283 } 5284 if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return"); 5285 return null; 5286 } 5287 5288 /* 5289 * Returns if intent can be forwarded from the sourceUserId to the targetUserId 5290 */ 5291 @Override 5292 public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId, 5293 int targetUserId) { 5294 mContext.enforceCallingOrSelfPermission( 5295 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 5296 List<CrossProfileIntentFilter> matches = 5297 getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId); 5298 if (matches != null) { 5299 int size = matches.size(); 5300 for (int i = 0; i < size; i++) { 5301 if (matches.get(i).getTargetUserId() == targetUserId) return true; 5302 } 5303 } 5304 if (hasWebURI(intent)) { 5305 // cross-profile app linking works only towards the parent. 5306 final UserInfo parent = getProfileParent(sourceUserId); 5307 synchronized(mPackages) { 5308 int flags = updateFlagsForResolve(0, parent.id, intent); 5309 CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr( 5310 intent, resolvedType, flags, sourceUserId, parent.id); 5311 return xpDomainInfo != null; 5312 } 5313 } 5314 return false; 5315 } 5316 5317 private UserInfo getProfileParent(int userId) { 5318 final long identity = Binder.clearCallingIdentity(); 5319 try { 5320 return sUserManager.getProfileParent(userId); 5321 } finally { 5322 Binder.restoreCallingIdentity(identity); 5323 } 5324 } 5325 5326 private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent, 5327 String resolvedType, int userId) { 5328 CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId); 5329 if (resolver != null) { 5330 return resolver.queryIntent(intent, resolvedType, false, userId); 5331 } 5332 return null; 5333 } 5334 5335 @Override 5336 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent, 5337 String resolvedType, int flags, int userId) { 5338 try { 5339 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities"); 5340 5341 return new ParceledListSlice<>( 5342 queryIntentActivitiesInternal(intent, resolvedType, flags, userId)); 5343 } finally { 5344 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 5345 } 5346 } 5347 5348 private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, 5349 String resolvedType, int flags, int userId) { 5350 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5351 flags = updateFlagsForResolve(flags, userId, intent); 5352 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5353 false /* requireFullPermission */, false /* checkShell */, 5354 "query intent activities"); 5355 ComponentName comp = intent.getComponent(); 5356 if (comp == null) { 5357 if (intent.getSelector() != null) { 5358 intent = intent.getSelector(); 5359 comp = intent.getComponent(); 5360 } 5361 } 5362 5363 if (comp != null) { 5364 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 5365 final ActivityInfo ai = getActivityInfo(comp, flags, userId); 5366 if (ai != null) { 5367 final ResolveInfo ri = new ResolveInfo(); 5368 ri.activityInfo = ai; 5369 list.add(ri); 5370 } 5371 return list; 5372 } 5373 5374 // reader 5375 boolean sortResult = false; 5376 boolean addEphemeral = false; 5377 boolean matchEphemeralPackage = false; 5378 List<ResolveInfo> result; 5379 final String pkgName = intent.getPackage(); 5380 synchronized (mPackages) { 5381 if (pkgName == null) { 5382 List<CrossProfileIntentFilter> matchingFilters = 5383 getMatchingCrossProfileIntentFilters(intent, resolvedType, userId); 5384 // Check for results that need to skip the current profile. 5385 ResolveInfo xpResolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent, 5386 resolvedType, flags, userId); 5387 if (xpResolveInfo != null) { 5388 List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1); 5389 xpResult.add(xpResolveInfo); 5390 return filterIfNotSystemUser(xpResult, userId); 5391 } 5392 5393 // Check for results in the current profile. 5394 result = filterIfNotSystemUser(mActivities.queryIntent( 5395 intent, resolvedType, flags, userId), userId); 5396 addEphemeral = 5397 isEphemeralAllowed(intent, result, userId, false /*skipPackageCheck*/); 5398 5399 // Check for cross profile results. 5400 boolean hasNonNegativePriorityResult = hasNonNegativePriority(result); 5401 xpResolveInfo = queryCrossProfileIntents( 5402 matchingFilters, intent, resolvedType, flags, userId, 5403 hasNonNegativePriorityResult); 5404 if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) { 5405 boolean isVisibleToUser = filterIfNotSystemUser( 5406 Collections.singletonList(xpResolveInfo), userId).size() > 0; 5407 if (isVisibleToUser) { 5408 result.add(xpResolveInfo); 5409 sortResult = true; 5410 } 5411 } 5412 if (hasWebURI(intent)) { 5413 CrossProfileDomainInfo xpDomainInfo = null; 5414 final UserInfo parent = getProfileParent(userId); 5415 if (parent != null) { 5416 xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType, 5417 flags, userId, parent.id); 5418 } 5419 if (xpDomainInfo != null) { 5420 if (xpResolveInfo != null) { 5421 // If we didn't remove it, the cross-profile ResolveInfo would be twice 5422 // in the result. 5423 result.remove(xpResolveInfo); 5424 } 5425 if (result.size() == 0 && !addEphemeral) { 5426 // No result in current profile, but found candidate in parent user. 5427 // And we are not going to add emphemeral app, so we can return the 5428 // result straight away. 5429 result.add(xpDomainInfo.resolveInfo); 5430 return result; 5431 } 5432 } else if (result.size() <= 1 && !addEphemeral) { 5433 // No result in parent user and <= 1 result in current profile, and we 5434 // are not going to add emphemeral app, so we can return the result without 5435 // further processing. 5436 return result; 5437 } 5438 // We have more than one candidate (combining results from current and parent 5439 // profile), so we need filtering and sorting. 5440 result = filterCandidatesWithDomainPreferredActivitiesLPr( 5441 intent, flags, result, xpDomainInfo, userId); 5442 sortResult = true; 5443 } 5444 } else { 5445 final PackageParser.Package pkg = mPackages.get(pkgName); 5446 if (pkg != null) { 5447 result = filterIfNotSystemUser( 5448 mActivities.queryIntentForPackage( 5449 intent, resolvedType, flags, pkg.activities, userId), 5450 userId); 5451 } else { 5452 // the caller wants to resolve for a particular package; however, there 5453 // were no installed results, so, try to find an ephemeral result 5454 addEphemeral = isEphemeralAllowed( 5455 intent, null /*result*/, userId, true /*skipPackageCheck*/); 5456 matchEphemeralPackage = true; 5457 result = new ArrayList<ResolveInfo>(); 5458 } 5459 } 5460 } 5461 if (addEphemeral) { 5462 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral"); 5463 final EphemeralResolveInfo ai = getEphemeralResolveInfo( 5464 mContext, mEphemeralResolverConnection, intent, resolvedType, userId, 5465 matchEphemeralPackage ? pkgName : null); 5466 if (ai != null) { 5467 if (DEBUG_EPHEMERAL) { 5468 Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list"); 5469 } 5470 final ResolveInfo ephemeralInstaller = new ResolveInfo(mEphemeralInstallerInfo); 5471 ephemeralInstaller.ephemeralResolveInfo = ai; 5472 // make sure this resolver is the default 5473 ephemeralInstaller.isDefault = true; 5474 ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART 5475 | IntentFilter.MATCH_ADJUSTMENT_NORMAL; 5476 // add a non-generic filter 5477 ephemeralInstaller.filter = new IntentFilter(intent.getAction()); 5478 ephemeralInstaller.filter.addDataPath( 5479 intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL); 5480 result.add(ephemeralInstaller); 5481 } 5482 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 5483 } 5484 if (sortResult) { 5485 Collections.sort(result, mResolvePrioritySorter); 5486 } 5487 return result; 5488 } 5489 5490 private static class CrossProfileDomainInfo { 5491 /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */ 5492 ResolveInfo resolveInfo; 5493 /* Best domain verification status of the activities found in the other profile */ 5494 int bestDomainVerificationStatus; 5495 } 5496 5497 private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent, 5498 String resolvedType, int flags, int sourceUserId, int parentUserId) { 5499 if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING, 5500 sourceUserId)) { 5501 return null; 5502 } 5503 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 5504 resolvedType, flags, parentUserId); 5505 5506 if (resultTargetUser == null || resultTargetUser.isEmpty()) { 5507 return null; 5508 } 5509 CrossProfileDomainInfo result = null; 5510 int size = resultTargetUser.size(); 5511 for (int i = 0; i < size; i++) { 5512 ResolveInfo riTargetUser = resultTargetUser.get(i); 5513 // Intent filter verification is only for filters that specify a host. So don't return 5514 // those that handle all web uris. 5515 if (riTargetUser.handleAllWebDataURI) { 5516 continue; 5517 } 5518 String packageName = riTargetUser.activityInfo.packageName; 5519 PackageSetting ps = mSettings.mPackages.get(packageName); 5520 if (ps == null) { 5521 continue; 5522 } 5523 long verificationState = getDomainVerificationStatusLPr(ps, parentUserId); 5524 int status = (int)(verificationState >> 32); 5525 if (result == null) { 5526 result = new CrossProfileDomainInfo(); 5527 result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(), 5528 sourceUserId, parentUserId); 5529 result.bestDomainVerificationStatus = status; 5530 } else { 5531 result.bestDomainVerificationStatus = bestDomainVerificationStatus(status, 5532 result.bestDomainVerificationStatus); 5533 } 5534 } 5535 // Don't consider matches with status NEVER across profiles. 5536 if (result != null && result.bestDomainVerificationStatus 5537 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5538 return null; 5539 } 5540 return result; 5541 } 5542 5543 /** 5544 * Verification statuses are ordered from the worse to the best, except for 5545 * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse. 5546 */ 5547 private int bestDomainVerificationStatus(int status1, int status2) { 5548 if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5549 return status2; 5550 } 5551 if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5552 return status1; 5553 } 5554 return (int) MathUtils.max(status1, status2); 5555 } 5556 5557 private boolean isUserEnabled(int userId) { 5558 long callingId = Binder.clearCallingIdentity(); 5559 try { 5560 UserInfo userInfo = sUserManager.getUserInfo(userId); 5561 return userInfo != null && userInfo.isEnabled(); 5562 } finally { 5563 Binder.restoreCallingIdentity(callingId); 5564 } 5565 } 5566 5567 /** 5568 * Filter out activities with systemUserOnly flag set, when current user is not System. 5569 * 5570 * @return filtered list 5571 */ 5572 private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) { 5573 if (userId == UserHandle.USER_SYSTEM) { 5574 return resolveInfos; 5575 } 5576 for (int i = resolveInfos.size() - 1; i >= 0; i--) { 5577 ResolveInfo info = resolveInfos.get(i); 5578 if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) { 5579 resolveInfos.remove(i); 5580 } 5581 } 5582 return resolveInfos; 5583 } 5584 5585 /** 5586 * @param resolveInfos list of resolve infos in descending priority order 5587 * @return if the list contains a resolve info with non-negative priority 5588 */ 5589 private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) { 5590 return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0; 5591 } 5592 5593 private static boolean hasWebURI(Intent intent) { 5594 if (intent.getData() == null) { 5595 return false; 5596 } 5597 final String scheme = intent.getScheme(); 5598 if (TextUtils.isEmpty(scheme)) { 5599 return false; 5600 } 5601 return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS); 5602 } 5603 5604 private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent, 5605 int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo, 5606 int userId) { 5607 final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0; 5608 5609 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) { 5610 Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " + 5611 candidates.size()); 5612 } 5613 5614 ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>(); 5615 ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>(); 5616 ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>(); 5617 ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>(); 5618 ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>(); 5619 ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>(); 5620 5621 synchronized (mPackages) { 5622 final int count = candidates.size(); 5623 // First, try to use linked apps. Partition the candidates into four lists: 5624 // one for the final results, one for the "do not use ever", one for "undefined status" 5625 // and finally one for "browser app type". 5626 for (int n=0; n<count; n++) { 5627 ResolveInfo info = candidates.get(n); 5628 String packageName = info.activityInfo.packageName; 5629 PackageSetting ps = mSettings.mPackages.get(packageName); 5630 if (ps != null) { 5631 // Add to the special match all list (Browser use case) 5632 if (info.handleAllWebDataURI) { 5633 matchAllList.add(info); 5634 continue; 5635 } 5636 // Try to get the status from User settings first 5637 long packedStatus = getDomainVerificationStatusLPr(ps, userId); 5638 int status = (int)(packedStatus >> 32); 5639 int linkGeneration = (int)(packedStatus & 0xFFFFFFFF); 5640 if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) { 5641 if (DEBUG_DOMAIN_VERIFICATION) { 5642 Slog.i(TAG, " + always: " + info.activityInfo.packageName 5643 + " : linkgen=" + linkGeneration); 5644 } 5645 // Use link-enabled generation as preferredOrder, i.e. 5646 // prefer newly-enabled over earlier-enabled. 5647 info.preferredOrder = linkGeneration; 5648 alwaysList.add(info); 5649 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 5650 if (DEBUG_DOMAIN_VERIFICATION) { 5651 Slog.i(TAG, " + never: " + info.activityInfo.packageName); 5652 } 5653 neverList.add(info); 5654 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) { 5655 if (DEBUG_DOMAIN_VERIFICATION) { 5656 Slog.i(TAG, " + always-ask: " + info.activityInfo.packageName); 5657 } 5658 alwaysAskList.add(info); 5659 } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED || 5660 status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) { 5661 if (DEBUG_DOMAIN_VERIFICATION) { 5662 Slog.i(TAG, " + ask: " + info.activityInfo.packageName); 5663 } 5664 undefinedList.add(info); 5665 } 5666 } 5667 } 5668 5669 // We'll want to include browser possibilities in a few cases 5670 boolean includeBrowser = false; 5671 5672 // First try to add the "always" resolution(s) for the current user, if any 5673 if (alwaysList.size() > 0) { 5674 result.addAll(alwaysList); 5675 } else { 5676 // Add all undefined apps as we want them to appear in the disambiguation dialog. 5677 result.addAll(undefinedList); 5678 // Maybe add one for the other profile. 5679 if (xpDomainInfo != null && ( 5680 xpDomainInfo.bestDomainVerificationStatus 5681 != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) { 5682 result.add(xpDomainInfo.resolveInfo); 5683 } 5684 includeBrowser = true; 5685 } 5686 5687 // The presence of any 'always ask' alternatives means we'll also offer browsers. 5688 // If there were 'always' entries their preferred order has been set, so we also 5689 // back that off to make the alternatives equivalent 5690 if (alwaysAskList.size() > 0) { 5691 for (ResolveInfo i : result) { 5692 i.preferredOrder = 0; 5693 } 5694 result.addAll(alwaysAskList); 5695 includeBrowser = true; 5696 } 5697 5698 if (includeBrowser) { 5699 // Also add browsers (all of them or only the default one) 5700 if (DEBUG_DOMAIN_VERIFICATION) { 5701 Slog.v(TAG, " ...including browsers in candidate set"); 5702 } 5703 if ((matchFlags & MATCH_ALL) != 0) { 5704 result.addAll(matchAllList); 5705 } else { 5706 // Browser/generic handling case. If there's a default browser, go straight 5707 // to that (but only if there is no other higher-priority match). 5708 final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId); 5709 int maxMatchPrio = 0; 5710 ResolveInfo defaultBrowserMatch = null; 5711 final int numCandidates = matchAllList.size(); 5712 for (int n = 0; n < numCandidates; n++) { 5713 ResolveInfo info = matchAllList.get(n); 5714 // track the highest overall match priority... 5715 if (info.priority > maxMatchPrio) { 5716 maxMatchPrio = info.priority; 5717 } 5718 // ...and the highest-priority default browser match 5719 if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) { 5720 if (defaultBrowserMatch == null 5721 || (defaultBrowserMatch.priority < info.priority)) { 5722 if (debug) { 5723 Slog.v(TAG, "Considering default browser match " + info); 5724 } 5725 defaultBrowserMatch = info; 5726 } 5727 } 5728 } 5729 if (defaultBrowserMatch != null 5730 && defaultBrowserMatch.priority >= maxMatchPrio 5731 && !TextUtils.isEmpty(defaultBrowserPackageName)) 5732 { 5733 if (debug) { 5734 Slog.v(TAG, "Default browser match " + defaultBrowserMatch); 5735 } 5736 result.add(defaultBrowserMatch); 5737 } else { 5738 result.addAll(matchAllList); 5739 } 5740 } 5741 5742 // If there is nothing selected, add all candidates and remove the ones that the user 5743 // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state 5744 if (result.size() == 0) { 5745 result.addAll(candidates); 5746 result.removeAll(neverList); 5747 } 5748 } 5749 } 5750 if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) { 5751 Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " + 5752 result.size()); 5753 for (ResolveInfo info : result) { 5754 Slog.v(TAG, " + " + info.activityInfo); 5755 } 5756 } 5757 return result; 5758 } 5759 5760 // Returns a packed value as a long: 5761 // 5762 // high 'int'-sized word: link status: undefined/ask/never/always. 5763 // low 'int'-sized word: relative priority among 'always' results. 5764 private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) { 5765 long result = ps.getDomainVerificationStatusForUser(userId); 5766 // if none available, get the master status 5767 if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 5768 if (ps.getIntentFilterVerificationInfo() != null) { 5769 result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32; 5770 } 5771 } 5772 return result; 5773 } 5774 5775 private ResolveInfo querySkipCurrentProfileIntents( 5776 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 5777 int flags, int sourceUserId) { 5778 if (matchingFilters != null) { 5779 int size = matchingFilters.size(); 5780 for (int i = 0; i < size; i ++) { 5781 CrossProfileIntentFilter filter = matchingFilters.get(i); 5782 if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) { 5783 // Checking if there are activities in the target user that can handle the 5784 // intent. 5785 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent, 5786 resolvedType, flags, sourceUserId); 5787 if (resolveInfo != null) { 5788 return resolveInfo; 5789 } 5790 } 5791 } 5792 } 5793 return null; 5794 } 5795 5796 // Return matching ResolveInfo in target user if any. 5797 private ResolveInfo queryCrossProfileIntents( 5798 List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, 5799 int flags, int sourceUserId, boolean matchInCurrentProfile) { 5800 if (matchingFilters != null) { 5801 // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and 5802 // match the same intent. For performance reasons, it is better not to 5803 // run queryIntent twice for the same userId 5804 SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray(); 5805 int size = matchingFilters.size(); 5806 for (int i = 0; i < size; i++) { 5807 CrossProfileIntentFilter filter = matchingFilters.get(i); 5808 int targetUserId = filter.getTargetUserId(); 5809 boolean skipCurrentProfile = 5810 (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0; 5811 boolean skipCurrentProfileIfNoMatchFound = 5812 (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0; 5813 if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId) 5814 && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) { 5815 // Checking if there are activities in the target user that can handle the 5816 // intent. 5817 ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent, 5818 resolvedType, flags, sourceUserId); 5819 if (resolveInfo != null) return resolveInfo; 5820 alreadyTriedUserIds.put(targetUserId, true); 5821 } 5822 } 5823 } 5824 return null; 5825 } 5826 5827 /** 5828 * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that 5829 * will forward the intent to the filter's target user. 5830 * Otherwise, returns null. 5831 */ 5832 private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent, 5833 String resolvedType, int flags, int sourceUserId) { 5834 int targetUserId = filter.getTargetUserId(); 5835 List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, 5836 resolvedType, flags, targetUserId); 5837 if (resultTargetUser != null && isUserEnabled(targetUserId)) { 5838 // If all the matches in the target profile are suspended, return null. 5839 for (int i = resultTargetUser.size() - 1; i >= 0; i--) { 5840 if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags 5841 & ApplicationInfo.FLAG_SUSPENDED) == 0) { 5842 return createForwardingResolveInfoUnchecked(filter, sourceUserId, 5843 targetUserId); 5844 } 5845 } 5846 } 5847 return null; 5848 } 5849 5850 private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter, 5851 int sourceUserId, int targetUserId) { 5852 ResolveInfo forwardingResolveInfo = new ResolveInfo(); 5853 long ident = Binder.clearCallingIdentity(); 5854 boolean targetIsProfile; 5855 try { 5856 targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile(); 5857 } finally { 5858 Binder.restoreCallingIdentity(ident); 5859 } 5860 String className; 5861 if (targetIsProfile) { 5862 className = FORWARD_INTENT_TO_MANAGED_PROFILE; 5863 } else { 5864 className = FORWARD_INTENT_TO_PARENT; 5865 } 5866 ComponentName forwardingActivityComponentName = new ComponentName( 5867 mAndroidApplication.packageName, className); 5868 ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0, 5869 sourceUserId); 5870 if (!targetIsProfile) { 5871 forwardingActivityInfo.showUserIcon = targetUserId; 5872 forwardingResolveInfo.noResourceId = true; 5873 } 5874 forwardingResolveInfo.activityInfo = forwardingActivityInfo; 5875 forwardingResolveInfo.priority = 0; 5876 forwardingResolveInfo.preferredOrder = 0; 5877 forwardingResolveInfo.match = 0; 5878 forwardingResolveInfo.isDefault = true; 5879 forwardingResolveInfo.filter = filter; 5880 forwardingResolveInfo.targetUserId = targetUserId; 5881 return forwardingResolveInfo; 5882 } 5883 5884 @Override 5885 public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller, 5886 Intent[] specifics, String[] specificTypes, Intent intent, 5887 String resolvedType, int flags, int userId) { 5888 return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics, 5889 specificTypes, intent, resolvedType, flags, userId)); 5890 } 5891 5892 private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller, 5893 Intent[] specifics, String[] specificTypes, Intent intent, 5894 String resolvedType, int flags, int userId) { 5895 if (!sUserManager.exists(userId)) return Collections.emptyList(); 5896 flags = updateFlagsForResolve(flags, userId, intent); 5897 enforceCrossUserPermission(Binder.getCallingUid(), userId, 5898 false /* requireFullPermission */, false /* checkShell */, 5899 "query intent activity options"); 5900 final String resultsAction = intent.getAction(); 5901 5902 final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags 5903 | PackageManager.GET_RESOLVED_FILTER, userId); 5904 5905 if (DEBUG_INTENT_MATCHING) { 5906 Log.v(TAG, "Query " + intent + ": " + results); 5907 } 5908 5909 int specificsPos = 0; 5910 int N; 5911 5912 // todo: note that the algorithm used here is O(N^2). This 5913 // isn't a problem in our current environment, but if we start running 5914 // into situations where we have more than 5 or 10 matches then this 5915 // should probably be changed to something smarter... 5916 5917 // First we go through and resolve each of the specific items 5918 // that were supplied, taking care of removing any corresponding 5919 // duplicate items in the generic resolve list. 5920 if (specifics != null) { 5921 for (int i=0; i<specifics.length; i++) { 5922 final Intent sintent = specifics[i]; 5923 if (sintent == null) { 5924 continue; 5925 } 5926 5927 if (DEBUG_INTENT_MATCHING) { 5928 Log.v(TAG, "Specific #" + i + ": " + sintent); 5929 } 5930 5931 String action = sintent.getAction(); 5932 if (resultsAction != null && resultsAction.equals(action)) { 5933 // If this action was explicitly requested, then don't 5934 // remove things that have it. 5935 action = null; 5936 } 5937 5938 ResolveInfo ri = null; 5939 ActivityInfo ai = null; 5940 5941 ComponentName comp = sintent.getComponent(); 5942 if (comp == null) { 5943 ri = resolveIntent( 5944 sintent, 5945 specificTypes != null ? specificTypes[i] : null, 5946 flags, userId); 5947 if (ri == null) { 5948 continue; 5949 } 5950 if (ri == mResolveInfo) { 5951 // ACK! Must do something better with this. 5952 } 5953 ai = ri.activityInfo; 5954 comp = new ComponentName(ai.applicationInfo.packageName, 5955 ai.name); 5956 } else { 5957 ai = getActivityInfo(comp, flags, userId); 5958 if (ai == null) { 5959 continue; 5960 } 5961 } 5962 5963 // Look for any generic query activities that are duplicates 5964 // of this specific one, and remove them from the results. 5965 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai); 5966 N = results.size(); 5967 int j; 5968 for (j=specificsPos; j<N; j++) { 5969 ResolveInfo sri = results.get(j); 5970 if ((sri.activityInfo.name.equals(comp.getClassName()) 5971 && sri.activityInfo.applicationInfo.packageName.equals( 5972 comp.getPackageName())) 5973 || (action != null && sri.filter.matchAction(action))) { 5974 results.remove(j); 5975 if (DEBUG_INTENT_MATCHING) Log.v( 5976 TAG, "Removing duplicate item from " + j 5977 + " due to specific " + specificsPos); 5978 if (ri == null) { 5979 ri = sri; 5980 } 5981 j--; 5982 N--; 5983 } 5984 } 5985 5986 // Add this specific item to its proper place. 5987 if (ri == null) { 5988 ri = new ResolveInfo(); 5989 ri.activityInfo = ai; 5990 } 5991 results.add(specificsPos, ri); 5992 ri.specificIndex = i; 5993 specificsPos++; 5994 } 5995 } 5996 5997 // Now we go through the remaining generic results and remove any 5998 // duplicate actions that are found here. 5999 N = results.size(); 6000 for (int i=specificsPos; i<N-1; i++) { 6001 final ResolveInfo rii = results.get(i); 6002 if (rii.filter == null) { 6003 continue; 6004 } 6005 6006 // Iterate over all of the actions of this result's intent 6007 // filter... typically this should be just one. 6008 final Iterator<String> it = rii.filter.actionsIterator(); 6009 if (it == null) { 6010 continue; 6011 } 6012 while (it.hasNext()) { 6013 final String action = it.next(); 6014 if (resultsAction != null && resultsAction.equals(action)) { 6015 // If this action was explicitly requested, then don't 6016 // remove things that have it. 6017 continue; 6018 } 6019 for (int j=i+1; j<N; j++) { 6020 final ResolveInfo rij = results.get(j); 6021 if (rij.filter != null && rij.filter.hasAction(action)) { 6022 results.remove(j); 6023 if (DEBUG_INTENT_MATCHING) Log.v( 6024 TAG, "Removing duplicate item from " + j 6025 + " due to action " + action + " at " + i); 6026 j--; 6027 N--; 6028 } 6029 } 6030 } 6031 6032 // If the caller didn't request filter information, drop it now 6033 // so we don't have to marshall/unmarshall it. 6034 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 6035 rii.filter = null; 6036 } 6037 } 6038 6039 // Filter out the caller activity if so requested. 6040 if (caller != null) { 6041 N = results.size(); 6042 for (int i=0; i<N; i++) { 6043 ActivityInfo ainfo = results.get(i).activityInfo; 6044 if (caller.getPackageName().equals(ainfo.applicationInfo.packageName) 6045 && caller.getClassName().equals(ainfo.name)) { 6046 results.remove(i); 6047 break; 6048 } 6049 } 6050 } 6051 6052 // If the caller didn't request filter information, 6053 // drop them now so we don't have to 6054 // marshall/unmarshall it. 6055 if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) { 6056 N = results.size(); 6057 for (int i=0; i<N; i++) { 6058 results.get(i).filter = null; 6059 } 6060 } 6061 6062 if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results); 6063 return results; 6064 } 6065 6066 @Override 6067 public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent, 6068 String resolvedType, int flags, int userId) { 6069 return new ParceledListSlice<>( 6070 queryIntentReceiversInternal(intent, resolvedType, flags, userId)); 6071 } 6072 6073 private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent, 6074 String resolvedType, int flags, int userId) { 6075 if (!sUserManager.exists(userId)) return Collections.emptyList(); 6076 flags = updateFlagsForResolve(flags, userId, intent); 6077 ComponentName comp = intent.getComponent(); 6078 if (comp == null) { 6079 if (intent.getSelector() != null) { 6080 intent = intent.getSelector(); 6081 comp = intent.getComponent(); 6082 } 6083 } 6084 if (comp != null) { 6085 List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 6086 ActivityInfo ai = getReceiverInfo(comp, flags, userId); 6087 if (ai != null) { 6088 ResolveInfo ri = new ResolveInfo(); 6089 ri.activityInfo = ai; 6090 list.add(ri); 6091 } 6092 return list; 6093 } 6094 6095 // reader 6096 synchronized (mPackages) { 6097 String pkgName = intent.getPackage(); 6098 if (pkgName == null) { 6099 return mReceivers.queryIntent(intent, resolvedType, flags, userId); 6100 } 6101 final PackageParser.Package pkg = mPackages.get(pkgName); 6102 if (pkg != null) { 6103 return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers, 6104 userId); 6105 } 6106 return Collections.emptyList(); 6107 } 6108 } 6109 6110 @Override 6111 public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) { 6112 if (!sUserManager.exists(userId)) return null; 6113 flags = updateFlagsForResolve(flags, userId, intent); 6114 List<ResolveInfo> query = queryIntentServicesInternal(intent, resolvedType, flags, userId); 6115 if (query != null) { 6116 if (query.size() >= 1) { 6117 // If there is more than one service with the same priority, 6118 // just arbitrarily pick the first one. 6119 return query.get(0); 6120 } 6121 } 6122 return null; 6123 } 6124 6125 @Override 6126 public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent, 6127 String resolvedType, int flags, int userId) { 6128 return new ParceledListSlice<>( 6129 queryIntentServicesInternal(intent, resolvedType, flags, userId)); 6130 } 6131 6132 private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent, 6133 String resolvedType, int flags, int userId) { 6134 if (!sUserManager.exists(userId)) return Collections.emptyList(); 6135 flags = updateFlagsForResolve(flags, userId, intent); 6136 ComponentName comp = intent.getComponent(); 6137 if (comp == null) { 6138 if (intent.getSelector() != null) { 6139 intent = intent.getSelector(); 6140 comp = intent.getComponent(); 6141 } 6142 } 6143 if (comp != null) { 6144 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 6145 final ServiceInfo si = getServiceInfo(comp, flags, userId); 6146 if (si != null) { 6147 final ResolveInfo ri = new ResolveInfo(); 6148 ri.serviceInfo = si; 6149 list.add(ri); 6150 } 6151 return list; 6152 } 6153 6154 // reader 6155 synchronized (mPackages) { 6156 String pkgName = intent.getPackage(); 6157 if (pkgName == null) { 6158 return mServices.queryIntent(intent, resolvedType, flags, userId); 6159 } 6160 final PackageParser.Package pkg = mPackages.get(pkgName); 6161 if (pkg != null) { 6162 return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services, 6163 userId); 6164 } 6165 return Collections.emptyList(); 6166 } 6167 } 6168 6169 @Override 6170 public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent, 6171 String resolvedType, int flags, int userId) { 6172 return new ParceledListSlice<>( 6173 queryIntentContentProvidersInternal(intent, resolvedType, flags, userId)); 6174 } 6175 6176 private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal( 6177 Intent intent, String resolvedType, int flags, int userId) { 6178 if (!sUserManager.exists(userId)) return Collections.emptyList(); 6179 flags = updateFlagsForResolve(flags, userId, intent); 6180 ComponentName comp = intent.getComponent(); 6181 if (comp == null) { 6182 if (intent.getSelector() != null) { 6183 intent = intent.getSelector(); 6184 comp = intent.getComponent(); 6185 } 6186 } 6187 if (comp != null) { 6188 final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); 6189 final ProviderInfo pi = getProviderInfo(comp, flags, userId); 6190 if (pi != null) { 6191 final ResolveInfo ri = new ResolveInfo(); 6192 ri.providerInfo = pi; 6193 list.add(ri); 6194 } 6195 return list; 6196 } 6197 6198 // reader 6199 synchronized (mPackages) { 6200 String pkgName = intent.getPackage(); 6201 if (pkgName == null) { 6202 return mProviders.queryIntent(intent, resolvedType, flags, userId); 6203 } 6204 final PackageParser.Package pkg = mPackages.get(pkgName); 6205 if (pkg != null) { 6206 return mProviders.queryIntentForPackage( 6207 intent, resolvedType, flags, pkg.providers, userId); 6208 } 6209 return Collections.emptyList(); 6210 } 6211 } 6212 6213 @Override 6214 public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) { 6215 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 6216 flags = updateFlagsForPackage(flags, userId, null); 6217 final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0; 6218 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6219 true /* requireFullPermission */, false /* checkShell */, 6220 "get installed packages"); 6221 6222 // writer 6223 synchronized (mPackages) { 6224 ArrayList<PackageInfo> list; 6225 if (listUninstalled) { 6226 list = new ArrayList<PackageInfo>(mSettings.mPackages.size()); 6227 for (PackageSetting ps : mSettings.mPackages.values()) { 6228 final PackageInfo pi; 6229 if (ps.pkg != null) { 6230 pi = generatePackageInfo(ps, flags, userId); 6231 } else { 6232 pi = generatePackageInfo(ps, flags, userId); 6233 } 6234 if (pi != null) { 6235 list.add(pi); 6236 } 6237 } 6238 } else { 6239 list = new ArrayList<PackageInfo>(mPackages.size()); 6240 for (PackageParser.Package p : mPackages.values()) { 6241 final PackageInfo pi = 6242 generatePackageInfo((PackageSetting)p.mExtras, flags, userId); 6243 if (pi != null) { 6244 list.add(pi); 6245 } 6246 } 6247 } 6248 6249 return new ParceledListSlice<PackageInfo>(list); 6250 } 6251 } 6252 6253 private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps, 6254 String[] permissions, boolean[] tmp, int flags, int userId) { 6255 int numMatch = 0; 6256 final PermissionsState permissionsState = ps.getPermissionsState(); 6257 for (int i=0; i<permissions.length; i++) { 6258 final String permission = permissions[i]; 6259 if (permissionsState.hasPermission(permission, userId)) { 6260 tmp[i] = true; 6261 numMatch++; 6262 } else { 6263 tmp[i] = false; 6264 } 6265 } 6266 if (numMatch == 0) { 6267 return; 6268 } 6269 final PackageInfo pi; 6270 if (ps.pkg != null) { 6271 pi = generatePackageInfo(ps, flags, userId); 6272 } else { 6273 pi = generatePackageInfo(ps, flags, userId); 6274 } 6275 // The above might return null in cases of uninstalled apps or install-state 6276 // skew across users/profiles. 6277 if (pi != null) { 6278 if ((flags&PackageManager.GET_PERMISSIONS) == 0) { 6279 if (numMatch == permissions.length) { 6280 pi.requestedPermissions = permissions; 6281 } else { 6282 pi.requestedPermissions = new String[numMatch]; 6283 numMatch = 0; 6284 for (int i=0; i<permissions.length; i++) { 6285 if (tmp[i]) { 6286 pi.requestedPermissions[numMatch] = permissions[i]; 6287 numMatch++; 6288 } 6289 } 6290 } 6291 } 6292 list.add(pi); 6293 } 6294 } 6295 6296 @Override 6297 public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions( 6298 String[] permissions, int flags, int userId) { 6299 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 6300 flags = updateFlagsForPackage(flags, userId, permissions); 6301 final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0; 6302 6303 // writer 6304 synchronized (mPackages) { 6305 ArrayList<PackageInfo> list = new ArrayList<PackageInfo>(); 6306 boolean[] tmpBools = new boolean[permissions.length]; 6307 if (listUninstalled) { 6308 for (PackageSetting ps : mSettings.mPackages.values()) { 6309 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId); 6310 } 6311 } else { 6312 for (PackageParser.Package pkg : mPackages.values()) { 6313 PackageSetting ps = (PackageSetting)pkg.mExtras; 6314 if (ps != null) { 6315 addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, 6316 userId); 6317 } 6318 } 6319 } 6320 6321 return new ParceledListSlice<PackageInfo>(list); 6322 } 6323 } 6324 6325 @Override 6326 public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) { 6327 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 6328 flags = updateFlagsForApplication(flags, userId, null); 6329 final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0; 6330 6331 // writer 6332 synchronized (mPackages) { 6333 ArrayList<ApplicationInfo> list; 6334 if (listUninstalled) { 6335 list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size()); 6336 for (PackageSetting ps : mSettings.mPackages.values()) { 6337 ApplicationInfo ai; 6338 if (ps.pkg != null) { 6339 ai = PackageParser.generateApplicationInfo(ps.pkg, flags, 6340 ps.readUserState(userId), userId); 6341 } else { 6342 ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId); 6343 } 6344 if (ai != null) { 6345 list.add(ai); 6346 } 6347 } 6348 } else { 6349 list = new ArrayList<ApplicationInfo>(mPackages.size()); 6350 for (PackageParser.Package p : mPackages.values()) { 6351 if (p.mExtras != null) { 6352 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 6353 ((PackageSetting)p.mExtras).readUserState(userId), userId); 6354 if (ai != null) { 6355 list.add(ai); 6356 } 6357 } 6358 } 6359 } 6360 6361 return new ParceledListSlice<ApplicationInfo>(list); 6362 } 6363 } 6364 6365 @Override 6366 public ParceledListSlice<EphemeralApplicationInfo> getEphemeralApplications(int userId) { 6367 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) { 6368 return null; 6369 } 6370 6371 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS, 6372 "getEphemeralApplications"); 6373 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6374 true /* requireFullPermission */, false /* checkShell */, 6375 "getEphemeralApplications"); 6376 synchronized (mPackages) { 6377 List<EphemeralApplicationInfo> ephemeralApps = mEphemeralApplicationRegistry 6378 .getEphemeralApplicationsLPw(userId); 6379 if (ephemeralApps != null) { 6380 return new ParceledListSlice<>(ephemeralApps); 6381 } 6382 } 6383 return null; 6384 } 6385 6386 @Override 6387 public boolean isEphemeralApplication(String packageName, int userId) { 6388 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6389 true /* requireFullPermission */, false /* checkShell */, 6390 "isEphemeral"); 6391 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) { 6392 return false; 6393 } 6394 6395 if (!isCallerSameApp(packageName)) { 6396 return false; 6397 } 6398 synchronized (mPackages) { 6399 PackageParser.Package pkg = mPackages.get(packageName); 6400 if (pkg != null) { 6401 return pkg.applicationInfo.isEphemeralApp(); 6402 } 6403 } 6404 return false; 6405 } 6406 6407 @Override 6408 public byte[] getEphemeralApplicationCookie(String packageName, int userId) { 6409 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) { 6410 return null; 6411 } 6412 6413 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6414 true /* requireFullPermission */, false /* checkShell */, 6415 "getCookie"); 6416 if (!isCallerSameApp(packageName)) { 6417 return null; 6418 } 6419 synchronized (mPackages) { 6420 return mEphemeralApplicationRegistry.getEphemeralApplicationCookieLPw( 6421 packageName, userId); 6422 } 6423 } 6424 6425 @Override 6426 public boolean setEphemeralApplicationCookie(String packageName, byte[] cookie, int userId) { 6427 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) { 6428 return true; 6429 } 6430 6431 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6432 true /* requireFullPermission */, true /* checkShell */, 6433 "setCookie"); 6434 if (!isCallerSameApp(packageName)) { 6435 return false; 6436 } 6437 synchronized (mPackages) { 6438 return mEphemeralApplicationRegistry.setEphemeralApplicationCookieLPw( 6439 packageName, cookie, userId); 6440 } 6441 } 6442 6443 @Override 6444 public Bitmap getEphemeralApplicationIcon(String packageName, int userId) { 6445 if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) { 6446 return null; 6447 } 6448 6449 mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS, 6450 "getEphemeralApplicationIcon"); 6451 enforceCrossUserPermission(Binder.getCallingUid(), userId, 6452 true /* requireFullPermission */, false /* checkShell */, 6453 "getEphemeralApplicationIcon"); 6454 synchronized (mPackages) { 6455 return mEphemeralApplicationRegistry.getEphemeralApplicationIconLPw( 6456 packageName, userId); 6457 } 6458 } 6459 6460 private boolean isCallerSameApp(String packageName) { 6461 PackageParser.Package pkg = mPackages.get(packageName); 6462 return pkg != null 6463 && UserHandle.getAppId(Binder.getCallingUid()) == pkg.applicationInfo.uid; 6464 } 6465 6466 @Override 6467 public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) { 6468 return new ParceledListSlice<>(getPersistentApplicationsInternal(flags)); 6469 } 6470 6471 private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) { 6472 final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>(); 6473 6474 // reader 6475 synchronized (mPackages) { 6476 final Iterator<PackageParser.Package> i = mPackages.values().iterator(); 6477 final int userId = UserHandle.getCallingUserId(); 6478 while (i.hasNext()) { 6479 final PackageParser.Package p = i.next(); 6480 if (p.applicationInfo == null) continue; 6481 6482 final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0) 6483 && !p.applicationInfo.isDirectBootAware(); 6484 final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0) 6485 && p.applicationInfo.isDirectBootAware(); 6486 6487 if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0 6488 && (!mSafeMode || isSystemApp(p)) 6489 && (matchesUnaware || matchesAware)) { 6490 PackageSetting ps = mSettings.mPackages.get(p.packageName); 6491 if (ps != null) { 6492 ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, 6493 ps.readUserState(userId), userId); 6494 if (ai != null) { 6495 finalList.add(ai); 6496 } 6497 } 6498 } 6499 } 6500 } 6501 6502 return finalList; 6503 } 6504 6505 @Override 6506 public ProviderInfo resolveContentProvider(String name, int flags, int userId) { 6507 if (!sUserManager.exists(userId)) return null; 6508 flags = updateFlagsForComponent(flags, userId, name); 6509 // reader 6510 synchronized (mPackages) { 6511 final PackageParser.Provider provider = mProvidersByAuthority.get(name); 6512 PackageSetting ps = provider != null 6513 ? mSettings.mPackages.get(provider.owner.packageName) 6514 : null; 6515 return ps != null 6516 && mSettings.isEnabledAndMatchLPr(provider.info, flags, userId) 6517 ? PackageParser.generateProviderInfo(provider, flags, 6518 ps.readUserState(userId), userId) 6519 : null; 6520 } 6521 } 6522 6523 /** 6524 * @deprecated 6525 */ 6526 @Deprecated 6527 public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) { 6528 // reader 6529 synchronized (mPackages) { 6530 final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority 6531 .entrySet().iterator(); 6532 final int userId = UserHandle.getCallingUserId(); 6533 while (i.hasNext()) { 6534 Map.Entry<String, PackageParser.Provider> entry = i.next(); 6535 PackageParser.Provider p = entry.getValue(); 6536 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 6537 6538 if (ps != null && p.syncable 6539 && (!mSafeMode || (p.info.applicationInfo.flags 6540 &ApplicationInfo.FLAG_SYSTEM) != 0)) { 6541 ProviderInfo info = PackageParser.generateProviderInfo(p, 0, 6542 ps.readUserState(userId), userId); 6543 if (info != null) { 6544 outNames.add(entry.getKey()); 6545 outInfo.add(info); 6546 } 6547 } 6548 } 6549 } 6550 } 6551 6552 @Override 6553 public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName, 6554 int uid, int flags) { 6555 final int userId = processName != null ? UserHandle.getUserId(uid) 6556 : UserHandle.getCallingUserId(); 6557 if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); 6558 flags = updateFlagsForComponent(flags, userId, processName); 6559 6560 ArrayList<ProviderInfo> finalList = null; 6561 // reader 6562 synchronized (mPackages) { 6563 final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator(); 6564 while (i.hasNext()) { 6565 final PackageParser.Provider p = i.next(); 6566 PackageSetting ps = mSettings.mPackages.get(p.owner.packageName); 6567 if (ps != null && p.info.authority != null 6568 && (processName == null 6569 || (p.info.processName.equals(processName) 6570 && UserHandle.isSameApp(p.info.applicationInfo.uid, uid))) 6571 && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) { 6572 if (finalList == null) { 6573 finalList = new ArrayList<ProviderInfo>(3); 6574 } 6575 ProviderInfo info = PackageParser.generateProviderInfo(p, flags, 6576 ps.readUserState(userId), userId); 6577 if (info != null) { 6578 finalList.add(info); 6579 } 6580 } 6581 } 6582 } 6583 6584 if (finalList != null) { 6585 Collections.sort(finalList, mProviderInitOrderSorter); 6586 return new ParceledListSlice<ProviderInfo>(finalList); 6587 } 6588 6589 return ParceledListSlice.emptyList(); 6590 } 6591 6592 @Override 6593 public InstrumentationInfo getInstrumentationInfo(ComponentName name, int flags) { 6594 // reader 6595 synchronized (mPackages) { 6596 final PackageParser.Instrumentation i = mInstrumentation.get(name); 6597 return PackageParser.generateInstrumentationInfo(i, flags); 6598 } 6599 } 6600 6601 @Override 6602 public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation( 6603 String targetPackage, int flags) { 6604 return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags)); 6605 } 6606 6607 private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage, 6608 int flags) { 6609 ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>(); 6610 6611 // reader 6612 synchronized (mPackages) { 6613 final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator(); 6614 while (i.hasNext()) { 6615 final PackageParser.Instrumentation p = i.next(); 6616 if (targetPackage == null 6617 || targetPackage.equals(p.info.targetPackage)) { 6618 InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p, 6619 flags); 6620 if (ii != null) { 6621 finalList.add(ii); 6622 } 6623 } 6624 } 6625 } 6626 6627 return finalList; 6628 } 6629 6630 private void createIdmapsForPackageLI(PackageParser.Package pkg) { 6631 ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName); 6632 if (overlays == null) { 6633 Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages"); 6634 return; 6635 } 6636 for (PackageParser.Package opkg : overlays.values()) { 6637 // Not much to do if idmap fails: we already logged the error 6638 // and we certainly don't want to abort installation of pkg simply 6639 // because an overlay didn't fit properly. For these reasons, 6640 // ignore the return value of createIdmapForPackagePairLI. 6641 createIdmapForPackagePairLI(pkg, opkg); 6642 } 6643 } 6644 6645 private boolean createIdmapForPackagePairLI(PackageParser.Package pkg, 6646 PackageParser.Package opkg) { 6647 if (!opkg.mTrustedOverlay) { 6648 Slog.w(TAG, "Skipping target and overlay pair " + pkg.baseCodePath + " and " + 6649 opkg.baseCodePath + ": overlay not trusted"); 6650 return false; 6651 } 6652 ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName); 6653 if (overlaySet == null) { 6654 Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " + 6655 opkg.baseCodePath + " but target package has no known overlays"); 6656 return false; 6657 } 6658 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 6659 // TODO: generate idmap for split APKs 6660 try { 6661 mInstaller.idmap(pkg.baseCodePath, opkg.baseCodePath, sharedGid); 6662 } catch (InstallerException e) { 6663 Slog.e(TAG, "Failed to generate idmap for " + pkg.baseCodePath + " and " 6664 + opkg.baseCodePath); 6665 return false; 6666 } 6667 PackageParser.Package[] overlayArray = 6668 overlaySet.values().toArray(new PackageParser.Package[0]); 6669 Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() { 6670 public int compare(PackageParser.Package p1, PackageParser.Package p2) { 6671 return p1.mOverlayPriority - p2.mOverlayPriority; 6672 } 6673 }; 6674 Arrays.sort(overlayArray, cmp); 6675 6676 pkg.applicationInfo.resourceDirs = new String[overlayArray.length]; 6677 int i = 0; 6678 for (PackageParser.Package p : overlayArray) { 6679 pkg.applicationInfo.resourceDirs[i++] = p.baseCodePath; 6680 } 6681 return true; 6682 } 6683 6684 private void scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime) { 6685 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + dir.getAbsolutePath() + "]"); 6686 try { 6687 scanDirLI(dir, parseFlags, scanFlags, currentTime); 6688 } finally { 6689 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6690 } 6691 } 6692 6693 private void scanDirLI(File dir, final int parseFlags, int scanFlags, long currentTime) { 6694 final File[] files = dir.listFiles(); 6695 if (ArrayUtils.isEmpty(files)) { 6696 Log.d(TAG, "No files in app dir " + dir); 6697 return; 6698 } 6699 6700 if (DEBUG_PACKAGE_SCANNING) { 6701 Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags 6702 + " flags=0x" + Integer.toHexString(parseFlags)); 6703 } 6704 6705 for (File file : files) { 6706 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 6707 && !PackageInstallerService.isStageName(file.getName()); 6708 if (!isPackage) { 6709 // Ignore entries which are not packages 6710 continue; 6711 } 6712 try { 6713 scanPackageTracedLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK, 6714 scanFlags, currentTime, null); 6715 } catch (PackageManagerException e) { 6716 Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage()); 6717 6718 // Delete invalid userdata apps 6719 if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 && 6720 e.error == PackageManager.INSTALL_FAILED_INVALID_APK) { 6721 logCriticalInfo(Log.WARN, "Deleting invalid package at " + file); 6722 removeCodePathLI(file); 6723 } 6724 } 6725 } 6726 } 6727 6728 private static File getSettingsProblemFile() { 6729 File dataDir = Environment.getDataDirectory(); 6730 File systemDir = new File(dataDir, "system"); 6731 File fname = new File(systemDir, "uiderrors.txt"); 6732 return fname; 6733 } 6734 6735 static void reportSettingsProblem(int priority, String msg) { 6736 logCriticalInfo(priority, msg); 6737 } 6738 6739 static void logCriticalInfo(int priority, String msg) { 6740 Slog.println(priority, TAG, msg); 6741 EventLogTags.writePmCriticalInfo(msg); 6742 try { 6743 File fname = getSettingsProblemFile(); 6744 FileOutputStream out = new FileOutputStream(fname, true); 6745 PrintWriter pw = new FastPrintWriter(out); 6746 SimpleDateFormat formatter = new SimpleDateFormat(); 6747 String dateString = formatter.format(new Date(System.currentTimeMillis())); 6748 pw.println(dateString + ": " + msg); 6749 pw.close(); 6750 FileUtils.setPermissions( 6751 fname.toString(), 6752 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH, 6753 -1, -1); 6754 } catch (java.io.IOException e) { 6755 } 6756 } 6757 6758 private long getLastModifiedTime(PackageParser.Package pkg, File srcFile) { 6759 if (srcFile.isDirectory()) { 6760 final File baseFile = new File(pkg.baseCodePath); 6761 long maxModifiedTime = baseFile.lastModified(); 6762 if (pkg.splitCodePaths != null) { 6763 for (int i = pkg.splitCodePaths.length - 1; i >=0; --i) { 6764 final File splitFile = new File(pkg.splitCodePaths[i]); 6765 maxModifiedTime = Math.max(maxModifiedTime, splitFile.lastModified()); 6766 } 6767 } 6768 return maxModifiedTime; 6769 } 6770 return srcFile.lastModified(); 6771 } 6772 6773 private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile, 6774 final int policyFlags) throws PackageManagerException { 6775 // When upgrading from pre-N MR1, verify the package time stamp using the package 6776 // directory and not the APK file. 6777 final long lastModifiedTime = mIsPreNMR1Upgrade 6778 ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg, srcFile); 6779 if (ps != null 6780 && ps.codePath.equals(srcFile) 6781 && ps.timeStamp == lastModifiedTime 6782 && !isCompatSignatureUpdateNeeded(pkg) 6783 && !isRecoverSignatureUpdateNeeded(pkg)) { 6784 long mSigningKeySetId = ps.keySetData.getProperSigningKeySet(); 6785 KeySetManagerService ksms = mSettings.mKeySetManagerService; 6786 ArraySet<PublicKey> signingKs; 6787 synchronized (mPackages) { 6788 signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId); 6789 } 6790 if (ps.signatures.mSignatures != null 6791 && ps.signatures.mSignatures.length != 0 6792 && signingKs != null) { 6793 // Optimization: reuse the existing cached certificates 6794 // if the package appears to be unchanged. 6795 pkg.mSignatures = ps.signatures.mSignatures; 6796 pkg.mSigningKeys = signingKs; 6797 return; 6798 } 6799 6800 Slog.w(TAG, "PackageSetting for " + ps.name 6801 + " is missing signatures. Collecting certs again to recover them."); 6802 } else { 6803 Slog.i(TAG, srcFile.toString() + " changed; collecting certs"); 6804 } 6805 6806 try { 6807 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates"); 6808 PackageParser.collectCertificates(pkg, policyFlags); 6809 } catch (PackageParserException e) { 6810 throw PackageManagerException.from(e); 6811 } finally { 6812 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6813 } 6814 } 6815 6816 /** 6817 * Traces a package scan. 6818 * @see #scanPackageLI(File, int, int, long, UserHandle) 6819 */ 6820 private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags, 6821 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 6822 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]"); 6823 try { 6824 return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user); 6825 } finally { 6826 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6827 } 6828 } 6829 6830 /** 6831 * Scans a package and returns the newly parsed package. 6832 * Returns {@code null} in case of errors and the error code is stored in mLastScanError 6833 */ 6834 private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags, 6835 long currentTime, UserHandle user) throws PackageManagerException { 6836 if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile); 6837 PackageParser pp = new PackageParser(); 6838 pp.setSeparateProcesses(mSeparateProcesses); 6839 pp.setOnlyCoreApps(mOnlyCore); 6840 pp.setDisplayMetrics(mMetrics); 6841 6842 if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) { 6843 parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY; 6844 } 6845 6846 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage"); 6847 final PackageParser.Package pkg; 6848 try { 6849 pkg = pp.parsePackage(scanFile, parseFlags); 6850 } catch (PackageParserException e) { 6851 throw PackageManagerException.from(e); 6852 } finally { 6853 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 6854 } 6855 6856 return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user); 6857 } 6858 6859 /** 6860 * Scans a package and returns the newly parsed package. 6861 * @throws PackageManagerException on a parse error. 6862 */ 6863 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile, 6864 final int policyFlags, int scanFlags, long currentTime, UserHandle user) 6865 throws PackageManagerException { 6866 // If the package has children and this is the first dive in the function 6867 // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all 6868 // packages (parent and children) would be successfully scanned before the 6869 // actual scan since scanning mutates internal state and we want to atomically 6870 // install the package and its children. 6871 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 6872 if (pkg.childPackages != null && pkg.childPackages.size() > 0) { 6873 scanFlags |= SCAN_CHECK_ONLY; 6874 } 6875 } else { 6876 scanFlags &= ~SCAN_CHECK_ONLY; 6877 } 6878 6879 // Scan the parent 6880 PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, policyFlags, 6881 scanFlags, currentTime, user); 6882 6883 // Scan the children 6884 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 6885 for (int i = 0; i < childCount; i++) { 6886 PackageParser.Package childPackage = pkg.childPackages.get(i); 6887 scanPackageInternalLI(childPackage, scanFile, policyFlags, scanFlags, 6888 currentTime, user); 6889 } 6890 6891 6892 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 6893 return scanPackageLI(pkg, scanFile, policyFlags, scanFlags, currentTime, user); 6894 } 6895 6896 return scannedPkg; 6897 } 6898 6899 /** 6900 * Scans a package and returns the newly parsed package. 6901 * @throws PackageManagerException on a parse error. 6902 */ 6903 private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile, 6904 int policyFlags, int scanFlags, long currentTime, UserHandle user) 6905 throws PackageManagerException { 6906 PackageSetting ps = null; 6907 PackageSetting updatedPkg; 6908 // reader 6909 synchronized (mPackages) { 6910 // Look to see if we already know about this package. 6911 String oldName = mSettings.getRenamedPackageLPr(pkg.packageName); 6912 if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) { 6913 // This package has been renamed to its original name. Let's 6914 // use that. 6915 ps = mSettings.getPackageLPr(oldName); 6916 } 6917 // If there was no original package, see one for the real package name. 6918 if (ps == null) { 6919 ps = mSettings.getPackageLPr(pkg.packageName); 6920 } 6921 // Check to see if this package could be hiding/updating a system 6922 // package. Must look for it either under the original or real 6923 // package name depending on our state. 6924 updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName); 6925 if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg); 6926 6927 // If this is a package we don't know about on the system partition, we 6928 // may need to remove disabled child packages on the system partition 6929 // or may need to not add child packages if the parent apk is updated 6930 // on the data partition and no longer defines this child package. 6931 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) { 6932 // If this is a parent package for an updated system app and this system 6933 // app got an OTA update which no longer defines some of the child packages 6934 // we have to prune them from the disabled system packages. 6935 PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName); 6936 if (disabledPs != null) { 6937 final int scannedChildCount = (pkg.childPackages != null) 6938 ? pkg.childPackages.size() : 0; 6939 final int disabledChildCount = disabledPs.childPackageNames != null 6940 ? disabledPs.childPackageNames.size() : 0; 6941 for (int i = 0; i < disabledChildCount; i++) { 6942 String disabledChildPackageName = disabledPs.childPackageNames.get(i); 6943 boolean disabledPackageAvailable = false; 6944 for (int j = 0; j < scannedChildCount; j++) { 6945 PackageParser.Package childPkg = pkg.childPackages.get(j); 6946 if (childPkg.packageName.equals(disabledChildPackageName)) { 6947 disabledPackageAvailable = true; 6948 break; 6949 } 6950 } 6951 if (!disabledPackageAvailable) { 6952 mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName); 6953 } 6954 } 6955 } 6956 } 6957 } 6958 6959 boolean updatedPkgBetter = false; 6960 // First check if this is a system package that may involve an update 6961 if (updatedPkg != null && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) { 6962 // If new package is not located in "/system/priv-app" (e.g. due to an OTA), 6963 // it needs to drop FLAG_PRIVILEGED. 6964 if (locationIsPrivileged(scanFile)) { 6965 updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 6966 } else { 6967 updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 6968 } 6969 6970 if (ps != null && !ps.codePath.equals(scanFile)) { 6971 // The path has changed from what was last scanned... check the 6972 // version of the new path against what we have stored to determine 6973 // what to do. 6974 if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath); 6975 if (pkg.mVersionCode <= ps.versionCode) { 6976 // The system package has been updated and the code path does not match 6977 // Ignore entry. Skip it. 6978 if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile 6979 + " ignored: updated version " + ps.versionCode 6980 + " better than this " + pkg.mVersionCode); 6981 if (!updatedPkg.codePath.equals(scanFile)) { 6982 Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg " 6983 + ps.name + " changing from " + updatedPkg.codePathString 6984 + " to " + scanFile); 6985 updatedPkg.codePath = scanFile; 6986 updatedPkg.codePathString = scanFile.toString(); 6987 updatedPkg.resourcePath = scanFile; 6988 updatedPkg.resourcePathString = scanFile.toString(); 6989 } 6990 updatedPkg.pkg = pkg; 6991 updatedPkg.versionCode = pkg.mVersionCode; 6992 6993 // Update the disabled system child packages to point to the package too. 6994 final int childCount = updatedPkg.childPackageNames != null 6995 ? updatedPkg.childPackageNames.size() : 0; 6996 for (int i = 0; i < childCount; i++) { 6997 String childPackageName = updatedPkg.childPackageNames.get(i); 6998 PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr( 6999 childPackageName); 7000 if (updatedChildPkg != null) { 7001 updatedChildPkg.pkg = pkg; 7002 updatedChildPkg.versionCode = pkg.mVersionCode; 7003 } 7004 } 7005 7006 throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at " 7007 + scanFile + " ignored: updated version " + ps.versionCode 7008 + " better than this " + pkg.mVersionCode); 7009 } else { 7010 // The current app on the system partition is better than 7011 // what we have updated to on the data partition; switch 7012 // back to the system partition version. 7013 // At this point, its safely assumed that package installation for 7014 // apps in system partition will go through. If not there won't be a working 7015 // version of the app 7016 // writer 7017 synchronized (mPackages) { 7018 // Just remove the loaded entries from package lists. 7019 mPackages.remove(ps.name); 7020 } 7021 7022 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 7023 + " reverting from " + ps.codePathString 7024 + ": new version " + pkg.mVersionCode 7025 + " better than installed " + ps.versionCode); 7026 7027 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 7028 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 7029 synchronized (mInstallLock) { 7030 args.cleanUpResourcesLI(); 7031 } 7032 synchronized (mPackages) { 7033 mSettings.enableSystemPackageLPw(ps.name); 7034 } 7035 updatedPkgBetter = true; 7036 } 7037 } 7038 } 7039 7040 if (updatedPkg != null) { 7041 // An updated system app will not have the PARSE_IS_SYSTEM flag set 7042 // initially 7043 policyFlags |= PackageParser.PARSE_IS_SYSTEM; 7044 7045 // An updated privileged app will not have the PARSE_IS_PRIVILEGED 7046 // flag set initially 7047 if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) { 7048 policyFlags |= PackageParser.PARSE_IS_PRIVILEGED; 7049 } 7050 } 7051 7052 // Verify certificates against what was last scanned 7053 collectCertificatesLI(ps, pkg, scanFile, policyFlags); 7054 7055 /* 7056 * A new system app appeared, but we already had a non-system one of the 7057 * same name installed earlier. 7058 */ 7059 boolean shouldHideSystemApp = false; 7060 if (updatedPkg == null && ps != null 7061 && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) { 7062 /* 7063 * Check to make sure the signatures match first. If they don't, 7064 * wipe the installed application and its data. 7065 */ 7066 if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures) 7067 != PackageManager.SIGNATURE_MATCH) { 7068 logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but" 7069 + " signatures don't match existing userdata copy; removing"); 7070 try (PackageFreezer freezer = freezePackage(pkg.packageName, 7071 "scanPackageInternalLI")) { 7072 deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null); 7073 } 7074 ps = null; 7075 } else { 7076 /* 7077 * If the newly-added system app is an older version than the 7078 * already installed version, hide it. It will be scanned later 7079 * and re-added like an update. 7080 */ 7081 if (pkg.mVersionCode <= ps.versionCode) { 7082 shouldHideSystemApp = true; 7083 logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile 7084 + " but new version " + pkg.mVersionCode + " better than installed " 7085 + ps.versionCode + "; hiding system"); 7086 } else { 7087 /* 7088 * The newly found system app is a newer version that the 7089 * one previously installed. Simply remove the 7090 * already-installed application and replace it with our own 7091 * while keeping the application data. 7092 */ 7093 logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile 7094 + " reverting from " + ps.codePathString + ": new version " 7095 + pkg.mVersionCode + " better than installed " + ps.versionCode); 7096 InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 7097 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 7098 synchronized (mInstallLock) { 7099 args.cleanUpResourcesLI(); 7100 } 7101 } 7102 } 7103 } 7104 7105 // The apk is forward locked (not public) if its code and resources 7106 // are kept in different files. (except for app in either system or 7107 // vendor path). 7108 // TODO grab this value from PackageSettings 7109 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 7110 if (ps != null && !ps.codePath.equals(ps.resourcePath)) { 7111 policyFlags |= PackageParser.PARSE_FORWARD_LOCK; 7112 } 7113 } 7114 7115 // TODO: extend to support forward-locked splits 7116 String resourcePath = null; 7117 String baseResourcePath = null; 7118 if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) { 7119 if (ps != null && ps.resourcePathString != null) { 7120 resourcePath = ps.resourcePathString; 7121 baseResourcePath = ps.resourcePathString; 7122 } else { 7123 // Should not happen at all. Just log an error. 7124 Slog.e(TAG, "Resource path not set for package " + pkg.packageName); 7125 } 7126 } else { 7127 resourcePath = pkg.codePath; 7128 baseResourcePath = pkg.baseCodePath; 7129 } 7130 7131 // Set application objects path explicitly. 7132 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 7133 pkg.setApplicationInfoCodePath(pkg.codePath); 7134 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 7135 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 7136 pkg.setApplicationInfoResourcePath(resourcePath); 7137 pkg.setApplicationInfoBaseResourcePath(baseResourcePath); 7138 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 7139 7140 // Note that we invoke the following method only if we are about to unpack an application 7141 PackageParser.Package scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags 7142 | SCAN_UPDATE_SIGNATURE, currentTime, user); 7143 7144 /* 7145 * If the system app should be overridden by a previously installed 7146 * data, hide the system app now and let the /data/app scan pick it up 7147 * again. 7148 */ 7149 if (shouldHideSystemApp) { 7150 synchronized (mPackages) { 7151 mSettings.disableSystemPackageLPw(pkg.packageName, true); 7152 } 7153 } 7154 7155 return scannedPkg; 7156 } 7157 7158 private static String fixProcessName(String defProcessName, 7159 String processName) { 7160 if (processName == null) { 7161 return defProcessName; 7162 } 7163 return processName; 7164 } 7165 7166 private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg) 7167 throws PackageManagerException { 7168 if (pkgSetting.signatures.mSignatures != null) { 7169 // Already existing package. Make sure signatures match 7170 boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures) 7171 == PackageManager.SIGNATURE_MATCH; 7172 if (!match) { 7173 match = compareSignaturesCompat(pkgSetting.signatures, pkg) 7174 == PackageManager.SIGNATURE_MATCH; 7175 } 7176 if (!match) { 7177 match = compareSignaturesRecover(pkgSetting.signatures, pkg) 7178 == PackageManager.SIGNATURE_MATCH; 7179 } 7180 if (!match) { 7181 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 7182 + pkg.packageName + " signatures do not match the " 7183 + "previously installed version; ignoring!"); 7184 } 7185 } 7186 7187 // Check for shared user signatures 7188 if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) { 7189 // Already existing package. Make sure signatures match 7190 boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 7191 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 7192 if (!match) { 7193 match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg) 7194 == PackageManager.SIGNATURE_MATCH; 7195 } 7196 if (!match) { 7197 match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg) 7198 == PackageManager.SIGNATURE_MATCH; 7199 } 7200 if (!match) { 7201 throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 7202 "Package " + pkg.packageName 7203 + " has no signatures that match those in shared user " 7204 + pkgSetting.sharedUser.name + "; ignoring!"); 7205 } 7206 } 7207 } 7208 7209 /** 7210 * Enforces that only the system UID or root's UID can call a method exposed 7211 * via Binder. 7212 * 7213 * @param message used as message if SecurityException is thrown 7214 * @throws SecurityException if the caller is not system or root 7215 */ 7216 private static final void enforceSystemOrRoot(String message) { 7217 final int uid = Binder.getCallingUid(); 7218 if (uid != Process.SYSTEM_UID && uid != 0) { 7219 throw new SecurityException(message); 7220 } 7221 } 7222 7223 @Override 7224 public void performFstrimIfNeeded() { 7225 enforceSystemOrRoot("Only the system can request fstrim"); 7226 7227 // Before everything else, see whether we need to fstrim. 7228 try { 7229 IMountService ms = PackageHelper.getMountService(); 7230 if (ms != null) { 7231 boolean doTrim = false; 7232 final long interval = android.provider.Settings.Global.getLong( 7233 mContext.getContentResolver(), 7234 android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL, 7235 DEFAULT_MANDATORY_FSTRIM_INTERVAL); 7236 if (interval > 0) { 7237 final long timeSinceLast = System.currentTimeMillis() - ms.lastMaintenance(); 7238 if (timeSinceLast > interval) { 7239 doTrim = true; 7240 Slog.w(TAG, "No disk maintenance in " + timeSinceLast 7241 + "; running immediately"); 7242 } 7243 } 7244 if (doTrim) { 7245 final boolean dexOptDialogShown; 7246 synchronized (mPackages) { 7247 dexOptDialogShown = mDexOptDialogShown; 7248 } 7249 if (!isFirstBoot() && dexOptDialogShown) { 7250 try { 7251 ActivityManagerNative.getDefault().showBootMessage( 7252 mContext.getResources().getString( 7253 R.string.android_upgrading_fstrim), true); 7254 } catch (RemoteException e) { 7255 } 7256 } 7257 ms.runMaintenance(); 7258 } 7259 } else { 7260 Slog.e(TAG, "Mount service unavailable!"); 7261 } 7262 } catch (RemoteException e) { 7263 // Can't happen; MountService is local 7264 } 7265 } 7266 7267 @Override 7268 public void updatePackagesIfNeeded() { 7269 enforceSystemOrRoot("Only the system can request package update"); 7270 7271 // We need to re-extract after an OTA. 7272 boolean causeUpgrade = isUpgrade(); 7273 7274 // First boot or factory reset. 7275 // Note: we also handle devices that are upgrading to N right now as if it is their 7276 // first boot, as they do not have profile data. 7277 boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade; 7278 7279 // We need to re-extract after a pruned cache, as AoT-ed files will be out of date. 7280 boolean causePrunedCache = VMRuntime.didPruneDalvikCache(); 7281 7282 if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) { 7283 return; 7284 } 7285 7286 List<PackageParser.Package> pkgs; 7287 synchronized (mPackages) { 7288 pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this); 7289 } 7290 7291 final long startTime = System.nanoTime(); 7292 final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */, 7293 getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT)); 7294 7295 final int elapsedTimeSeconds = 7296 (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime); 7297 7298 MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]); 7299 MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]); 7300 MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]); 7301 MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size()); 7302 MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds); 7303 } 7304 7305 /** 7306 * Performs dexopt on the set of packages in {@code packages} and returns an int array 7307 * containing statistics about the invocation. The array consists of three elements, 7308 * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped} 7309 * and {@code numberOfPackagesFailed}. 7310 */ 7311 private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog, 7312 String compilerFilter) { 7313 7314 int numberOfPackagesVisited = 0; 7315 int numberOfPackagesOptimized = 0; 7316 int numberOfPackagesSkipped = 0; 7317 int numberOfPackagesFailed = 0; 7318 final int numberOfPackagesToDexopt = pkgs.size(); 7319 7320 for (PackageParser.Package pkg : pkgs) { 7321 numberOfPackagesVisited++; 7322 7323 if (!PackageDexOptimizer.canOptimizePackage(pkg)) { 7324 if (DEBUG_DEXOPT) { 7325 Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName); 7326 } 7327 numberOfPackagesSkipped++; 7328 continue; 7329 } 7330 7331 if (DEBUG_DEXOPT) { 7332 Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " + 7333 numberOfPackagesToDexopt + ": " + pkg.packageName); 7334 } 7335 7336 if (showDialog) { 7337 try { 7338 ActivityManagerNative.getDefault().showBootMessage( 7339 mContext.getResources().getString(R.string.android_upgrading_apk, 7340 numberOfPackagesVisited, numberOfPackagesToDexopt), true); 7341 } catch (RemoteException e) { 7342 } 7343 synchronized (mPackages) { 7344 mDexOptDialogShown = true; 7345 } 7346 } 7347 7348 // If the OTA updates a system app which was previously preopted to a non-preopted state 7349 // the app might end up being verified at runtime. That's because by default the apps 7350 // are verify-profile but for preopted apps there's no profile. 7351 // Do a hacky check to ensure that if we have no profiles (a reasonable indication 7352 // that before the OTA the app was preopted) the app gets compiled with a non-profile 7353 // filter (by default interpret-only). 7354 // Note that at this stage unused apps are already filtered. 7355 if (isSystemApp(pkg) && 7356 DexFile.isProfileGuidedCompilerFilter(compilerFilter) && 7357 !Environment.getReferenceProfile(pkg.packageName).exists()) { 7358 compilerFilter = getNonProfileGuidedCompilerFilter(compilerFilter); 7359 } 7360 7361 // If the OTA updates a system app which was previously preopted to a non-preopted state 7362 // the app might end up being verified at runtime. That's because by default the apps 7363 // are verify-profile but for preopted apps there's no profile. 7364 // Do a hacky check to ensure that if we have no profiles (a reasonable indication 7365 // that before the OTA the app was preopted) the app gets compiled with a non-profile 7366 // filter (by default interpret-only). 7367 // Note that at this stage unused apps are already filtered. 7368 if (isSystemApp(pkg) && 7369 DexFile.isProfileGuidedCompilerFilter(compilerFilter) && 7370 !Environment.getReferenceProfile(pkg.packageName).exists()) { 7371 compilerFilter = getNonProfileGuidedCompilerFilter(compilerFilter); 7372 } 7373 7374 // checkProfiles is false to avoid merging profiles during boot which 7375 // might interfere with background compilation (b/28612421). 7376 // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will 7377 // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a 7378 // trade-off worth doing to save boot time work. 7379 int dexOptStatus = performDexOptTraced(pkg.packageName, 7380 false /* checkProfiles */, 7381 compilerFilter, 7382 false /* force */); 7383 switch (dexOptStatus) { 7384 case PackageDexOptimizer.DEX_OPT_PERFORMED: 7385 numberOfPackagesOptimized++; 7386 break; 7387 case PackageDexOptimizer.DEX_OPT_SKIPPED: 7388 numberOfPackagesSkipped++; 7389 break; 7390 case PackageDexOptimizer.DEX_OPT_FAILED: 7391 numberOfPackagesFailed++; 7392 break; 7393 default: 7394 Log.e(TAG, "Unexpected dexopt return code " + dexOptStatus); 7395 break; 7396 } 7397 } 7398 7399 return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped, 7400 numberOfPackagesFailed }; 7401 } 7402 7403 @Override 7404 public void notifyPackageUse(String packageName, int reason) { 7405 synchronized (mPackages) { 7406 PackageParser.Package p = mPackages.get(packageName); 7407 if (p == null) { 7408 return; 7409 } 7410 p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis(); 7411 } 7412 } 7413 7414 // TODO: this is not used nor needed. Delete it. 7415 @Override 7416 public boolean performDexOptIfNeeded(String packageName) { 7417 int dexOptStatus = performDexOptTraced(packageName, 7418 false /* checkProfiles */, getFullCompilerFilter(), false /* force */); 7419 return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED; 7420 } 7421 7422 @Override 7423 public boolean performDexOpt(String packageName, 7424 boolean checkProfiles, int compileReason, boolean force) { 7425 int dexOptStatus = performDexOptTraced(packageName, checkProfiles, 7426 getCompilerFilterForReason(compileReason), force); 7427 return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED; 7428 } 7429 7430 @Override 7431 public boolean performDexOptMode(String packageName, 7432 boolean checkProfiles, String targetCompilerFilter, boolean force) { 7433 int dexOptStatus = performDexOptTraced(packageName, checkProfiles, 7434 targetCompilerFilter, force); 7435 return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED; 7436 } 7437 7438 private int performDexOptTraced(String packageName, 7439 boolean checkProfiles, String targetCompilerFilter, boolean force) { 7440 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 7441 try { 7442 return performDexOptInternal(packageName, checkProfiles, 7443 targetCompilerFilter, force); 7444 } finally { 7445 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7446 } 7447 } 7448 7449 // Run dexopt on a given package. Returns true if dexopt did not fail, i.e. 7450 // if the package can now be considered up to date for the given filter. 7451 private int performDexOptInternal(String packageName, 7452 boolean checkProfiles, String targetCompilerFilter, boolean force) { 7453 PackageParser.Package p; 7454 synchronized (mPackages) { 7455 p = mPackages.get(packageName); 7456 if (p == null) { 7457 // Package could not be found. Report failure. 7458 return PackageDexOptimizer.DEX_OPT_FAILED; 7459 } 7460 mPackageUsage.maybeWriteAsync(mPackages); 7461 mCompilerStats.maybeWriteAsync(); 7462 } 7463 long callingId = Binder.clearCallingIdentity(); 7464 try { 7465 synchronized (mInstallLock) { 7466 return performDexOptInternalWithDependenciesLI(p, checkProfiles, 7467 targetCompilerFilter, force); 7468 } 7469 } finally { 7470 Binder.restoreCallingIdentity(callingId); 7471 } 7472 } 7473 7474 public ArraySet<String> getOptimizablePackages() { 7475 ArraySet<String> pkgs = new ArraySet<String>(); 7476 synchronized (mPackages) { 7477 for (PackageParser.Package p : mPackages.values()) { 7478 if (PackageDexOptimizer.canOptimizePackage(p)) { 7479 pkgs.add(p.packageName); 7480 } 7481 } 7482 } 7483 return pkgs; 7484 } 7485 7486 private int performDexOptInternalWithDependenciesLI(PackageParser.Package p, 7487 boolean checkProfiles, String targetCompilerFilter, 7488 boolean force) { 7489 // Select the dex optimizer based on the force parameter. 7490 // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to 7491 // allocate an object here. 7492 PackageDexOptimizer pdo = force 7493 ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer) 7494 : mPackageDexOptimizer; 7495 7496 // Optimize all dependencies first. Note: we ignore the return value and march on 7497 // on errors. 7498 Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p); 7499 final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo); 7500 if (!deps.isEmpty()) { 7501 for (PackageParser.Package depPackage : deps) { 7502 // TODO: Analyze and investigate if we (should) profile libraries. 7503 // Currently this will do a full compilation of the library by default. 7504 pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets, 7505 false /* checkProfiles */, 7506 getCompilerFilterForReason(REASON_NON_SYSTEM_LIBRARY), 7507 getOrCreateCompilerPackageStats(depPackage)); 7508 } 7509 } 7510 return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles, 7511 targetCompilerFilter, getOrCreateCompilerPackageStats(p)); 7512 } 7513 7514 Collection<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) { 7515 if (p.usesLibraries != null || p.usesOptionalLibraries != null) { 7516 ArrayList<PackageParser.Package> retValue = new ArrayList<>(); 7517 Set<String> collectedNames = new HashSet<>(); 7518 findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames); 7519 7520 retValue.remove(p); 7521 7522 return retValue; 7523 } else { 7524 return Collections.emptyList(); 7525 } 7526 } 7527 7528 private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p, 7529 Collection<PackageParser.Package> collected, Set<String> collectedNames) { 7530 if (!collectedNames.contains(p.packageName)) { 7531 collectedNames.add(p.packageName); 7532 collected.add(p); 7533 7534 if (p.usesLibraries != null) { 7535 findSharedNonSystemLibrariesRecursive(p.usesLibraries, collected, collectedNames); 7536 } 7537 if (p.usesOptionalLibraries != null) { 7538 findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries, collected, 7539 collectedNames); 7540 } 7541 } 7542 } 7543 7544 private void findSharedNonSystemLibrariesRecursive(Collection<String> libs, 7545 Collection<PackageParser.Package> collected, Set<String> collectedNames) { 7546 for (String libName : libs) { 7547 PackageParser.Package libPkg = findSharedNonSystemLibrary(libName); 7548 if (libPkg != null) { 7549 findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames); 7550 } 7551 } 7552 } 7553 7554 private PackageParser.Package findSharedNonSystemLibrary(String libName) { 7555 synchronized (mPackages) { 7556 PackageManagerService.SharedLibraryEntry lib = mSharedLibraries.get(libName); 7557 if (lib != null && lib.apk != null) { 7558 return mPackages.get(lib.apk); 7559 } 7560 } 7561 return null; 7562 } 7563 7564 public void shutdown() { 7565 mPackageUsage.writeNow(mPackages); 7566 mCompilerStats.writeNow(); 7567 } 7568 7569 @Override 7570 public void dumpProfiles(String packageName) { 7571 PackageParser.Package pkg; 7572 synchronized (mPackages) { 7573 pkg = mPackages.get(packageName); 7574 if (pkg == null) { 7575 throw new IllegalArgumentException("Unknown package: " + packageName); 7576 } 7577 } 7578 /* Only the shell, root, or the app user should be able to dump profiles. */ 7579 int callingUid = Binder.getCallingUid(); 7580 if (callingUid != Process.SHELL_UID && 7581 callingUid != Process.ROOT_UID && 7582 callingUid != pkg.applicationInfo.uid) { 7583 throw new SecurityException("dumpProfiles"); 7584 } 7585 7586 synchronized (mInstallLock) { 7587 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles"); 7588 final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); 7589 try { 7590 List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly(); 7591 String gid = Integer.toString(sharedGid); 7592 String codePaths = TextUtils.join(";", allCodePaths); 7593 mInstaller.dumpProfiles(gid, packageName, codePaths); 7594 } catch (InstallerException e) { 7595 Slog.w(TAG, "Failed to dump profiles", e); 7596 } 7597 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7598 } 7599 } 7600 7601 @Override 7602 public void forceDexOpt(String packageName) { 7603 enforceSystemOrRoot("forceDexOpt"); 7604 7605 PackageParser.Package pkg; 7606 synchronized (mPackages) { 7607 pkg = mPackages.get(packageName); 7608 if (pkg == null) { 7609 throw new IllegalArgumentException("Unknown package: " + packageName); 7610 } 7611 } 7612 7613 synchronized (mInstallLock) { 7614 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 7615 7616 // Whoever is calling forceDexOpt wants a fully compiled package. 7617 // Don't use profiles since that may cause compilation to be skipped. 7618 final int res = performDexOptInternalWithDependenciesLI(pkg, 7619 false /* checkProfiles */, getCompilerFilterForReason(REASON_FORCED_DEXOPT), 7620 true /* force */); 7621 7622 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7623 if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) { 7624 throw new IllegalStateException("Failed to dexopt: " + res); 7625 } 7626 } 7627 } 7628 7629 private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) { 7630 if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) { 7631 Slog.w(TAG, "Unable to update from " + oldPkg.name 7632 + " to " + newPkg.packageName 7633 + ": old package not in system partition"); 7634 return false; 7635 } else if (mPackages.get(oldPkg.name) != null) { 7636 Slog.w(TAG, "Unable to update from " + oldPkg.name 7637 + " to " + newPkg.packageName 7638 + ": old package still exists"); 7639 return false; 7640 } 7641 return true; 7642 } 7643 7644 void removeCodePathLI(File codePath) { 7645 if (codePath.isDirectory()) { 7646 try { 7647 mInstaller.rmPackageDir(codePath.getAbsolutePath()); 7648 } catch (InstallerException e) { 7649 Slog.w(TAG, "Failed to remove code path", e); 7650 } 7651 } else { 7652 codePath.delete(); 7653 } 7654 } 7655 7656 private int[] resolveUserIds(int userId) { 7657 return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId }; 7658 } 7659 7660 private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) { 7661 if (pkg == null) { 7662 Slog.wtf(TAG, "Package was null!", new Throwable()); 7663 return; 7664 } 7665 clearAppDataLeafLIF(pkg, userId, flags); 7666 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7667 for (int i = 0; i < childCount; i++) { 7668 clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags); 7669 } 7670 } 7671 7672 private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) { 7673 final PackageSetting ps; 7674 synchronized (mPackages) { 7675 ps = mSettings.mPackages.get(pkg.packageName); 7676 } 7677 for (int realUserId : resolveUserIds(userId)) { 7678 final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0; 7679 try { 7680 mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags, 7681 ceDataInode); 7682 } catch (InstallerException e) { 7683 Slog.w(TAG, String.valueOf(e)); 7684 } 7685 } 7686 } 7687 7688 private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) { 7689 if (pkg == null) { 7690 Slog.wtf(TAG, "Package was null!", new Throwable()); 7691 return; 7692 } 7693 destroyAppDataLeafLIF(pkg, userId, flags); 7694 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7695 for (int i = 0; i < childCount; i++) { 7696 destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags); 7697 } 7698 } 7699 7700 private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) { 7701 final PackageSetting ps; 7702 synchronized (mPackages) { 7703 ps = mSettings.mPackages.get(pkg.packageName); 7704 } 7705 for (int realUserId : resolveUserIds(userId)) { 7706 final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0; 7707 try { 7708 mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags, 7709 ceDataInode); 7710 } catch (InstallerException e) { 7711 Slog.w(TAG, String.valueOf(e)); 7712 } 7713 } 7714 } 7715 7716 private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) { 7717 if (pkg == null) { 7718 Slog.wtf(TAG, "Package was null!", new Throwable()); 7719 return; 7720 } 7721 destroyAppProfilesLeafLIF(pkg); 7722 destroyAppReferenceProfileLeafLIF(pkg, userId, true /* removeBaseMarker */); 7723 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7724 for (int i = 0; i < childCount; i++) { 7725 destroyAppProfilesLeafLIF(pkg.childPackages.get(i)); 7726 destroyAppReferenceProfileLeafLIF(pkg.childPackages.get(i), userId, 7727 true /* removeBaseMarker */); 7728 } 7729 } 7730 7731 private void destroyAppReferenceProfileLeafLIF(PackageParser.Package pkg, int userId, 7732 boolean removeBaseMarker) { 7733 if (pkg.isForwardLocked()) { 7734 return; 7735 } 7736 7737 for (String path : pkg.getAllCodePathsExcludingResourceOnly()) { 7738 try { 7739 path = PackageManagerServiceUtils.realpath(new File(path)); 7740 } catch (IOException e) { 7741 // TODO: Should we return early here ? 7742 Slog.w(TAG, "Failed to get canonical path", e); 7743 continue; 7744 } 7745 7746 final String useMarker = path.replace('/', '@'); 7747 for (int realUserId : resolveUserIds(userId)) { 7748 File profileDir = Environment.getDataProfilesDeForeignDexDirectory(realUserId); 7749 if (removeBaseMarker) { 7750 File foreignUseMark = new File(profileDir, useMarker); 7751 if (foreignUseMark.exists()) { 7752 if (!foreignUseMark.delete()) { 7753 Slog.w(TAG, "Unable to delete foreign user mark for package: " 7754 + pkg.packageName); 7755 } 7756 } 7757 } 7758 7759 File[] markers = profileDir.listFiles(); 7760 if (markers != null) { 7761 final String searchString = "@" + pkg.packageName + "@"; 7762 // We also delete all markers that contain the package name we're 7763 // uninstalling. These are associated with secondary dex-files belonging 7764 // to the package. Reconstructing the path of these dex files is messy 7765 // in general. 7766 for (File marker : markers) { 7767 if (marker.getName().indexOf(searchString) > 0) { 7768 if (!marker.delete()) { 7769 Slog.w(TAG, "Unable to delete foreign user mark for package: " 7770 + pkg.packageName); 7771 } 7772 } 7773 } 7774 } 7775 } 7776 } 7777 } 7778 7779 private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) { 7780 try { 7781 mInstaller.destroyAppProfiles(pkg.packageName); 7782 } catch (InstallerException e) { 7783 Slog.w(TAG, String.valueOf(e)); 7784 } 7785 } 7786 7787 private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) { 7788 if (pkg == null) { 7789 Slog.wtf(TAG, "Package was null!", new Throwable()); 7790 return; 7791 } 7792 clearAppProfilesLeafLIF(pkg); 7793 // We don't remove the base foreign use marker when clearing profiles because 7794 // we will rename it when the app is updated. Unlike the actual profile contents, 7795 // the foreign use marker is good across installs. 7796 destroyAppReferenceProfileLeafLIF(pkg, userId, false /* removeBaseMarker */); 7797 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7798 for (int i = 0; i < childCount; i++) { 7799 clearAppProfilesLeafLIF(pkg.childPackages.get(i)); 7800 } 7801 } 7802 7803 private void clearAppProfilesLeafLIF(PackageParser.Package pkg) { 7804 try { 7805 mInstaller.clearAppProfiles(pkg.packageName); 7806 } catch (InstallerException e) { 7807 Slog.w(TAG, String.valueOf(e)); 7808 } 7809 } 7810 7811 private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime, 7812 long lastUpdateTime) { 7813 // Set parent install/update time 7814 PackageSetting ps = (PackageSetting) pkg.mExtras; 7815 if (ps != null) { 7816 ps.firstInstallTime = firstInstallTime; 7817 ps.lastUpdateTime = lastUpdateTime; 7818 } 7819 // Set children install/update time 7820 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7821 for (int i = 0; i < childCount; i++) { 7822 PackageParser.Package childPkg = pkg.childPackages.get(i); 7823 ps = (PackageSetting) childPkg.mExtras; 7824 if (ps != null) { 7825 ps.firstInstallTime = firstInstallTime; 7826 ps.lastUpdateTime = lastUpdateTime; 7827 } 7828 } 7829 } 7830 7831 private void addSharedLibraryLPr(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file, 7832 PackageParser.Package changingLib) { 7833 if (file.path != null) { 7834 usesLibraryFiles.add(file.path); 7835 return; 7836 } 7837 PackageParser.Package p = mPackages.get(file.apk); 7838 if (changingLib != null && changingLib.packageName.equals(file.apk)) { 7839 // If we are doing this while in the middle of updating a library apk, 7840 // then we need to make sure to use that new apk for determining the 7841 // dependencies here. (We haven't yet finished committing the new apk 7842 // to the package manager state.) 7843 if (p == null || p.packageName.equals(changingLib.packageName)) { 7844 p = changingLib; 7845 } 7846 } 7847 if (p != null) { 7848 usesLibraryFiles.addAll(p.getAllCodePaths()); 7849 } 7850 } 7851 7852 private void updateSharedLibrariesLPr(PackageParser.Package pkg, 7853 PackageParser.Package changingLib) throws PackageManagerException { 7854 if (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null) { 7855 final ArraySet<String> usesLibraryFiles = new ArraySet<>(); 7856 int N = pkg.usesLibraries != null ? pkg.usesLibraries.size() : 0; 7857 for (int i=0; i<N; i++) { 7858 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesLibraries.get(i)); 7859 if (file == null) { 7860 throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY, 7861 "Package " + pkg.packageName + " requires unavailable shared library " 7862 + pkg.usesLibraries.get(i) + "; failing!"); 7863 } 7864 addSharedLibraryLPr(usesLibraryFiles, file, changingLib); 7865 } 7866 N = pkg.usesOptionalLibraries != null ? pkg.usesOptionalLibraries.size() : 0; 7867 for (int i=0; i<N; i++) { 7868 final SharedLibraryEntry file = mSharedLibraries.get(pkg.usesOptionalLibraries.get(i)); 7869 if (file == null) { 7870 Slog.w(TAG, "Package " + pkg.packageName 7871 + " desires unavailable shared library " 7872 + pkg.usesOptionalLibraries.get(i) + "; ignoring!"); 7873 } else { 7874 addSharedLibraryLPr(usesLibraryFiles, file, changingLib); 7875 } 7876 } 7877 N = usesLibraryFiles.size(); 7878 if (N > 0) { 7879 pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[N]); 7880 } else { 7881 pkg.usesLibraryFiles = null; 7882 } 7883 } 7884 } 7885 7886 private static boolean hasString(List<String> list, List<String> which) { 7887 if (list == null) { 7888 return false; 7889 } 7890 for (int i=list.size()-1; i>=0; i--) { 7891 for (int j=which.size()-1; j>=0; j--) { 7892 if (which.get(j).equals(list.get(i))) { 7893 return true; 7894 } 7895 } 7896 } 7897 return false; 7898 } 7899 7900 private void updateAllSharedLibrariesLPw() { 7901 for (PackageParser.Package pkg : mPackages.values()) { 7902 try { 7903 updateSharedLibrariesLPr(pkg, null); 7904 } catch (PackageManagerException e) { 7905 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 7906 } 7907 } 7908 } 7909 7910 private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw( 7911 PackageParser.Package changingPkg) { 7912 ArrayList<PackageParser.Package> res = null; 7913 for (PackageParser.Package pkg : mPackages.values()) { 7914 if (hasString(pkg.usesLibraries, changingPkg.libraryNames) 7915 || hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)) { 7916 if (res == null) { 7917 res = new ArrayList<PackageParser.Package>(); 7918 } 7919 res.add(pkg); 7920 try { 7921 updateSharedLibrariesLPr(pkg, changingPkg); 7922 } catch (PackageManagerException e) { 7923 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 7924 } 7925 } 7926 } 7927 return res; 7928 } 7929 7930 /** 7931 * Derive the value of the {@code cpuAbiOverride} based on the provided 7932 * value and an optional stored value from the package settings. 7933 */ 7934 private static String deriveAbiOverride(String abiOverride, PackageSetting settings) { 7935 String cpuAbiOverride = null; 7936 7937 if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) { 7938 cpuAbiOverride = null; 7939 } else if (abiOverride != null) { 7940 cpuAbiOverride = abiOverride; 7941 } else if (settings != null) { 7942 cpuAbiOverride = settings.cpuAbiOverrideString; 7943 } 7944 7945 return cpuAbiOverride; 7946 } 7947 7948 private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg, 7949 final int policyFlags, int scanFlags, long currentTime, UserHandle user) 7950 throws PackageManagerException { 7951 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage"); 7952 // If the package has children and this is the first dive in the function 7953 // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see 7954 // whether all packages (parent and children) would be successfully scanned 7955 // before the actual scan since scanning mutates internal state and we want 7956 // to atomically install the package and its children. 7957 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 7958 if (pkg.childPackages != null && pkg.childPackages.size() > 0) { 7959 scanFlags |= SCAN_CHECK_ONLY; 7960 } 7961 } else { 7962 scanFlags &= ~SCAN_CHECK_ONLY; 7963 } 7964 7965 final PackageParser.Package scannedPkg; 7966 try { 7967 // Scan the parent 7968 scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags, currentTime, user); 7969 // Scan the children 7970 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 7971 for (int i = 0; i < childCount; i++) { 7972 PackageParser.Package childPkg = pkg.childPackages.get(i); 7973 scanPackageLI(childPkg, policyFlags, 7974 scanFlags, currentTime, user); 7975 } 7976 } finally { 7977 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 7978 } 7979 7980 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 7981 return scanPackageTracedLI(pkg, policyFlags, scanFlags, currentTime, user); 7982 } 7983 7984 return scannedPkg; 7985 } 7986 7987 private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags, 7988 int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { 7989 boolean success = false; 7990 try { 7991 final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags, 7992 currentTime, user); 7993 success = true; 7994 return res; 7995 } finally { 7996 if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) { 7997 // DELETE_DATA_ON_FAILURES is only used by frozen paths 7998 destroyAppDataLIF(pkg, UserHandle.USER_ALL, 7999 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 8000 destroyAppProfilesLIF(pkg, UserHandle.USER_ALL); 8001 } 8002 } 8003 } 8004 8005 /** 8006 * Returns {@code true} if the given file contains code. Otherwise {@code false}. 8007 */ 8008 private static boolean apkHasCode(String fileName) { 8009 StrictJarFile jarFile = null; 8010 try { 8011 jarFile = new StrictJarFile(fileName, 8012 false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/); 8013 return jarFile.findEntry("classes.dex") != null; 8014 } catch (IOException ignore) { 8015 } finally { 8016 try { 8017 if (jarFile != null) { 8018 jarFile.close(); 8019 } 8020 } catch (IOException ignore) {} 8021 } 8022 return false; 8023 } 8024 8025 /** 8026 * Enforces code policy for the package. This ensures that if an APK has 8027 * declared hasCode="true" in its manifest that the APK actually contains 8028 * code. 8029 * 8030 * @throws PackageManagerException If bytecode could not be found when it should exist 8031 */ 8032 private static void assertCodePolicy(PackageParser.Package pkg) 8033 throws PackageManagerException { 8034 final boolean shouldHaveCode = 8035 (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0; 8036 if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) { 8037 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 8038 "Package " + pkg.baseCodePath + " code is missing"); 8039 } 8040 8041 if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) { 8042 for (int i = 0; i < pkg.splitCodePaths.length; i++) { 8043 final boolean splitShouldHaveCode = 8044 (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0; 8045 if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) { 8046 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 8047 "Package " + pkg.splitCodePaths[i] + " code is missing"); 8048 } 8049 } 8050 } 8051 } 8052 8053 private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, 8054 final int policyFlags, final int scanFlags, long currentTime, UserHandle user) 8055 throws PackageManagerException { 8056 if (DEBUG_PACKAGE_SCANNING) { 8057 if ((policyFlags & PackageParser.PARSE_CHATTY) != 0) 8058 Log.d(TAG, "Scanning package " + pkg.packageName); 8059 } 8060 8061 applyPolicy(pkg, policyFlags); 8062 8063 assertPackageIsValid(pkg, policyFlags); 8064 8065 // Initialize package source and resource directories 8066 final File scanFile = new File(pkg.codePath); 8067 final File destCodeFile = new File(pkg.applicationInfo.getCodePath()); 8068 final File destResourceFile = new File(pkg.applicationInfo.getResourcePath()); 8069 8070 SharedUserSetting suid = null; 8071 PackageSetting pkgSetting = null; 8072 8073 // Getting the package setting may have a side-effect, so if we 8074 // are only checking if scan would succeed, stash a copy of the 8075 // old setting to restore at the end. 8076 PackageSetting nonMutatedPs = null; 8077 8078 // writer 8079 synchronized (mPackages) { 8080 if (pkg.mSharedUserId != null) { 8081 // SIDE EFFECTS; may potentially allocate a new shared user 8082 suid = mSettings.getSharedUserLPw( 8083 pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/); 8084 if (DEBUG_PACKAGE_SCANNING) { 8085 if ((policyFlags & PackageParser.PARSE_CHATTY) != 0) 8086 Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId 8087 + "): packages=" + suid.packages); 8088 } 8089 } 8090 8091 // Check if we are renaming from an original package name. 8092 PackageSetting origPackage = null; 8093 String realName = null; 8094 if (pkg.mOriginalPackages != null) { 8095 // This package may need to be renamed to a previously 8096 // installed name. Let's check on that... 8097 final String renamed = mSettings.getRenamedPackageLPr(pkg.mRealPackage); 8098 if (pkg.mOriginalPackages.contains(renamed)) { 8099 // This package had originally been installed as the 8100 // original name, and we have already taken care of 8101 // transitioning to the new one. Just update the new 8102 // one to continue using the old name. 8103 realName = pkg.mRealPackage; 8104 if (!pkg.packageName.equals(renamed)) { 8105 // Callers into this function may have already taken 8106 // care of renaming the package; only do it here if 8107 // it is not already done. 8108 pkg.setPackageName(renamed); 8109 } 8110 } else { 8111 for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) { 8112 if ((origPackage = mSettings.getPackageLPr( 8113 pkg.mOriginalPackages.get(i))) != null) { 8114 // We do have the package already installed under its 8115 // original name... should we use it? 8116 if (!verifyPackageUpdateLPr(origPackage, pkg)) { 8117 // New package is not compatible with original. 8118 origPackage = null; 8119 continue; 8120 } else if (origPackage.sharedUser != null) { 8121 // Make sure uid is compatible between packages. 8122 if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) { 8123 Slog.w(TAG, "Unable to migrate data from " + origPackage.name 8124 + " to " + pkg.packageName + ": old uid " 8125 + origPackage.sharedUser.name 8126 + " differs from " + pkg.mSharedUserId); 8127 origPackage = null; 8128 continue; 8129 } 8130 // TODO: Add case when shared user id is added [b/28144775] 8131 } else { 8132 if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package " 8133 + pkg.packageName + " to old name " + origPackage.name); 8134 } 8135 break; 8136 } 8137 } 8138 } 8139 } 8140 8141 if (mTransferedPackages.contains(pkg.packageName)) { 8142 Slog.w(TAG, "Package " + pkg.packageName 8143 + " was transferred to another, but its .apk remains"); 8144 } 8145 8146 // See comments in nonMutatedPs declaration 8147 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 8148 PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName); 8149 if (foundPs != null) { 8150 nonMutatedPs = new PackageSetting(foundPs); 8151 } 8152 } 8153 8154 pkgSetting = mSettings.getPackageLPr(pkg.packageName); 8155 if (pkgSetting != null && pkgSetting.sharedUser != suid) { 8156 PackageManagerService.reportSettingsProblem(Log.WARN, 8157 "Package " + pkg.packageName + " shared user changed from " 8158 + (pkgSetting.sharedUser != null 8159 ? pkgSetting.sharedUser.name : "<nothing>") 8160 + " to " 8161 + (suid != null ? suid.name : "<nothing>") 8162 + "; replacing with new"); 8163 pkgSetting = null; 8164 } 8165 final PackageSetting oldPkgSetting = 8166 pkgSetting == null ? null : new PackageSetting(pkgSetting); 8167 final PackageSetting disabledPkgSetting = 8168 mSettings.getDisabledSystemPkgLPr(pkg.packageName); 8169 if (pkgSetting == null) { 8170 final String parentPackageName = (pkg.parentPackage != null) 8171 ? pkg.parentPackage.packageName : null; 8172 // REMOVE SharedUserSetting from method; update in a separate call 8173 pkgSetting = Settings.createNewSetting(pkg.packageName, origPackage, 8174 disabledPkgSetting, realName, suid, destCodeFile, destResourceFile, 8175 pkg.applicationInfo.nativeLibraryRootDir, pkg.applicationInfo.primaryCpuAbi, 8176 pkg.applicationInfo.secondaryCpuAbi, pkg.mVersionCode, 8177 pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, user, 8178 true /*allowInstall*/, parentPackageName, pkg.getChildPackageNames(), 8179 UserManagerService.getInstance()); 8180 // SIDE EFFECTS; updates system state; move elsewhere 8181 if (origPackage != null) { 8182 mSettings.addRenamedPackageLPw(pkg.packageName, origPackage.name); 8183 } 8184 mSettings.addUserToSettingLPw(pkgSetting); 8185 } else { 8186 // REMOVE SharedUserSetting from method; update in a separate call 8187 Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, suid, destCodeFile, 8188 pkg.applicationInfo.nativeLibraryDir, pkg.applicationInfo.primaryCpuAbi, 8189 pkg.applicationInfo.secondaryCpuAbi, pkg.applicationInfo.flags, 8190 pkg.applicationInfo.privateFlags, pkg.getChildPackageNames(), 8191 UserManagerService.getInstance()); 8192 } 8193 // SIDE EFFECTS; persists system state to files on disk; move elsewhere 8194 mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting); 8195 8196 // SIDE EFFECTS; modifies system state; move elsewhere 8197 if (pkgSetting.origPackage != null) { 8198 // If we are first transitioning from an original package, 8199 // fix up the new package's name now. We need to do this after 8200 // looking up the package under its new name, so getPackageLP 8201 // can take care of fiddling things correctly. 8202 pkg.setPackageName(origPackage.name); 8203 8204 // File a report about this. 8205 String msg = "New package " + pkgSetting.realName 8206 + " renamed to replace old package " + pkgSetting.name; 8207 reportSettingsProblem(Log.WARN, msg); 8208 8209 // Make a note of it. 8210 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 8211 mTransferedPackages.add(origPackage.name); 8212 } 8213 8214 // No longer need to retain this. 8215 pkgSetting.origPackage = null; 8216 } 8217 8218 // SIDE EFFECTS; modifies system state; move elsewhere 8219 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) { 8220 // Make a note of it. 8221 mTransferedPackages.add(pkg.packageName); 8222 } 8223 8224 if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) { 8225 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; 8226 } 8227 8228 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 8229 // Check all shared libraries and map to their actual file path. 8230 // We only do this here for apps not on a system dir, because those 8231 // are the only ones that can fail an install due to this. We 8232 // will take care of the system apps by updating all of their 8233 // library paths after the scan is done. 8234 updateSharedLibrariesLPr(pkg, null); 8235 } 8236 8237 if (mFoundPolicyFile) { 8238 SELinuxMMAC.assignSeinfoValue(pkg); 8239 } 8240 8241 pkg.applicationInfo.uid = pkgSetting.appId; 8242 pkg.mExtras = pkgSetting; 8243 if (shouldCheckUpgradeKeySetLP(pkgSetting, scanFlags)) { 8244 if (checkUpgradeKeySetLP(pkgSetting, pkg)) { 8245 // We just determined the app is signed correctly, so bring 8246 // over the latest parsed certs. 8247 pkgSetting.signatures.mSignatures = pkg.mSignatures; 8248 } else { 8249 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 8250 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 8251 "Package " + pkg.packageName + " upgrade keys do not match the " 8252 + "previously installed version"); 8253 } else { 8254 pkgSetting.signatures.mSignatures = pkg.mSignatures; 8255 String msg = "System package " + pkg.packageName 8256 + " signature changed; retaining data."; 8257 reportSettingsProblem(Log.WARN, msg); 8258 } 8259 } 8260 } else { 8261 try { 8262 // SIDE EFFECTS; compareSignaturesCompat() changes KeysetManagerService 8263 verifySignaturesLP(pkgSetting, pkg); 8264 // We just determined the app is signed correctly, so bring 8265 // over the latest parsed certs. 8266 pkgSetting.signatures.mSignatures = pkg.mSignatures; 8267 } catch (PackageManagerException e) { 8268 if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { 8269 throw e; 8270 } 8271 // The signature has changed, but this package is in the system 8272 // image... let's recover! 8273 pkgSetting.signatures.mSignatures = pkg.mSignatures; 8274 // However... if this package is part of a shared user, but it 8275 // doesn't match the signature of the shared user, let's fail. 8276 // What this means is that you can't change the signatures 8277 // associated with an overall shared user, which doesn't seem all 8278 // that unreasonable. 8279 if (pkgSetting.sharedUser != null) { 8280 if (compareSignatures(pkgSetting.sharedUser.signatures.mSignatures, 8281 pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) { 8282 throw new PackageManagerException( 8283 INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES, 8284 "Signature mismatch for shared user: " 8285 + pkgSetting.sharedUser); 8286 } 8287 } 8288 // File a report about this. 8289 String msg = "System package " + pkg.packageName 8290 + " signature changed; retaining data."; 8291 reportSettingsProblem(Log.WARN, msg); 8292 } 8293 } 8294 8295 if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) { 8296 // This package wants to adopt ownership of permissions from 8297 // another package. 8298 for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) { 8299 final String origName = pkg.mAdoptPermissions.get(i); 8300 final PackageSetting orig = mSettings.getPackageLPr(origName); 8301 if (orig != null) { 8302 if (verifyPackageUpdateLPr(orig, pkg)) { 8303 Slog.i(TAG, "Adopting permissions from " + origName + " to " 8304 + pkg.packageName); 8305 // SIDE EFFECTS; updates permissions system state; move elsewhere 8306 mSettings.transferPermissionsLPw(origName, pkg.packageName); 8307 } 8308 } 8309 } 8310 } 8311 } 8312 8313 pkg.applicationInfo.processName = fixProcessName( 8314 pkg.applicationInfo.packageName, 8315 pkg.applicationInfo.processName); 8316 8317 if (pkg != mPlatformPackage) { 8318 // Get all of our default paths setup 8319 pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM); 8320 } 8321 8322 final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting); 8323 8324 if ((scanFlags & SCAN_NEW_INSTALL) == 0) { 8325 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi"); 8326 derivePackageAbi( 8327 pkg, scanFile, cpuAbiOverride, true /*extractLibs*/, mAppLib32InstallDir); 8328 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 8329 8330 // Some system apps still use directory structure for native libraries 8331 // in which case we might end up not detecting abi solely based on apk 8332 // structure. Try to detect abi based on directory structure. 8333 if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() && 8334 pkg.applicationInfo.primaryCpuAbi == null) { 8335 setBundledAppAbisAndRoots(pkg, pkgSetting); 8336 setNativeLibraryPaths(pkg, mAppLib32InstallDir); 8337 } 8338 } else { 8339 if ((scanFlags & SCAN_MOVE) != 0) { 8340 // We haven't run dex-opt for this move (since we've moved the compiled output too) 8341 // but we already have this packages package info in the PackageSetting. We just 8342 // use that and derive the native library path based on the new codepath. 8343 pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString; 8344 pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString; 8345 } 8346 8347 // Set native library paths again. For moves, the path will be updated based on the 8348 // ABIs we've determined above. For non-moves, the path will be updated based on the 8349 // ABIs we determined during compilation, but the path will depend on the final 8350 // package path (after the rename away from the stage path). 8351 setNativeLibraryPaths(pkg, mAppLib32InstallDir); 8352 } 8353 8354 // This is a special case for the "system" package, where the ABI is 8355 // dictated by the zygote configuration (and init.rc). We should keep track 8356 // of this ABI so that we can deal with "normal" applications that run under 8357 // the same UID correctly. 8358 if (mPlatformPackage == pkg) { 8359 pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ? 8360 Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]; 8361 } 8362 8363 // If there's a mismatch between the abi-override in the package setting 8364 // and the abiOverride specified for the install. Warn about this because we 8365 // would've already compiled the app without taking the package setting into 8366 // account. 8367 if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) { 8368 if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) { 8369 Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride + 8370 " for package " + pkg.packageName); 8371 } 8372 } 8373 8374 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 8375 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 8376 pkgSetting.cpuAbiOverrideString = cpuAbiOverride; 8377 8378 // Copy the derived override back to the parsed package, so that we can 8379 // update the package settings accordingly. 8380 pkg.cpuAbiOverride = cpuAbiOverride; 8381 8382 if (DEBUG_ABI_SELECTION) { 8383 Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName 8384 + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa=" 8385 + pkg.applicationInfo.nativeLibraryRootRequiresIsa); 8386 } 8387 8388 // Push the derived path down into PackageSettings so we know what to 8389 // clean up at uninstall time. 8390 pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir; 8391 8392 if (DEBUG_ABI_SELECTION) { 8393 Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" + 8394 " primary=" + pkg.applicationInfo.primaryCpuAbi + 8395 " secondary=" + pkg.applicationInfo.secondaryCpuAbi); 8396 } 8397 8398 // SIDE EFFECTS; removes DEX files from disk; move elsewhere 8399 if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) { 8400 // We don't do this here during boot because we can do it all 8401 // at once after scanning all existing packages. 8402 // 8403 // We also do this *before* we perform dexopt on this package, so that 8404 // we can avoid redundant dexopts, and also to make sure we've got the 8405 // code and package path correct. 8406 adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg); 8407 } 8408 8409 if (mFactoryTest && pkg.requestedPermissions.contains( 8410 android.Manifest.permission.FACTORY_TEST)) { 8411 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST; 8412 } 8413 8414 if (isSystemApp(pkg)) { 8415 pkgSetting.isOrphaned = true; 8416 } 8417 8418 // Take care of first install / last update times. 8419 final long scanFileTime = getLastModifiedTime(pkg, scanFile); 8420 if (currentTime != 0) { 8421 if (pkgSetting.firstInstallTime == 0) { 8422 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime; 8423 } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) { 8424 pkgSetting.lastUpdateTime = currentTime; 8425 } 8426 } else if (pkgSetting.firstInstallTime == 0) { 8427 // We need *something*. Take time time stamp of the file. 8428 pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime; 8429 } else if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) { 8430 if (scanFileTime != pkgSetting.timeStamp) { 8431 // A package on the system image has changed; consider this 8432 // to be an update. 8433 pkgSetting.lastUpdateTime = scanFileTime; 8434 } 8435 } 8436 pkgSetting.setTimeStamp(scanFileTime); 8437 8438 if ((scanFlags & SCAN_CHECK_ONLY) != 0) { 8439 if (nonMutatedPs != null) { 8440 synchronized (mPackages) { 8441 mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs); 8442 } 8443 } 8444 } else { 8445 // Modify state for the given package setting 8446 commitPackageSettings(pkg, pkgSetting, user, scanFlags, 8447 (policyFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/); 8448 } 8449 return pkg; 8450 } 8451 8452 /** 8453 * Applies policy to the parsed package based upon the given policy flags. 8454 * Ensures the package is in a good state. 8455 * <p> 8456 * Implementation detail: This method must NOT have any side effect. It would 8457 * ideally be static, but, it requires locks to read system state. 8458 */ 8459 private void applyPolicy(PackageParser.Package pkg, int policyFlags) { 8460 if ((policyFlags&PackageParser.PARSE_IS_SYSTEM) != 0) { 8461 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; 8462 if (pkg.applicationInfo.isDirectBootAware()) { 8463 // we're direct boot aware; set for all components 8464 for (PackageParser.Service s : pkg.services) { 8465 s.info.encryptionAware = s.info.directBootAware = true; 8466 } 8467 for (PackageParser.Provider p : pkg.providers) { 8468 p.info.encryptionAware = p.info.directBootAware = true; 8469 } 8470 for (PackageParser.Activity a : pkg.activities) { 8471 a.info.encryptionAware = a.info.directBootAware = true; 8472 } 8473 for (PackageParser.Activity r : pkg.receivers) { 8474 r.info.encryptionAware = r.info.directBootAware = true; 8475 } 8476 } 8477 } else { 8478 // Only allow system apps to be flagged as core apps. 8479 pkg.coreApp = false; 8480 // clear flags not applicable to regular apps 8481 pkg.applicationInfo.privateFlags &= 8482 ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE; 8483 pkg.applicationInfo.privateFlags &= 8484 ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE; 8485 } 8486 pkg.mTrustedOverlay = (policyFlags&PackageParser.PARSE_TRUSTED_OVERLAY) != 0; 8487 8488 if ((policyFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) { 8489 pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; 8490 } 8491 8492 if (!isSystemApp(pkg)) { 8493 // Only system apps can use these features. 8494 pkg.mOriginalPackages = null; 8495 pkg.mRealPackage = null; 8496 pkg.mAdoptPermissions = null; 8497 } 8498 } 8499 8500 /** 8501 * Asserts the parsed package is valid according to teh given policy. If the 8502 * package is invalid, for whatever reason, throws {@link PackgeManagerException}. 8503 * <p> 8504 * Implementation detail: This method must NOT have any side effects. It would 8505 * ideally be static, but, it requires locks to read system state. 8506 * 8507 * @throws PackageManagerException If the package fails any of the validation checks 8508 */ 8509 private void assertPackageIsValid(PackageParser.Package pkg, int policyFlags) 8510 throws PackageManagerException { 8511 if ((policyFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) { 8512 assertCodePolicy(pkg); 8513 } 8514 8515 if (pkg.applicationInfo.getCodePath() == null || 8516 pkg.applicationInfo.getResourcePath() == null) { 8517 // Bail out. The resource and code paths haven't been set. 8518 throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, 8519 "Code and resource paths haven't been set correctly"); 8520 } 8521 8522 // Make sure we're not adding any bogus keyset info 8523 KeySetManagerService ksms = mSettings.mKeySetManagerService; 8524 ksms.assertScannedPackageValid(pkg); 8525 8526 synchronized (mPackages) { 8527 // The special "android" package can only be defined once 8528 if (pkg.packageName.equals("android")) { 8529 if (mAndroidApplication != null) { 8530 Slog.w(TAG, "*************************************************"); 8531 Slog.w(TAG, "Core android package being redefined. Skipping."); 8532 Slog.w(TAG, " codePath=" + pkg.codePath); 8533 Slog.w(TAG, "*************************************************"); 8534 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 8535 "Core android package being redefined. Skipping."); 8536 } 8537 } 8538 8539 // A package name must be unique; don't allow duplicates 8540 if (mPackages.containsKey(pkg.packageName) 8541 || mSharedLibraries.containsKey(pkg.packageName)) { 8542 throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE, 8543 "Application package " + pkg.packageName 8544 + " already installed. Skipping duplicate."); 8545 } 8546 8547 // Only privileged apps and updated privileged apps can add child packages. 8548 if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) { 8549 if ((policyFlags & PARSE_IS_PRIVILEGED) == 0) { 8550 throw new PackageManagerException("Only privileged apps can add child " 8551 + "packages. Ignoring package " + pkg.packageName); 8552 } 8553 final int childCount = pkg.childPackages.size(); 8554 for (int i = 0; i < childCount; i++) { 8555 PackageParser.Package childPkg = pkg.childPackages.get(i); 8556 if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName, 8557 childPkg.packageName)) { 8558 throw new PackageManagerException("Can't override child of " 8559 + "another disabled app. Ignoring package " + pkg.packageName); 8560 } 8561 } 8562 } 8563 8564 // If we're only installing presumed-existing packages, require that the 8565 // scanned APK is both already known and at the path previously established 8566 // for it. Previously unknown packages we pick up normally, but if we have an 8567 // a priori expectation about this package's install presence, enforce it. 8568 // With a singular exception for new system packages. When an OTA contains 8569 // a new system package, we allow the codepath to change from a system location 8570 // to the user-installed location. If we don't allow this change, any newer, 8571 // user-installed version of the application will be ignored. 8572 if ((policyFlags & SCAN_REQUIRE_KNOWN) != 0) { 8573 if (mExpectingBetter.containsKey(pkg.packageName)) { 8574 logCriticalInfo(Log.WARN, 8575 "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName); 8576 } else { 8577 PackageSetting known = mSettings.getPackageLPr(pkg.packageName); 8578 if (known != null) { 8579 if (DEBUG_PACKAGE_SCANNING) { 8580 Log.d(TAG, "Examining " + pkg.codePath 8581 + " and requiring known paths " + known.codePathString 8582 + " & " + known.resourcePathString); 8583 } 8584 if (!pkg.applicationInfo.getCodePath().equals(known.codePathString) 8585 || !pkg.applicationInfo.getResourcePath().equals( 8586 known.resourcePathString)) { 8587 throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED, 8588 "Application package " + pkg.packageName 8589 + " found at " + pkg.applicationInfo.getCodePath() 8590 + " but expected at " + known.codePathString 8591 + "; ignoring."); 8592 } 8593 } 8594 } 8595 } 8596 8597 // Verify that this new package doesn't have any content providers 8598 // that conflict with existing packages. Only do this if the 8599 // package isn't already installed, since we don't want to break 8600 // things that are installed. 8601 if ((policyFlags & SCAN_NEW_INSTALL) != 0) { 8602 final int N = pkg.providers.size(); 8603 int i; 8604 for (i=0; i<N; i++) { 8605 PackageParser.Provider p = pkg.providers.get(i); 8606 if (p.info.authority != null) { 8607 String names[] = p.info.authority.split(";"); 8608 for (int j = 0; j < names.length; j++) { 8609 if (mProvidersByAuthority.containsKey(names[j])) { 8610 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 8611 final String otherPackageName = 8612 ((other != null && other.getComponentName() != null) ? 8613 other.getComponentName().getPackageName() : "?"); 8614 throw new PackageManagerException( 8615 INSTALL_FAILED_CONFLICTING_PROVIDER, 8616 "Can't install because provider name " + names[j] 8617 + " (in package " + pkg.applicationInfo.packageName 8618 + ") is already used by " + otherPackageName); 8619 } 8620 } 8621 } 8622 } 8623 } 8624 } 8625 } 8626 8627 /** 8628 * Adds a scanned package to the system. When this method is finished, the package will 8629 * be available for query, resolution, etc... 8630 */ 8631 private void commitPackageSettings(PackageParser.Package pkg, PackageSetting pkgSetting, 8632 UserHandle user, int scanFlags, boolean chatty) throws PackageManagerException { 8633 final String pkgName = pkg.packageName; 8634 if (mCustomResolverComponentName != null && 8635 mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) { 8636 setUpCustomResolverActivity(pkg); 8637 } 8638 8639 if (pkg.packageName.equals("android")) { 8640 synchronized (mPackages) { 8641 if ((scanFlags & SCAN_CHECK_ONLY) == 0) { 8642 // Set up information for our fall-back user intent resolution activity. 8643 mPlatformPackage = pkg; 8644 pkg.mVersionCode = mSdkVersion; 8645 mAndroidApplication = pkg.applicationInfo; 8646 8647 if (!mResolverReplaced) { 8648 mResolveActivity.applicationInfo = mAndroidApplication; 8649 mResolveActivity.name = ResolverActivity.class.getName(); 8650 mResolveActivity.packageName = mAndroidApplication.packageName; 8651 mResolveActivity.processName = "system:ui"; 8652 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 8653 mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER; 8654 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS; 8655 mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert; 8656 mResolveActivity.exported = true; 8657 mResolveActivity.enabled = true; 8658 mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE; 8659 mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE 8660 | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE 8661 | ActivityInfo.CONFIG_SCREEN_LAYOUT 8662 | ActivityInfo.CONFIG_ORIENTATION 8663 | ActivityInfo.CONFIG_KEYBOARD 8664 | ActivityInfo.CONFIG_KEYBOARD_HIDDEN; 8665 mResolveInfo.activityInfo = mResolveActivity; 8666 mResolveInfo.priority = 0; 8667 mResolveInfo.preferredOrder = 0; 8668 mResolveInfo.match = 0; 8669 mResolveComponentName = new ComponentName( 8670 mAndroidApplication.packageName, mResolveActivity.name); 8671 } 8672 } 8673 } 8674 } 8675 8676 ArrayList<PackageParser.Package> clientLibPkgs = null; 8677 // writer 8678 synchronized (mPackages) { 8679 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 8680 // Only system apps can add new shared libraries. 8681 if (pkg.libraryNames != null) { 8682 for (int i=0; i<pkg.libraryNames.size(); i++) { 8683 String name = pkg.libraryNames.get(i); 8684 boolean allowed = false; 8685 if (pkg.isUpdatedSystemApp()) { 8686 // New library entries can only be added through the 8687 // system image. This is important to get rid of a lot 8688 // of nasty edge cases: for example if we allowed a non- 8689 // system update of the app to add a library, then uninstalling 8690 // the update would make the library go away, and assumptions 8691 // we made such as through app install filtering would now 8692 // have allowed apps on the device which aren't compatible 8693 // with it. Better to just have the restriction here, be 8694 // conservative, and create many fewer cases that can negatively 8695 // impact the user experience. 8696 final PackageSetting sysPs = mSettings 8697 .getDisabledSystemPkgLPr(pkg.packageName); 8698 if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) { 8699 for (int j=0; j<sysPs.pkg.libraryNames.size(); j++) { 8700 if (name.equals(sysPs.pkg.libraryNames.get(j))) { 8701 allowed = true; 8702 break; 8703 } 8704 } 8705 } 8706 } else { 8707 allowed = true; 8708 } 8709 if (allowed) { 8710 if (!mSharedLibraries.containsKey(name)) { 8711 mSharedLibraries.put(name, new SharedLibraryEntry(null, pkg.packageName)); 8712 } else if (!name.equals(pkg.packageName)) { 8713 Slog.w(TAG, "Package " + pkg.packageName + " library " 8714 + name + " already exists; skipping"); 8715 } 8716 } else { 8717 Slog.w(TAG, "Package " + pkg.packageName + " declares lib " 8718 + name + " that is not declared on system image; skipping"); 8719 } 8720 } 8721 if ((scanFlags & SCAN_BOOTING) == 0) { 8722 // If we are not booting, we need to update any applications 8723 // that are clients of our shared library. If we are booting, 8724 // this will all be done once the scan is complete. 8725 clientLibPkgs = updateAllSharedLibrariesLPw(pkg); 8726 } 8727 } 8728 } 8729 } 8730 8731 if ((scanFlags & SCAN_BOOTING) != 0) { 8732 // No apps can run during boot scan, so they don't need to be frozen 8733 } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) { 8734 // Caller asked to not kill app, so it's probably not frozen 8735 } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) { 8736 // Caller asked us to ignore frozen check for some reason; they 8737 // probably didn't know the package name 8738 } else { 8739 // We're doing major surgery on this package, so it better be frozen 8740 // right now to keep it from launching 8741 checkPackageFrozen(pkgName); 8742 } 8743 8744 // Also need to kill any apps that are dependent on the library. 8745 if (clientLibPkgs != null) { 8746 for (int i=0; i<clientLibPkgs.size(); i++) { 8747 PackageParser.Package clientPkg = clientLibPkgs.get(i); 8748 killApplication(clientPkg.applicationInfo.packageName, 8749 clientPkg.applicationInfo.uid, "update lib"); 8750 } 8751 } 8752 8753 // writer 8754 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 8755 8756 boolean createIdmapFailed = false; 8757 synchronized (mPackages) { 8758 // We don't expect installation to fail beyond this point 8759 8760 if (pkgSetting.pkg != null) { 8761 // Note that |user| might be null during the initial boot scan. If a codePath 8762 // for an app has changed during a boot scan, it's due to an app update that's 8763 // part of the system partition and marker changes must be applied to all users. 8764 final int userId = ((user != null) ? user : UserHandle.ALL).getIdentifier(); 8765 final int[] userIds = resolveUserIds(userId); 8766 maybeRenameForeignDexMarkers(pkgSetting.pkg, pkg, userIds); 8767 } 8768 8769 // Add the new setting to mSettings 8770 mSettings.insertPackageSettingLPw(pkgSetting, pkg); 8771 // Add the new setting to mPackages 8772 mPackages.put(pkg.applicationInfo.packageName, pkg); 8773 // Make sure we don't accidentally delete its data. 8774 final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator(); 8775 while (iter.hasNext()) { 8776 PackageCleanItem item = iter.next(); 8777 if (pkgName.equals(item.packageName)) { 8778 iter.remove(); 8779 } 8780 } 8781 8782 // Add the package's KeySets to the global KeySetManagerService 8783 KeySetManagerService ksms = mSettings.mKeySetManagerService; 8784 ksms.addScannedPackageLPw(pkg); 8785 8786 int N = pkg.providers.size(); 8787 StringBuilder r = null; 8788 int i; 8789 for (i=0; i<N; i++) { 8790 PackageParser.Provider p = pkg.providers.get(i); 8791 p.info.processName = fixProcessName(pkg.applicationInfo.processName, 8792 p.info.processName); 8793 mProviders.addProvider(p); 8794 p.syncable = p.info.isSyncable; 8795 if (p.info.authority != null) { 8796 String names[] = p.info.authority.split(";"); 8797 p.info.authority = null; 8798 for (int j = 0; j < names.length; j++) { 8799 if (j == 1 && p.syncable) { 8800 // We only want the first authority for a provider to possibly be 8801 // syncable, so if we already added this provider using a different 8802 // authority clear the syncable flag. We copy the provider before 8803 // changing it because the mProviders object contains a reference 8804 // to a provider that we don't want to change. 8805 // Only do this for the second authority since the resulting provider 8806 // object can be the same for all future authorities for this provider. 8807 p = new PackageParser.Provider(p); 8808 p.syncable = false; 8809 } 8810 if (!mProvidersByAuthority.containsKey(names[j])) { 8811 mProvidersByAuthority.put(names[j], p); 8812 if (p.info.authority == null) { 8813 p.info.authority = names[j]; 8814 } else { 8815 p.info.authority = p.info.authority + ";" + names[j]; 8816 } 8817 if (DEBUG_PACKAGE_SCANNING) { 8818 if (chatty) 8819 Log.d(TAG, "Registered content provider: " + names[j] 8820 + ", className = " + p.info.name + ", isSyncable = " 8821 + p.info.isSyncable); 8822 } 8823 } else { 8824 PackageParser.Provider other = mProvidersByAuthority.get(names[j]); 8825 Slog.w(TAG, "Skipping provider name " + names[j] + 8826 " (in package " + pkg.applicationInfo.packageName + 8827 "): name already used by " 8828 + ((other != null && other.getComponentName() != null) 8829 ? other.getComponentName().getPackageName() : "?")); 8830 } 8831 } 8832 } 8833 if (chatty) { 8834 if (r == null) { 8835 r = new StringBuilder(256); 8836 } else { 8837 r.append(' '); 8838 } 8839 r.append(p.info.name); 8840 } 8841 } 8842 if (r != null) { 8843 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Providers: " + r); 8844 } 8845 8846 N = pkg.services.size(); 8847 r = null; 8848 for (i=0; i<N; i++) { 8849 PackageParser.Service s = pkg.services.get(i); 8850 s.info.processName = fixProcessName(pkg.applicationInfo.processName, 8851 s.info.processName); 8852 mServices.addService(s); 8853 if (chatty) { 8854 if (r == null) { 8855 r = new StringBuilder(256); 8856 } else { 8857 r.append(' '); 8858 } 8859 r.append(s.info.name); 8860 } 8861 } 8862 if (r != null) { 8863 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Services: " + r); 8864 } 8865 8866 N = pkg.receivers.size(); 8867 r = null; 8868 for (i=0; i<N; i++) { 8869 PackageParser.Activity a = pkg.receivers.get(i); 8870 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 8871 a.info.processName); 8872 mReceivers.addActivity(a, "receiver"); 8873 if (chatty) { 8874 if (r == null) { 8875 r = new StringBuilder(256); 8876 } else { 8877 r.append(' '); 8878 } 8879 r.append(a.info.name); 8880 } 8881 } 8882 if (r != null) { 8883 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Receivers: " + r); 8884 } 8885 8886 N = pkg.activities.size(); 8887 r = null; 8888 for (i=0; i<N; i++) { 8889 PackageParser.Activity a = pkg.activities.get(i); 8890 a.info.processName = fixProcessName(pkg.applicationInfo.processName, 8891 a.info.processName); 8892 mActivities.addActivity(a, "activity"); 8893 if (chatty) { 8894 if (r == null) { 8895 r = new StringBuilder(256); 8896 } else { 8897 r.append(' '); 8898 } 8899 r.append(a.info.name); 8900 } 8901 } 8902 if (r != null) { 8903 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Activities: " + r); 8904 } 8905 8906 N = pkg.permissionGroups.size(); 8907 r = null; 8908 for (i=0; i<N; i++) { 8909 PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i); 8910 PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name); 8911 final String curPackageName = cur == null ? null : cur.info.packageName; 8912 final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName); 8913 if (cur == null || isPackageUpdate) { 8914 mPermissionGroups.put(pg.info.name, pg); 8915 if (chatty) { 8916 if (r == null) { 8917 r = new StringBuilder(256); 8918 } else { 8919 r.append(' '); 8920 } 8921 if (isPackageUpdate) { 8922 r.append("UPD:"); 8923 } 8924 r.append(pg.info.name); 8925 } 8926 } else { 8927 Slog.w(TAG, "Permission group " + pg.info.name + " from package " 8928 + pg.info.packageName + " ignored: original from " 8929 + cur.info.packageName); 8930 if (chatty) { 8931 if (r == null) { 8932 r = new StringBuilder(256); 8933 } else { 8934 r.append(' '); 8935 } 8936 r.append("DUP:"); 8937 r.append(pg.info.name); 8938 } 8939 } 8940 } 8941 if (r != null) { 8942 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permission Groups: " + r); 8943 } 8944 8945 N = pkg.permissions.size(); 8946 r = null; 8947 for (i=0; i<N; i++) { 8948 PackageParser.Permission p = pkg.permissions.get(i); 8949 8950 // Assume by default that we did not install this permission into the system. 8951 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED; 8952 8953 // Now that permission groups have a special meaning, we ignore permission 8954 // groups for legacy apps to prevent unexpected behavior. In particular, 8955 // permissions for one app being granted to someone just becase they happen 8956 // to be in a group defined by another app (before this had no implications). 8957 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) { 8958 p.group = mPermissionGroups.get(p.info.group); 8959 // Warn for a permission in an unknown group. 8960 if (p.info.group != null && p.group == null) { 8961 Slog.w(TAG, "Permission " + p.info.name + " from package " 8962 + p.info.packageName + " in an unknown group " + p.info.group); 8963 } 8964 } 8965 8966 ArrayMap<String, BasePermission> permissionMap = 8967 p.tree ? mSettings.mPermissionTrees 8968 : mSettings.mPermissions; 8969 BasePermission bp = permissionMap.get(p.info.name); 8970 8971 // Allow system apps to redefine non-system permissions 8972 if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) { 8973 final boolean currentOwnerIsSystem = (bp.perm != null 8974 && isSystemApp(bp.perm.owner)); 8975 if (isSystemApp(p.owner)) { 8976 if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) { 8977 // It's a built-in permission and no owner, take ownership now 8978 bp.packageSetting = pkgSetting; 8979 bp.perm = p; 8980 bp.uid = pkg.applicationInfo.uid; 8981 bp.sourcePackage = p.info.packageName; 8982 p.info.flags |= PermissionInfo.FLAG_INSTALLED; 8983 } else if (!currentOwnerIsSystem) { 8984 String msg = "New decl " + p.owner + " of permission " 8985 + p.info.name + " is system; overriding " + bp.sourcePackage; 8986 reportSettingsProblem(Log.WARN, msg); 8987 bp = null; 8988 } 8989 } 8990 } 8991 8992 if (bp == null) { 8993 bp = new BasePermission(p.info.name, p.info.packageName, 8994 BasePermission.TYPE_NORMAL); 8995 permissionMap.put(p.info.name, bp); 8996 } 8997 8998 if (bp.perm == null) { 8999 if (bp.sourcePackage == null 9000 || bp.sourcePackage.equals(p.info.packageName)) { 9001 BasePermission tree = findPermissionTreeLP(p.info.name); 9002 if (tree == null 9003 || tree.sourcePackage.equals(p.info.packageName)) { 9004 bp.packageSetting = pkgSetting; 9005 bp.perm = p; 9006 bp.uid = pkg.applicationInfo.uid; 9007 bp.sourcePackage = p.info.packageName; 9008 p.info.flags |= PermissionInfo.FLAG_INSTALLED; 9009 if (chatty) { 9010 if (r == null) { 9011 r = new StringBuilder(256); 9012 } else { 9013 r.append(' '); 9014 } 9015 r.append(p.info.name); 9016 } 9017 } else { 9018 Slog.w(TAG, "Permission " + p.info.name + " from package " 9019 + p.info.packageName + " ignored: base tree " 9020 + tree.name + " is from package " 9021 + tree.sourcePackage); 9022 } 9023 } else { 9024 Slog.w(TAG, "Permission " + p.info.name + " from package " 9025 + p.info.packageName + " ignored: original from " 9026 + bp.sourcePackage); 9027 } 9028 } else if (chatty) { 9029 if (r == null) { 9030 r = new StringBuilder(256); 9031 } else { 9032 r.append(' '); 9033 } 9034 r.append("DUP:"); 9035 r.append(p.info.name); 9036 } 9037 if (bp.perm == p) { 9038 bp.protectionLevel = p.info.protectionLevel; 9039 } 9040 } 9041 9042 if (r != null) { 9043 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Permissions: " + r); 9044 } 9045 9046 N = pkg.instrumentation.size(); 9047 r = null; 9048 for (i=0; i<N; i++) { 9049 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 9050 a.info.packageName = pkg.applicationInfo.packageName; 9051 a.info.sourceDir = pkg.applicationInfo.sourceDir; 9052 a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir; 9053 a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs; 9054 a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs; 9055 a.info.dataDir = pkg.applicationInfo.dataDir; 9056 a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir; 9057 a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir; 9058 a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir; 9059 a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir; 9060 mInstrumentation.put(a.getComponentName(), a); 9061 if (chatty) { 9062 if (r == null) { 9063 r = new StringBuilder(256); 9064 } else { 9065 r.append(' '); 9066 } 9067 r.append(a.info.name); 9068 } 9069 } 9070 if (r != null) { 9071 if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r); 9072 } 9073 9074 if (pkg.protectedBroadcasts != null) { 9075 N = pkg.protectedBroadcasts.size(); 9076 for (i=0; i<N; i++) { 9077 mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i)); 9078 } 9079 } 9080 9081 // Create idmap files for pairs of (packages, overlay packages). 9082 // Note: "android", ie framework-res.apk, is handled by native layers. 9083 if (pkg.mOverlayTarget != null) { 9084 // This is an overlay package. 9085 if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) { 9086 if (!mOverlays.containsKey(pkg.mOverlayTarget)) { 9087 mOverlays.put(pkg.mOverlayTarget, 9088 new ArrayMap<String, PackageParser.Package>()); 9089 } 9090 ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget); 9091 map.put(pkg.packageName, pkg); 9092 PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget); 9093 if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) { 9094 createIdmapFailed = true; 9095 } 9096 } 9097 } else if (mOverlays.containsKey(pkg.packageName) && 9098 !pkg.packageName.equals("android")) { 9099 // This is a regular package, with one or more known overlay packages. 9100 createIdmapsForPackageLI(pkg); 9101 } 9102 } 9103 9104 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 9105 9106 if (createIdmapFailed) { 9107 throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 9108 "scanPackageLI failed to createIdmap"); 9109 } 9110 } 9111 9112 private static void maybeRenameForeignDexMarkers(PackageParser.Package existing, 9113 PackageParser.Package update, int[] userIds) { 9114 if (existing.applicationInfo == null || update.applicationInfo == null) { 9115 // This isn't due to an app installation. 9116 return; 9117 } 9118 9119 final File oldCodePath = new File(existing.applicationInfo.getCodePath()); 9120 final File newCodePath = new File(update.applicationInfo.getCodePath()); 9121 9122 // The codePath hasn't changed, so there's nothing for us to do. 9123 if (Objects.equals(oldCodePath, newCodePath)) { 9124 return; 9125 } 9126 9127 File canonicalNewCodePath; 9128 try { 9129 canonicalNewCodePath = new File(PackageManagerServiceUtils.realpath(newCodePath)); 9130 } catch (IOException e) { 9131 Slog.w(TAG, "Failed to get canonical path.", e); 9132 return; 9133 } 9134 9135 // This is a bit of a hack. The oldCodePath doesn't exist at this point (because 9136 // we've already renamed / deleted it) so we cannot call realpath on it. Here we assume 9137 // that the last component of the path (i.e, the name) doesn't need canonicalization 9138 // (i.e, that it isn't ".", ".." or a symbolic link). This is a valid assumption for now 9139 // but may change in the future. Hopefully this function won't exist at that point. 9140 final File canonicalOldCodePath = new File(canonicalNewCodePath.getParentFile(), 9141 oldCodePath.getName()); 9142 9143 // Calculate the prefixes of the markers. These are just the paths with "/" replaced 9144 // with "@". 9145 String oldMarkerPrefix = canonicalOldCodePath.getAbsolutePath().replace('/', '@'); 9146 if (!oldMarkerPrefix.endsWith("@")) { 9147 oldMarkerPrefix += "@"; 9148 } 9149 String newMarkerPrefix = canonicalNewCodePath.getAbsolutePath().replace('/', '@'); 9150 if (!newMarkerPrefix.endsWith("@")) { 9151 newMarkerPrefix += "@"; 9152 } 9153 9154 List<String> updatedPaths = update.getAllCodePathsExcludingResourceOnly(); 9155 List<String> markerSuffixes = new ArrayList<String>(updatedPaths.size()); 9156 for (String updatedPath : updatedPaths) { 9157 String updatedPathName = new File(updatedPath).getName(); 9158 markerSuffixes.add(updatedPathName.replace('/', '@')); 9159 } 9160 9161 for (int userId : userIds) { 9162 File profileDir = Environment.getDataProfilesDeForeignDexDirectory(userId); 9163 9164 for (String markerSuffix : markerSuffixes) { 9165 File oldForeignUseMark = new File(profileDir, oldMarkerPrefix + markerSuffix); 9166 File newForeignUseMark = new File(profileDir, newMarkerPrefix + markerSuffix); 9167 if (oldForeignUseMark.exists()) { 9168 try { 9169 Os.rename(oldForeignUseMark.getAbsolutePath(), 9170 newForeignUseMark.getAbsolutePath()); 9171 } catch (ErrnoException e) { 9172 Slog.w(TAG, "Failed to rename foreign use marker", e); 9173 oldForeignUseMark.delete(); 9174 } 9175 } 9176 } 9177 } 9178 } 9179 9180 /** 9181 * Derive the ABI of a non-system package located at {@code scanFile}. This information 9182 * is derived purely on the basis of the contents of {@code scanFile} and 9183 * {@code cpuAbiOverride}. 9184 * 9185 * If {@code extractLibs} is true, native libraries are extracted from the app if required. 9186 */ 9187 private static void derivePackageAbi(PackageParser.Package pkg, File scanFile, 9188 String cpuAbiOverride, boolean extractLibs, 9189 File appLib32InstallDir) 9190 throws PackageManagerException { 9191 // TODO: We can probably be smarter about this stuff. For installed apps, 9192 // we can calculate this information at install time once and for all. For 9193 // system apps, we can probably assume that this information doesn't change 9194 // after the first boot scan. As things stand, we do lots of unnecessary work. 9195 9196 // Give ourselves some initial paths; we'll come back for another 9197 // pass once we've determined ABI below. 9198 setNativeLibraryPaths(pkg, appLib32InstallDir); 9199 9200 // We would never need to extract libs for forward-locked and external packages, 9201 // since the container service will do it for us. We shouldn't attempt to 9202 // extract libs from system app when it was not updated. 9203 if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() || 9204 (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) { 9205 extractLibs = false; 9206 } 9207 9208 final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir; 9209 final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa; 9210 9211 NativeLibraryHelper.Handle handle = null; 9212 try { 9213 handle = NativeLibraryHelper.Handle.create(pkg); 9214 // TODO(multiArch): This can be null for apps that didn't go through the 9215 // usual installation process. We can calculate it again, like we 9216 // do during install time. 9217 // 9218 // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally 9219 // unnecessary. 9220 final File nativeLibraryRoot = new File(nativeLibraryRootStr); 9221 9222 // Null out the abis so that they can be recalculated. 9223 pkg.applicationInfo.primaryCpuAbi = null; 9224 pkg.applicationInfo.secondaryCpuAbi = null; 9225 if (isMultiArch(pkg.applicationInfo)) { 9226 // Warn if we've set an abiOverride for multi-lib packages.. 9227 // By definition, we need to copy both 32 and 64 bit libraries for 9228 // such packages. 9229 if (pkg.cpuAbiOverride != null 9230 && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) { 9231 Slog.w(TAG, "Ignoring abiOverride for multi arch application."); 9232 } 9233 9234 int abi32 = PackageManager.NO_NATIVE_LIBRARIES; 9235 int abi64 = PackageManager.NO_NATIVE_LIBRARIES; 9236 if (Build.SUPPORTED_32_BIT_ABIS.length > 0) { 9237 if (extractLibs) { 9238 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries"); 9239 abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 9240 nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS, 9241 useIsaSpecificSubdirs); 9242 } else { 9243 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi"); 9244 abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS); 9245 } 9246 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 9247 } 9248 9249 maybeThrowExceptionForMultiArchCopy( 9250 "Error unpackaging 32 bit native libs for multiarch app.", abi32); 9251 9252 if (Build.SUPPORTED_64_BIT_ABIS.length > 0) { 9253 if (extractLibs) { 9254 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries"); 9255 abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 9256 nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS, 9257 useIsaSpecificSubdirs); 9258 } else { 9259 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi"); 9260 abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS); 9261 } 9262 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 9263 } 9264 9265 maybeThrowExceptionForMultiArchCopy( 9266 "Error unpackaging 64 bit native libs for multiarch app.", abi64); 9267 9268 if (abi64 >= 0) { 9269 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64]; 9270 } 9271 9272 if (abi32 >= 0) { 9273 final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32]; 9274 if (abi64 >= 0) { 9275 if (pkg.use32bitAbi) { 9276 pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi; 9277 pkg.applicationInfo.primaryCpuAbi = abi; 9278 } else { 9279 pkg.applicationInfo.secondaryCpuAbi = abi; 9280 } 9281 } else { 9282 pkg.applicationInfo.primaryCpuAbi = abi; 9283 } 9284 } 9285 9286 } else { 9287 String[] abiList = (cpuAbiOverride != null) ? 9288 new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS; 9289 9290 // Enable gross and lame hacks for apps that are built with old 9291 // SDK tools. We must scan their APKs for renderscript bitcode and 9292 // not launch them if it's present. Don't bother checking on devices 9293 // that don't have 64 bit support. 9294 boolean needsRenderScriptOverride = false; 9295 if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null && 9296 NativeLibraryHelper.hasRenderscriptBitcode(handle)) { 9297 abiList = Build.SUPPORTED_32_BIT_ABIS; 9298 needsRenderScriptOverride = true; 9299 } 9300 9301 final int copyRet; 9302 if (extractLibs) { 9303 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries"); 9304 copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, 9305 nativeLibraryRoot, abiList, useIsaSpecificSubdirs); 9306 } else { 9307 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi"); 9308 copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList); 9309 } 9310 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 9311 9312 if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { 9313 throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, 9314 "Error unpackaging native libs for app, errorCode=" + copyRet); 9315 } 9316 9317 if (copyRet >= 0) { 9318 pkg.applicationInfo.primaryCpuAbi = abiList[copyRet]; 9319 } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) { 9320 pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride; 9321 } else if (needsRenderScriptOverride) { 9322 pkg.applicationInfo.primaryCpuAbi = abiList[0]; 9323 } 9324 } 9325 } catch (IOException ioe) { 9326 Slog.e(TAG, "Unable to get canonical file " + ioe.toString()); 9327 } finally { 9328 IoUtils.closeQuietly(handle); 9329 } 9330 9331 // Now that we've calculated the ABIs and determined if it's an internal app, 9332 // we will go ahead and populate the nativeLibraryPath. 9333 setNativeLibraryPaths(pkg, appLib32InstallDir); 9334 } 9335 9336 /** 9337 * Adjusts ABIs for a set of packages belonging to a shared user so that they all match. 9338 * i.e, so that all packages can be run inside a single process if required. 9339 * 9340 * Optionally, callers can pass in a parsed package via {@code newPackage} in which case 9341 * this function will either try and make the ABI for all packages in {@code packagesForUser} 9342 * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match 9343 * the ABI selected for {@code packagesForUser}. This variant is used when installing or 9344 * updating a package that belongs to a shared user. 9345 * 9346 * NOTE: We currently only match for the primary CPU abi string. Matching the secondary 9347 * adds unnecessary complexity. 9348 */ 9349 private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser, 9350 PackageParser.Package scannedPackage) { 9351 String requiredInstructionSet = null; 9352 if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) { 9353 requiredInstructionSet = VMRuntime.getInstructionSet( 9354 scannedPackage.applicationInfo.primaryCpuAbi); 9355 } 9356 9357 PackageSetting requirer = null; 9358 for (PackageSetting ps : packagesForUser) { 9359 // If packagesForUser contains scannedPackage, we skip it. This will happen 9360 // when scannedPackage is an update of an existing package. Without this check, 9361 // we will never be able to change the ABI of any package belonging to a shared 9362 // user, even if it's compatible with other packages. 9363 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 9364 if (ps.primaryCpuAbiString == null) { 9365 continue; 9366 } 9367 9368 final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString); 9369 if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) { 9370 // We have a mismatch between instruction sets (say arm vs arm64) warn about 9371 // this but there's not much we can do. 9372 String errorMessage = "Instruction set mismatch, " 9373 + ((requirer == null) ? "[caller]" : requirer) 9374 + " requires " + requiredInstructionSet + " whereas " + ps 9375 + " requires " + instructionSet; 9376 Slog.w(TAG, errorMessage); 9377 } 9378 9379 if (requiredInstructionSet == null) { 9380 requiredInstructionSet = instructionSet; 9381 requirer = ps; 9382 } 9383 } 9384 } 9385 9386 if (requiredInstructionSet != null) { 9387 String adjustedAbi; 9388 if (requirer != null) { 9389 // requirer != null implies that either scannedPackage was null or that scannedPackage 9390 // did not require an ABI, in which case we have to adjust scannedPackage to match 9391 // the ABI of the set (which is the same as requirer's ABI) 9392 adjustedAbi = requirer.primaryCpuAbiString; 9393 if (scannedPackage != null) { 9394 scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi; 9395 } 9396 } else { 9397 // requirer == null implies that we're updating all ABIs in the set to 9398 // match scannedPackage. 9399 adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi; 9400 } 9401 9402 for (PackageSetting ps : packagesForUser) { 9403 if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) { 9404 if (ps.primaryCpuAbiString != null) { 9405 continue; 9406 } 9407 9408 ps.primaryCpuAbiString = adjustedAbi; 9409 if (ps.pkg != null && ps.pkg.applicationInfo != null && 9410 !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) { 9411 ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi; 9412 Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi 9413 + " (requirer=" 9414 + (requirer == null ? "null" : requirer.pkg.packageName) 9415 + ", scannedPackage=" 9416 + (scannedPackage != null ? scannedPackage.packageName : "null") 9417 + ")"); 9418 try { 9419 mInstaller.rmdex(ps.codePathString, 9420 getDexCodeInstructionSet(getPreferredInstructionSet())); 9421 } catch (InstallerException ignored) { 9422 } 9423 } 9424 } 9425 } 9426 } 9427 } 9428 9429 private void setUpCustomResolverActivity(PackageParser.Package pkg) { 9430 synchronized (mPackages) { 9431 mResolverReplaced = true; 9432 // Set up information for custom user intent resolution activity. 9433 mResolveActivity.applicationInfo = pkg.applicationInfo; 9434 mResolveActivity.name = mCustomResolverComponentName.getClassName(); 9435 mResolveActivity.packageName = pkg.applicationInfo.packageName; 9436 mResolveActivity.processName = pkg.applicationInfo.packageName; 9437 mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 9438 mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS | 9439 ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 9440 mResolveActivity.theme = 0; 9441 mResolveActivity.exported = true; 9442 mResolveActivity.enabled = true; 9443 mResolveInfo.activityInfo = mResolveActivity; 9444 mResolveInfo.priority = 0; 9445 mResolveInfo.preferredOrder = 0; 9446 mResolveInfo.match = 0; 9447 mResolveComponentName = mCustomResolverComponentName; 9448 Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " + 9449 mResolveComponentName); 9450 } 9451 } 9452 9453 private void setUpEphemeralInstallerActivityLP(ComponentName installerComponent) { 9454 final PackageParser.Package pkg = mPackages.get(installerComponent.getPackageName()); 9455 9456 // Set up information for ephemeral installer activity 9457 mEphemeralInstallerActivity.applicationInfo = pkg.applicationInfo; 9458 mEphemeralInstallerActivity.name = mEphemeralInstallerComponent.getClassName(); 9459 mEphemeralInstallerActivity.packageName = pkg.applicationInfo.packageName; 9460 mEphemeralInstallerActivity.processName = pkg.applicationInfo.packageName; 9461 mEphemeralInstallerActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE; 9462 mEphemeralInstallerActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS 9463 | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS; 9464 mEphemeralInstallerActivity.theme = 0; 9465 mEphemeralInstallerActivity.exported = true; 9466 mEphemeralInstallerActivity.enabled = true; 9467 mEphemeralInstallerInfo.activityInfo = mEphemeralInstallerActivity; 9468 mEphemeralInstallerInfo.priority = 0; 9469 mEphemeralInstallerInfo.preferredOrder = 1; 9470 mEphemeralInstallerInfo.isDefault = true; 9471 mEphemeralInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART 9472 | IntentFilter.MATCH_ADJUSTMENT_NORMAL; 9473 9474 if (DEBUG_EPHEMERAL) { 9475 Slog.d(TAG, "Set ephemeral installer activity: " + mEphemeralInstallerComponent); 9476 } 9477 } 9478 9479 private static String calculateBundledApkRoot(final String codePathString) { 9480 final File codePath = new File(codePathString); 9481 final File codeRoot; 9482 if (FileUtils.contains(Environment.getRootDirectory(), codePath)) { 9483 codeRoot = Environment.getRootDirectory(); 9484 } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) { 9485 codeRoot = Environment.getOemDirectory(); 9486 } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) { 9487 codeRoot = Environment.getVendorDirectory(); 9488 } else { 9489 // Unrecognized code path; take its top real segment as the apk root: 9490 // e.g. /something/app/blah.apk => /something 9491 try { 9492 File f = codePath.getCanonicalFile(); 9493 File parent = f.getParentFile(); // non-null because codePath is a file 9494 File tmp; 9495 while ((tmp = parent.getParentFile()) != null) { 9496 f = parent; 9497 parent = tmp; 9498 } 9499 codeRoot = f; 9500 Slog.w(TAG, "Unrecognized code path " 9501 + codePath + " - using " + codeRoot); 9502 } catch (IOException e) { 9503 // Can't canonicalize the code path -- shenanigans? 9504 Slog.w(TAG, "Can't canonicalize code path " + codePath); 9505 return Environment.getRootDirectory().getPath(); 9506 } 9507 } 9508 return codeRoot.getPath(); 9509 } 9510 9511 /** 9512 * Derive and set the location of native libraries for the given package, 9513 * which varies depending on where and how the package was installed. 9514 */ 9515 private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) { 9516 final ApplicationInfo info = pkg.applicationInfo; 9517 final String codePath = pkg.codePath; 9518 final File codeFile = new File(codePath); 9519 final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp(); 9520 final boolean asecApp = info.isForwardLocked() || info.isExternalAsec(); 9521 9522 info.nativeLibraryRootDir = null; 9523 info.nativeLibraryRootRequiresIsa = false; 9524 info.nativeLibraryDir = null; 9525 info.secondaryNativeLibraryDir = null; 9526 9527 if (isApkFile(codeFile)) { 9528 // Monolithic install 9529 if (bundledApp) { 9530 // If "/system/lib64/apkname" exists, assume that is the per-package 9531 // native library directory to use; otherwise use "/system/lib/apkname". 9532 final String apkRoot = calculateBundledApkRoot(info.sourceDir); 9533 final boolean is64Bit = VMRuntime.is64BitInstructionSet( 9534 getPrimaryInstructionSet(info)); 9535 9536 // This is a bundled system app so choose the path based on the ABI. 9537 // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this 9538 // is just the default path. 9539 final String apkName = deriveCodePathName(codePath); 9540 final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME; 9541 info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir, 9542 apkName).getAbsolutePath(); 9543 9544 if (info.secondaryCpuAbi != null) { 9545 final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME; 9546 info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot), 9547 secondaryLibDir, apkName).getAbsolutePath(); 9548 } 9549 } else if (asecApp) { 9550 info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME) 9551 .getAbsolutePath(); 9552 } else { 9553 final String apkName = deriveCodePathName(codePath); 9554 info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName) 9555 .getAbsolutePath(); 9556 } 9557 9558 info.nativeLibraryRootRequiresIsa = false; 9559 info.nativeLibraryDir = info.nativeLibraryRootDir; 9560 } else { 9561 // Cluster install 9562 info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath(); 9563 info.nativeLibraryRootRequiresIsa = true; 9564 9565 info.nativeLibraryDir = new File(info.nativeLibraryRootDir, 9566 getPrimaryInstructionSet(info)).getAbsolutePath(); 9567 9568 if (info.secondaryCpuAbi != null) { 9569 info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir, 9570 VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath(); 9571 } 9572 } 9573 } 9574 9575 /** 9576 * Calculate the abis and roots for a bundled app. These can uniquely 9577 * be determined from the contents of the system partition, i.e whether 9578 * it contains 64 or 32 bit shared libraries etc. We do not validate any 9579 * of this information, and instead assume that the system was built 9580 * sensibly. 9581 */ 9582 private static void setBundledAppAbisAndRoots(PackageParser.Package pkg, 9583 PackageSetting pkgSetting) { 9584 final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath()); 9585 9586 // If "/system/lib64/apkname" exists, assume that is the per-package 9587 // native library directory to use; otherwise use "/system/lib/apkname". 9588 final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir); 9589 setBundledAppAbi(pkg, apkRoot, apkName); 9590 // pkgSetting might be null during rescan following uninstall of updates 9591 // to a bundled app, so accommodate that possibility. The settings in 9592 // that case will be established later from the parsed package. 9593 // 9594 // If the settings aren't null, sync them up with what we've just derived. 9595 // note that apkRoot isn't stored in the package settings. 9596 if (pkgSetting != null) { 9597 pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; 9598 pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; 9599 } 9600 } 9601 9602 /** 9603 * Deduces the ABI of a bundled app and sets the relevant fields on the 9604 * parsed pkg object. 9605 * 9606 * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem} 9607 * under which system libraries are installed. 9608 * @param apkName the name of the installed package. 9609 */ 9610 private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) { 9611 final File codeFile = new File(pkg.codePath); 9612 9613 final boolean has64BitLibs; 9614 final boolean has32BitLibs; 9615 if (isApkFile(codeFile)) { 9616 // Monolithic install 9617 has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists(); 9618 has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists(); 9619 } else { 9620 // Cluster install 9621 final File rootDir = new File(codeFile, LIB_DIR_NAME); 9622 if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS) 9623 && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) { 9624 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]); 9625 has64BitLibs = (new File(rootDir, isa)).exists(); 9626 } else { 9627 has64BitLibs = false; 9628 } 9629 if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS) 9630 && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) { 9631 final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]); 9632 has32BitLibs = (new File(rootDir, isa)).exists(); 9633 } else { 9634 has32BitLibs = false; 9635 } 9636 } 9637 9638 if (has64BitLibs && !has32BitLibs) { 9639 // The package has 64 bit libs, but not 32 bit libs. Its primary 9640 // ABI should be 64 bit. We can safely assume here that the bundled 9641 // native libraries correspond to the most preferred ABI in the list. 9642 9643 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 9644 pkg.applicationInfo.secondaryCpuAbi = null; 9645 } else if (has32BitLibs && !has64BitLibs) { 9646 // The package has 32 bit libs but not 64 bit libs. Its primary 9647 // ABI should be 32 bit. 9648 9649 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 9650 pkg.applicationInfo.secondaryCpuAbi = null; 9651 } else if (has32BitLibs && has64BitLibs) { 9652 // The application has both 64 and 32 bit bundled libraries. We check 9653 // here that the app declares multiArch support, and warn if it doesn't. 9654 // 9655 // We will be lenient here and record both ABIs. The primary will be the 9656 // ABI that's higher on the list, i.e, a device that's configured to prefer 9657 // 64 bit apps will see a 64 bit primary ABI, 9658 9659 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) { 9660 Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch."); 9661 } 9662 9663 if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) { 9664 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 9665 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 9666 } else { 9667 pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0]; 9668 pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0]; 9669 } 9670 } else { 9671 pkg.applicationInfo.primaryCpuAbi = null; 9672 pkg.applicationInfo.secondaryCpuAbi = null; 9673 } 9674 } 9675 9676 private void killApplication(String pkgName, int appId, String reason) { 9677 killApplication(pkgName, appId, UserHandle.USER_ALL, reason); 9678 } 9679 9680 private void killApplication(String pkgName, int appId, int userId, String reason) { 9681 // Request the ActivityManager to kill the process(only for existing packages) 9682 // so that we do not end up in a confused state while the user is still using the older 9683 // version of the application while the new one gets installed. 9684 final long token = Binder.clearCallingIdentity(); 9685 try { 9686 IActivityManager am = ActivityManagerNative.getDefault(); 9687 if (am != null) { 9688 try { 9689 am.killApplication(pkgName, appId, userId, reason); 9690 } catch (RemoteException e) { 9691 } 9692 } 9693 } finally { 9694 Binder.restoreCallingIdentity(token); 9695 } 9696 } 9697 9698 private void removePackageLI(PackageParser.Package pkg, boolean chatty) { 9699 // Remove the parent package setting 9700 PackageSetting ps = (PackageSetting) pkg.mExtras; 9701 if (ps != null) { 9702 removePackageLI(ps, chatty); 9703 } 9704 // Remove the child package setting 9705 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 9706 for (int i = 0; i < childCount; i++) { 9707 PackageParser.Package childPkg = pkg.childPackages.get(i); 9708 ps = (PackageSetting) childPkg.mExtras; 9709 if (ps != null) { 9710 removePackageLI(ps, chatty); 9711 } 9712 } 9713 } 9714 9715 void removePackageLI(PackageSetting ps, boolean chatty) { 9716 if (DEBUG_INSTALL) { 9717 if (chatty) 9718 Log.d(TAG, "Removing package " + ps.name); 9719 } 9720 9721 // writer 9722 synchronized (mPackages) { 9723 mPackages.remove(ps.name); 9724 final PackageParser.Package pkg = ps.pkg; 9725 if (pkg != null) { 9726 cleanPackageDataStructuresLILPw(pkg, chatty); 9727 } 9728 } 9729 } 9730 9731 void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) { 9732 if (DEBUG_INSTALL) { 9733 if (chatty) 9734 Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName); 9735 } 9736 9737 // writer 9738 synchronized (mPackages) { 9739 // Remove the parent package 9740 mPackages.remove(pkg.applicationInfo.packageName); 9741 cleanPackageDataStructuresLILPw(pkg, chatty); 9742 9743 // Remove the child packages 9744 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 9745 for (int i = 0; i < childCount; i++) { 9746 PackageParser.Package childPkg = pkg.childPackages.get(i); 9747 mPackages.remove(childPkg.applicationInfo.packageName); 9748 cleanPackageDataStructuresLILPw(childPkg, chatty); 9749 } 9750 } 9751 } 9752 9753 void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) { 9754 int N = pkg.providers.size(); 9755 StringBuilder r = null; 9756 int i; 9757 for (i=0; i<N; i++) { 9758 PackageParser.Provider p = pkg.providers.get(i); 9759 mProviders.removeProvider(p); 9760 if (p.info.authority == null) { 9761 9762 /* There was another ContentProvider with this authority when 9763 * this app was installed so this authority is null, 9764 * Ignore it as we don't have to unregister the provider. 9765 */ 9766 continue; 9767 } 9768 String names[] = p.info.authority.split(";"); 9769 for (int j = 0; j < names.length; j++) { 9770 if (mProvidersByAuthority.get(names[j]) == p) { 9771 mProvidersByAuthority.remove(names[j]); 9772 if (DEBUG_REMOVE) { 9773 if (chatty) 9774 Log.d(TAG, "Unregistered content provider: " + names[j] 9775 + ", className = " + p.info.name + ", isSyncable = " 9776 + p.info.isSyncable); 9777 } 9778 } 9779 } 9780 if (DEBUG_REMOVE && chatty) { 9781 if (r == null) { 9782 r = new StringBuilder(256); 9783 } else { 9784 r.append(' '); 9785 } 9786 r.append(p.info.name); 9787 } 9788 } 9789 if (r != null) { 9790 if (DEBUG_REMOVE) Log.d(TAG, " Providers: " + r); 9791 } 9792 9793 N = pkg.services.size(); 9794 r = null; 9795 for (i=0; i<N; i++) { 9796 PackageParser.Service s = pkg.services.get(i); 9797 mServices.removeService(s); 9798 if (chatty) { 9799 if (r == null) { 9800 r = new StringBuilder(256); 9801 } else { 9802 r.append(' '); 9803 } 9804 r.append(s.info.name); 9805 } 9806 } 9807 if (r != null) { 9808 if (DEBUG_REMOVE) Log.d(TAG, " Services: " + r); 9809 } 9810 9811 N = pkg.receivers.size(); 9812 r = null; 9813 for (i=0; i<N; i++) { 9814 PackageParser.Activity a = pkg.receivers.get(i); 9815 mReceivers.removeActivity(a, "receiver"); 9816 if (DEBUG_REMOVE && chatty) { 9817 if (r == null) { 9818 r = new StringBuilder(256); 9819 } else { 9820 r.append(' '); 9821 } 9822 r.append(a.info.name); 9823 } 9824 } 9825 if (r != null) { 9826 if (DEBUG_REMOVE) Log.d(TAG, " Receivers: " + r); 9827 } 9828 9829 N = pkg.activities.size(); 9830 r = null; 9831 for (i=0; i<N; i++) { 9832 PackageParser.Activity a = pkg.activities.get(i); 9833 mActivities.removeActivity(a, "activity"); 9834 if (DEBUG_REMOVE && chatty) { 9835 if (r == null) { 9836 r = new StringBuilder(256); 9837 } else { 9838 r.append(' '); 9839 } 9840 r.append(a.info.name); 9841 } 9842 } 9843 if (r != null) { 9844 if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r); 9845 } 9846 9847 N = pkg.permissions.size(); 9848 r = null; 9849 for (i=0; i<N; i++) { 9850 PackageParser.Permission p = pkg.permissions.get(i); 9851 BasePermission bp = mSettings.mPermissions.get(p.info.name); 9852 if (bp == null) { 9853 bp = mSettings.mPermissionTrees.get(p.info.name); 9854 } 9855 if (bp != null && bp.perm == p) { 9856 bp.perm = null; 9857 if (DEBUG_REMOVE && chatty) { 9858 if (r == null) { 9859 r = new StringBuilder(256); 9860 } else { 9861 r.append(' '); 9862 } 9863 r.append(p.info.name); 9864 } 9865 } 9866 if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 9867 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name); 9868 if (appOpPkgs != null) { 9869 appOpPkgs.remove(pkg.packageName); 9870 } 9871 } 9872 } 9873 if (r != null) { 9874 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 9875 } 9876 9877 N = pkg.requestedPermissions.size(); 9878 r = null; 9879 for (i=0; i<N; i++) { 9880 String perm = pkg.requestedPermissions.get(i); 9881 BasePermission bp = mSettings.mPermissions.get(perm); 9882 if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 9883 ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm); 9884 if (appOpPkgs != null) { 9885 appOpPkgs.remove(pkg.packageName); 9886 if (appOpPkgs.isEmpty()) { 9887 mAppOpPermissionPackages.remove(perm); 9888 } 9889 } 9890 } 9891 } 9892 if (r != null) { 9893 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r); 9894 } 9895 9896 N = pkg.instrumentation.size(); 9897 r = null; 9898 for (i=0; i<N; i++) { 9899 PackageParser.Instrumentation a = pkg.instrumentation.get(i); 9900 mInstrumentation.remove(a.getComponentName()); 9901 if (DEBUG_REMOVE && chatty) { 9902 if (r == null) { 9903 r = new StringBuilder(256); 9904 } else { 9905 r.append(' '); 9906 } 9907 r.append(a.info.name); 9908 } 9909 } 9910 if (r != null) { 9911 if (DEBUG_REMOVE) Log.d(TAG, " Instrumentation: " + r); 9912 } 9913 9914 r = null; 9915 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9916 // Only system apps can hold shared libraries. 9917 if (pkg.libraryNames != null) { 9918 for (i=0; i<pkg.libraryNames.size(); i++) { 9919 String name = pkg.libraryNames.get(i); 9920 SharedLibraryEntry cur = mSharedLibraries.get(name); 9921 if (cur != null && cur.apk != null && cur.apk.equals(pkg.packageName)) { 9922 mSharedLibraries.remove(name); 9923 if (DEBUG_REMOVE && chatty) { 9924 if (r == null) { 9925 r = new StringBuilder(256); 9926 } else { 9927 r.append(' '); 9928 } 9929 r.append(name); 9930 } 9931 } 9932 } 9933 } 9934 } 9935 if (r != null) { 9936 if (DEBUG_REMOVE) Log.d(TAG, " Libraries: " + r); 9937 } 9938 } 9939 9940 private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) { 9941 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) { 9942 if (pkgInfo.permissions.get(i).info.name.equals(perm)) { 9943 return true; 9944 } 9945 } 9946 return false; 9947 } 9948 9949 static final int UPDATE_PERMISSIONS_ALL = 1<<0; 9950 static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1; 9951 static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2; 9952 9953 private void updatePermissionsLPw(PackageParser.Package pkg, int flags) { 9954 // Update the parent permissions 9955 updatePermissionsLPw(pkg.packageName, pkg, flags); 9956 // Update the child permissions 9957 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 9958 for (int i = 0; i < childCount; i++) { 9959 PackageParser.Package childPkg = pkg.childPackages.get(i); 9960 updatePermissionsLPw(childPkg.packageName, childPkg, flags); 9961 } 9962 } 9963 9964 private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo, 9965 int flags) { 9966 final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null; 9967 updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags); 9968 } 9969 9970 private void updatePermissionsLPw(String changingPkg, 9971 PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) { 9972 // Make sure there are no dangling permission trees. 9973 Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator(); 9974 while (it.hasNext()) { 9975 final BasePermission bp = it.next(); 9976 if (bp.packageSetting == null) { 9977 // We may not yet have parsed the package, so just see if 9978 // we still know about its settings. 9979 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 9980 } 9981 if (bp.packageSetting == null) { 9982 Slog.w(TAG, "Removing dangling permission tree: " + bp.name 9983 + " from package " + bp.sourcePackage); 9984 it.remove(); 9985 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 9986 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 9987 Slog.i(TAG, "Removing old permission tree: " + bp.name 9988 + " from package " + bp.sourcePackage); 9989 flags |= UPDATE_PERMISSIONS_ALL; 9990 it.remove(); 9991 } 9992 } 9993 } 9994 9995 // Make sure all dynamic permissions have been assigned to a package, 9996 // and make sure there are no dangling permissions. 9997 it = mSettings.mPermissions.values().iterator(); 9998 while (it.hasNext()) { 9999 final BasePermission bp = it.next(); 10000 if (bp.type == BasePermission.TYPE_DYNAMIC) { 10001 if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name=" 10002 + bp.name + " pkg=" + bp.sourcePackage 10003 + " info=" + bp.pendingInfo); 10004 if (bp.packageSetting == null && bp.pendingInfo != null) { 10005 final BasePermission tree = findPermissionTreeLP(bp.name); 10006 if (tree != null && tree.perm != null) { 10007 bp.packageSetting = tree.packageSetting; 10008 bp.perm = new PackageParser.Permission(tree.perm.owner, 10009 new PermissionInfo(bp.pendingInfo)); 10010 bp.perm.info.packageName = tree.perm.info.packageName; 10011 bp.perm.info.name = bp.name; 10012 bp.uid = tree.uid; 10013 } 10014 } 10015 } 10016 if (bp.packageSetting == null) { 10017 // We may not yet have parsed the package, so just see if 10018 // we still know about its settings. 10019 bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); 10020 } 10021 if (bp.packageSetting == null) { 10022 Slog.w(TAG, "Removing dangling permission: " + bp.name 10023 + " from package " + bp.sourcePackage); 10024 it.remove(); 10025 } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { 10026 if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { 10027 Slog.i(TAG, "Removing old permission: " + bp.name 10028 + " from package " + bp.sourcePackage); 10029 flags |= UPDATE_PERMISSIONS_ALL; 10030 it.remove(); 10031 } 10032 } 10033 } 10034 10035 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions"); 10036 // Now update the permissions for all packages, in particular 10037 // replace the granted permissions of the system packages. 10038 if ((flags&UPDATE_PERMISSIONS_ALL) != 0) { 10039 for (PackageParser.Package pkg : mPackages.values()) { 10040 if (pkg != pkgInfo) { 10041 // Only replace for packages on requested volume 10042 final String volumeUuid = getVolumeUuidForPackage(pkg); 10043 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0) 10044 && Objects.equals(replaceVolumeUuid, volumeUuid); 10045 grantPermissionsLPw(pkg, replace, changingPkg); 10046 } 10047 } 10048 } 10049 10050 if (pkgInfo != null) { 10051 // Only replace for packages on requested volume 10052 final String volumeUuid = getVolumeUuidForPackage(pkgInfo); 10053 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0) 10054 && Objects.equals(replaceVolumeUuid, volumeUuid); 10055 grantPermissionsLPw(pkgInfo, replace, changingPkg); 10056 } 10057 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 10058 } 10059 10060 private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace, 10061 String packageOfInterest) { 10062 // IMPORTANT: There are two types of permissions: install and runtime. 10063 // Install time permissions are granted when the app is installed to 10064 // all device users and users added in the future. Runtime permissions 10065 // are granted at runtime explicitly to specific users. Normal and signature 10066 // protected permissions are install time permissions. Dangerous permissions 10067 // are install permissions if the app's target SDK is Lollipop MR1 or older, 10068 // otherwise they are runtime permissions. This function does not manage 10069 // runtime permissions except for the case an app targeting Lollipop MR1 10070 // being upgraded to target a newer SDK, in which case dangerous permissions 10071 // are transformed from install time to runtime ones. 10072 10073 final PackageSetting ps = (PackageSetting) pkg.mExtras; 10074 if (ps == null) { 10075 return; 10076 } 10077 10078 PermissionsState permissionsState = ps.getPermissionsState(); 10079 PermissionsState origPermissions = permissionsState; 10080 10081 final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); 10082 10083 boolean runtimePermissionsRevoked = false; 10084 int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY; 10085 10086 boolean changedInstallPermission = false; 10087 10088 if (replace) { 10089 ps.installPermissionsFixed = false; 10090 if (!ps.isSharedUser()) { 10091 origPermissions = new PermissionsState(permissionsState); 10092 permissionsState.reset(); 10093 } else { 10094 // We need to know only about runtime permission changes since the 10095 // calling code always writes the install permissions state but 10096 // the runtime ones are written only if changed. The only cases of 10097 // changed runtime permissions here are promotion of an install to 10098 // runtime and revocation of a runtime from a shared user. 10099 changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw( 10100 ps.sharedUser, UserManagerService.getInstance().getUserIds()); 10101 if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) { 10102 runtimePermissionsRevoked = true; 10103 } 10104 } 10105 } 10106 10107 permissionsState.setGlobalGids(mGlobalGids); 10108 10109 final int N = pkg.requestedPermissions.size(); 10110 for (int i=0; i<N; i++) { 10111 final String name = pkg.requestedPermissions.get(i); 10112 final BasePermission bp = mSettings.mPermissions.get(name); 10113 10114 if (DEBUG_INSTALL) { 10115 Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp); 10116 } 10117 10118 if (bp == null || bp.packageSetting == null) { 10119 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 10120 Slog.w(TAG, "Unknown permission " + name 10121 + " in package " + pkg.packageName); 10122 } 10123 continue; 10124 } 10125 10126 10127 // Limit ephemeral apps to ephemeral allowed permissions. 10128 if (pkg.applicationInfo.isEphemeralApp() && !bp.isEphemeral()) { 10129 Log.i(TAG, "Denying non-ephemeral permission " + bp.name + " for package " 10130 + pkg.packageName); 10131 continue; 10132 } 10133 10134 final String perm = bp.name; 10135 boolean allowedSig = false; 10136 int grant = GRANT_DENIED; 10137 10138 // Keep track of app op permissions. 10139 if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) { 10140 ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name); 10141 if (pkgs == null) { 10142 pkgs = new ArraySet<>(); 10143 mAppOpPermissionPackages.put(bp.name, pkgs); 10144 } 10145 pkgs.add(pkg.packageName); 10146 } 10147 10148 final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; 10149 final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion 10150 >= Build.VERSION_CODES.M; 10151 switch (level) { 10152 case PermissionInfo.PROTECTION_NORMAL: { 10153 // For all apps normal permissions are install time ones. 10154 grant = GRANT_INSTALL; 10155 } break; 10156 10157 case PermissionInfo.PROTECTION_DANGEROUS: { 10158 // If a permission review is required for legacy apps we represent 10159 // their permissions as always granted runtime ones since we need 10160 // to keep the review required permission flag per user while an 10161 // install permission's state is shared across all users. 10162 if (!appSupportsRuntimePermissions && !mPermissionReviewRequired) { 10163 // For legacy apps dangerous permissions are install time ones. 10164 grant = GRANT_INSTALL; 10165 } else if (origPermissions.hasInstallPermission(bp.name)) { 10166 // For legacy apps that became modern, install becomes runtime. 10167 grant = GRANT_UPGRADE; 10168 } else if (mPromoteSystemApps 10169 && isSystemApp(ps) 10170 && mExistingSystemPackages.contains(ps.name)) { 10171 // For legacy system apps, install becomes runtime. 10172 // We cannot check hasInstallPermission() for system apps since those 10173 // permissions were granted implicitly and not persisted pre-M. 10174 grant = GRANT_UPGRADE; 10175 } else { 10176 // For modern apps keep runtime permissions unchanged. 10177 grant = GRANT_RUNTIME; 10178 } 10179 } break; 10180 10181 case PermissionInfo.PROTECTION_SIGNATURE: { 10182 // For all apps signature permissions are install time ones. 10183 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions); 10184 if (allowedSig) { 10185 grant = GRANT_INSTALL; 10186 } 10187 } break; 10188 } 10189 10190 if (DEBUG_INSTALL) { 10191 Log.i(TAG, "Package " + pkg.packageName + " granting " + perm); 10192 } 10193 10194 if (grant != GRANT_DENIED) { 10195 if (!isSystemApp(ps) && ps.installPermissionsFixed) { 10196 // If this is an existing, non-system package, then 10197 // we can't add any new permissions to it. 10198 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) { 10199 // Except... if this is a permission that was added 10200 // to the platform (note: need to only do this when 10201 // updating the platform). 10202 if (!isNewPlatformPermissionForPackage(perm, pkg)) { 10203 grant = GRANT_DENIED; 10204 } 10205 } 10206 } 10207 10208 switch (grant) { 10209 case GRANT_INSTALL: { 10210 // Revoke this as runtime permission to handle the case of 10211 // a runtime permission being downgraded to an install one. 10212 // Also in permission review mode we keep dangerous permissions 10213 // for legacy apps 10214 for (int userId : UserManagerService.getInstance().getUserIds()) { 10215 if (origPermissions.getRuntimePermissionState( 10216 bp.name, userId) != null) { 10217 // Revoke the runtime permission and clear the flags. 10218 origPermissions.revokeRuntimePermission(bp, userId); 10219 origPermissions.updatePermissionFlags(bp, userId, 10220 PackageManager.MASK_PERMISSION_FLAGS, 0); 10221 // If we revoked a permission permission, we have to write. 10222 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 10223 changedRuntimePermissionUserIds, userId); 10224 } 10225 } 10226 // Grant an install permission. 10227 if (permissionsState.grantInstallPermission(bp) != 10228 PermissionsState.PERMISSION_OPERATION_FAILURE) { 10229 changedInstallPermission = true; 10230 } 10231 } break; 10232 10233 case GRANT_RUNTIME: { 10234 // Grant previously granted runtime permissions. 10235 for (int userId : UserManagerService.getInstance().getUserIds()) { 10236 PermissionState permissionState = origPermissions 10237 .getRuntimePermissionState(bp.name, userId); 10238 int flags = permissionState != null 10239 ? permissionState.getFlags() : 0; 10240 if (origPermissions.hasRuntimePermission(bp.name, userId)) { 10241 if (permissionsState.grantRuntimePermission(bp, userId) == 10242 PermissionsState.PERMISSION_OPERATION_FAILURE) { 10243 // If we cannot put the permission as it was, we have to write. 10244 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 10245 changedRuntimePermissionUserIds, userId); 10246 } 10247 // If the app supports runtime permissions no need for a review. 10248 if (mPermissionReviewRequired 10249 && appSupportsRuntimePermissions 10250 && (flags & PackageManager 10251 .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) { 10252 flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; 10253 // Since we changed the flags, we have to write. 10254 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 10255 changedRuntimePermissionUserIds, userId); 10256 } 10257 } else if (mPermissionReviewRequired 10258 && !appSupportsRuntimePermissions) { 10259 // For legacy apps that need a permission review, every new 10260 // runtime permission is granted but it is pending a review. 10261 // We also need to review only platform defined runtime 10262 // permissions as these are the only ones the platform knows 10263 // how to disable the API to simulate revocation as legacy 10264 // apps don't expect to run with revoked permissions. 10265 if (PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage)) { 10266 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) { 10267 flags |= FLAG_PERMISSION_REVIEW_REQUIRED; 10268 // We changed the flags, hence have to write. 10269 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 10270 changedRuntimePermissionUserIds, userId); 10271 } 10272 } 10273 if (permissionsState.grantRuntimePermission(bp, userId) 10274 != PermissionsState.PERMISSION_OPERATION_FAILURE) { 10275 // We changed the permission, hence have to write. 10276 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 10277 changedRuntimePermissionUserIds, userId); 10278 } 10279 } 10280 // Propagate the permission flags. 10281 permissionsState.updatePermissionFlags(bp, userId, flags, flags); 10282 } 10283 } break; 10284 10285 case GRANT_UPGRADE: { 10286 // Grant runtime permissions for a previously held install permission. 10287 PermissionState permissionState = origPermissions 10288 .getInstallPermissionState(bp.name); 10289 final int flags = permissionState != null ? permissionState.getFlags() : 0; 10290 10291 if (origPermissions.revokeInstallPermission(bp) 10292 != PermissionsState.PERMISSION_OPERATION_FAILURE) { 10293 // We will be transferring the permission flags, so clear them. 10294 origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL, 10295 PackageManager.MASK_PERMISSION_FLAGS, 0); 10296 changedInstallPermission = true; 10297 } 10298 10299 // If the permission is not to be promoted to runtime we ignore it and 10300 // also its other flags as they are not applicable to install permissions. 10301 if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) { 10302 for (int userId : currentUserIds) { 10303 if (permissionsState.grantRuntimePermission(bp, userId) != 10304 PermissionsState.PERMISSION_OPERATION_FAILURE) { 10305 // Transfer the permission flags. 10306 permissionsState.updatePermissionFlags(bp, userId, 10307 flags, flags); 10308 // If we granted the permission, we have to write. 10309 changedRuntimePermissionUserIds = ArrayUtils.appendInt( 10310 changedRuntimePermissionUserIds, userId); 10311 } 10312 } 10313 } 10314 } break; 10315 10316 default: { 10317 if (packageOfInterest == null 10318 || packageOfInterest.equals(pkg.packageName)) { 10319 Slog.w(TAG, "Not granting permission " + perm 10320 + " to package " + pkg.packageName 10321 + " because it was previously installed without"); 10322 } 10323 } break; 10324 } 10325 } else { 10326 if (permissionsState.revokeInstallPermission(bp) != 10327 PermissionsState.PERMISSION_OPERATION_FAILURE) { 10328 // Also drop the permission flags. 10329 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 10330 PackageManager.MASK_PERMISSION_FLAGS, 0); 10331 changedInstallPermission = true; 10332 Slog.i(TAG, "Un-granting permission " + perm 10333 + " from package " + pkg.packageName 10334 + " (protectionLevel=" + bp.protectionLevel 10335 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 10336 + ")"); 10337 } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) { 10338 // Don't print warning for app op permissions, since it is fine for them 10339 // not to be granted, there is a UI for the user to decide. 10340 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) { 10341 Slog.w(TAG, "Not granting permission " + perm 10342 + " to package " + pkg.packageName 10343 + " (protectionLevel=" + bp.protectionLevel 10344 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags) 10345 + ")"); 10346 } 10347 } 10348 } 10349 } 10350 10351 if ((changedInstallPermission || replace) && !ps.installPermissionsFixed && 10352 !isSystemApp(ps) || isUpdatedSystemApp(ps)){ 10353 // This is the first that we have heard about this package, so the 10354 // permissions we have now selected are fixed until explicitly 10355 // changed. 10356 ps.installPermissionsFixed = true; 10357 } 10358 10359 // Persist the runtime permissions state for users with changes. If permissions 10360 // were revoked because no app in the shared user declares them we have to 10361 // write synchronously to avoid losing runtime permissions state. 10362 for (int userId : changedRuntimePermissionUserIds) { 10363 mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked); 10364 } 10365 } 10366 10367 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) { 10368 boolean allowed = false; 10369 final int NP = PackageParser.NEW_PERMISSIONS.length; 10370 for (int ip=0; ip<NP; ip++) { 10371 final PackageParser.NewPermissionInfo npi 10372 = PackageParser.NEW_PERMISSIONS[ip]; 10373 if (npi.name.equals(perm) 10374 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) { 10375 allowed = true; 10376 Log.i(TAG, "Auto-granting " + perm + " to old pkg " 10377 + pkg.packageName); 10378 break; 10379 } 10380 } 10381 return allowed; 10382 } 10383 10384 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg, 10385 BasePermission bp, PermissionsState origPermissions) { 10386 boolean allowed; 10387 allowed = (compareSignatures( 10388 bp.packageSetting.signatures.mSignatures, pkg.mSignatures) 10389 == PackageManager.SIGNATURE_MATCH) 10390 || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures) 10391 == PackageManager.SIGNATURE_MATCH); 10392 if (!allowed && (bp.protectionLevel 10393 & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) { 10394 if (isSystemApp(pkg)) { 10395 // For updated system applications, a system permission 10396 // is granted only if it had been defined by the original application. 10397 if (pkg.isUpdatedSystemApp()) { 10398 final PackageSetting sysPs = mSettings 10399 .getDisabledSystemPkgLPr(pkg.packageName); 10400 if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) { 10401 // If the original was granted this permission, we take 10402 // that grant decision as read and propagate it to the 10403 // update. 10404 if (sysPs.isPrivileged()) { 10405 allowed = true; 10406 } 10407 } else { 10408 // The system apk may have been updated with an older 10409 // version of the one on the data partition, but which 10410 // granted a new system permission that it didn't have 10411 // before. In this case we do want to allow the app to 10412 // now get the new permission if the ancestral apk is 10413 // privileged to get it. 10414 if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) { 10415 for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) { 10416 if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) { 10417 allowed = true; 10418 break; 10419 } 10420 } 10421 } 10422 // Also if a privileged parent package on the system image or any of 10423 // its children requested a privileged permission, the updated child 10424 // packages can also get the permission. 10425 if (pkg.parentPackage != null) { 10426 final PackageSetting disabledSysParentPs = mSettings 10427 .getDisabledSystemPkgLPr(pkg.parentPackage.packageName); 10428 if (disabledSysParentPs != null && disabledSysParentPs.pkg != null 10429 && disabledSysParentPs.isPrivileged()) { 10430 if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) { 10431 allowed = true; 10432 } else if (disabledSysParentPs.pkg.childPackages != null) { 10433 final int count = disabledSysParentPs.pkg.childPackages.size(); 10434 for (int i = 0; i < count; i++) { 10435 PackageParser.Package disabledSysChildPkg = 10436 disabledSysParentPs.pkg.childPackages.get(i); 10437 if (isPackageRequestingPermission(disabledSysChildPkg, 10438 perm)) { 10439 allowed = true; 10440 break; 10441 } 10442 } 10443 } 10444 } 10445 } 10446 } 10447 } else { 10448 allowed = isPrivilegedApp(pkg); 10449 } 10450 } 10451 } 10452 if (!allowed) { 10453 if (!allowed && (bp.protectionLevel 10454 & PermissionInfo.PROTECTION_FLAG_PRE23) != 0 10455 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 10456 // If this was a previously normal/dangerous permission that got moved 10457 // to a system permission as part of the runtime permission redesign, then 10458 // we still want to blindly grant it to old apps. 10459 allowed = true; 10460 } 10461 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0 10462 && pkg.packageName.equals(mRequiredInstallerPackage)) { 10463 // If this permission is to be granted to the system installer and 10464 // this app is an installer, then it gets the permission. 10465 allowed = true; 10466 } 10467 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0 10468 && pkg.packageName.equals(mRequiredVerifierPackage)) { 10469 // If this permission is to be granted to the system verifier and 10470 // this app is a verifier, then it gets the permission. 10471 allowed = true; 10472 } 10473 if (!allowed && (bp.protectionLevel 10474 & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0 10475 && isSystemApp(pkg)) { 10476 // Any pre-installed system app is allowed to get this permission. 10477 allowed = true; 10478 } 10479 if (!allowed && (bp.protectionLevel 10480 & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) { 10481 // For development permissions, a development permission 10482 // is granted only if it was already granted. 10483 allowed = origPermissions.hasInstallPermission(perm); 10484 } 10485 if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0 10486 && pkg.packageName.equals(mSetupWizardPackage)) { 10487 // If this permission is to be granted to the system setup wizard and 10488 // this app is a setup wizard, then it gets the permission. 10489 allowed = true; 10490 } 10491 } 10492 return allowed; 10493 } 10494 10495 private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) { 10496 final int permCount = pkg.requestedPermissions.size(); 10497 for (int j = 0; j < permCount; j++) { 10498 String requestedPermission = pkg.requestedPermissions.get(j); 10499 if (permission.equals(requestedPermission)) { 10500 return true; 10501 } 10502 } 10503 return false; 10504 } 10505 10506 final class ActivityIntentResolver 10507 extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> { 10508 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 10509 boolean defaultOnly, int userId) { 10510 if (!sUserManager.exists(userId)) return null; 10511 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 10512 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 10513 } 10514 10515 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 10516 int userId) { 10517 if (!sUserManager.exists(userId)) return null; 10518 mFlags = flags; 10519 return super.queryIntent(intent, resolvedType, 10520 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 10521 } 10522 10523 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 10524 int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) { 10525 if (!sUserManager.exists(userId)) return null; 10526 if (packageActivities == null) { 10527 return null; 10528 } 10529 mFlags = flags; 10530 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 10531 final int N = packageActivities.size(); 10532 ArrayList<PackageParser.ActivityIntentInfo[]> listCut = 10533 new ArrayList<PackageParser.ActivityIntentInfo[]>(N); 10534 10535 ArrayList<PackageParser.ActivityIntentInfo> intentFilters; 10536 for (int i = 0; i < N; ++i) { 10537 intentFilters = packageActivities.get(i).intents; 10538 if (intentFilters != null && intentFilters.size() > 0) { 10539 PackageParser.ActivityIntentInfo[] array = 10540 new PackageParser.ActivityIntentInfo[intentFilters.size()]; 10541 intentFilters.toArray(array); 10542 listCut.add(array); 10543 } 10544 } 10545 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 10546 } 10547 10548 /** 10549 * Finds a privileged activity that matches the specified activity names. 10550 */ 10551 private PackageParser.Activity findMatchingActivity( 10552 List<PackageParser.Activity> activityList, ActivityInfo activityInfo) { 10553 for (PackageParser.Activity sysActivity : activityList) { 10554 if (sysActivity.info.name.equals(activityInfo.name)) { 10555 return sysActivity; 10556 } 10557 if (sysActivity.info.name.equals(activityInfo.targetActivity)) { 10558 return sysActivity; 10559 } 10560 if (sysActivity.info.targetActivity != null) { 10561 if (sysActivity.info.targetActivity.equals(activityInfo.name)) { 10562 return sysActivity; 10563 } 10564 if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) { 10565 return sysActivity; 10566 } 10567 } 10568 } 10569 return null; 10570 } 10571 10572 public class IterGenerator<E> { 10573 public Iterator<E> generate(ActivityIntentInfo info) { 10574 return null; 10575 } 10576 } 10577 10578 public class ActionIterGenerator extends IterGenerator<String> { 10579 @Override 10580 public Iterator<String> generate(ActivityIntentInfo info) { 10581 return info.actionsIterator(); 10582 } 10583 } 10584 10585 public class CategoriesIterGenerator extends IterGenerator<String> { 10586 @Override 10587 public Iterator<String> generate(ActivityIntentInfo info) { 10588 return info.categoriesIterator(); 10589 } 10590 } 10591 10592 public class SchemesIterGenerator extends IterGenerator<String> { 10593 @Override 10594 public Iterator<String> generate(ActivityIntentInfo info) { 10595 return info.schemesIterator(); 10596 } 10597 } 10598 10599 public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> { 10600 @Override 10601 public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) { 10602 return info.authoritiesIterator(); 10603 } 10604 } 10605 10606 /** 10607 * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE 10608 * MODIFIED. Do not pass in a list that should not be changed. 10609 */ 10610 private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList, 10611 IterGenerator<T> generator, Iterator<T> searchIterator) { 10612 // loop through the set of actions; every one must be found in the intent filter 10613 while (searchIterator.hasNext()) { 10614 // we must have at least one filter in the list to consider a match 10615 if (intentList.size() == 0) { 10616 break; 10617 } 10618 10619 final T searchAction = searchIterator.next(); 10620 10621 // loop through the set of intent filters 10622 final Iterator<ActivityIntentInfo> intentIter = intentList.iterator(); 10623 while (intentIter.hasNext()) { 10624 final ActivityIntentInfo intentInfo = intentIter.next(); 10625 boolean selectionFound = false; 10626 10627 // loop through the intent filter's selection criteria; at least one 10628 // of them must match the searched criteria 10629 final Iterator<T> intentSelectionIter = generator.generate(intentInfo); 10630 while (intentSelectionIter != null && intentSelectionIter.hasNext()) { 10631 final T intentSelection = intentSelectionIter.next(); 10632 if (intentSelection != null && intentSelection.equals(searchAction)) { 10633 selectionFound = true; 10634 break; 10635 } 10636 } 10637 10638 // the selection criteria wasn't found in this filter's set; this filter 10639 // is not a potential match 10640 if (!selectionFound) { 10641 intentIter.remove(); 10642 } 10643 } 10644 } 10645 } 10646 10647 private boolean isProtectedAction(ActivityIntentInfo filter) { 10648 final Iterator<String> actionsIter = filter.actionsIterator(); 10649 while (actionsIter != null && actionsIter.hasNext()) { 10650 final String filterAction = actionsIter.next(); 10651 if (PROTECTED_ACTIONS.contains(filterAction)) { 10652 return true; 10653 } 10654 } 10655 return false; 10656 } 10657 10658 /** 10659 * Adjusts the priority of the given intent filter according to policy. 10660 * <p> 10661 * <ul> 10662 * <li>The priority for non privileged applications is capped to '0'</li> 10663 * <li>The priority for protected actions on privileged applications is capped to '0'</li> 10664 * <li>The priority for unbundled updates to privileged applications is capped to the 10665 * priority defined on the system partition</li> 10666 * </ul> 10667 * <p> 10668 * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is 10669 * allowed to obtain any priority on any action. 10670 */ 10671 private void adjustPriority( 10672 List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) { 10673 // nothing to do; priority is fine as-is 10674 if (intent.getPriority() <= 0) { 10675 return; 10676 } 10677 10678 final ActivityInfo activityInfo = intent.activity.info; 10679 final ApplicationInfo applicationInfo = activityInfo.applicationInfo; 10680 10681 final boolean privilegedApp = 10682 ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0); 10683 if (!privilegedApp) { 10684 // non-privileged applications can never define a priority >0 10685 Slog.w(TAG, "Non-privileged app; cap priority to 0;" 10686 + " package: " + applicationInfo.packageName 10687 + " activity: " + intent.activity.className 10688 + " origPrio: " + intent.getPriority()); 10689 intent.setPriority(0); 10690 return; 10691 } 10692 10693 if (systemActivities == null) { 10694 // the system package is not disabled; we're parsing the system partition 10695 if (isProtectedAction(intent)) { 10696 if (mDeferProtectedFilters) { 10697 // We can't deal with these just yet. No component should ever obtain a 10698 // >0 priority for a protected actions, with ONE exception -- the setup 10699 // wizard. The setup wizard, however, cannot be known until we're able to 10700 // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do 10701 // until all intent filters have been processed. Chicken, meet egg. 10702 // Let the filter temporarily have a high priority and rectify the 10703 // priorities after all system packages have been scanned. 10704 mProtectedFilters.add(intent); 10705 if (DEBUG_FILTERS) { 10706 Slog.i(TAG, "Protected action; save for later;" 10707 + " package: " + applicationInfo.packageName 10708 + " activity: " + intent.activity.className 10709 + " origPrio: " + intent.getPriority()); 10710 } 10711 return; 10712 } else { 10713 if (DEBUG_FILTERS && mSetupWizardPackage == null) { 10714 Slog.i(TAG, "No setup wizard;" 10715 + " All protected intents capped to priority 0"); 10716 } 10717 if (intent.activity.info.packageName.equals(mSetupWizardPackage)) { 10718 if (DEBUG_FILTERS) { 10719 Slog.i(TAG, "Found setup wizard;" 10720 + " allow priority " + intent.getPriority() + ";" 10721 + " package: " + intent.activity.info.packageName 10722 + " activity: " + intent.activity.className 10723 + " priority: " + intent.getPriority()); 10724 } 10725 // setup wizard gets whatever it wants 10726 return; 10727 } 10728 Slog.w(TAG, "Protected action; cap priority to 0;" 10729 + " package: " + intent.activity.info.packageName 10730 + " activity: " + intent.activity.className 10731 + " origPrio: " + intent.getPriority()); 10732 intent.setPriority(0); 10733 return; 10734 } 10735 } 10736 // privileged apps on the system image get whatever priority they request 10737 return; 10738 } 10739 10740 // privileged app unbundled update ... try to find the same activity 10741 final PackageParser.Activity foundActivity = 10742 findMatchingActivity(systemActivities, activityInfo); 10743 if (foundActivity == null) { 10744 // this is a new activity; it cannot obtain >0 priority 10745 if (DEBUG_FILTERS) { 10746 Slog.i(TAG, "New activity; cap priority to 0;" 10747 + " package: " + applicationInfo.packageName 10748 + " activity: " + intent.activity.className 10749 + " origPrio: " + intent.getPriority()); 10750 } 10751 intent.setPriority(0); 10752 return; 10753 } 10754 10755 // found activity, now check for filter equivalence 10756 10757 // a shallow copy is enough; we modify the list, not its contents 10758 final List<ActivityIntentInfo> intentListCopy = 10759 new ArrayList<>(foundActivity.intents); 10760 final List<ActivityIntentInfo> foundFilters = findFilters(intent); 10761 10762 // find matching action subsets 10763 final Iterator<String> actionsIterator = intent.actionsIterator(); 10764 if (actionsIterator != null) { 10765 getIntentListSubset( 10766 intentListCopy, new ActionIterGenerator(), actionsIterator); 10767 if (intentListCopy.size() == 0) { 10768 // no more intents to match; we're not equivalent 10769 if (DEBUG_FILTERS) { 10770 Slog.i(TAG, "Mismatched action; cap priority to 0;" 10771 + " package: " + applicationInfo.packageName 10772 + " activity: " + intent.activity.className 10773 + " origPrio: " + intent.getPriority()); 10774 } 10775 intent.setPriority(0); 10776 return; 10777 } 10778 } 10779 10780 // find matching category subsets 10781 final Iterator<String> categoriesIterator = intent.categoriesIterator(); 10782 if (categoriesIterator != null) { 10783 getIntentListSubset(intentListCopy, new CategoriesIterGenerator(), 10784 categoriesIterator); 10785 if (intentListCopy.size() == 0) { 10786 // no more intents to match; we're not equivalent 10787 if (DEBUG_FILTERS) { 10788 Slog.i(TAG, "Mismatched category; cap priority to 0;" 10789 + " package: " + applicationInfo.packageName 10790 + " activity: " + intent.activity.className 10791 + " origPrio: " + intent.getPriority()); 10792 } 10793 intent.setPriority(0); 10794 return; 10795 } 10796 } 10797 10798 // find matching schemes subsets 10799 final Iterator<String> schemesIterator = intent.schemesIterator(); 10800 if (schemesIterator != null) { 10801 getIntentListSubset(intentListCopy, new SchemesIterGenerator(), 10802 schemesIterator); 10803 if (intentListCopy.size() == 0) { 10804 // no more intents to match; we're not equivalent 10805 if (DEBUG_FILTERS) { 10806 Slog.i(TAG, "Mismatched scheme; cap priority to 0;" 10807 + " package: " + applicationInfo.packageName 10808 + " activity: " + intent.activity.className 10809 + " origPrio: " + intent.getPriority()); 10810 } 10811 intent.setPriority(0); 10812 return; 10813 } 10814 } 10815 10816 // find matching authorities subsets 10817 final Iterator<IntentFilter.AuthorityEntry> 10818 authoritiesIterator = intent.authoritiesIterator(); 10819 if (authoritiesIterator != null) { 10820 getIntentListSubset(intentListCopy, 10821 new AuthoritiesIterGenerator(), 10822 authoritiesIterator); 10823 if (intentListCopy.size() == 0) { 10824 // no more intents to match; we're not equivalent 10825 if (DEBUG_FILTERS) { 10826 Slog.i(TAG, "Mismatched authority; cap priority to 0;" 10827 + " package: " + applicationInfo.packageName 10828 + " activity: " + intent.activity.className 10829 + " origPrio: " + intent.getPriority()); 10830 } 10831 intent.setPriority(0); 10832 return; 10833 } 10834 } 10835 10836 // we found matching filter(s); app gets the max priority of all intents 10837 int cappedPriority = 0; 10838 for (int i = intentListCopy.size() - 1; i >= 0; --i) { 10839 cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority()); 10840 } 10841 if (intent.getPriority() > cappedPriority) { 10842 if (DEBUG_FILTERS) { 10843 Slog.i(TAG, "Found matching filter(s);" 10844 + " cap priority to " + cappedPriority + ";" 10845 + " package: " + applicationInfo.packageName 10846 + " activity: " + intent.activity.className 10847 + " origPrio: " + intent.getPriority()); 10848 } 10849 intent.setPriority(cappedPriority); 10850 return; 10851 } 10852 // all this for nothing; the requested priority was <= what was on the system 10853 } 10854 10855 public final void addActivity(PackageParser.Activity a, String type) { 10856 mActivities.put(a.getComponentName(), a); 10857 if (DEBUG_SHOW_INFO) 10858 Log.v( 10859 TAG, " " + type + " " + 10860 (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":"); 10861 if (DEBUG_SHOW_INFO) 10862 Log.v(TAG, " Class=" + a.info.name); 10863 final int NI = a.intents.size(); 10864 for (int j=0; j<NI; j++) { 10865 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 10866 if ("activity".equals(type)) { 10867 final PackageSetting ps = 10868 mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName); 10869 final List<PackageParser.Activity> systemActivities = 10870 ps != null && ps.pkg != null ? ps.pkg.activities : null; 10871 adjustPriority(systemActivities, intent); 10872 } 10873 if (DEBUG_SHOW_INFO) { 10874 Log.v(TAG, " IntentFilter:"); 10875 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10876 } 10877 if (!intent.debugCheck()) { 10878 Log.w(TAG, "==> For Activity " + a.info.name); 10879 } 10880 addFilter(intent); 10881 } 10882 } 10883 10884 public final void removeActivity(PackageParser.Activity a, String type) { 10885 mActivities.remove(a.getComponentName()); 10886 if (DEBUG_SHOW_INFO) { 10887 Log.v(TAG, " " + type + " " 10888 + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel 10889 : a.info.name) + ":"); 10890 Log.v(TAG, " Class=" + a.info.name); 10891 } 10892 final int NI = a.intents.size(); 10893 for (int j=0; j<NI; j++) { 10894 PackageParser.ActivityIntentInfo intent = a.intents.get(j); 10895 if (DEBUG_SHOW_INFO) { 10896 Log.v(TAG, " IntentFilter:"); 10897 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 10898 } 10899 removeFilter(intent); 10900 } 10901 } 10902 10903 @Override 10904 protected boolean allowFilterResult( 10905 PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) { 10906 ActivityInfo filterAi = filter.activity.info; 10907 for (int i=dest.size()-1; i>=0; i--) { 10908 ActivityInfo destAi = dest.get(i).activityInfo; 10909 if (destAi.name == filterAi.name 10910 && destAi.packageName == filterAi.packageName) { 10911 return false; 10912 } 10913 } 10914 return true; 10915 } 10916 10917 @Override 10918 protected ActivityIntentInfo[] newArray(int size) { 10919 return new ActivityIntentInfo[size]; 10920 } 10921 10922 @Override 10923 protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) { 10924 if (!sUserManager.exists(userId)) return true; 10925 PackageParser.Package p = filter.activity.owner; 10926 if (p != null) { 10927 PackageSetting ps = (PackageSetting)p.mExtras; 10928 if (ps != null) { 10929 // System apps are never considered stopped for purposes of 10930 // filtering, because there may be no way for the user to 10931 // actually re-launch them. 10932 return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0 10933 && ps.getStopped(userId); 10934 } 10935 } 10936 return false; 10937 } 10938 10939 @Override 10940 protected boolean isPackageForFilter(String packageName, 10941 PackageParser.ActivityIntentInfo info) { 10942 return packageName.equals(info.activity.owner.packageName); 10943 } 10944 10945 @Override 10946 protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info, 10947 int match, int userId) { 10948 if (!sUserManager.exists(userId)) return null; 10949 if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) { 10950 return null; 10951 } 10952 final PackageParser.Activity activity = info.activity; 10953 PackageSetting ps = (PackageSetting) activity.owner.mExtras; 10954 if (ps == null) { 10955 return null; 10956 } 10957 ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags, 10958 ps.readUserState(userId), userId); 10959 if (ai == null) { 10960 return null; 10961 } 10962 final ResolveInfo res = new ResolveInfo(); 10963 res.activityInfo = ai; 10964 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 10965 res.filter = info; 10966 } 10967 if (info != null) { 10968 res.handleAllWebDataURI = info.handleAllWebDataURI(); 10969 } 10970 res.priority = info.getPriority(); 10971 res.preferredOrder = activity.owner.mPreferredOrder; 10972 //System.out.println("Result: " + res.activityInfo.className + 10973 // " = " + res.priority); 10974 res.match = match; 10975 res.isDefault = info.hasDefault; 10976 res.labelRes = info.labelRes; 10977 res.nonLocalizedLabel = info.nonLocalizedLabel; 10978 if (userNeedsBadging(userId)) { 10979 res.noResourceId = true; 10980 } else { 10981 res.icon = info.icon; 10982 } 10983 res.iconResourceId = info.icon; 10984 res.system = res.activityInfo.applicationInfo.isSystemApp(); 10985 return res; 10986 } 10987 10988 @Override 10989 protected void sortResults(List<ResolveInfo> results) { 10990 Collections.sort(results, mResolvePrioritySorter); 10991 } 10992 10993 @Override 10994 protected void dumpFilter(PrintWriter out, String prefix, 10995 PackageParser.ActivityIntentInfo filter) { 10996 out.print(prefix); out.print( 10997 Integer.toHexString(System.identityHashCode(filter.activity))); 10998 out.print(' '); 10999 filter.activity.printComponentShortName(out); 11000 out.print(" filter "); 11001 out.println(Integer.toHexString(System.identityHashCode(filter))); 11002 } 11003 11004 @Override 11005 protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) { 11006 return filter.activity; 11007 } 11008 11009 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 11010 PackageParser.Activity activity = (PackageParser.Activity)label; 11011 out.print(prefix); out.print( 11012 Integer.toHexString(System.identityHashCode(activity))); 11013 out.print(' '); 11014 activity.printComponentShortName(out); 11015 if (count > 1) { 11016 out.print(" ("); out.print(count); out.print(" filters)"); 11017 } 11018 out.println(); 11019 } 11020 11021 // Keys are String (activity class name), values are Activity. 11022 private final ArrayMap<ComponentName, PackageParser.Activity> mActivities 11023 = new ArrayMap<ComponentName, PackageParser.Activity>(); 11024 private int mFlags; 11025 } 11026 11027 private final class ServiceIntentResolver 11028 extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> { 11029 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 11030 boolean defaultOnly, int userId) { 11031 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 11032 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 11033 } 11034 11035 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 11036 int userId) { 11037 if (!sUserManager.exists(userId)) return null; 11038 mFlags = flags; 11039 return super.queryIntent(intent, resolvedType, 11040 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 11041 } 11042 11043 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 11044 int flags, ArrayList<PackageParser.Service> packageServices, int userId) { 11045 if (!sUserManager.exists(userId)) return null; 11046 if (packageServices == null) { 11047 return null; 11048 } 11049 mFlags = flags; 11050 final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; 11051 final int N = packageServices.size(); 11052 ArrayList<PackageParser.ServiceIntentInfo[]> listCut = 11053 new ArrayList<PackageParser.ServiceIntentInfo[]>(N); 11054 11055 ArrayList<PackageParser.ServiceIntentInfo> intentFilters; 11056 for (int i = 0; i < N; ++i) { 11057 intentFilters = packageServices.get(i).intents; 11058 if (intentFilters != null && intentFilters.size() > 0) { 11059 PackageParser.ServiceIntentInfo[] array = 11060 new PackageParser.ServiceIntentInfo[intentFilters.size()]; 11061 intentFilters.toArray(array); 11062 listCut.add(array); 11063 } 11064 } 11065 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 11066 } 11067 11068 public final void addService(PackageParser.Service s) { 11069 mServices.put(s.getComponentName(), s); 11070 if (DEBUG_SHOW_INFO) { 11071 Log.v(TAG, " " 11072 + (s.info.nonLocalizedLabel != null 11073 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 11074 Log.v(TAG, " Class=" + s.info.name); 11075 } 11076 final int NI = s.intents.size(); 11077 int j; 11078 for (j=0; j<NI; j++) { 11079 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 11080 if (DEBUG_SHOW_INFO) { 11081 Log.v(TAG, " IntentFilter:"); 11082 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 11083 } 11084 if (!intent.debugCheck()) { 11085 Log.w(TAG, "==> For Service " + s.info.name); 11086 } 11087 addFilter(intent); 11088 } 11089 } 11090 11091 public final void removeService(PackageParser.Service s) { 11092 mServices.remove(s.getComponentName()); 11093 if (DEBUG_SHOW_INFO) { 11094 Log.v(TAG, " " + (s.info.nonLocalizedLabel != null 11095 ? s.info.nonLocalizedLabel : s.info.name) + ":"); 11096 Log.v(TAG, " Class=" + s.info.name); 11097 } 11098 final int NI = s.intents.size(); 11099 int j; 11100 for (j=0; j<NI; j++) { 11101 PackageParser.ServiceIntentInfo intent = s.intents.get(j); 11102 if (DEBUG_SHOW_INFO) { 11103 Log.v(TAG, " IntentFilter:"); 11104 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 11105 } 11106 removeFilter(intent); 11107 } 11108 } 11109 11110 @Override 11111 protected boolean allowFilterResult( 11112 PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) { 11113 ServiceInfo filterSi = filter.service.info; 11114 for (int i=dest.size()-1; i>=0; i--) { 11115 ServiceInfo destAi = dest.get(i).serviceInfo; 11116 if (destAi.name == filterSi.name 11117 && destAi.packageName == filterSi.packageName) { 11118 return false; 11119 } 11120 } 11121 return true; 11122 } 11123 11124 @Override 11125 protected PackageParser.ServiceIntentInfo[] newArray(int size) { 11126 return new PackageParser.ServiceIntentInfo[size]; 11127 } 11128 11129 @Override 11130 protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) { 11131 if (!sUserManager.exists(userId)) return true; 11132 PackageParser.Package p = filter.service.owner; 11133 if (p != null) { 11134 PackageSetting ps = (PackageSetting)p.mExtras; 11135 if (ps != null) { 11136 // System apps are never considered stopped for purposes of 11137 // filtering, because there may be no way for the user to 11138 // actually re-launch them. 11139 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 11140 && ps.getStopped(userId); 11141 } 11142 } 11143 return false; 11144 } 11145 11146 @Override 11147 protected boolean isPackageForFilter(String packageName, 11148 PackageParser.ServiceIntentInfo info) { 11149 return packageName.equals(info.service.owner.packageName); 11150 } 11151 11152 @Override 11153 protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter, 11154 int match, int userId) { 11155 if (!sUserManager.exists(userId)) return null; 11156 final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter; 11157 if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) { 11158 return null; 11159 } 11160 final PackageParser.Service service = info.service; 11161 PackageSetting ps = (PackageSetting) service.owner.mExtras; 11162 if (ps == null) { 11163 return null; 11164 } 11165 ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags, 11166 ps.readUserState(userId), userId); 11167 if (si == null) { 11168 return null; 11169 } 11170 final ResolveInfo res = new ResolveInfo(); 11171 res.serviceInfo = si; 11172 if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { 11173 res.filter = filter; 11174 } 11175 res.priority = info.getPriority(); 11176 res.preferredOrder = service.owner.mPreferredOrder; 11177 res.match = match; 11178 res.isDefault = info.hasDefault; 11179 res.labelRes = info.labelRes; 11180 res.nonLocalizedLabel = info.nonLocalizedLabel; 11181 res.icon = info.icon; 11182 res.system = res.serviceInfo.applicationInfo.isSystemApp(); 11183 return res; 11184 } 11185 11186 @Override 11187 protected void sortResults(List<ResolveInfo> results) { 11188 Collections.sort(results, mResolvePrioritySorter); 11189 } 11190 11191 @Override 11192 protected void dumpFilter(PrintWriter out, String prefix, 11193 PackageParser.ServiceIntentInfo filter) { 11194 out.print(prefix); out.print( 11195 Integer.toHexString(System.identityHashCode(filter.service))); 11196 out.print(' '); 11197 filter.service.printComponentShortName(out); 11198 out.print(" filter "); 11199 out.println(Integer.toHexString(System.identityHashCode(filter))); 11200 } 11201 11202 @Override 11203 protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) { 11204 return filter.service; 11205 } 11206 11207 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 11208 PackageParser.Service service = (PackageParser.Service)label; 11209 out.print(prefix); out.print( 11210 Integer.toHexString(System.identityHashCode(service))); 11211 out.print(' '); 11212 service.printComponentShortName(out); 11213 if (count > 1) { 11214 out.print(" ("); out.print(count); out.print(" filters)"); 11215 } 11216 out.println(); 11217 } 11218 11219// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { 11220// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); 11221// final List<ResolveInfo> retList = Lists.newArrayList(); 11222// while (i.hasNext()) { 11223// final ResolveInfo resolveInfo = (ResolveInfo) i; 11224// if (isEnabledLP(resolveInfo.serviceInfo)) { 11225// retList.add(resolveInfo); 11226// } 11227// } 11228// return retList; 11229// } 11230 11231 // Keys are String (activity class name), values are Activity. 11232 private final ArrayMap<ComponentName, PackageParser.Service> mServices 11233 = new ArrayMap<ComponentName, PackageParser.Service>(); 11234 private int mFlags; 11235 }; 11236 11237 private final class ProviderIntentResolver 11238 extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> { 11239 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, 11240 boolean defaultOnly, int userId) { 11241 mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; 11242 return super.queryIntent(intent, resolvedType, defaultOnly, userId); 11243 } 11244 11245 public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, 11246 int userId) { 11247 if (!sUserManager.exists(userId)) 11248 return null; 11249 mFlags = flags; 11250 return super.queryIntent(intent, resolvedType, 11251 (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); 11252 } 11253 11254 public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, 11255 int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) { 11256 if (!sUserManager.exists(userId)) 11257 return null; 11258 if (packageProviders == null) { 11259 return null; 11260 } 11261 mFlags = flags; 11262 final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; 11263 final int N = packageProviders.size(); 11264 ArrayList<PackageParser.ProviderIntentInfo[]> listCut = 11265 new ArrayList<PackageParser.ProviderIntentInfo[]>(N); 11266 11267 ArrayList<PackageParser.ProviderIntentInfo> intentFilters; 11268 for (int i = 0; i < N; ++i) { 11269 intentFilters = packageProviders.get(i).intents; 11270 if (intentFilters != null && intentFilters.size() > 0) { 11271 PackageParser.ProviderIntentInfo[] array = 11272 new PackageParser.ProviderIntentInfo[intentFilters.size()]; 11273 intentFilters.toArray(array); 11274 listCut.add(array); 11275 } 11276 } 11277 return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); 11278 } 11279 11280 public final void addProvider(PackageParser.Provider p) { 11281 if (mProviders.containsKey(p.getComponentName())) { 11282 Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring"); 11283 return; 11284 } 11285 11286 mProviders.put(p.getComponentName(), p); 11287 if (DEBUG_SHOW_INFO) { 11288 Log.v(TAG, " " 11289 + (p.info.nonLocalizedLabel != null 11290 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 11291 Log.v(TAG, " Class=" + p.info.name); 11292 } 11293 final int NI = p.intents.size(); 11294 int j; 11295 for (j = 0; j < NI; j++) { 11296 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 11297 if (DEBUG_SHOW_INFO) { 11298 Log.v(TAG, " IntentFilter:"); 11299 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 11300 } 11301 if (!intent.debugCheck()) { 11302 Log.w(TAG, "==> For Provider " + p.info.name); 11303 } 11304 addFilter(intent); 11305 } 11306 } 11307 11308 public final void removeProvider(PackageParser.Provider p) { 11309 mProviders.remove(p.getComponentName()); 11310 if (DEBUG_SHOW_INFO) { 11311 Log.v(TAG, " " + (p.info.nonLocalizedLabel != null 11312 ? p.info.nonLocalizedLabel : p.info.name) + ":"); 11313 Log.v(TAG, " Class=" + p.info.name); 11314 } 11315 final int NI = p.intents.size(); 11316 int j; 11317 for (j = 0; j < NI; j++) { 11318 PackageParser.ProviderIntentInfo intent = p.intents.get(j); 11319 if (DEBUG_SHOW_INFO) { 11320 Log.v(TAG, " IntentFilter:"); 11321 intent.dump(new LogPrinter(Log.VERBOSE, TAG), " "); 11322 } 11323 removeFilter(intent); 11324 } 11325 } 11326 11327 @Override 11328 protected boolean allowFilterResult( 11329 PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) { 11330 ProviderInfo filterPi = filter.provider.info; 11331 for (int i = dest.size() - 1; i >= 0; i--) { 11332 ProviderInfo destPi = dest.get(i).providerInfo; 11333 if (destPi.name == filterPi.name 11334 && destPi.packageName == filterPi.packageName) { 11335 return false; 11336 } 11337 } 11338 return true; 11339 } 11340 11341 @Override 11342 protected PackageParser.ProviderIntentInfo[] newArray(int size) { 11343 return new PackageParser.ProviderIntentInfo[size]; 11344 } 11345 11346 @Override 11347 protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) { 11348 if (!sUserManager.exists(userId)) 11349 return true; 11350 PackageParser.Package p = filter.provider.owner; 11351 if (p != null) { 11352 PackageSetting ps = (PackageSetting) p.mExtras; 11353 if (ps != null) { 11354 // System apps are never considered stopped for purposes of 11355 // filtering, because there may be no way for the user to 11356 // actually re-launch them. 11357 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0 11358 && ps.getStopped(userId); 11359 } 11360 } 11361 return false; 11362 } 11363 11364 @Override 11365 protected boolean isPackageForFilter(String packageName, 11366 PackageParser.ProviderIntentInfo info) { 11367 return packageName.equals(info.provider.owner.packageName); 11368 } 11369 11370 @Override 11371 protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter, 11372 int match, int userId) { 11373 if (!sUserManager.exists(userId)) 11374 return null; 11375 final PackageParser.ProviderIntentInfo info = filter; 11376 if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) { 11377 return null; 11378 } 11379 final PackageParser.Provider provider = info.provider; 11380 PackageSetting ps = (PackageSetting) provider.owner.mExtras; 11381 if (ps == null) { 11382 return null; 11383 } 11384 ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags, 11385 ps.readUserState(userId), userId); 11386 if (pi == null) { 11387 return null; 11388 } 11389 final ResolveInfo res = new ResolveInfo(); 11390 res.providerInfo = pi; 11391 if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) { 11392 res.filter = filter; 11393 } 11394 res.priority = info.getPriority(); 11395 res.preferredOrder = provider.owner.mPreferredOrder; 11396 res.match = match; 11397 res.isDefault = info.hasDefault; 11398 res.labelRes = info.labelRes; 11399 res.nonLocalizedLabel = info.nonLocalizedLabel; 11400 res.icon = info.icon; 11401 res.system = res.providerInfo.applicationInfo.isSystemApp(); 11402 return res; 11403 } 11404 11405 @Override 11406 protected void sortResults(List<ResolveInfo> results) { 11407 Collections.sort(results, mResolvePrioritySorter); 11408 } 11409 11410 @Override 11411 protected void dumpFilter(PrintWriter out, String prefix, 11412 PackageParser.ProviderIntentInfo filter) { 11413 out.print(prefix); 11414 out.print( 11415 Integer.toHexString(System.identityHashCode(filter.provider))); 11416 out.print(' '); 11417 filter.provider.printComponentShortName(out); 11418 out.print(" filter "); 11419 out.println(Integer.toHexString(System.identityHashCode(filter))); 11420 } 11421 11422 @Override 11423 protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) { 11424 return filter.provider; 11425 } 11426 11427 protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) { 11428 PackageParser.Provider provider = (PackageParser.Provider)label; 11429 out.print(prefix); out.print( 11430 Integer.toHexString(System.identityHashCode(provider))); 11431 out.print(' '); 11432 provider.printComponentShortName(out); 11433 if (count > 1) { 11434 out.print(" ("); out.print(count); out.print(" filters)"); 11435 } 11436 out.println(); 11437 } 11438 11439 private final ArrayMap<ComponentName, PackageParser.Provider> mProviders 11440 = new ArrayMap<ComponentName, PackageParser.Provider>(); 11441 private int mFlags; 11442 } 11443 11444 private static final class EphemeralIntentResolver 11445 extends IntentResolver<EphemeralResolveIntentInfo, EphemeralResolveInfo> { 11446 /** 11447 * The result that has the highest defined order. Ordering applies on a 11448 * per-package basis. Mapping is from package name to Pair of order and 11449 * EphemeralResolveInfo. 11450 * <p> 11451 * NOTE: This is implemented as a field variable for convenience and efficiency. 11452 * By having a field variable, we're able to track filter ordering as soon as 11453 * a non-zero order is defined. Otherwise, multiple loops across the result set 11454 * would be needed to apply ordering. If the intent resolver becomes re-entrant, 11455 * this needs to be contained entirely within {@link #filterResults()}. 11456 */ 11457 final ArrayMap<String, Pair<Integer, EphemeralResolveInfo>> mOrderResult = new ArrayMap<>(); 11458 11459 @Override 11460 protected EphemeralResolveIntentInfo[] newArray(int size) { 11461 return new EphemeralResolveIntentInfo[size]; 11462 } 11463 11464 @Override 11465 protected boolean isPackageForFilter(String packageName, EphemeralResolveIntentInfo info) { 11466 return true; 11467 } 11468 11469 @Override 11470 protected EphemeralResolveInfo newResult(EphemeralResolveIntentInfo info, int match, 11471 int userId) { 11472 if (!sUserManager.exists(userId)) { 11473 return null; 11474 } 11475 final String packageName = info.getEphemeralResolveInfo().getPackageName(); 11476 final Integer order = info.getOrder(); 11477 final Pair<Integer, EphemeralResolveInfo> lastOrderResult = 11478 mOrderResult.get(packageName); 11479 // ordering is enabled and this item's order isn't high enough 11480 if (lastOrderResult != null && lastOrderResult.first >= order) { 11481 return null; 11482 } 11483 final EphemeralResolveInfo res = info.getEphemeralResolveInfo(); 11484 if (order > 0) { 11485 // non-zero order, enable ordering 11486 mOrderResult.put(packageName, new Pair<>(order, res)); 11487 } 11488 return res; 11489 } 11490 11491 @Override 11492 protected void filterResults(List<EphemeralResolveInfo> results) { 11493 // only do work if ordering is enabled [most of the time it won't be] 11494 if (mOrderResult.size() == 0) { 11495 return; 11496 } 11497 int resultSize = results.size(); 11498 for (int i = 0; i < resultSize; i++) { 11499 final EphemeralResolveInfo info = results.get(i); 11500 final String packageName = info.getPackageName(); 11501 final Pair<Integer, EphemeralResolveInfo> savedInfo = mOrderResult.get(packageName); 11502 if (savedInfo == null) { 11503 // package doesn't having ordering 11504 continue; 11505 } 11506 if (savedInfo.second == info) { 11507 // circled back to the highest ordered item; remove from order list 11508 mOrderResult.remove(savedInfo); 11509 if (mOrderResult.size() == 0) { 11510 // no more ordered items 11511 break; 11512 } 11513 continue; 11514 } 11515 // item has a worse order, remove it from the result list 11516 results.remove(i); 11517 resultSize--; 11518 i--; 11519 } 11520 } 11521 } 11522 11523 private static final Comparator<ResolveInfo> mResolvePrioritySorter = 11524 new Comparator<ResolveInfo>() { 11525 public int compare(ResolveInfo r1, ResolveInfo r2) { 11526 int v1 = r1.priority; 11527 int v2 = r2.priority; 11528 //System.out.println("Comparing: q1=" + q1 + " q2=" + q2); 11529 if (v1 != v2) { 11530 return (v1 > v2) ? -1 : 1; 11531 } 11532 v1 = r1.preferredOrder; 11533 v2 = r2.preferredOrder; 11534 if (v1 != v2) { 11535 return (v1 > v2) ? -1 : 1; 11536 } 11537 if (r1.isDefault != r2.isDefault) { 11538 return r1.isDefault ? -1 : 1; 11539 } 11540 v1 = r1.match; 11541 v2 = r2.match; 11542 //System.out.println("Comparing: m1=" + m1 + " m2=" + m2); 11543 if (v1 != v2) { 11544 return (v1 > v2) ? -1 : 1; 11545 } 11546 if (r1.system != r2.system) { 11547 return r1.system ? -1 : 1; 11548 } 11549 if (r1.activityInfo != null) { 11550 return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName); 11551 } 11552 if (r1.serviceInfo != null) { 11553 return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName); 11554 } 11555 if (r1.providerInfo != null) { 11556 return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName); 11557 } 11558 return 0; 11559 } 11560 }; 11561 11562 private static final Comparator<ProviderInfo> mProviderInitOrderSorter = 11563 new Comparator<ProviderInfo>() { 11564 public int compare(ProviderInfo p1, ProviderInfo p2) { 11565 final int v1 = p1.initOrder; 11566 final int v2 = p2.initOrder; 11567 return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0); 11568 } 11569 }; 11570 11571 final void sendPackageBroadcast(final String action, final String pkg, final Bundle extras, 11572 final int flags, final String targetPkg, final IIntentReceiver finishedReceiver, 11573 final int[] userIds) { 11574 mHandler.post(new Runnable() { 11575 @Override 11576 public void run() { 11577 try { 11578 final IActivityManager am = ActivityManagerNative.getDefault(); 11579 if (am == null) return; 11580 final int[] resolvedUserIds; 11581 if (userIds == null) { 11582 resolvedUserIds = am.getRunningUserIds(); 11583 } else { 11584 resolvedUserIds = userIds; 11585 } 11586 for (int id : resolvedUserIds) { 11587 final Intent intent = new Intent(action, 11588 pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null); 11589 if (extras != null) { 11590 intent.putExtras(extras); 11591 } 11592 if (targetPkg != null) { 11593 intent.setPackage(targetPkg); 11594 } 11595 // Modify the UID when posting to other users 11596 int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); 11597 if (uid > 0 && UserHandle.getUserId(uid) != id) { 11598 uid = UserHandle.getUid(id, UserHandle.getAppId(uid)); 11599 intent.putExtra(Intent.EXTRA_UID, uid); 11600 } 11601 intent.putExtra(Intent.EXTRA_USER_HANDLE, id); 11602 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags); 11603 if (DEBUG_BROADCASTS) { 11604 RuntimeException here = new RuntimeException("here"); 11605 here.fillInStackTrace(); 11606 Slog.d(TAG, "Sending to user " + id + ": " 11607 + intent.toShortString(false, true, false, false) 11608 + " " + intent.getExtras(), here); 11609 } 11610 am.broadcastIntent(null, intent, null, finishedReceiver, 11611 0, null, null, null, android.app.AppOpsManager.OP_NONE, 11612 null, finishedReceiver != null, false, id); 11613 } 11614 } catch (RemoteException ex) { 11615 } 11616 } 11617 }); 11618 } 11619 11620 /** 11621 * Check if the external storage media is available. This is true if there 11622 * is a mounted external storage medium or if the external storage is 11623 * emulated. 11624 */ 11625 private boolean isExternalMediaAvailable() { 11626 return mMediaMounted || Environment.isExternalStorageEmulated(); 11627 } 11628 11629 @Override 11630 public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) { 11631 // writer 11632 synchronized (mPackages) { 11633 if (!isExternalMediaAvailable()) { 11634 // If the external storage is no longer mounted at this point, 11635 // the caller may not have been able to delete all of this 11636 // packages files and can not delete any more. Bail. 11637 return null; 11638 } 11639 final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned; 11640 if (lastPackage != null) { 11641 pkgs.remove(lastPackage); 11642 } 11643 if (pkgs.size() > 0) { 11644 return pkgs.get(0); 11645 } 11646 } 11647 return null; 11648 } 11649 11650 void schedulePackageCleaning(String packageName, int userId, boolean andCode) { 11651 final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE, 11652 userId, andCode ? 1 : 0, packageName); 11653 if (mSystemReady) { 11654 msg.sendToTarget(); 11655 } else { 11656 if (mPostSystemReadyMessages == null) { 11657 mPostSystemReadyMessages = new ArrayList<>(); 11658 } 11659 mPostSystemReadyMessages.add(msg); 11660 } 11661 } 11662 11663 void startCleaningPackages() { 11664 // reader 11665 if (!isExternalMediaAvailable()) { 11666 return; 11667 } 11668 synchronized (mPackages) { 11669 if (mSettings.mPackagesToBeCleaned.isEmpty()) { 11670 return; 11671 } 11672 } 11673 Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE); 11674 intent.setComponent(DEFAULT_CONTAINER_COMPONENT); 11675 IActivityManager am = ActivityManagerNative.getDefault(); 11676 if (am != null) { 11677 try { 11678 am.startService(null, intent, null, mContext.getOpPackageName(), 11679 UserHandle.USER_SYSTEM); 11680 } catch (RemoteException e) { 11681 } 11682 } 11683 } 11684 11685 @Override 11686 public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer, 11687 int installFlags, String installerPackageName, int userId) { 11688 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null); 11689 11690 final int callingUid = Binder.getCallingUid(); 11691 enforceCrossUserPermission(callingUid, userId, 11692 true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser"); 11693 11694 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 11695 try { 11696 if (observer != null) { 11697 observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null); 11698 } 11699 } catch (RemoteException re) { 11700 } 11701 return; 11702 } 11703 11704 if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) { 11705 installFlags |= PackageManager.INSTALL_FROM_ADB; 11706 11707 } else { 11708 // Caller holds INSTALL_PACKAGES permission, so we're less strict 11709 // about installerPackageName. 11710 11711 installFlags &= ~PackageManager.INSTALL_FROM_ADB; 11712 installFlags &= ~PackageManager.INSTALL_ALL_USERS; 11713 } 11714 11715 UserHandle user; 11716 if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) { 11717 user = UserHandle.ALL; 11718 } else { 11719 user = new UserHandle(userId); 11720 } 11721 11722 // Only system components can circumvent runtime permissions when installing. 11723 if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0 11724 && mContext.checkCallingOrSelfPermission(Manifest.permission 11725 .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) { 11726 throw new SecurityException("You need the " 11727 + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission " 11728 + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag"); 11729 } 11730 11731 final File originFile = new File(originPath); 11732 final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile); 11733 11734 final Message msg = mHandler.obtainMessage(INIT_COPY); 11735 final VerificationInfo verificationInfo = new VerificationInfo( 11736 null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid); 11737 final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer, 11738 installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user, 11739 null /*packageAbiOverride*/, null /*grantedPermissions*/, 11740 null /*certificates*/); 11741 params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params)); 11742 msg.obj = params; 11743 11744 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser", 11745 System.identityHashCode(msg.obj)); 11746 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 11747 System.identityHashCode(msg.obj)); 11748 11749 mHandler.sendMessage(msg); 11750 } 11751 11752 void installStage(String packageName, File stagedDir, String stagedCid, 11753 IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams, 11754 String installerPackageName, int installerUid, UserHandle user, 11755 Certificate[][] certificates) { 11756 if (DEBUG_EPHEMERAL) { 11757 if ((sessionParams.installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) { 11758 Slog.d(TAG, "Ephemeral install of " + packageName); 11759 } 11760 } 11761 final VerificationInfo verificationInfo = new VerificationInfo( 11762 sessionParams.originatingUri, sessionParams.referrerUri, 11763 sessionParams.originatingUid, installerUid); 11764 11765 final OriginInfo origin; 11766 if (stagedDir != null) { 11767 origin = OriginInfo.fromStagedFile(stagedDir); 11768 } else { 11769 origin = OriginInfo.fromStagedContainer(stagedCid); 11770 } 11771 11772 final Message msg = mHandler.obtainMessage(INIT_COPY); 11773 final InstallParams params = new InstallParams(origin, null, observer, 11774 sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid, 11775 verificationInfo, user, sessionParams.abiOverride, 11776 sessionParams.grantedRuntimePermissions, certificates); 11777 params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params)); 11778 msg.obj = params; 11779 11780 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage", 11781 System.identityHashCode(msg.obj)); 11782 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 11783 System.identityHashCode(msg.obj)); 11784 11785 mHandler.sendMessage(msg); 11786 } 11787 11788 private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting, 11789 int userId) { 11790 final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting); 11791 sendPackageAddedForNewUsers(packageName, isSystem, pkgSetting.appId, userId); 11792 } 11793 11794 private void sendPackageAddedForNewUsers(String packageName, boolean isSystem, 11795 int appId, int... userIds) { 11796 if (ArrayUtils.isEmpty(userIds)) { 11797 return; 11798 } 11799 Bundle extras = new Bundle(1); 11800 // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast 11801 extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userIds[0], appId)); 11802 11803 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, 11804 packageName, extras, 0, null, null, userIds); 11805 if (isSystem) { 11806 mHandler.post(() -> { 11807 for (int userId : userIds) { 11808 sendBootCompletedBroadcastToSystemApp(packageName, userId); 11809 } 11810 } 11811 ); 11812 } 11813 } 11814 11815 /** 11816 * The just-installed/enabled app is bundled on the system, so presumed to be able to run 11817 * automatically without needing an explicit launch. 11818 * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones. 11819 */ 11820 private void sendBootCompletedBroadcastToSystemApp(String packageName, int userId) { 11821 // If user is not running, the app didn't miss any broadcast 11822 if (!mUserManagerInternal.isUserRunning(userId)) { 11823 return; 11824 } 11825 final IActivityManager am = ActivityManagerNative.getDefault(); 11826 try { 11827 // Deliver LOCKED_BOOT_COMPLETED first 11828 Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED) 11829 .setPackage(packageName); 11830 final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED}; 11831 am.broadcastIntent(null, lockedBcIntent, null, null, 0, null, null, requiredPermissions, 11832 android.app.AppOpsManager.OP_NONE, null, false, false, userId); 11833 11834 // Deliver BOOT_COMPLETED only if user is unlocked 11835 if (mUserManagerInternal.isUserUnlockingOrUnlocked(userId)) { 11836 Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName); 11837 am.broadcastIntent(null, bcIntent, null, null, 0, null, null, requiredPermissions, 11838 android.app.AppOpsManager.OP_NONE, null, false, false, userId); 11839 } 11840 } catch (RemoteException e) { 11841 throw e.rethrowFromSystemServer(); 11842 } 11843 } 11844 11845 @Override 11846 public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, 11847 int userId) { 11848 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 11849 PackageSetting pkgSetting; 11850 final int uid = Binder.getCallingUid(); 11851 enforceCrossUserPermission(uid, userId, 11852 true /* requireFullPermission */, true /* checkShell */, 11853 "setApplicationHiddenSetting for user " + userId); 11854 11855 if (hidden && isPackageDeviceAdmin(packageName, userId)) { 11856 Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin"); 11857 return false; 11858 } 11859 11860 long callingId = Binder.clearCallingIdentity(); 11861 try { 11862 boolean sendAdded = false; 11863 boolean sendRemoved = false; 11864 // writer 11865 synchronized (mPackages) { 11866 pkgSetting = mSettings.mPackages.get(packageName); 11867 if (pkgSetting == null) { 11868 return false; 11869 } 11870 // Do not allow "android" is being disabled 11871 if ("android".equals(packageName)) { 11872 Slog.w(TAG, "Cannot hide package: android"); 11873 return false; 11874 } 11875 // Only allow protected packages to hide themselves. 11876 if (hidden && !UserHandle.isSameApp(uid, pkgSetting.appId) 11877 && mProtectedPackages.isPackageStateProtected(userId, packageName)) { 11878 Slog.w(TAG, "Not hiding protected package: " + packageName); 11879 return false; 11880 } 11881 11882 if (pkgSetting.getHidden(userId) != hidden) { 11883 pkgSetting.setHidden(hidden, userId); 11884 mSettings.writePackageRestrictionsLPr(userId); 11885 if (hidden) { 11886 sendRemoved = true; 11887 } else { 11888 sendAdded = true; 11889 } 11890 } 11891 } 11892 if (sendAdded) { 11893 sendPackageAddedForUser(packageName, pkgSetting, userId); 11894 return true; 11895 } 11896 if (sendRemoved) { 11897 killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId), 11898 "hiding pkg"); 11899 sendApplicationHiddenForUser(packageName, pkgSetting, userId); 11900 return true; 11901 } 11902 } finally { 11903 Binder.restoreCallingIdentity(callingId); 11904 } 11905 return false; 11906 } 11907 11908 private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting, 11909 int userId) { 11910 final PackageRemovedInfo info = new PackageRemovedInfo(); 11911 info.removedPackage = packageName; 11912 info.removedUsers = new int[] {userId}; 11913 info.uid = UserHandle.getUid(userId, pkgSetting.appId); 11914 info.sendPackageRemovedBroadcasts(true /*killApp*/); 11915 } 11916 11917 private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) { 11918 if (pkgList.length > 0) { 11919 Bundle extras = new Bundle(1); 11920 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 11921 11922 sendPackageBroadcast( 11923 suspended ? Intent.ACTION_PACKAGES_SUSPENDED 11924 : Intent.ACTION_PACKAGES_UNSUSPENDED, 11925 null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null, 11926 new int[] {userId}); 11927 } 11928 } 11929 11930 /** 11931 * Returns true if application is not found or there was an error. Otherwise it returns 11932 * the hidden state of the package for the given user. 11933 */ 11934 @Override 11935 public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) { 11936 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 11937 enforceCrossUserPermission(Binder.getCallingUid(), userId, 11938 true /* requireFullPermission */, false /* checkShell */, 11939 "getApplicationHidden for user " + userId); 11940 PackageSetting pkgSetting; 11941 long callingId = Binder.clearCallingIdentity(); 11942 try { 11943 // writer 11944 synchronized (mPackages) { 11945 pkgSetting = mSettings.mPackages.get(packageName); 11946 if (pkgSetting == null) { 11947 return true; 11948 } 11949 return pkgSetting.getHidden(userId); 11950 } 11951 } finally { 11952 Binder.restoreCallingIdentity(callingId); 11953 } 11954 } 11955 11956 /** 11957 * @hide 11958 */ 11959 @Override 11960 public int installExistingPackageAsUser(String packageName, int userId) { 11961 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, 11962 null); 11963 PackageSetting pkgSetting; 11964 final int uid = Binder.getCallingUid(); 11965 enforceCrossUserPermission(uid, userId, 11966 true /* requireFullPermission */, true /* checkShell */, 11967 "installExistingPackage for user " + userId); 11968 if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { 11969 return PackageManager.INSTALL_FAILED_USER_RESTRICTED; 11970 } 11971 11972 long callingId = Binder.clearCallingIdentity(); 11973 try { 11974 boolean installed = false; 11975 11976 // writer 11977 synchronized (mPackages) { 11978 pkgSetting = mSettings.mPackages.get(packageName); 11979 if (pkgSetting == null) { 11980 return PackageManager.INSTALL_FAILED_INVALID_URI; 11981 } 11982 if (!pkgSetting.getInstalled(userId)) { 11983 pkgSetting.setInstalled(true, userId); 11984 pkgSetting.setHidden(false, userId); 11985 mSettings.writePackageRestrictionsLPr(userId); 11986 installed = true; 11987 } 11988 } 11989 11990 if (installed) { 11991 if (pkgSetting.pkg != null) { 11992 synchronized (mInstallLock) { 11993 // We don't need to freeze for a brand new install 11994 prepareAppDataAfterInstallLIF(pkgSetting.pkg); 11995 } 11996 } 11997 sendPackageAddedForUser(packageName, pkgSetting, userId); 11998 } 11999 } finally { 12000 Binder.restoreCallingIdentity(callingId); 12001 } 12002 12003 return PackageManager.INSTALL_SUCCEEDED; 12004 } 12005 12006 boolean isUserRestricted(int userId, String restrictionKey) { 12007 Bundle restrictions = sUserManager.getUserRestrictions(userId); 12008 if (restrictions.getBoolean(restrictionKey, false)) { 12009 Log.w(TAG, "User is restricted: " + restrictionKey); 12010 return true; 12011 } 12012 return false; 12013 } 12014 12015 @Override 12016 public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended, 12017 int userId) { 12018 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); 12019 enforceCrossUserPermission(Binder.getCallingUid(), userId, 12020 true /* requireFullPermission */, true /* checkShell */, 12021 "setPackagesSuspended for user " + userId); 12022 12023 if (ArrayUtils.isEmpty(packageNames)) { 12024 return packageNames; 12025 } 12026 12027 // List of package names for whom the suspended state has changed. 12028 List<String> changedPackages = new ArrayList<>(packageNames.length); 12029 // List of package names for whom the suspended state is not set as requested in this 12030 // method. 12031 List<String> unactionedPackages = new ArrayList<>(packageNames.length); 12032 long callingId = Binder.clearCallingIdentity(); 12033 try { 12034 for (int i = 0; i < packageNames.length; i++) { 12035 String packageName = packageNames[i]; 12036 boolean changed = false; 12037 final int appId; 12038 synchronized (mPackages) { 12039 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName); 12040 if (pkgSetting == null) { 12041 Slog.w(TAG, "Could not find package setting for package \"" + packageName 12042 + "\". Skipping suspending/un-suspending."); 12043 unactionedPackages.add(packageName); 12044 continue; 12045 } 12046 appId = pkgSetting.appId; 12047 if (pkgSetting.getSuspended(userId) != suspended) { 12048 if (!canSuspendPackageForUserLocked(packageName, userId)) { 12049 unactionedPackages.add(packageName); 12050 continue; 12051 } 12052 pkgSetting.setSuspended(suspended, userId); 12053 mSettings.writePackageRestrictionsLPr(userId); 12054 changed = true; 12055 changedPackages.add(packageName); 12056 } 12057 } 12058 12059 if (changed && suspended) { 12060 killApplication(packageName, UserHandle.getUid(userId, appId), 12061 "suspending package"); 12062 } 12063 } 12064 } finally { 12065 Binder.restoreCallingIdentity(callingId); 12066 } 12067 12068 if (!changedPackages.isEmpty()) { 12069 sendPackagesSuspendedForUser(changedPackages.toArray( 12070 new String[changedPackages.size()]), userId, suspended); 12071 } 12072 12073 return unactionedPackages.toArray(new String[unactionedPackages.size()]); 12074 } 12075 12076 @Override 12077 public boolean isPackageSuspendedForUser(String packageName, int userId) { 12078 enforceCrossUserPermission(Binder.getCallingUid(), userId, 12079 true /* requireFullPermission */, false /* checkShell */, 12080 "isPackageSuspendedForUser for user " + userId); 12081 synchronized (mPackages) { 12082 final PackageSetting pkgSetting = mSettings.mPackages.get(packageName); 12083 if (pkgSetting == null) { 12084 throw new IllegalArgumentException("Unknown target package: " + packageName); 12085 } 12086 return pkgSetting.getSuspended(userId); 12087 } 12088 } 12089 12090 private boolean canSuspendPackageForUserLocked(String packageName, int userId) { 12091 if (isPackageDeviceAdmin(packageName, userId)) { 12092 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 12093 + "\": has an active device admin"); 12094 return false; 12095 } 12096 12097 String activeLauncherPackageName = getActiveLauncherPackageName(userId); 12098 if (packageName.equals(activeLauncherPackageName)) { 12099 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 12100 + "\": contains the active launcher"); 12101 return false; 12102 } 12103 12104 if (packageName.equals(mRequiredInstallerPackage)) { 12105 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 12106 + "\": required for package installation"); 12107 return false; 12108 } 12109 12110 if (packageName.equals(mRequiredUninstallerPackage)) { 12111 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 12112 + "\": required for package uninstallation"); 12113 return false; 12114 } 12115 12116 if (packageName.equals(mRequiredVerifierPackage)) { 12117 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 12118 + "\": required for package verification"); 12119 return false; 12120 } 12121 12122 if (packageName.equals(getDefaultDialerPackageName(userId))) { 12123 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 12124 + "\": is the default dialer"); 12125 return false; 12126 } 12127 12128 if (mProtectedPackages.isPackageStateProtected(userId, packageName)) { 12129 Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName 12130 + "\": protected package"); 12131 return false; 12132 } 12133 12134 return true; 12135 } 12136 12137 private String getActiveLauncherPackageName(int userId) { 12138 Intent intent = new Intent(Intent.ACTION_MAIN); 12139 intent.addCategory(Intent.CATEGORY_HOME); 12140 ResolveInfo resolveInfo = resolveIntent( 12141 intent, 12142 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 12143 PackageManager.MATCH_DEFAULT_ONLY, 12144 userId); 12145 12146 return resolveInfo == null ? null : resolveInfo.activityInfo.packageName; 12147 } 12148 12149 private String getDefaultDialerPackageName(int userId) { 12150 synchronized (mPackages) { 12151 return mSettings.getDefaultDialerPackageNameLPw(userId); 12152 } 12153 } 12154 12155 @Override 12156 public void verifyPendingInstall(int id, int verificationCode) throws RemoteException { 12157 mContext.enforceCallingOrSelfPermission( 12158 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 12159 "Only package verification agents can verify applications"); 12160 12161 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 12162 final PackageVerificationResponse response = new PackageVerificationResponse( 12163 verificationCode, Binder.getCallingUid()); 12164 msg.arg1 = id; 12165 msg.obj = response; 12166 mHandler.sendMessage(msg); 12167 } 12168 12169 @Override 12170 public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, 12171 long millisecondsToDelay) { 12172 mContext.enforceCallingOrSelfPermission( 12173 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 12174 "Only package verification agents can extend verification timeouts"); 12175 12176 final PackageVerificationState state = mPendingVerification.get(id); 12177 final PackageVerificationResponse response = new PackageVerificationResponse( 12178 verificationCodeAtTimeout, Binder.getCallingUid()); 12179 12180 if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) { 12181 millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT; 12182 } 12183 if (millisecondsToDelay < 0) { 12184 millisecondsToDelay = 0; 12185 } 12186 if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW) 12187 && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) { 12188 verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT; 12189 } 12190 12191 if ((state != null) && !state.timeoutExtended()) { 12192 state.extendTimeout(); 12193 12194 final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED); 12195 msg.arg1 = id; 12196 msg.obj = response; 12197 mHandler.sendMessageDelayed(msg, millisecondsToDelay); 12198 } 12199 } 12200 12201 private void broadcastPackageVerified(int verificationId, Uri packageUri, 12202 int verificationCode, UserHandle user) { 12203 final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED); 12204 intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE); 12205 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 12206 intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 12207 intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode); 12208 12209 mContext.sendBroadcastAsUser(intent, user, 12210 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT); 12211 } 12212 12213 private ComponentName matchComponentForVerifier(String packageName, 12214 List<ResolveInfo> receivers) { 12215 ActivityInfo targetReceiver = null; 12216 12217 final int NR = receivers.size(); 12218 for (int i = 0; i < NR; i++) { 12219 final ResolveInfo info = receivers.get(i); 12220 if (info.activityInfo == null) { 12221 continue; 12222 } 12223 12224 if (packageName.equals(info.activityInfo.packageName)) { 12225 targetReceiver = info.activityInfo; 12226 break; 12227 } 12228 } 12229 12230 if (targetReceiver == null) { 12231 return null; 12232 } 12233 12234 return new ComponentName(targetReceiver.packageName, targetReceiver.name); 12235 } 12236 12237 private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo, 12238 List<ResolveInfo> receivers, final PackageVerificationState verificationState) { 12239 if (pkgInfo.verifiers.length == 0) { 12240 return null; 12241 } 12242 12243 final int N = pkgInfo.verifiers.length; 12244 final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1); 12245 for (int i = 0; i < N; i++) { 12246 final VerifierInfo verifierInfo = pkgInfo.verifiers[i]; 12247 12248 final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName, 12249 receivers); 12250 if (comp == null) { 12251 continue; 12252 } 12253 12254 final int verifierUid = getUidForVerifier(verifierInfo); 12255 if (verifierUid == -1) { 12256 continue; 12257 } 12258 12259 if (DEBUG_VERIFY) { 12260 Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName 12261 + " with the correct signature"); 12262 } 12263 sufficientVerifiers.add(comp); 12264 verificationState.addSufficientVerifier(verifierUid); 12265 } 12266 12267 return sufficientVerifiers; 12268 } 12269 12270 private int getUidForVerifier(VerifierInfo verifierInfo) { 12271 synchronized (mPackages) { 12272 final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName); 12273 if (pkg == null) { 12274 return -1; 12275 } else if (pkg.mSignatures.length != 1) { 12276 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 12277 + " has more than one signature; ignoring"); 12278 return -1; 12279 } 12280 12281 /* 12282 * If the public key of the package's signature does not match 12283 * our expected public key, then this is a different package and 12284 * we should skip. 12285 */ 12286 12287 final byte[] expectedPublicKey; 12288 try { 12289 final Signature verifierSig = pkg.mSignatures[0]; 12290 final PublicKey publicKey = verifierSig.getPublicKey(); 12291 expectedPublicKey = publicKey.getEncoded(); 12292 } catch (CertificateException e) { 12293 return -1; 12294 } 12295 12296 final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded(); 12297 12298 if (!Arrays.equals(actualPublicKey, expectedPublicKey)) { 12299 Slog.i(TAG, "Verifier package " + verifierInfo.packageName 12300 + " does not have the expected public key; ignoring"); 12301 return -1; 12302 } 12303 12304 return pkg.applicationInfo.uid; 12305 } 12306 } 12307 12308 @Override 12309 public void finishPackageInstall(int token, boolean didLaunch) { 12310 enforceSystemOrRoot("Only the system is allowed to finish installs"); 12311 12312 if (DEBUG_INSTALL) { 12313 Slog.v(TAG, "BM finishing package install for " + token); 12314 } 12315 Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token); 12316 12317 final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0); 12318 mHandler.sendMessage(msg); 12319 } 12320 12321 /** 12322 * Get the verification agent timeout. 12323 * 12324 * @return verification timeout in milliseconds 12325 */ 12326 private long getVerificationTimeout() { 12327 return android.provider.Settings.Global.getLong(mContext.getContentResolver(), 12328 android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT, 12329 DEFAULT_VERIFICATION_TIMEOUT); 12330 } 12331 12332 /** 12333 * Get the default verification agent response code. 12334 * 12335 * @return default verification response code 12336 */ 12337 private int getDefaultVerificationResponse() { 12338 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 12339 android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE, 12340 DEFAULT_VERIFICATION_RESPONSE); 12341 } 12342 12343 /** 12344 * Check whether or not package verification has been enabled. 12345 * 12346 * @return true if verification should be performed 12347 */ 12348 private boolean isVerificationEnabled(int userId, int installFlags) { 12349 if (!DEFAULT_VERIFY_ENABLE) { 12350 return false; 12351 } 12352 // Ephemeral apps don't get the full verification treatment 12353 if ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) { 12354 if (DEBUG_EPHEMERAL) { 12355 Slog.d(TAG, "INSTALL_EPHEMERAL so skipping verification"); 12356 } 12357 return false; 12358 } 12359 12360 boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS); 12361 12362 // Check if installing from ADB 12363 if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) { 12364 // Do not run verification in a test harness environment 12365 if (ActivityManager.isRunningInTestHarness()) { 12366 return false; 12367 } 12368 if (ensureVerifyAppsEnabled) { 12369 return true; 12370 } 12371 // Check if the developer does not want package verification for ADB installs 12372 if (android.provider.Settings.Global.getInt(mContext.getContentResolver(), 12373 android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) { 12374 return false; 12375 } 12376 } 12377 12378 if (ensureVerifyAppsEnabled) { 12379 return true; 12380 } 12381 12382 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 12383 android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1; 12384 } 12385 12386 @Override 12387 public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains) 12388 throws RemoteException { 12389 mContext.enforceCallingOrSelfPermission( 12390 Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, 12391 "Only intentfilter verification agents can verify applications"); 12392 12393 final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED); 12394 final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse( 12395 Binder.getCallingUid(), verificationCode, failedDomains); 12396 msg.arg1 = id; 12397 msg.obj = response; 12398 mHandler.sendMessage(msg); 12399 } 12400 12401 @Override 12402 public int getIntentVerificationStatus(String packageName, int userId) { 12403 synchronized (mPackages) { 12404 return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId); 12405 } 12406 } 12407 12408 @Override 12409 public boolean updateIntentVerificationStatus(String packageName, int status, int userId) { 12410 mContext.enforceCallingOrSelfPermission( 12411 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 12412 12413 boolean result = false; 12414 synchronized (mPackages) { 12415 result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId); 12416 } 12417 if (result) { 12418 scheduleWritePackageRestrictionsLocked(userId); 12419 } 12420 return result; 12421 } 12422 12423 @Override 12424 public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications( 12425 String packageName) { 12426 synchronized (mPackages) { 12427 return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName)); 12428 } 12429 } 12430 12431 @Override 12432 public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) { 12433 if (TextUtils.isEmpty(packageName)) { 12434 return ParceledListSlice.emptyList(); 12435 } 12436 synchronized (mPackages) { 12437 PackageParser.Package pkg = mPackages.get(packageName); 12438 if (pkg == null || pkg.activities == null) { 12439 return ParceledListSlice.emptyList(); 12440 } 12441 final int count = pkg.activities.size(); 12442 ArrayList<IntentFilter> result = new ArrayList<>(); 12443 for (int n=0; n<count; n++) { 12444 PackageParser.Activity activity = pkg.activities.get(n); 12445 if (activity.intents != null && activity.intents.size() > 0) { 12446 result.addAll(activity.intents); 12447 } 12448 } 12449 return new ParceledListSlice<>(result); 12450 } 12451 } 12452 12453 @Override 12454 public boolean setDefaultBrowserPackageName(String packageName, int userId) { 12455 mContext.enforceCallingOrSelfPermission( 12456 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 12457 12458 synchronized (mPackages) { 12459 boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId); 12460 if (packageName != null) { 12461 result |= updateIntentVerificationStatus(packageName, 12462 PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, 12463 userId); 12464 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr( 12465 packageName, userId); 12466 } 12467 return result; 12468 } 12469 } 12470 12471 @Override 12472 public String getDefaultBrowserPackageName(int userId) { 12473 synchronized (mPackages) { 12474 return mSettings.getDefaultBrowserPackageNameLPw(userId); 12475 } 12476 } 12477 12478 /** 12479 * Get the "allow unknown sources" setting. 12480 * 12481 * @return the current "allow unknown sources" setting 12482 */ 12483 private int getUnknownSourcesSettings() { 12484 return android.provider.Settings.Secure.getInt(mContext.getContentResolver(), 12485 android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS, 12486 -1); 12487 } 12488 12489 @Override 12490 public void setInstallerPackageName(String targetPackage, String installerPackageName) { 12491 final int uid = Binder.getCallingUid(); 12492 // writer 12493 synchronized (mPackages) { 12494 PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage); 12495 if (targetPackageSetting == null) { 12496 throw new IllegalArgumentException("Unknown target package: " + targetPackage); 12497 } 12498 12499 PackageSetting installerPackageSetting; 12500 if (installerPackageName != null) { 12501 installerPackageSetting = mSettings.mPackages.get(installerPackageName); 12502 if (installerPackageSetting == null) { 12503 throw new IllegalArgumentException("Unknown installer package: " 12504 + installerPackageName); 12505 } 12506 } else { 12507 installerPackageSetting = null; 12508 } 12509 12510 Signature[] callerSignature; 12511 Object obj = mSettings.getUserIdLPr(uid); 12512 if (obj != null) { 12513 if (obj instanceof SharedUserSetting) { 12514 callerSignature = ((SharedUserSetting)obj).signatures.mSignatures; 12515 } else if (obj instanceof PackageSetting) { 12516 callerSignature = ((PackageSetting)obj).signatures.mSignatures; 12517 } else { 12518 throw new SecurityException("Bad object " + obj + " for uid " + uid); 12519 } 12520 } else { 12521 throw new SecurityException("Unknown calling UID: " + uid); 12522 } 12523 12524 // Verify: can't set installerPackageName to a package that is 12525 // not signed with the same cert as the caller. 12526 if (installerPackageSetting != null) { 12527 if (compareSignatures(callerSignature, 12528 installerPackageSetting.signatures.mSignatures) 12529 != PackageManager.SIGNATURE_MATCH) { 12530 throw new SecurityException( 12531 "Caller does not have same cert as new installer package " 12532 + installerPackageName); 12533 } 12534 } 12535 12536 // Verify: if target already has an installer package, it must 12537 // be signed with the same cert as the caller. 12538 if (targetPackageSetting.installerPackageName != null) { 12539 PackageSetting setting = mSettings.mPackages.get( 12540 targetPackageSetting.installerPackageName); 12541 // If the currently set package isn't valid, then it's always 12542 // okay to change it. 12543 if (setting != null) { 12544 if (compareSignatures(callerSignature, 12545 setting.signatures.mSignatures) 12546 != PackageManager.SIGNATURE_MATCH) { 12547 throw new SecurityException( 12548 "Caller does not have same cert as old installer package " 12549 + targetPackageSetting.installerPackageName); 12550 } 12551 } 12552 } 12553 12554 // Okay! 12555 targetPackageSetting.installerPackageName = installerPackageName; 12556 if (installerPackageName != null) { 12557 mSettings.mInstallerPackages.add(installerPackageName); 12558 } 12559 scheduleWriteSettingsLocked(); 12560 } 12561 } 12562 12563 private void processPendingInstall(final InstallArgs args, final int currentStatus) { 12564 // Queue up an async operation since the package installation may take a little while. 12565 mHandler.post(new Runnable() { 12566 public void run() { 12567 mHandler.removeCallbacks(this); 12568 // Result object to be returned 12569 PackageInstalledInfo res = new PackageInstalledInfo(); 12570 res.setReturnCode(currentStatus); 12571 res.uid = -1; 12572 res.pkg = null; 12573 res.removedInfo = null; 12574 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 12575 args.doPreInstall(res.returnCode); 12576 synchronized (mInstallLock) { 12577 installPackageTracedLI(args, res); 12578 } 12579 args.doPostInstall(res.returnCode, res.uid); 12580 } 12581 12582 // A restore should be performed at this point if (a) the install 12583 // succeeded, (b) the operation is not an update, and (c) the new 12584 // package has not opted out of backup participation. 12585 final boolean update = res.removedInfo != null 12586 && res.removedInfo.removedPackage != null; 12587 final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags; 12588 boolean doRestore = !update 12589 && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0); 12590 12591 // Set up the post-install work request bookkeeping. This will be used 12592 // and cleaned up by the post-install event handling regardless of whether 12593 // there's a restore pass performed. Token values are >= 1. 12594 int token; 12595 if (mNextInstallToken < 0) mNextInstallToken = 1; 12596 token = mNextInstallToken++; 12597 12598 PostInstallData data = new PostInstallData(args, res); 12599 mRunningInstalls.put(token, data); 12600 if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token); 12601 12602 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) { 12603 // Pass responsibility to the Backup Manager. It will perform a 12604 // restore if appropriate, then pass responsibility back to the 12605 // Package Manager to run the post-install observer callbacks 12606 // and broadcasts. 12607 IBackupManager bm = IBackupManager.Stub.asInterface( 12608 ServiceManager.getService(Context.BACKUP_SERVICE)); 12609 if (bm != null) { 12610 if (DEBUG_INSTALL) Log.v(TAG, "token " + token 12611 + " to BM for possible restore"); 12612 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token); 12613 try { 12614 // TODO: http://b/22388012 12615 if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) { 12616 bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token); 12617 } else { 12618 doRestore = false; 12619 } 12620 } catch (RemoteException e) { 12621 // can't happen; the backup manager is local 12622 } catch (Exception e) { 12623 Slog.e(TAG, "Exception trying to enqueue restore", e); 12624 doRestore = false; 12625 } 12626 } else { 12627 Slog.e(TAG, "Backup Manager not found!"); 12628 doRestore = false; 12629 } 12630 } 12631 12632 if (!doRestore) { 12633 // No restore possible, or the Backup Manager was mysteriously not 12634 // available -- just fire the post-install work request directly. 12635 if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token); 12636 12637 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token); 12638 12639 Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0); 12640 mHandler.sendMessage(msg); 12641 } 12642 } 12643 }); 12644 } 12645 12646 /** 12647 * Callback from PackageSettings whenever an app is first transitioned out of the 12648 * 'stopped' state. Normally we just issue the broadcast, but we can't do that if 12649 * the app was "launched" for a restoreAtInstall operation. Therefore we check 12650 * here whether the app is the target of an ongoing install, and only send the 12651 * broadcast immediately if it is not in that state. If it *is* undergoing a restore, 12652 * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL 12653 * handling. 12654 */ 12655 void notifyFirstLaunch(final String pkgName, final String installerPackage, final int userId) { 12656 // Serialize this with the rest of the install-process message chain. In the 12657 // restore-at-install case, this Runnable will necessarily run before the 12658 // POST_INSTALL message is processed, so the contents of mRunningInstalls 12659 // are coherent. In the non-restore case, the app has already completed install 12660 // and been launched through some other means, so it is not in a problematic 12661 // state for observers to see the FIRST_LAUNCH signal. 12662 mHandler.post(new Runnable() { 12663 @Override 12664 public void run() { 12665 for (int i = 0; i < mRunningInstalls.size(); i++) { 12666 final PostInstallData data = mRunningInstalls.valueAt(i); 12667 if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 12668 continue; 12669 } 12670 if (pkgName.equals(data.res.pkg.applicationInfo.packageName)) { 12671 // right package; but is it for the right user? 12672 for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) { 12673 if (userId == data.res.newUsers[uIndex]) { 12674 if (DEBUG_BACKUP) { 12675 Slog.i(TAG, "Package " + pkgName 12676 + " being restored so deferring FIRST_LAUNCH"); 12677 } 12678 return; 12679 } 12680 } 12681 } 12682 } 12683 // didn't find it, so not being restored 12684 if (DEBUG_BACKUP) { 12685 Slog.i(TAG, "Package " + pkgName + " sending normal FIRST_LAUNCH"); 12686 } 12687 sendFirstLaunchBroadcast(pkgName, installerPackage, new int[] {userId}); 12688 } 12689 }); 12690 } 12691 12692 private void sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds) { 12693 sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0, 12694 installerPkg, null, userIds); 12695 } 12696 12697 private abstract class HandlerParams { 12698 private static final int MAX_RETRIES = 4; 12699 12700 /** 12701 * Number of times startCopy() has been attempted and had a non-fatal 12702 * error. 12703 */ 12704 private int mRetries = 0; 12705 12706 /** User handle for the user requesting the information or installation. */ 12707 private final UserHandle mUser; 12708 String traceMethod; 12709 int traceCookie; 12710 12711 HandlerParams(UserHandle user) { 12712 mUser = user; 12713 } 12714 12715 UserHandle getUser() { 12716 return mUser; 12717 } 12718 12719 HandlerParams setTraceMethod(String traceMethod) { 12720 this.traceMethod = traceMethod; 12721 return this; 12722 } 12723 12724 HandlerParams setTraceCookie(int traceCookie) { 12725 this.traceCookie = traceCookie; 12726 return this; 12727 } 12728 12729 final boolean startCopy() { 12730 boolean res; 12731 try { 12732 if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this); 12733 12734 if (++mRetries > MAX_RETRIES) { 12735 Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up"); 12736 mHandler.sendEmptyMessage(MCS_GIVE_UP); 12737 handleServiceError(); 12738 return false; 12739 } else { 12740 handleStartCopy(); 12741 res = true; 12742 } 12743 } catch (RemoteException e) { 12744 if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT"); 12745 mHandler.sendEmptyMessage(MCS_RECONNECT); 12746 res = false; 12747 } 12748 handleReturnCode(); 12749 return res; 12750 } 12751 12752 final void serviceError() { 12753 if (DEBUG_INSTALL) Slog.i(TAG, "serviceError"); 12754 handleServiceError(); 12755 handleReturnCode(); 12756 } 12757 12758 abstract void handleStartCopy() throws RemoteException; 12759 abstract void handleServiceError(); 12760 abstract void handleReturnCode(); 12761 } 12762 12763 class MeasureParams extends HandlerParams { 12764 private final PackageStats mStats; 12765 private boolean mSuccess; 12766 12767 private final IPackageStatsObserver mObserver; 12768 12769 public MeasureParams(PackageStats stats, IPackageStatsObserver observer) { 12770 super(new UserHandle(stats.userHandle)); 12771 mObserver = observer; 12772 mStats = stats; 12773 } 12774 12775 @Override 12776 public String toString() { 12777 return "MeasureParams{" 12778 + Integer.toHexString(System.identityHashCode(this)) 12779 + " " + mStats.packageName + "}"; 12780 } 12781 12782 @Override 12783 void handleStartCopy() throws RemoteException { 12784 synchronized (mInstallLock) { 12785 mSuccess = getPackageSizeInfoLI(mStats.packageName, mStats.userHandle, mStats); 12786 } 12787 12788 if (mSuccess) { 12789 boolean mounted = false; 12790 try { 12791 final String status = Environment.getExternalStorageState(); 12792 mounted = (Environment.MEDIA_MOUNTED.equals(status) 12793 || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status)); 12794 } catch (Exception e) { 12795 } 12796 12797 if (mounted) { 12798 final UserEnvironment userEnv = new UserEnvironment(mStats.userHandle); 12799 12800 mStats.externalCacheSize = calculateDirectorySize(mContainerService, 12801 userEnv.buildExternalStorageAppCacheDirs(mStats.packageName)); 12802 12803 mStats.externalDataSize = calculateDirectorySize(mContainerService, 12804 userEnv.buildExternalStorageAppDataDirs(mStats.packageName)); 12805 12806 // Always subtract cache size, since it's a subdirectory 12807 mStats.externalDataSize -= mStats.externalCacheSize; 12808 12809 mStats.externalMediaSize = calculateDirectorySize(mContainerService, 12810 userEnv.buildExternalStorageAppMediaDirs(mStats.packageName)); 12811 12812 mStats.externalObbSize = calculateDirectorySize(mContainerService, 12813 userEnv.buildExternalStorageAppObbDirs(mStats.packageName)); 12814 } 12815 } 12816 } 12817 12818 @Override 12819 void handleReturnCode() { 12820 if (mObserver != null) { 12821 try { 12822 mObserver.onGetStatsCompleted(mStats, mSuccess); 12823 } catch (RemoteException e) { 12824 Slog.i(TAG, "Observer no longer exists."); 12825 } 12826 } 12827 } 12828 12829 @Override 12830 void handleServiceError() { 12831 Slog.e(TAG, "Could not measure application " + mStats.packageName 12832 + " external storage"); 12833 } 12834 } 12835 12836 private static long calculateDirectorySize(IMediaContainerService mcs, File[] paths) 12837 throws RemoteException { 12838 long result = 0; 12839 for (File path : paths) { 12840 result += mcs.calculateDirectorySize(path.getAbsolutePath()); 12841 } 12842 return result; 12843 } 12844 12845 private static void clearDirectory(IMediaContainerService mcs, File[] paths) { 12846 for (File path : paths) { 12847 try { 12848 mcs.clearDirectory(path.getAbsolutePath()); 12849 } catch (RemoteException e) { 12850 } 12851 } 12852 } 12853 12854 static class OriginInfo { 12855 /** 12856 * Location where install is coming from, before it has been 12857 * copied/renamed into place. This could be a single monolithic APK 12858 * file, or a cluster directory. This location may be untrusted. 12859 */ 12860 final File file; 12861 final String cid; 12862 12863 /** 12864 * Flag indicating that {@link #file} or {@link #cid} has already been 12865 * staged, meaning downstream users don't need to defensively copy the 12866 * contents. 12867 */ 12868 final boolean staged; 12869 12870 /** 12871 * Flag indicating that {@link #file} or {@link #cid} is an already 12872 * installed app that is being moved. 12873 */ 12874 final boolean existing; 12875 12876 final String resolvedPath; 12877 final File resolvedFile; 12878 12879 static OriginInfo fromNothing() { 12880 return new OriginInfo(null, null, false, false); 12881 } 12882 12883 static OriginInfo fromUntrustedFile(File file) { 12884 return new OriginInfo(file, null, false, false); 12885 } 12886 12887 static OriginInfo fromExistingFile(File file) { 12888 return new OriginInfo(file, null, false, true); 12889 } 12890 12891 static OriginInfo fromStagedFile(File file) { 12892 return new OriginInfo(file, null, true, false); 12893 } 12894 12895 static OriginInfo fromStagedContainer(String cid) { 12896 return new OriginInfo(null, cid, true, false); 12897 } 12898 12899 private OriginInfo(File file, String cid, boolean staged, boolean existing) { 12900 this.file = file; 12901 this.cid = cid; 12902 this.staged = staged; 12903 this.existing = existing; 12904 12905 if (cid != null) { 12906 resolvedPath = PackageHelper.getSdDir(cid); 12907 resolvedFile = new File(resolvedPath); 12908 } else if (file != null) { 12909 resolvedPath = file.getAbsolutePath(); 12910 resolvedFile = file; 12911 } else { 12912 resolvedPath = null; 12913 resolvedFile = null; 12914 } 12915 } 12916 } 12917 12918 static class MoveInfo { 12919 final int moveId; 12920 final String fromUuid; 12921 final String toUuid; 12922 final String packageName; 12923 final String dataAppName; 12924 final int appId; 12925 final String seinfo; 12926 final int targetSdkVersion; 12927 12928 public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName, 12929 String dataAppName, int appId, String seinfo, int targetSdkVersion) { 12930 this.moveId = moveId; 12931 this.fromUuid = fromUuid; 12932 this.toUuid = toUuid; 12933 this.packageName = packageName; 12934 this.dataAppName = dataAppName; 12935 this.appId = appId; 12936 this.seinfo = seinfo; 12937 this.targetSdkVersion = targetSdkVersion; 12938 } 12939 } 12940 12941 static class VerificationInfo { 12942 /** A constant used to indicate that a uid value is not present. */ 12943 public static final int NO_UID = -1; 12944 12945 /** URI referencing where the package was downloaded from. */ 12946 final Uri originatingUri; 12947 12948 /** HTTP referrer URI associated with the originatingURI. */ 12949 final Uri referrer; 12950 12951 /** UID of the application that the install request originated from. */ 12952 final int originatingUid; 12953 12954 /** UID of application requesting the install */ 12955 final int installerUid; 12956 12957 VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) { 12958 this.originatingUri = originatingUri; 12959 this.referrer = referrer; 12960 this.originatingUid = originatingUid; 12961 this.installerUid = installerUid; 12962 } 12963 } 12964 12965 class InstallParams extends HandlerParams { 12966 final OriginInfo origin; 12967 final MoveInfo move; 12968 final IPackageInstallObserver2 observer; 12969 int installFlags; 12970 final String installerPackageName; 12971 final String volumeUuid; 12972 private InstallArgs mArgs; 12973 private int mRet; 12974 final String packageAbiOverride; 12975 final String[] grantedRuntimePermissions; 12976 final VerificationInfo verificationInfo; 12977 final Certificate[][] certificates; 12978 12979 InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 12980 int installFlags, String installerPackageName, String volumeUuid, 12981 VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride, 12982 String[] grantedPermissions, Certificate[][] certificates) { 12983 super(user); 12984 this.origin = origin; 12985 this.move = move; 12986 this.observer = observer; 12987 this.installFlags = installFlags; 12988 this.installerPackageName = installerPackageName; 12989 this.volumeUuid = volumeUuid; 12990 this.verificationInfo = verificationInfo; 12991 this.packageAbiOverride = packageAbiOverride; 12992 this.grantedRuntimePermissions = grantedPermissions; 12993 this.certificates = certificates; 12994 } 12995 12996 @Override 12997 public String toString() { 12998 return "InstallParams{" + Integer.toHexString(System.identityHashCode(this)) 12999 + " file=" + origin.file + " cid=" + origin.cid + "}"; 13000 } 13001 13002 private int installLocationPolicy(PackageInfoLite pkgLite) { 13003 String packageName = pkgLite.packageName; 13004 int installLocation = pkgLite.installLocation; 13005 boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 13006 // reader 13007 synchronized (mPackages) { 13008 // Currently installed package which the new package is attempting to replace or 13009 // null if no such package is installed. 13010 PackageParser.Package installedPkg = mPackages.get(packageName); 13011 // Package which currently owns the data which the new package will own if installed. 13012 // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg 13013 // will be null whereas dataOwnerPkg will contain information about the package 13014 // which was uninstalled while keeping its data. 13015 PackageParser.Package dataOwnerPkg = installedPkg; 13016 if (dataOwnerPkg == null) { 13017 PackageSetting ps = mSettings.mPackages.get(packageName); 13018 if (ps != null) { 13019 dataOwnerPkg = ps.pkg; 13020 } 13021 } 13022 13023 if (dataOwnerPkg != null) { 13024 // If installed, the package will get access to data left on the device by its 13025 // predecessor. As a security measure, this is permited only if this is not a 13026 // version downgrade or if the predecessor package is marked as debuggable and 13027 // a downgrade is explicitly requested. 13028 // 13029 // On debuggable platform builds, downgrades are permitted even for 13030 // non-debuggable packages to make testing easier. Debuggable platform builds do 13031 // not offer security guarantees and thus it's OK to disable some security 13032 // mechanisms to make debugging/testing easier on those builds. However, even on 13033 // debuggable builds downgrades of packages are permitted only if requested via 13034 // installFlags. This is because we aim to keep the behavior of debuggable 13035 // platform builds as close as possible to the behavior of non-debuggable 13036 // platform builds. 13037 final boolean downgradeRequested = 13038 (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0; 13039 final boolean packageDebuggable = 13040 (dataOwnerPkg.applicationInfo.flags 13041 & ApplicationInfo.FLAG_DEBUGGABLE) != 0; 13042 final boolean downgradePermitted = 13043 (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable)); 13044 if (!downgradePermitted) { 13045 try { 13046 checkDowngrade(dataOwnerPkg, pkgLite); 13047 } catch (PackageManagerException e) { 13048 Slog.w(TAG, "Downgrade detected: " + e.getMessage()); 13049 return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE; 13050 } 13051 } 13052 } 13053 13054 if (installedPkg != null) { 13055 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 13056 // Check for updated system application. 13057 if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 13058 if (onSd) { 13059 Slog.w(TAG, "Cannot install update to system app on sdcard"); 13060 return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION; 13061 } 13062 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 13063 } else { 13064 if (onSd) { 13065 // Install flag overrides everything. 13066 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 13067 } 13068 // If current upgrade specifies particular preference 13069 if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) { 13070 // Application explicitly specified internal. 13071 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 13072 } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) { 13073 // App explictly prefers external. Let policy decide 13074 } else { 13075 // Prefer previous location 13076 if (isExternal(installedPkg)) { 13077 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 13078 } 13079 return PackageHelper.RECOMMEND_INSTALL_INTERNAL; 13080 } 13081 } 13082 } else { 13083 // Invalid install. Return error code 13084 return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS; 13085 } 13086 } 13087 } 13088 // All the special cases have been taken care of. 13089 // Return result based on recommended install location. 13090 if (onSd) { 13091 return PackageHelper.RECOMMEND_INSTALL_EXTERNAL; 13092 } 13093 return pkgLite.recommendedInstallLocation; 13094 } 13095 13096 /* 13097 * Invoke remote method to get package information and install 13098 * location values. Override install location based on default 13099 * policy if needed and then create install arguments based 13100 * on the install location. 13101 */ 13102 public void handleStartCopy() throws RemoteException { 13103 int ret = PackageManager.INSTALL_SUCCEEDED; 13104 13105 // If we're already staged, we've firmly committed to an install location 13106 if (origin.staged) { 13107 if (origin.file != null) { 13108 installFlags |= PackageManager.INSTALL_INTERNAL; 13109 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 13110 } else if (origin.cid != null) { 13111 installFlags |= PackageManager.INSTALL_EXTERNAL; 13112 installFlags &= ~PackageManager.INSTALL_INTERNAL; 13113 } else { 13114 throw new IllegalStateException("Invalid stage location"); 13115 } 13116 } 13117 13118 final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 13119 final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0; 13120 final boolean ephemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; 13121 PackageInfoLite pkgLite = null; 13122 13123 if (onInt && onSd) { 13124 // Check if both bits are set. 13125 Slog.w(TAG, "Conflicting flags specified for installing on both internal and external"); 13126 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 13127 } else if (onSd && ephemeral) { 13128 Slog.w(TAG, "Conflicting flags specified for installing ephemeral on external"); 13129 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 13130 } else { 13131 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags, 13132 packageAbiOverride); 13133 13134 if (DEBUG_EPHEMERAL && ephemeral) { 13135 Slog.v(TAG, "pkgLite for install: " + pkgLite); 13136 } 13137 13138 /* 13139 * If we have too little free space, try to free cache 13140 * before giving up. 13141 */ 13142 if (!origin.staged && pkgLite.recommendedInstallLocation 13143 == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 13144 // TODO: focus freeing disk space on the target device 13145 final StorageManager storage = StorageManager.from(mContext); 13146 final long lowThreshold = storage.getStorageLowBytes( 13147 Environment.getDataDirectory()); 13148 13149 final long sizeBytes = mContainerService.calculateInstalledSize( 13150 origin.resolvedPath, isForwardLocked(), packageAbiOverride); 13151 13152 try { 13153 mInstaller.freeCache(null, sizeBytes + lowThreshold); 13154 pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, 13155 installFlags, packageAbiOverride); 13156 } catch (InstallerException e) { 13157 Slog.w(TAG, "Failed to free cache", e); 13158 } 13159 13160 /* 13161 * The cache free must have deleted the file we 13162 * downloaded to install. 13163 * 13164 * TODO: fix the "freeCache" call to not delete 13165 * the file we care about. 13166 */ 13167 if (pkgLite.recommendedInstallLocation 13168 == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 13169 pkgLite.recommendedInstallLocation 13170 = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE; 13171 } 13172 } 13173 } 13174 13175 if (ret == PackageManager.INSTALL_SUCCEEDED) { 13176 int loc = pkgLite.recommendedInstallLocation; 13177 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) { 13178 ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; 13179 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) { 13180 ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS; 13181 } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { 13182 ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 13183 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) { 13184 ret = PackageManager.INSTALL_FAILED_INVALID_APK; 13185 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { 13186 ret = PackageManager.INSTALL_FAILED_INVALID_URI; 13187 } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) { 13188 ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE; 13189 } else { 13190 // Override with defaults if needed. 13191 loc = installLocationPolicy(pkgLite); 13192 if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) { 13193 ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE; 13194 } else if (!onSd && !onInt) { 13195 // Override install location with flags 13196 if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) { 13197 // Set the flag to install on external media. 13198 installFlags |= PackageManager.INSTALL_EXTERNAL; 13199 installFlags &= ~PackageManager.INSTALL_INTERNAL; 13200 } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) { 13201 if (DEBUG_EPHEMERAL) { 13202 Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag"); 13203 } 13204 installFlags |= PackageManager.INSTALL_EPHEMERAL; 13205 installFlags &= ~(PackageManager.INSTALL_EXTERNAL 13206 |PackageManager.INSTALL_INTERNAL); 13207 } else { 13208 // Make sure the flag for installing on external 13209 // media is unset 13210 installFlags |= PackageManager.INSTALL_INTERNAL; 13211 installFlags &= ~PackageManager.INSTALL_EXTERNAL; 13212 } 13213 } 13214 } 13215 } 13216 13217 final InstallArgs args = createInstallArgs(this); 13218 mArgs = args; 13219 13220 if (ret == PackageManager.INSTALL_SUCCEEDED) { 13221 // TODO: http://b/22976637 13222 // Apps installed for "all" users use the device owner to verify the app 13223 UserHandle verifierUser = getUser(); 13224 if (verifierUser == UserHandle.ALL) { 13225 verifierUser = UserHandle.SYSTEM; 13226 } 13227 13228 /* 13229 * Determine if we have any installed package verifiers. If we 13230 * do, then we'll defer to them to verify the packages. 13231 */ 13232 final int requiredUid = mRequiredVerifierPackage == null ? -1 13233 : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 13234 verifierUser.getIdentifier()); 13235 if (!origin.existing && requiredUid != -1 13236 && isVerificationEnabled(verifierUser.getIdentifier(), installFlags)) { 13237 final Intent verification = new Intent( 13238 Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); 13239 verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 13240 verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)), 13241 PACKAGE_MIME_TYPE); 13242 verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 13243 13244 // Query all live verifiers based on current user state 13245 final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification, 13246 PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier()); 13247 13248 if (DEBUG_VERIFY) { 13249 Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent " 13250 + verification.toString() + " with " + pkgLite.verifiers.length 13251 + " optional verifiers"); 13252 } 13253 13254 final int verificationId = mPendingVerificationToken++; 13255 13256 verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId); 13257 13258 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE, 13259 installerPackageName); 13260 13261 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, 13262 installFlags); 13263 13264 verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME, 13265 pkgLite.packageName); 13266 13267 verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE, 13268 pkgLite.versionCode); 13269 13270 if (verificationInfo != null) { 13271 if (verificationInfo.originatingUri != null) { 13272 verification.putExtra(Intent.EXTRA_ORIGINATING_URI, 13273 verificationInfo.originatingUri); 13274 } 13275 if (verificationInfo.referrer != null) { 13276 verification.putExtra(Intent.EXTRA_REFERRER, 13277 verificationInfo.referrer); 13278 } 13279 if (verificationInfo.originatingUid >= 0) { 13280 verification.putExtra(Intent.EXTRA_ORIGINATING_UID, 13281 verificationInfo.originatingUid); 13282 } 13283 if (verificationInfo.installerUid >= 0) { 13284 verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID, 13285 verificationInfo.installerUid); 13286 } 13287 } 13288 13289 final PackageVerificationState verificationState = new PackageVerificationState( 13290 requiredUid, args); 13291 13292 mPendingVerification.append(verificationId, verificationState); 13293 13294 final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite, 13295 receivers, verificationState); 13296 13297 /* 13298 * If any sufficient verifiers were listed in the package 13299 * manifest, attempt to ask them. 13300 */ 13301 if (sufficientVerifiers != null) { 13302 final int N = sufficientVerifiers.size(); 13303 if (N == 0) { 13304 Slog.i(TAG, "Additional verifiers required, but none installed."); 13305 ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE; 13306 } else { 13307 for (int i = 0; i < N; i++) { 13308 final ComponentName verifierComponent = sufficientVerifiers.get(i); 13309 13310 final Intent sufficientIntent = new Intent(verification); 13311 sufficientIntent.setComponent(verifierComponent); 13312 mContext.sendBroadcastAsUser(sufficientIntent, verifierUser); 13313 } 13314 } 13315 } 13316 13317 final ComponentName requiredVerifierComponent = matchComponentForVerifier( 13318 mRequiredVerifierPackage, receivers); 13319 if (ret == PackageManager.INSTALL_SUCCEEDED 13320 && mRequiredVerifierPackage != null) { 13321 Trace.asyncTraceBegin( 13322 TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId); 13323 /* 13324 * Send the intent to the required verification agent, 13325 * but only start the verification timeout after the 13326 * target BroadcastReceivers have run. 13327 */ 13328 verification.setComponent(requiredVerifierComponent); 13329 mContext.sendOrderedBroadcastAsUser(verification, verifierUser, 13330 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 13331 new BroadcastReceiver() { 13332 @Override 13333 public void onReceive(Context context, Intent intent) { 13334 final Message msg = mHandler 13335 .obtainMessage(CHECK_PENDING_VERIFICATION); 13336 msg.arg1 = verificationId; 13337 mHandler.sendMessageDelayed(msg, getVerificationTimeout()); 13338 } 13339 }, null, 0, null, null); 13340 13341 /* 13342 * We don't want the copy to proceed until verification 13343 * succeeds, so null out this field. 13344 */ 13345 mArgs = null; 13346 } 13347 } else { 13348 /* 13349 * No package verification is enabled, so immediately start 13350 * the remote call to initiate copy using temporary file. 13351 */ 13352 ret = args.copyApk(mContainerService, true); 13353 } 13354 } 13355 13356 mRet = ret; 13357 } 13358 13359 @Override 13360 void handleReturnCode() { 13361 // If mArgs is null, then MCS couldn't be reached. When it 13362 // reconnects, it will try again to install. At that point, this 13363 // will succeed. 13364 if (mArgs != null) { 13365 processPendingInstall(mArgs, mRet); 13366 } 13367 } 13368 13369 @Override 13370 void handleServiceError() { 13371 mArgs = createInstallArgs(this); 13372 mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 13373 } 13374 13375 public boolean isForwardLocked() { 13376 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 13377 } 13378 } 13379 13380 /** 13381 * Used during creation of InstallArgs 13382 * 13383 * @param installFlags package installation flags 13384 * @return true if should be installed on external storage 13385 */ 13386 private static boolean installOnExternalAsec(int installFlags) { 13387 if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) { 13388 return false; 13389 } 13390 if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) { 13391 return true; 13392 } 13393 return false; 13394 } 13395 13396 /** 13397 * Used during creation of InstallArgs 13398 * 13399 * @param installFlags package installation flags 13400 * @return true if should be installed as forward locked 13401 */ 13402 private static boolean installForwardLocked(int installFlags) { 13403 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 13404 } 13405 13406 private InstallArgs createInstallArgs(InstallParams params) { 13407 if (params.move != null) { 13408 return new MoveInstallArgs(params); 13409 } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) { 13410 return new AsecInstallArgs(params); 13411 } else { 13412 return new FileInstallArgs(params); 13413 } 13414 } 13415 13416 /** 13417 * Create args that describe an existing installed package. Typically used 13418 * when cleaning up old installs, or used as a move source. 13419 */ 13420 private InstallArgs createInstallArgsForExisting(int installFlags, String codePath, 13421 String resourcePath, String[] instructionSets) { 13422 final boolean isInAsec; 13423 if (installOnExternalAsec(installFlags)) { 13424 /* Apps on SD card are always in ASEC containers. */ 13425 isInAsec = true; 13426 } else if (installForwardLocked(installFlags) 13427 && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) { 13428 /* 13429 * Forward-locked apps are only in ASEC containers if they're the 13430 * new style 13431 */ 13432 isInAsec = true; 13433 } else { 13434 isInAsec = false; 13435 } 13436 13437 if (isInAsec) { 13438 return new AsecInstallArgs(codePath, instructionSets, 13439 installOnExternalAsec(installFlags), installForwardLocked(installFlags)); 13440 } else { 13441 return new FileInstallArgs(codePath, resourcePath, instructionSets); 13442 } 13443 } 13444 13445 static abstract class InstallArgs { 13446 /** @see InstallParams#origin */ 13447 final OriginInfo origin; 13448 /** @see InstallParams#move */ 13449 final MoveInfo move; 13450 13451 final IPackageInstallObserver2 observer; 13452 // Always refers to PackageManager flags only 13453 final int installFlags; 13454 final String installerPackageName; 13455 final String volumeUuid; 13456 final UserHandle user; 13457 final String abiOverride; 13458 final String[] installGrantPermissions; 13459 /** If non-null, drop an async trace when the install completes */ 13460 final String traceMethod; 13461 final int traceCookie; 13462 final Certificate[][] certificates; 13463 13464 // The list of instruction sets supported by this app. This is currently 13465 // only used during the rmdex() phase to clean up resources. We can get rid of this 13466 // if we move dex files under the common app path. 13467 /* nullable */ String[] instructionSets; 13468 13469 InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer, 13470 int installFlags, String installerPackageName, String volumeUuid, 13471 UserHandle user, String[] instructionSets, 13472 String abiOverride, String[] installGrantPermissions, 13473 String traceMethod, int traceCookie, Certificate[][] certificates) { 13474 this.origin = origin; 13475 this.move = move; 13476 this.installFlags = installFlags; 13477 this.observer = observer; 13478 this.installerPackageName = installerPackageName; 13479 this.volumeUuid = volumeUuid; 13480 this.user = user; 13481 this.instructionSets = instructionSets; 13482 this.abiOverride = abiOverride; 13483 this.installGrantPermissions = installGrantPermissions; 13484 this.traceMethod = traceMethod; 13485 this.traceCookie = traceCookie; 13486 this.certificates = certificates; 13487 } 13488 13489 abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException; 13490 abstract int doPreInstall(int status); 13491 13492 /** 13493 * Rename package into final resting place. All paths on the given 13494 * scanned package should be updated to reflect the rename. 13495 */ 13496 abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath); 13497 abstract int doPostInstall(int status, int uid); 13498 13499 /** @see PackageSettingBase#codePathString */ 13500 abstract String getCodePath(); 13501 /** @see PackageSettingBase#resourcePathString */ 13502 abstract String getResourcePath(); 13503 13504 // Need installer lock especially for dex file removal. 13505 abstract void cleanUpResourcesLI(); 13506 abstract boolean doPostDeleteLI(boolean delete); 13507 13508 /** 13509 * Called before the source arguments are copied. This is used mostly 13510 * for MoveParams when it needs to read the source file to put it in the 13511 * destination. 13512 */ 13513 int doPreCopy() { 13514 return PackageManager.INSTALL_SUCCEEDED; 13515 } 13516 13517 /** 13518 * Called after the source arguments are copied. This is used mostly for 13519 * MoveParams when it needs to read the source file to put it in the 13520 * destination. 13521 */ 13522 int doPostCopy(int uid) { 13523 return PackageManager.INSTALL_SUCCEEDED; 13524 } 13525 13526 protected boolean isFwdLocked() { 13527 return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0; 13528 } 13529 13530 protected boolean isExternalAsec() { 13531 return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; 13532 } 13533 13534 protected boolean isEphemeral() { 13535 return (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; 13536 } 13537 13538 UserHandle getUser() { 13539 return user; 13540 } 13541 } 13542 13543 private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) { 13544 if (!allCodePaths.isEmpty()) { 13545 if (instructionSets == null) { 13546 throw new IllegalStateException("instructionSet == null"); 13547 } 13548 String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets); 13549 for (String codePath : allCodePaths) { 13550 for (String dexCodeInstructionSet : dexCodeInstructionSets) { 13551 try { 13552 mInstaller.rmdex(codePath, dexCodeInstructionSet); 13553 } catch (InstallerException ignored) { 13554 } 13555 } 13556 } 13557 } 13558 } 13559 13560 /** 13561 * Logic to handle installation of non-ASEC applications, including copying 13562 * and renaming logic. 13563 */ 13564 class FileInstallArgs extends InstallArgs { 13565 private File codeFile; 13566 private File resourceFile; 13567 13568 // Example topology: 13569 // /data/app/com.example/base.apk 13570 // /data/app/com.example/split_foo.apk 13571 // /data/app/com.example/lib/arm/libfoo.so 13572 // /data/app/com.example/lib/arm64/libfoo.so 13573 // /data/app/com.example/dalvik/arm/base.apk@classes.dex 13574 13575 /** New install */ 13576 FileInstallArgs(InstallParams params) { 13577 super(params.origin, params.move, params.observer, params.installFlags, 13578 params.installerPackageName, params.volumeUuid, 13579 params.getUser(), null /*instructionSets*/, params.packageAbiOverride, 13580 params.grantedRuntimePermissions, 13581 params.traceMethod, params.traceCookie, params.certificates); 13582 if (isFwdLocked()) { 13583 throw new IllegalArgumentException("Forward locking only supported in ASEC"); 13584 } 13585 } 13586 13587 /** Existing install */ 13588 FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) { 13589 super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets, 13590 null, null, null, 0, null /*certificates*/); 13591 this.codeFile = (codePath != null) ? new File(codePath) : null; 13592 this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null; 13593 } 13594 13595 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 13596 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk"); 13597 try { 13598 return doCopyApk(imcs, temp); 13599 } finally { 13600 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 13601 } 13602 } 13603 13604 private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 13605 if (origin.staged) { 13606 if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy"); 13607 codeFile = origin.file; 13608 resourceFile = origin.file; 13609 return PackageManager.INSTALL_SUCCEEDED; 13610 } 13611 13612 try { 13613 final boolean isEphemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; 13614 final File tempDir = 13615 mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral); 13616 codeFile = tempDir; 13617 resourceFile = tempDir; 13618 } catch (IOException e) { 13619 Slog.w(TAG, "Failed to create copy file: " + e); 13620 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 13621 } 13622 13623 final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() { 13624 @Override 13625 public ParcelFileDescriptor open(String name, int mode) throws RemoteException { 13626 if (!FileUtils.isValidExtFilename(name)) { 13627 throw new IllegalArgumentException("Invalid filename: " + name); 13628 } 13629 try { 13630 final File file = new File(codeFile, name); 13631 final FileDescriptor fd = Os.open(file.getAbsolutePath(), 13632 O_RDWR | O_CREAT, 0644); 13633 Os.chmod(file.getAbsolutePath(), 0644); 13634 return new ParcelFileDescriptor(fd); 13635 } catch (ErrnoException e) { 13636 throw new RemoteException("Failed to open: " + e.getMessage()); 13637 } 13638 } 13639 }; 13640 13641 int ret = PackageManager.INSTALL_SUCCEEDED; 13642 ret = imcs.copyPackage(origin.file.getAbsolutePath(), target); 13643 if (ret != PackageManager.INSTALL_SUCCEEDED) { 13644 Slog.e(TAG, "Failed to copy package"); 13645 return ret; 13646 } 13647 13648 final File libraryRoot = new File(codeFile, LIB_DIR_NAME); 13649 NativeLibraryHelper.Handle handle = null; 13650 try { 13651 handle = NativeLibraryHelper.Handle.create(codeFile); 13652 ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot, 13653 abiOverride); 13654 } catch (IOException e) { 13655 Slog.e(TAG, "Copying native libraries failed", e); 13656 ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 13657 } finally { 13658 IoUtils.closeQuietly(handle); 13659 } 13660 13661 return ret; 13662 } 13663 13664 int doPreInstall(int status) { 13665 if (status != PackageManager.INSTALL_SUCCEEDED) { 13666 cleanUp(); 13667 } 13668 return status; 13669 } 13670 13671 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 13672 if (status != PackageManager.INSTALL_SUCCEEDED) { 13673 cleanUp(); 13674 return false; 13675 } 13676 13677 final File targetDir = codeFile.getParentFile(); 13678 final File beforeCodeFile = codeFile; 13679 final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName); 13680 13681 if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile); 13682 try { 13683 Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath()); 13684 } catch (ErrnoException e) { 13685 Slog.w(TAG, "Failed to rename", e); 13686 return false; 13687 } 13688 13689 if (!SELinux.restoreconRecursive(afterCodeFile)) { 13690 Slog.w(TAG, "Failed to restorecon"); 13691 return false; 13692 } 13693 13694 // Reflect the rename internally 13695 codeFile = afterCodeFile; 13696 resourceFile = afterCodeFile; 13697 13698 // Reflect the rename in scanned details 13699 pkg.setCodePath(afterCodeFile.getAbsolutePath()); 13700 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile, 13701 afterCodeFile, pkg.baseCodePath)); 13702 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile, 13703 afterCodeFile, pkg.splitCodePaths)); 13704 13705 // Reflect the rename in app info 13706 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 13707 pkg.setApplicationInfoCodePath(pkg.codePath); 13708 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 13709 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 13710 pkg.setApplicationInfoResourcePath(pkg.codePath); 13711 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 13712 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 13713 13714 return true; 13715 } 13716 13717 int doPostInstall(int status, int uid) { 13718 if (status != PackageManager.INSTALL_SUCCEEDED) { 13719 cleanUp(); 13720 } 13721 return status; 13722 } 13723 13724 @Override 13725 String getCodePath() { 13726 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 13727 } 13728 13729 @Override 13730 String getResourcePath() { 13731 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 13732 } 13733 13734 private boolean cleanUp() { 13735 if (codeFile == null || !codeFile.exists()) { 13736 return false; 13737 } 13738 13739 removeCodePathLI(codeFile); 13740 13741 if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) { 13742 resourceFile.delete(); 13743 } 13744 13745 return true; 13746 } 13747 13748 void cleanUpResourcesLI() { 13749 // Try enumerating all code paths before deleting 13750 List<String> allCodePaths = Collections.EMPTY_LIST; 13751 if (codeFile != null && codeFile.exists()) { 13752 try { 13753 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 13754 allCodePaths = pkg.getAllCodePaths(); 13755 } catch (PackageParserException e) { 13756 // Ignored; we tried our best 13757 } 13758 } 13759 13760 cleanUp(); 13761 removeDexFiles(allCodePaths, instructionSets); 13762 } 13763 13764 boolean doPostDeleteLI(boolean delete) { 13765 // XXX err, shouldn't we respect the delete flag? 13766 cleanUpResourcesLI(); 13767 return true; 13768 } 13769 } 13770 13771 private boolean isAsecExternal(String cid) { 13772 final String asecPath = PackageHelper.getSdFilesystem(cid); 13773 return !asecPath.startsWith(mAsecInternalPath); 13774 } 13775 13776 private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws 13777 PackageManagerException { 13778 if (copyRet < 0) { 13779 if (copyRet != PackageManager.NO_NATIVE_LIBRARIES && 13780 copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) { 13781 throw new PackageManagerException(copyRet, message); 13782 } 13783 } 13784 } 13785 13786 /** 13787 * Extract the MountService "container ID" from the full code path of an 13788 * .apk. 13789 */ 13790 static String cidFromCodePath(String fullCodePath) { 13791 int eidx = fullCodePath.lastIndexOf("/"); 13792 String subStr1 = fullCodePath.substring(0, eidx); 13793 int sidx = subStr1.lastIndexOf("/"); 13794 return subStr1.substring(sidx+1, eidx); 13795 } 13796 13797 /** 13798 * Logic to handle installation of ASEC applications, including copying and 13799 * renaming logic. 13800 */ 13801 class AsecInstallArgs extends InstallArgs { 13802 static final String RES_FILE_NAME = "pkg.apk"; 13803 static final String PUBLIC_RES_FILE_NAME = "res.zip"; 13804 13805 String cid; 13806 String packagePath; 13807 String resourcePath; 13808 13809 /** New install */ 13810 AsecInstallArgs(InstallParams params) { 13811 super(params.origin, params.move, params.observer, params.installFlags, 13812 params.installerPackageName, params.volumeUuid, 13813 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 13814 params.grantedRuntimePermissions, 13815 params.traceMethod, params.traceCookie, params.certificates); 13816 } 13817 13818 /** Existing install */ 13819 AsecInstallArgs(String fullCodePath, String[] instructionSets, 13820 boolean isExternal, boolean isForwardLocked) { 13821 super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0) 13822 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, 13823 instructionSets, null, null, null, 0, null /*certificates*/); 13824 // Hackily pretend we're still looking at a full code path 13825 if (!fullCodePath.endsWith(RES_FILE_NAME)) { 13826 fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath(); 13827 } 13828 13829 // Extract cid from fullCodePath 13830 int eidx = fullCodePath.lastIndexOf("/"); 13831 String subStr1 = fullCodePath.substring(0, eidx); 13832 int sidx = subStr1.lastIndexOf("/"); 13833 cid = subStr1.substring(sidx+1, eidx); 13834 setMountPath(subStr1); 13835 } 13836 13837 AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) { 13838 super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0) 13839 | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, 13840 instructionSets, null, null, null, 0, null /*certificates*/); 13841 this.cid = cid; 13842 setMountPath(PackageHelper.getSdDir(cid)); 13843 } 13844 13845 void createCopyFile() { 13846 cid = mInstallerService.allocateExternalStageCidLegacy(); 13847 } 13848 13849 int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { 13850 if (origin.staged && origin.cid != null) { 13851 if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy"); 13852 cid = origin.cid; 13853 setMountPath(PackageHelper.getSdDir(cid)); 13854 return PackageManager.INSTALL_SUCCEEDED; 13855 } 13856 13857 if (temp) { 13858 createCopyFile(); 13859 } else { 13860 /* 13861 * Pre-emptively destroy the container since it's destroyed if 13862 * copying fails due to it existing anyway. 13863 */ 13864 PackageHelper.destroySdDir(cid); 13865 } 13866 13867 final String newMountPath = imcs.copyPackageToContainer( 13868 origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(), 13869 isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */)); 13870 13871 if (newMountPath != null) { 13872 setMountPath(newMountPath); 13873 return PackageManager.INSTALL_SUCCEEDED; 13874 } else { 13875 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 13876 } 13877 } 13878 13879 @Override 13880 String getCodePath() { 13881 return packagePath; 13882 } 13883 13884 @Override 13885 String getResourcePath() { 13886 return resourcePath; 13887 } 13888 13889 int doPreInstall(int status) { 13890 if (status != PackageManager.INSTALL_SUCCEEDED) { 13891 // Destroy container 13892 PackageHelper.destroySdDir(cid); 13893 } else { 13894 boolean mounted = PackageHelper.isContainerMounted(cid); 13895 if (!mounted) { 13896 String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(), 13897 Process.SYSTEM_UID); 13898 if (newMountPath != null) { 13899 setMountPath(newMountPath); 13900 } else { 13901 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 13902 } 13903 } 13904 } 13905 return status; 13906 } 13907 13908 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 13909 String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME); 13910 String newMountPath = null; 13911 if (PackageHelper.isContainerMounted(cid)) { 13912 // Unmount the container 13913 if (!PackageHelper.unMountSdDir(cid)) { 13914 Slog.i(TAG, "Failed to unmount " + cid + " before renaming"); 13915 return false; 13916 } 13917 } 13918 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 13919 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId + 13920 " which might be stale. Will try to clean up."); 13921 // Clean up the stale container and proceed to recreate. 13922 if (!PackageHelper.destroySdDir(newCacheId)) { 13923 Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId); 13924 return false; 13925 } 13926 // Successfully cleaned up stale container. Try to rename again. 13927 if (!PackageHelper.renameSdDir(cid, newCacheId)) { 13928 Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId 13929 + " inspite of cleaning it up."); 13930 return false; 13931 } 13932 } 13933 if (!PackageHelper.isContainerMounted(newCacheId)) { 13934 Slog.w(TAG, "Mounting container " + newCacheId); 13935 newMountPath = PackageHelper.mountSdDir(newCacheId, 13936 getEncryptKey(), Process.SYSTEM_UID); 13937 } else { 13938 newMountPath = PackageHelper.getSdDir(newCacheId); 13939 } 13940 if (newMountPath == null) { 13941 Slog.w(TAG, "Failed to get cache path for " + newCacheId); 13942 return false; 13943 } 13944 Log.i(TAG, "Succesfully renamed " + cid + 13945 " to " + newCacheId + 13946 " at new path: " + newMountPath); 13947 cid = newCacheId; 13948 13949 final File beforeCodeFile = new File(packagePath); 13950 setMountPath(newMountPath); 13951 final File afterCodeFile = new File(packagePath); 13952 13953 // Reflect the rename in scanned details 13954 pkg.setCodePath(afterCodeFile.getAbsolutePath()); 13955 pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile, 13956 afterCodeFile, pkg.baseCodePath)); 13957 pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile, 13958 afterCodeFile, pkg.splitCodePaths)); 13959 13960 // Reflect the rename in app info 13961 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 13962 pkg.setApplicationInfoCodePath(pkg.codePath); 13963 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 13964 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 13965 pkg.setApplicationInfoResourcePath(pkg.codePath); 13966 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 13967 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 13968 13969 return true; 13970 } 13971 13972 private void setMountPath(String mountPath) { 13973 final File mountFile = new File(mountPath); 13974 13975 final File monolithicFile = new File(mountFile, RES_FILE_NAME); 13976 if (monolithicFile.exists()) { 13977 packagePath = monolithicFile.getAbsolutePath(); 13978 if (isFwdLocked()) { 13979 resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath(); 13980 } else { 13981 resourcePath = packagePath; 13982 } 13983 } else { 13984 packagePath = mountFile.getAbsolutePath(); 13985 resourcePath = packagePath; 13986 } 13987 } 13988 13989 int doPostInstall(int status, int uid) { 13990 if (status != PackageManager.INSTALL_SUCCEEDED) { 13991 cleanUp(); 13992 } else { 13993 final int groupOwner; 13994 final String protectedFile; 13995 if (isFwdLocked()) { 13996 groupOwner = UserHandle.getSharedAppGid(uid); 13997 protectedFile = RES_FILE_NAME; 13998 } else { 13999 groupOwner = -1; 14000 protectedFile = null; 14001 } 14002 14003 if (uid < Process.FIRST_APPLICATION_UID 14004 || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) { 14005 Slog.e(TAG, "Failed to finalize " + cid); 14006 PackageHelper.destroySdDir(cid); 14007 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 14008 } 14009 14010 boolean mounted = PackageHelper.isContainerMounted(cid); 14011 if (!mounted) { 14012 PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid()); 14013 } 14014 } 14015 return status; 14016 } 14017 14018 private void cleanUp() { 14019 if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp"); 14020 14021 // Destroy secure container 14022 PackageHelper.destroySdDir(cid); 14023 } 14024 14025 private List<String> getAllCodePaths() { 14026 final File codeFile = new File(getCodePath()); 14027 if (codeFile != null && codeFile.exists()) { 14028 try { 14029 final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0); 14030 return pkg.getAllCodePaths(); 14031 } catch (PackageParserException e) { 14032 // Ignored; we tried our best 14033 } 14034 } 14035 return Collections.EMPTY_LIST; 14036 } 14037 14038 void cleanUpResourcesLI() { 14039 // Enumerate all code paths before deleting 14040 cleanUpResourcesLI(getAllCodePaths()); 14041 } 14042 14043 private void cleanUpResourcesLI(List<String> allCodePaths) { 14044 cleanUp(); 14045 removeDexFiles(allCodePaths, instructionSets); 14046 } 14047 14048 String getPackageName() { 14049 return getAsecPackageName(cid); 14050 } 14051 14052 boolean doPostDeleteLI(boolean delete) { 14053 if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete); 14054 final List<String> allCodePaths = getAllCodePaths(); 14055 boolean mounted = PackageHelper.isContainerMounted(cid); 14056 if (mounted) { 14057 // Unmount first 14058 if (PackageHelper.unMountSdDir(cid)) { 14059 mounted = false; 14060 } 14061 } 14062 if (!mounted && delete) { 14063 cleanUpResourcesLI(allCodePaths); 14064 } 14065 return !mounted; 14066 } 14067 14068 @Override 14069 int doPreCopy() { 14070 if (isFwdLocked()) { 14071 if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE, 14072 MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) { 14073 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 14074 } 14075 } 14076 14077 return PackageManager.INSTALL_SUCCEEDED; 14078 } 14079 14080 @Override 14081 int doPostCopy(int uid) { 14082 if (isFwdLocked()) { 14083 if (uid < Process.FIRST_APPLICATION_UID 14084 || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid), 14085 RES_FILE_NAME)) { 14086 Slog.e(TAG, "Failed to finalize " + cid); 14087 PackageHelper.destroySdDir(cid); 14088 return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 14089 } 14090 } 14091 14092 return PackageManager.INSTALL_SUCCEEDED; 14093 } 14094 } 14095 14096 /** 14097 * Logic to handle movement of existing installed applications. 14098 */ 14099 class MoveInstallArgs extends InstallArgs { 14100 private File codeFile; 14101 private File resourceFile; 14102 14103 /** New install */ 14104 MoveInstallArgs(InstallParams params) { 14105 super(params.origin, params.move, params.observer, params.installFlags, 14106 params.installerPackageName, params.volumeUuid, 14107 params.getUser(), null /* instruction sets */, params.packageAbiOverride, 14108 params.grantedRuntimePermissions, 14109 params.traceMethod, params.traceCookie, params.certificates); 14110 } 14111 14112 int copyApk(IMediaContainerService imcs, boolean temp) { 14113 if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from " 14114 + move.fromUuid + " to " + move.toUuid); 14115 synchronized (mInstaller) { 14116 try { 14117 mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName, 14118 move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion); 14119 } catch (InstallerException e) { 14120 Slog.w(TAG, "Failed to move app", e); 14121 return PackageManager.INSTALL_FAILED_INTERNAL_ERROR; 14122 } 14123 } 14124 14125 codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName); 14126 resourceFile = codeFile; 14127 if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile); 14128 14129 return PackageManager.INSTALL_SUCCEEDED; 14130 } 14131 14132 int doPreInstall(int status) { 14133 if (status != PackageManager.INSTALL_SUCCEEDED) { 14134 cleanUp(move.toUuid); 14135 } 14136 return status; 14137 } 14138 14139 boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) { 14140 if (status != PackageManager.INSTALL_SUCCEEDED) { 14141 cleanUp(move.toUuid); 14142 return false; 14143 } 14144 14145 // Reflect the move in app info 14146 pkg.setApplicationVolumeUuid(pkg.volumeUuid); 14147 pkg.setApplicationInfoCodePath(pkg.codePath); 14148 pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath); 14149 pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths); 14150 pkg.setApplicationInfoResourcePath(pkg.codePath); 14151 pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath); 14152 pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); 14153 14154 return true; 14155 } 14156 14157 int doPostInstall(int status, int uid) { 14158 if (status == PackageManager.INSTALL_SUCCEEDED) { 14159 cleanUp(move.fromUuid); 14160 } else { 14161 cleanUp(move.toUuid); 14162 } 14163 return status; 14164 } 14165 14166 @Override 14167 String getCodePath() { 14168 return (codeFile != null) ? codeFile.getAbsolutePath() : null; 14169 } 14170 14171 @Override 14172 String getResourcePath() { 14173 return (resourceFile != null) ? resourceFile.getAbsolutePath() : null; 14174 } 14175 14176 private boolean cleanUp(String volumeUuid) { 14177 final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid), 14178 move.dataAppName); 14179 Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid); 14180 final int[] userIds = sUserManager.getUserIds(); 14181 synchronized (mInstallLock) { 14182 // Clean up both app data and code 14183 // All package moves are frozen until finished 14184 for (int userId : userIds) { 14185 try { 14186 mInstaller.destroyAppData(volumeUuid, move.packageName, userId, 14187 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0); 14188 } catch (InstallerException e) { 14189 Slog.w(TAG, String.valueOf(e)); 14190 } 14191 } 14192 removeCodePathLI(codeFile); 14193 } 14194 return true; 14195 } 14196 14197 void cleanUpResourcesLI() { 14198 throw new UnsupportedOperationException(); 14199 } 14200 14201 boolean doPostDeleteLI(boolean delete) { 14202 throw new UnsupportedOperationException(); 14203 } 14204 } 14205 14206 static String getAsecPackageName(String packageCid) { 14207 int idx = packageCid.lastIndexOf("-"); 14208 if (idx == -1) { 14209 return packageCid; 14210 } 14211 return packageCid.substring(0, idx); 14212 } 14213 14214 // Utility method used to create code paths based on package name and available index. 14215 private static String getNextCodePath(String oldCodePath, String prefix, String suffix) { 14216 String idxStr = ""; 14217 int idx = 1; 14218 // Fall back to default value of idx=1 if prefix is not 14219 // part of oldCodePath 14220 if (oldCodePath != null) { 14221 String subStr = oldCodePath; 14222 // Drop the suffix right away 14223 if (suffix != null && subStr.endsWith(suffix)) { 14224 subStr = subStr.substring(0, subStr.length() - suffix.length()); 14225 } 14226 // If oldCodePath already contains prefix find out the 14227 // ending index to either increment or decrement. 14228 int sidx = subStr.lastIndexOf(prefix); 14229 if (sidx != -1) { 14230 subStr = subStr.substring(sidx + prefix.length()); 14231 if (subStr != null) { 14232 if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) { 14233 subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length()); 14234 } 14235 try { 14236 idx = Integer.parseInt(subStr); 14237 if (idx <= 1) { 14238 idx++; 14239 } else { 14240 idx--; 14241 } 14242 } catch(NumberFormatException e) { 14243 } 14244 } 14245 } 14246 } 14247 idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx); 14248 return prefix + idxStr; 14249 } 14250 14251 private File getNextCodePath(File targetDir, String packageName) { 14252 int suffix = 1; 14253 File result; 14254 do { 14255 result = new File(targetDir, packageName + "-" + suffix); 14256 suffix++; 14257 } while (result.exists()); 14258 return result; 14259 } 14260 14261 // Utility method that returns the relative package path with respect 14262 // to the installation directory. Like say for /data/data/com.test-1.apk 14263 // string com.test-1 is returned. 14264 static String deriveCodePathName(String codePath) { 14265 if (codePath == null) { 14266 return null; 14267 } 14268 final File codeFile = new File(codePath); 14269 final String name = codeFile.getName(); 14270 if (codeFile.isDirectory()) { 14271 return name; 14272 } else if (name.endsWith(".apk") || name.endsWith(".tmp")) { 14273 final int lastDot = name.lastIndexOf('.'); 14274 return name.substring(0, lastDot); 14275 } else { 14276 Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK"); 14277 return null; 14278 } 14279 } 14280 14281 static class PackageInstalledInfo { 14282 String name; 14283 int uid; 14284 // The set of users that originally had this package installed. 14285 int[] origUsers; 14286 // The set of users that now have this package installed. 14287 int[] newUsers; 14288 PackageParser.Package pkg; 14289 int returnCode; 14290 String returnMsg; 14291 PackageRemovedInfo removedInfo; 14292 ArrayMap<String, PackageInstalledInfo> addedChildPackages; 14293 14294 public void setError(int code, String msg) { 14295 setReturnCode(code); 14296 setReturnMessage(msg); 14297 Slog.w(TAG, msg); 14298 } 14299 14300 public void setError(String msg, PackageParserException e) { 14301 setReturnCode(e.error); 14302 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e)); 14303 Slog.w(TAG, msg, e); 14304 } 14305 14306 public void setError(String msg, PackageManagerException e) { 14307 returnCode = e.error; 14308 setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e)); 14309 Slog.w(TAG, msg, e); 14310 } 14311 14312 public void setReturnCode(int returnCode) { 14313 this.returnCode = returnCode; 14314 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0; 14315 for (int i = 0; i < childCount; i++) { 14316 addedChildPackages.valueAt(i).returnCode = returnCode; 14317 } 14318 } 14319 14320 private void setReturnMessage(String returnMsg) { 14321 this.returnMsg = returnMsg; 14322 final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0; 14323 for (int i = 0; i < childCount; i++) { 14324 addedChildPackages.valueAt(i).returnMsg = returnMsg; 14325 } 14326 } 14327 14328 // In some error cases we want to convey more info back to the observer 14329 String origPackage; 14330 String origPermission; 14331 } 14332 14333 /* 14334 * Install a non-existing package. 14335 */ 14336 private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags, 14337 int scanFlags, UserHandle user, String installerPackageName, String volumeUuid, 14338 PackageInstalledInfo res) { 14339 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage"); 14340 14341 // Remember this for later, in case we need to rollback this install 14342 String pkgName = pkg.packageName; 14343 14344 if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg); 14345 14346 synchronized(mPackages) { 14347 final String renamedPackage = mSettings.getRenamedPackageLPr(pkgName); 14348 if (renamedPackage != null) { 14349 // A package with the same name is already installed, though 14350 // it has been renamed to an older name. The package we 14351 // are trying to install should be installed as an update to 14352 // the existing one, but that has not been requested, so bail. 14353 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 14354 + " without first uninstalling package running as " 14355 + renamedPackage); 14356 return; 14357 } 14358 if (mPackages.containsKey(pkgName)) { 14359 // Don't allow installation over an existing package with the same name. 14360 res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName 14361 + " without first uninstalling."); 14362 return; 14363 } 14364 } 14365 14366 try { 14367 PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 14368 System.currentTimeMillis(), user); 14369 14370 updateSettingsLI(newPackage, installerPackageName, null, res, user); 14371 14372 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 14373 prepareAppDataAfterInstallLIF(newPackage); 14374 14375 } else { 14376 // Remove package from internal structures, but keep around any 14377 // data that might have already existed 14378 deletePackageLIF(pkgName, UserHandle.ALL, false, null, 14379 PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null); 14380 } 14381 } catch (PackageManagerException e) { 14382 res.setError("Package couldn't be installed in " + pkg.codePath, e); 14383 } 14384 14385 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 14386 } 14387 14388 private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) { 14389 // Can't rotate keys during boot or if sharedUser. 14390 if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null 14391 || !oldPs.keySetData.isUsingUpgradeKeySets()) { 14392 return false; 14393 } 14394 // app is using upgradeKeySets; make sure all are valid 14395 KeySetManagerService ksms = mSettings.mKeySetManagerService; 14396 long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets(); 14397 for (int i = 0; i < upgradeKeySets.length; i++) { 14398 if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) { 14399 Slog.wtf(TAG, "Package " 14400 + (oldPs.name != null ? oldPs.name : "<null>") 14401 + " contains upgrade-key-set reference to unknown key-set: " 14402 + upgradeKeySets[i] 14403 + " reverting to signatures check."); 14404 return false; 14405 } 14406 } 14407 return true; 14408 } 14409 14410 private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) { 14411 // Upgrade keysets are being used. Determine if new package has a superset of the 14412 // required keys. 14413 long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets(); 14414 KeySetManagerService ksms = mSettings.mKeySetManagerService; 14415 for (int i = 0; i < upgradeKeySets.length; i++) { 14416 Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]); 14417 if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) { 14418 return true; 14419 } 14420 } 14421 return false; 14422 } 14423 14424 private static void updateDigest(MessageDigest digest, File file) throws IOException { 14425 try (DigestInputStream digestStream = 14426 new DigestInputStream(new FileInputStream(file), digest)) { 14427 while (digestStream.read() != -1) {} // nothing to do; just plow through the file 14428 } 14429 } 14430 14431 private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags, 14432 UserHandle user, String installerPackageName, PackageInstalledInfo res) { 14433 final boolean isEphemeral = (policyFlags & PackageParser.PARSE_IS_EPHEMERAL) != 0; 14434 14435 final PackageParser.Package oldPackage; 14436 final String pkgName = pkg.packageName; 14437 final int[] allUsers; 14438 final int[] installedUsers; 14439 14440 synchronized(mPackages) { 14441 oldPackage = mPackages.get(pkgName); 14442 if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage); 14443 14444 // don't allow upgrade to target a release SDK from a pre-release SDK 14445 final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion 14446 == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT; 14447 final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion 14448 == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT; 14449 if (oldTargetsPreRelease 14450 && !newTargetsPreRelease 14451 && ((policyFlags & PackageParser.PARSE_FORCE_SDK) == 0)) { 14452 Slog.w(TAG, "Can't install package targeting released sdk"); 14453 res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE); 14454 return; 14455 } 14456 14457 // don't allow an upgrade from full to ephemeral 14458 final boolean oldIsEphemeral = oldPackage.applicationInfo.isEphemeralApp(); 14459 if (isEphemeral && !oldIsEphemeral) { 14460 // can't downgrade from full to ephemeral 14461 Slog.w(TAG, "Can't replace app with ephemeral: " + pkgName); 14462 res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID); 14463 return; 14464 } 14465 14466 // verify signatures are valid 14467 final PackageSetting ps = mSettings.mPackages.get(pkgName); 14468 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { 14469 if (!checkUpgradeKeySetLP(ps, pkg)) { 14470 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 14471 "New package not signed by keys specified by upgrade-keysets: " 14472 + pkgName); 14473 return; 14474 } 14475 } else { 14476 // default to original signature matching 14477 if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures) 14478 != PackageManager.SIGNATURE_MATCH) { 14479 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, 14480 "New package has a different signature: " + pkgName); 14481 return; 14482 } 14483 } 14484 14485 // don't allow a system upgrade unless the upgrade hash matches 14486 if (oldPackage.restrictUpdateHash != null && oldPackage.isSystemApp()) { 14487 byte[] digestBytes = null; 14488 try { 14489 final MessageDigest digest = MessageDigest.getInstance("SHA-512"); 14490 updateDigest(digest, new File(pkg.baseCodePath)); 14491 if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) { 14492 for (String path : pkg.splitCodePaths) { 14493 updateDigest(digest, new File(path)); 14494 } 14495 } 14496 digestBytes = digest.digest(); 14497 } catch (NoSuchAlgorithmException | IOException e) { 14498 res.setError(INSTALL_FAILED_INVALID_APK, 14499 "Could not compute hash: " + pkgName); 14500 return; 14501 } 14502 if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) { 14503 res.setError(INSTALL_FAILED_INVALID_APK, 14504 "New package fails restrict-update check: " + pkgName); 14505 return; 14506 } 14507 // retain upgrade restriction 14508 pkg.restrictUpdateHash = oldPackage.restrictUpdateHash; 14509 } 14510 14511 // Check for shared user id changes 14512 String invalidPackageName = 14513 getParentOrChildPackageChangedSharedUser(oldPackage, pkg); 14514 if (invalidPackageName != null) { 14515 res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, 14516 "Package " + invalidPackageName + " tried to change user " 14517 + oldPackage.mSharedUserId); 14518 return; 14519 } 14520 14521 // In case of rollback, remember per-user/profile install state 14522 allUsers = sUserManager.getUserIds(); 14523 installedUsers = ps.queryInstalledUsers(allUsers, true); 14524 } 14525 14526 // Update what is removed 14527 res.removedInfo = new PackageRemovedInfo(); 14528 res.removedInfo.uid = oldPackage.applicationInfo.uid; 14529 res.removedInfo.removedPackage = oldPackage.packageName; 14530 res.removedInfo.isUpdate = true; 14531 res.removedInfo.origUsers = installedUsers; 14532 final int childCount = (oldPackage.childPackages != null) 14533 ? oldPackage.childPackages.size() : 0; 14534 for (int i = 0; i < childCount; i++) { 14535 boolean childPackageUpdated = false; 14536 PackageParser.Package childPkg = oldPackage.childPackages.get(i); 14537 if (res.addedChildPackages != null) { 14538 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName); 14539 if (childRes != null) { 14540 childRes.removedInfo.uid = childPkg.applicationInfo.uid; 14541 childRes.removedInfo.removedPackage = childPkg.packageName; 14542 childRes.removedInfo.isUpdate = true; 14543 childPackageUpdated = true; 14544 } 14545 } 14546 if (!childPackageUpdated) { 14547 PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(); 14548 childRemovedRes.removedPackage = childPkg.packageName; 14549 childRemovedRes.isUpdate = false; 14550 childRemovedRes.dataRemoved = true; 14551 synchronized (mPackages) { 14552 PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName); 14553 if (childPs != null) { 14554 childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true); 14555 } 14556 } 14557 if (res.removedInfo.removedChildPackages == null) { 14558 res.removedInfo.removedChildPackages = new ArrayMap<>(); 14559 } 14560 res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes); 14561 } 14562 } 14563 14564 boolean sysPkg = (isSystemApp(oldPackage)); 14565 if (sysPkg) { 14566 // Set the system/privileged flags as needed 14567 final boolean privileged = 14568 (oldPackage.applicationInfo.privateFlags 14569 & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; 14570 final int systemPolicyFlags = policyFlags 14571 | PackageParser.PARSE_IS_SYSTEM 14572 | (privileged ? PackageParser.PARSE_IS_PRIVILEGED : 0); 14573 14574 replaceSystemPackageLIF(oldPackage, pkg, systemPolicyFlags, scanFlags, 14575 user, allUsers, installerPackageName, res); 14576 } else { 14577 replaceNonSystemPackageLIF(oldPackage, pkg, policyFlags, scanFlags, 14578 user, allUsers, installerPackageName, res); 14579 } 14580 } 14581 14582 public List<String> getPreviousCodePaths(String packageName) { 14583 final PackageSetting ps = mSettings.mPackages.get(packageName); 14584 final List<String> result = new ArrayList<String>(); 14585 if (ps != null && ps.oldCodePaths != null) { 14586 result.addAll(ps.oldCodePaths); 14587 } 14588 return result; 14589 } 14590 14591 private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage, 14592 PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user, 14593 int[] allUsers, String installerPackageName, PackageInstalledInfo res) { 14594 if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old=" 14595 + deletedPackage); 14596 14597 String pkgName = deletedPackage.packageName; 14598 boolean deletedPkg = true; 14599 boolean addedPkg = false; 14600 boolean updatedSettings = false; 14601 final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0; 14602 final int deleteFlags = PackageManager.DELETE_KEEP_DATA 14603 | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP); 14604 14605 final long origUpdateTime = (pkg.mExtras != null) 14606 ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0; 14607 14608 // First delete the existing package while retaining the data directory 14609 if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags, 14610 res.removedInfo, true, pkg)) { 14611 // If the existing package wasn't successfully deleted 14612 res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI"); 14613 deletedPkg = false; 14614 } else { 14615 // Successfully deleted the old package; proceed with replace. 14616 14617 // If deleted package lived in a container, give users a chance to 14618 // relinquish resources before killing. 14619 if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) { 14620 if (DEBUG_INSTALL) { 14621 Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE"); 14622 } 14623 final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid }; 14624 final ArrayList<String> pkgList = new ArrayList<String>(1); 14625 pkgList.add(deletedPackage.applicationInfo.packageName); 14626 sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null); 14627 } 14628 14629 clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE 14630 | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 14631 clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL); 14632 14633 try { 14634 final PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, 14635 scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user); 14636 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user); 14637 14638 // Update the in-memory copy of the previous code paths. 14639 PackageSetting ps = mSettings.mPackages.get(pkgName); 14640 if (!killApp) { 14641 if (ps.oldCodePaths == null) { 14642 ps.oldCodePaths = new ArraySet<>(); 14643 } 14644 Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath); 14645 if (deletedPackage.splitCodePaths != null) { 14646 Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths); 14647 } 14648 } else { 14649 ps.oldCodePaths = null; 14650 } 14651 if (ps.childPackageNames != null) { 14652 for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) { 14653 final String childPkgName = ps.childPackageNames.get(i); 14654 final PackageSetting childPs = mSettings.mPackages.get(childPkgName); 14655 childPs.oldCodePaths = ps.oldCodePaths; 14656 } 14657 } 14658 prepareAppDataAfterInstallLIF(newPackage); 14659 addedPkg = true; 14660 } catch (PackageManagerException e) { 14661 res.setError("Package couldn't be installed in " + pkg.codePath, e); 14662 } 14663 } 14664 14665 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 14666 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName); 14667 14668 // Revert all internal state mutations and added folders for the failed install 14669 if (addedPkg) { 14670 deletePackageLIF(pkgName, null, true, allUsers, deleteFlags, 14671 res.removedInfo, true, null); 14672 } 14673 14674 // Restore the old package 14675 if (deletedPkg) { 14676 if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage); 14677 File restoreFile = new File(deletedPackage.codePath); 14678 // Parse old package 14679 boolean oldExternal = isExternal(deletedPackage); 14680 int oldParseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY | 14681 (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) | 14682 (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0); 14683 int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME; 14684 try { 14685 scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime, 14686 null); 14687 } catch (PackageManagerException e) { 14688 Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: " 14689 + e.getMessage()); 14690 return; 14691 } 14692 14693 synchronized (mPackages) { 14694 // Ensure the installer package name up to date 14695 setInstallerPackageNameLPw(deletedPackage, installerPackageName); 14696 14697 // Update permissions for restored package 14698 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL); 14699 14700 mSettings.writeLPr(); 14701 } 14702 14703 Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade"); 14704 } 14705 } else { 14706 synchronized (mPackages) { 14707 PackageSetting ps = mSettings.getPackageLPr(pkg.packageName); 14708 if (ps != null) { 14709 res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null; 14710 if (res.removedInfo.removedChildPackages != null) { 14711 final int childCount = res.removedInfo.removedChildPackages.size(); 14712 // Iterate in reverse as we may modify the collection 14713 for (int i = childCount - 1; i >= 0; i--) { 14714 String childPackageName = res.removedInfo.removedChildPackages.keyAt(i); 14715 if (res.addedChildPackages.containsKey(childPackageName)) { 14716 res.removedInfo.removedChildPackages.removeAt(i); 14717 } else { 14718 PackageRemovedInfo childInfo = res.removedInfo 14719 .removedChildPackages.valueAt(i); 14720 childInfo.removedForAllUsers = mPackages.get( 14721 childInfo.removedPackage) == null; 14722 } 14723 } 14724 } 14725 } 14726 } 14727 } 14728 } 14729 14730 private void replaceSystemPackageLIF(PackageParser.Package deletedPackage, 14731 PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user, 14732 int[] allUsers, String installerPackageName, PackageInstalledInfo res) { 14733 if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg 14734 + ", old=" + deletedPackage); 14735 14736 final boolean disabledSystem; 14737 14738 // Remove existing system package 14739 removePackageLI(deletedPackage, true); 14740 14741 synchronized (mPackages) { 14742 disabledSystem = disableSystemPackageLPw(deletedPackage, pkg); 14743 } 14744 if (!disabledSystem) { 14745 // We didn't need to disable the .apk as a current system package, 14746 // which means we are replacing another update that is already 14747 // installed. We need to make sure to delete the older one's .apk. 14748 res.removedInfo.args = createInstallArgsForExisting(0, 14749 deletedPackage.applicationInfo.getCodePath(), 14750 deletedPackage.applicationInfo.getResourcePath(), 14751 getAppDexInstructionSets(deletedPackage.applicationInfo)); 14752 } else { 14753 res.removedInfo.args = null; 14754 } 14755 14756 // Successfully disabled the old package. Now proceed with re-installation 14757 clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE 14758 | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 14759 clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL); 14760 14761 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 14762 pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP, 14763 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP); 14764 14765 PackageParser.Package newPackage = null; 14766 try { 14767 // Add the package to the internal data structures 14768 newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 0, user); 14769 14770 // Set the update and install times 14771 PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras; 14772 setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime, 14773 System.currentTimeMillis()); 14774 14775 // Update the package dynamic state if succeeded 14776 if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { 14777 // Now that the install succeeded make sure we remove data 14778 // directories for any child package the update removed. 14779 final int deletedChildCount = (deletedPackage.childPackages != null) 14780 ? deletedPackage.childPackages.size() : 0; 14781 final int newChildCount = (newPackage.childPackages != null) 14782 ? newPackage.childPackages.size() : 0; 14783 for (int i = 0; i < deletedChildCount; i++) { 14784 PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i); 14785 boolean childPackageDeleted = true; 14786 for (int j = 0; j < newChildCount; j++) { 14787 PackageParser.Package newChildPkg = newPackage.childPackages.get(j); 14788 if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) { 14789 childPackageDeleted = false; 14790 break; 14791 } 14792 } 14793 if (childPackageDeleted) { 14794 PackageSetting ps = mSettings.getDisabledSystemPkgLPr( 14795 deletedChildPkg.packageName); 14796 if (ps != null && res.removedInfo.removedChildPackages != null) { 14797 PackageRemovedInfo removedChildRes = res.removedInfo 14798 .removedChildPackages.get(deletedChildPkg.packageName); 14799 removePackageDataLIF(ps, allUsers, removedChildRes, 0, false); 14800 removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null; 14801 } 14802 } 14803 } 14804 14805 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user); 14806 prepareAppDataAfterInstallLIF(newPackage); 14807 } 14808 } catch (PackageManagerException e) { 14809 res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR); 14810 res.setError("Package couldn't be installed in " + pkg.codePath, e); 14811 } 14812 14813 if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) { 14814 // Re installation failed. Restore old information 14815 // Remove new pkg information 14816 if (newPackage != null) { 14817 removeInstalledPackageLI(newPackage, true); 14818 } 14819 // Add back the old system package 14820 try { 14821 scanPackageTracedLI(deletedPackage, policyFlags, SCAN_UPDATE_SIGNATURE, 0, user); 14822 } catch (PackageManagerException e) { 14823 Slog.e(TAG, "Failed to restore original package: " + e.getMessage()); 14824 } 14825 14826 synchronized (mPackages) { 14827 if (disabledSystem) { 14828 enableSystemPackageLPw(deletedPackage); 14829 } 14830 14831 // Ensure the installer package name up to date 14832 setInstallerPackageNameLPw(deletedPackage, installerPackageName); 14833 14834 // Update permissions for restored package 14835 updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL); 14836 14837 mSettings.writeLPr(); 14838 } 14839 14840 Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName 14841 + " after failed upgrade"); 14842 } 14843 } 14844 14845 /** 14846 * Checks whether the parent or any of the child packages have a change shared 14847 * user. For a package to be a valid update the shred users of the parent and 14848 * the children should match. We may later support changing child shared users. 14849 * @param oldPkg The updated package. 14850 * @param newPkg The update package. 14851 * @return The shared user that change between the versions. 14852 */ 14853 private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg, 14854 PackageParser.Package newPkg) { 14855 // Check parent shared user 14856 if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) { 14857 return newPkg.packageName; 14858 } 14859 // Check child shared users 14860 final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0; 14861 final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0; 14862 for (int i = 0; i < newChildCount; i++) { 14863 PackageParser.Package newChildPkg = newPkg.childPackages.get(i); 14864 // If this child was present, did it have the same shared user? 14865 for (int j = 0; j < oldChildCount; j++) { 14866 PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j); 14867 if (newChildPkg.packageName.equals(oldChildPkg.packageName) 14868 && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) { 14869 return newChildPkg.packageName; 14870 } 14871 } 14872 } 14873 return null; 14874 } 14875 14876 private void removeNativeBinariesLI(PackageSetting ps) { 14877 // Remove the lib path for the parent package 14878 if (ps != null) { 14879 NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString); 14880 // Remove the lib path for the child packages 14881 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0; 14882 for (int i = 0; i < childCount; i++) { 14883 PackageSetting childPs = null; 14884 synchronized (mPackages) { 14885 childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i)); 14886 } 14887 if (childPs != null) { 14888 NativeLibraryHelper.removeNativeBinariesLI(childPs 14889 .legacyNativeLibraryPathString); 14890 } 14891 } 14892 } 14893 } 14894 14895 private void enableSystemPackageLPw(PackageParser.Package pkg) { 14896 // Enable the parent package 14897 mSettings.enableSystemPackageLPw(pkg.packageName); 14898 // Enable the child packages 14899 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 14900 for (int i = 0; i < childCount; i++) { 14901 PackageParser.Package childPkg = pkg.childPackages.get(i); 14902 mSettings.enableSystemPackageLPw(childPkg.packageName); 14903 } 14904 } 14905 14906 private boolean disableSystemPackageLPw(PackageParser.Package oldPkg, 14907 PackageParser.Package newPkg) { 14908 // Disable the parent package (parent always replaced) 14909 boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true); 14910 // Disable the child packages 14911 final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0; 14912 for (int i = 0; i < childCount; i++) { 14913 PackageParser.Package childPkg = oldPkg.childPackages.get(i); 14914 final boolean replace = newPkg.hasChildPackage(childPkg.packageName); 14915 disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace); 14916 } 14917 return disabled; 14918 } 14919 14920 private void setInstallerPackageNameLPw(PackageParser.Package pkg, 14921 String installerPackageName) { 14922 // Enable the parent package 14923 mSettings.setInstallerPackageName(pkg.packageName, installerPackageName); 14924 // Enable the child packages 14925 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 14926 for (int i = 0; i < childCount; i++) { 14927 PackageParser.Package childPkg = pkg.childPackages.get(i); 14928 mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName); 14929 } 14930 } 14931 14932 private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) { 14933 // Collect all used permissions in the UID 14934 ArraySet<String> usedPermissions = new ArraySet<>(); 14935 final int packageCount = su.packages.size(); 14936 for (int i = 0; i < packageCount; i++) { 14937 PackageSetting ps = su.packages.valueAt(i); 14938 if (ps.pkg == null) { 14939 continue; 14940 } 14941 final int requestedPermCount = ps.pkg.requestedPermissions.size(); 14942 for (int j = 0; j < requestedPermCount; j++) { 14943 String permission = ps.pkg.requestedPermissions.get(j); 14944 BasePermission bp = mSettings.mPermissions.get(permission); 14945 if (bp != null) { 14946 usedPermissions.add(permission); 14947 } 14948 } 14949 } 14950 14951 PermissionsState permissionsState = su.getPermissionsState(); 14952 // Prune install permissions 14953 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates(); 14954 final int installPermCount = installPermStates.size(); 14955 for (int i = installPermCount - 1; i >= 0; i--) { 14956 PermissionState permissionState = installPermStates.get(i); 14957 if (!usedPermissions.contains(permissionState.getName())) { 14958 BasePermission bp = mSettings.mPermissions.get(permissionState.getName()); 14959 if (bp != null) { 14960 permissionsState.revokeInstallPermission(bp); 14961 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL, 14962 PackageManager.MASK_PERMISSION_FLAGS, 0); 14963 } 14964 } 14965 } 14966 14967 int[] runtimePermissionChangedUserIds = EmptyArray.INT; 14968 14969 // Prune runtime permissions 14970 for (int userId : allUserIds) { 14971 List<PermissionState> runtimePermStates = permissionsState 14972 .getRuntimePermissionStates(userId); 14973 final int runtimePermCount = runtimePermStates.size(); 14974 for (int i = runtimePermCount - 1; i >= 0; i--) { 14975 PermissionState permissionState = runtimePermStates.get(i); 14976 if (!usedPermissions.contains(permissionState.getName())) { 14977 BasePermission bp = mSettings.mPermissions.get(permissionState.getName()); 14978 if (bp != null) { 14979 permissionsState.revokeRuntimePermission(bp, userId); 14980 permissionsState.updatePermissionFlags(bp, userId, 14981 PackageManager.MASK_PERMISSION_FLAGS, 0); 14982 runtimePermissionChangedUserIds = ArrayUtils.appendInt( 14983 runtimePermissionChangedUserIds, userId); 14984 } 14985 } 14986 } 14987 } 14988 14989 return runtimePermissionChangedUserIds; 14990 } 14991 14992 private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName, 14993 int[] allUsers, PackageInstalledInfo res, UserHandle user) { 14994 // Update the parent package setting 14995 updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers, 14996 res, user); 14997 // Update the child packages setting 14998 final int childCount = (newPackage.childPackages != null) 14999 ? newPackage.childPackages.size() : 0; 15000 for (int i = 0; i < childCount; i++) { 15001 PackageParser.Package childPackage = newPackage.childPackages.get(i); 15002 PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName); 15003 updateSettingsInternalLI(childPackage, installerPackageName, allUsers, 15004 childRes.origUsers, childRes, user); 15005 } 15006 } 15007 15008 private void updateSettingsInternalLI(PackageParser.Package newPackage, 15009 String installerPackageName, int[] allUsers, int[] installedForUsers, 15010 PackageInstalledInfo res, UserHandle user) { 15011 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings"); 15012 15013 String pkgName = newPackage.packageName; 15014 synchronized (mPackages) { 15015 //write settings. the installStatus will be incomplete at this stage. 15016 //note that the new package setting would have already been 15017 //added to mPackages. It hasn't been persisted yet. 15018 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE); 15019 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings"); 15020 mSettings.writeLPr(); 15021 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 15022 } 15023 15024 if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath); 15025 synchronized (mPackages) { 15026 updatePermissionsLPw(newPackage.packageName, newPackage, 15027 UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0 15028 ? UPDATE_PERMISSIONS_ALL : 0)); 15029 // For system-bundled packages, we assume that installing an upgraded version 15030 // of the package implies that the user actually wants to run that new code, 15031 // so we enable the package. 15032 PackageSetting ps = mSettings.mPackages.get(pkgName); 15033 final int userId = user.getIdentifier(); 15034 if (ps != null) { 15035 if (isSystemApp(newPackage)) { 15036 if (DEBUG_INSTALL) { 15037 Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName); 15038 } 15039 // Enable system package for requested users 15040 if (res.origUsers != null) { 15041 for (int origUserId : res.origUsers) { 15042 if (userId == UserHandle.USER_ALL || userId == origUserId) { 15043 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, 15044 origUserId, installerPackageName); 15045 } 15046 } 15047 } 15048 // Also convey the prior install/uninstall state 15049 if (allUsers != null && installedForUsers != null) { 15050 for (int currentUserId : allUsers) { 15051 final boolean installed = ArrayUtils.contains( 15052 installedForUsers, currentUserId); 15053 if (DEBUG_INSTALL) { 15054 Slog.d(TAG, " user " + currentUserId + " => " + installed); 15055 } 15056 ps.setInstalled(installed, currentUserId); 15057 } 15058 // these install state changes will be persisted in the 15059 // upcoming call to mSettings.writeLPr(). 15060 } 15061 } 15062 // It's implied that when a user requests installation, they want the app to be 15063 // installed and enabled. 15064 if (userId != UserHandle.USER_ALL) { 15065 ps.setInstalled(true, userId); 15066 ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName); 15067 } 15068 } 15069 res.name = pkgName; 15070 res.uid = newPackage.applicationInfo.uid; 15071 res.pkg = newPackage; 15072 mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE); 15073 mSettings.setInstallerPackageName(pkgName, installerPackageName); 15074 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 15075 //to update install status 15076 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings"); 15077 mSettings.writeLPr(); 15078 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 15079 } 15080 15081 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 15082 } 15083 15084 private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) { 15085 try { 15086 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage"); 15087 installPackageLI(args, res); 15088 } finally { 15089 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 15090 } 15091 } 15092 15093 private void installPackageLI(InstallArgs args, PackageInstalledInfo res) { 15094 final int installFlags = args.installFlags; 15095 final String installerPackageName = args.installerPackageName; 15096 final String volumeUuid = args.volumeUuid; 15097 final File tmpPackageFile = new File(args.getCodePath()); 15098 final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0); 15099 final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) 15100 || (args.volumeUuid != null)); 15101 final boolean ephemeral = ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0); 15102 final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0); 15103 boolean replace = false; 15104 int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE; 15105 if (args.move != null) { 15106 // moving a complete application; perform an initial scan on the new install location 15107 scanFlags |= SCAN_INITIAL; 15108 } 15109 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) { 15110 scanFlags |= SCAN_DONT_KILL_APP; 15111 } 15112 15113 // Result object to be returned 15114 res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 15115 15116 if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile); 15117 15118 // Sanity check 15119 if (ephemeral && (forwardLocked || onExternal)) { 15120 Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked 15121 + " external=" + onExternal); 15122 res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID); 15123 return; 15124 } 15125 15126 // Retrieve PackageSettings and parse package 15127 final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY 15128 | PackageParser.PARSE_ENFORCE_CODE 15129 | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) 15130 | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0) 15131 | (ephemeral ? PackageParser.PARSE_IS_EPHEMERAL : 0) 15132 | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0); 15133 PackageParser pp = new PackageParser(); 15134 pp.setSeparateProcesses(mSeparateProcesses); 15135 pp.setDisplayMetrics(mMetrics); 15136 15137 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage"); 15138 final PackageParser.Package pkg; 15139 try { 15140 pkg = pp.parsePackage(tmpPackageFile, parseFlags); 15141 } catch (PackageParserException e) { 15142 res.setError("Failed parse during installPackageLI", e); 15143 return; 15144 } finally { 15145 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 15146 } 15147 15148 // If we are installing a clustered package add results for the children 15149 if (pkg.childPackages != null) { 15150 synchronized (mPackages) { 15151 final int childCount = pkg.childPackages.size(); 15152 for (int i = 0; i < childCount; i++) { 15153 PackageParser.Package childPkg = pkg.childPackages.get(i); 15154 PackageInstalledInfo childRes = new PackageInstalledInfo(); 15155 childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED); 15156 childRes.pkg = childPkg; 15157 childRes.name = childPkg.packageName; 15158 PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName); 15159 if (childPs != null) { 15160 childRes.origUsers = childPs.queryInstalledUsers( 15161 sUserManager.getUserIds(), true); 15162 } 15163 if ((mPackages.containsKey(childPkg.packageName))) { 15164 childRes.removedInfo = new PackageRemovedInfo(); 15165 childRes.removedInfo.removedPackage = childPkg.packageName; 15166 } 15167 if (res.addedChildPackages == null) { 15168 res.addedChildPackages = new ArrayMap<>(); 15169 } 15170 res.addedChildPackages.put(childPkg.packageName, childRes); 15171 } 15172 } 15173 } 15174 15175 // If package doesn't declare API override, mark that we have an install 15176 // time CPU ABI override. 15177 if (TextUtils.isEmpty(pkg.cpuAbiOverride)) { 15178 pkg.cpuAbiOverride = args.abiOverride; 15179 } 15180 15181 String pkgName = res.name = pkg.packageName; 15182 if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) { 15183 if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) { 15184 res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI"); 15185 return; 15186 } 15187 } 15188 15189 try { 15190 // either use what we've been given or parse directly from the APK 15191 if (args.certificates != null) { 15192 try { 15193 PackageParser.populateCertificates(pkg, args.certificates); 15194 } catch (PackageParserException e) { 15195 // there was something wrong with the certificates we were given; 15196 // try to pull them from the APK 15197 PackageParser.collectCertificates(pkg, parseFlags); 15198 } 15199 } else { 15200 PackageParser.collectCertificates(pkg, parseFlags); 15201 } 15202 } catch (PackageParserException e) { 15203 res.setError("Failed collect during installPackageLI", e); 15204 return; 15205 } 15206 15207 // Get rid of all references to package scan path via parser. 15208 pp = null; 15209 String oldCodePath = null; 15210 boolean systemApp = false; 15211 synchronized (mPackages) { 15212 // Check if installing already existing package 15213 if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { 15214 String oldName = mSettings.getRenamedPackageLPr(pkgName); 15215 if (pkg.mOriginalPackages != null 15216 && pkg.mOriginalPackages.contains(oldName) 15217 && mPackages.containsKey(oldName)) { 15218 // This package is derived from an original package, 15219 // and this device has been updating from that original 15220 // name. We must continue using the original name, so 15221 // rename the new package here. 15222 pkg.setPackageName(oldName); 15223 pkgName = pkg.packageName; 15224 replace = true; 15225 if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName=" 15226 + oldName + " pkgName=" + pkgName); 15227 } else if (mPackages.containsKey(pkgName)) { 15228 // This package, under its official name, already exists 15229 // on the device; we should replace it. 15230 replace = true; 15231 if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName); 15232 } 15233 15234 // Child packages are installed through the parent package 15235 if (pkg.parentPackage != null) { 15236 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME, 15237 "Package " + pkg.packageName + " is child of package " 15238 + pkg.parentPackage.parentPackage + ". Child packages " 15239 + "can be updated only through the parent package."); 15240 return; 15241 } 15242 15243 if (replace) { 15244 // Prevent apps opting out from runtime permissions 15245 PackageParser.Package oldPackage = mPackages.get(pkgName); 15246 final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion; 15247 final int newTargetSdk = pkg.applicationInfo.targetSdkVersion; 15248 if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1 15249 && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) { 15250 res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE, 15251 "Package " + pkg.packageName + " new target SDK " + newTargetSdk 15252 + " doesn't support runtime permissions but the old" 15253 + " target SDK " + oldTargetSdk + " does."); 15254 return; 15255 } 15256 15257 // Prevent installing of child packages 15258 if (oldPackage.parentPackage != null) { 15259 res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME, 15260 "Package " + pkg.packageName + " is child of package " 15261 + oldPackage.parentPackage + ". Child packages " 15262 + "can be updated only through the parent package."); 15263 return; 15264 } 15265 } 15266 } 15267 15268 PackageSetting ps = mSettings.mPackages.get(pkgName); 15269 if (ps != null) { 15270 if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps); 15271 15272 // Quick sanity check that we're signed correctly if updating; 15273 // we'll check this again later when scanning, but we want to 15274 // bail early here before tripping over redefined permissions. 15275 if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { 15276 if (!checkUpgradeKeySetLP(ps, pkg)) { 15277 res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " 15278 + pkg.packageName + " upgrade keys do not match the " 15279 + "previously installed version"); 15280 return; 15281 } 15282 } else { 15283 try { 15284 verifySignaturesLP(ps, pkg); 15285 } catch (PackageManagerException e) { 15286 res.setError(e.error, e.getMessage()); 15287 return; 15288 } 15289 } 15290 15291 oldCodePath = mSettings.mPackages.get(pkgName).codePathString; 15292 if (ps.pkg != null && ps.pkg.applicationInfo != null) { 15293 systemApp = (ps.pkg.applicationInfo.flags & 15294 ApplicationInfo.FLAG_SYSTEM) != 0; 15295 } 15296 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 15297 } 15298 15299 // Check whether the newly-scanned package wants to define an already-defined perm 15300 int N = pkg.permissions.size(); 15301 for (int i = N-1; i >= 0; i--) { 15302 PackageParser.Permission perm = pkg.permissions.get(i); 15303 BasePermission bp = mSettings.mPermissions.get(perm.info.name); 15304 if (bp != null) { 15305 // If the defining package is signed with our cert, it's okay. This 15306 // also includes the "updating the same package" case, of course. 15307 // "updating same package" could also involve key-rotation. 15308 final boolean sigsOk; 15309 if (bp.sourcePackage.equals(pkg.packageName) 15310 && (bp.packageSetting instanceof PackageSetting) 15311 && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting, 15312 scanFlags))) { 15313 sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg); 15314 } else { 15315 sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures, 15316 pkg.mSignatures) == PackageManager.SIGNATURE_MATCH; 15317 } 15318 if (!sigsOk) { 15319 // If the owning package is the system itself, we log but allow 15320 // install to proceed; we fail the install on all other permission 15321 // redefinitions. 15322 if (!bp.sourcePackage.equals("android")) { 15323 res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package " 15324 + pkg.packageName + " attempting to redeclare permission " 15325 + perm.info.name + " already owned by " + bp.sourcePackage); 15326 res.origPermission = perm.info.name; 15327 res.origPackage = bp.sourcePackage; 15328 return; 15329 } else { 15330 Slog.w(TAG, "Package " + pkg.packageName 15331 + " attempting to redeclare system permission " 15332 + perm.info.name + "; ignoring new declaration"); 15333 pkg.permissions.remove(i); 15334 } 15335 } 15336 } 15337 } 15338 } 15339 15340 if (systemApp) { 15341 if (onExternal) { 15342 // Abort update; system app can't be replaced with app on sdcard 15343 res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION, 15344 "Cannot install updates to system apps on sdcard"); 15345 return; 15346 } else if (ephemeral) { 15347 // Abort update; system app can't be replaced with an ephemeral app 15348 res.setError(INSTALL_FAILED_EPHEMERAL_INVALID, 15349 "Cannot update a system app with an ephemeral app"); 15350 return; 15351 } 15352 } 15353 15354 if (args.move != null) { 15355 // We did an in-place move, so dex is ready to roll 15356 scanFlags |= SCAN_NO_DEX; 15357 scanFlags |= SCAN_MOVE; 15358 15359 synchronized (mPackages) { 15360 final PackageSetting ps = mSettings.mPackages.get(pkgName); 15361 if (ps == null) { 15362 res.setError(INSTALL_FAILED_INTERNAL_ERROR, 15363 "Missing settings for moved package " + pkgName); 15364 } 15365 15366 // We moved the entire application as-is, so bring over the 15367 // previously derived ABI information. 15368 pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString; 15369 pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString; 15370 } 15371 15372 } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) { 15373 // Enable SCAN_NO_DEX flag to skip dexopt at a later stage 15374 scanFlags |= SCAN_NO_DEX; 15375 15376 try { 15377 String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ? 15378 args.abiOverride : pkg.cpuAbiOverride); 15379 derivePackageAbi(pkg, new File(pkg.codePath), abiOverride, 15380 true /*extractLibs*/, mAppLib32InstallDir); 15381 } catch (PackageManagerException pme) { 15382 Slog.e(TAG, "Error deriving application ABI", pme); 15383 res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI"); 15384 return; 15385 } 15386 15387 // Shared libraries for the package need to be updated. 15388 synchronized (mPackages) { 15389 try { 15390 updateSharedLibrariesLPr(pkg, null); 15391 } catch (PackageManagerException e) { 15392 Slog.e(TAG, "updateSharedLibrariesLPw failed: " + e.getMessage()); 15393 } 15394 } 15395 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt"); 15396 // Do not run PackageDexOptimizer through the local performDexOpt 15397 // method because `pkg` may not be in `mPackages` yet. 15398 // 15399 // Also, don't fail application installs if the dexopt step fails. 15400 mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles, 15401 null /* instructionSets */, false /* checkProfiles */, 15402 getCompilerFilterForReason(REASON_INSTALL), 15403 getOrCreateCompilerPackageStats(pkg)); 15404 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); 15405 15406 // Notify BackgroundDexOptService that the package has been changed. 15407 // If this is an update of a package which used to fail to compile, 15408 // BDOS will remove it from its blacklist. 15409 BackgroundDexOptService.notifyPackageChanged(pkg.packageName); 15410 } 15411 15412 if (!args.doRename(res.returnCode, pkg, oldCodePath)) { 15413 res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename"); 15414 return; 15415 } 15416 15417 startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg); 15418 15419 try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags, 15420 "installPackageLI")) { 15421 if (replace) { 15422 replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user, 15423 installerPackageName, res); 15424 } else { 15425 installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES, 15426 args.user, installerPackageName, volumeUuid, res); 15427 } 15428 } 15429 synchronized (mPackages) { 15430 final PackageSetting ps = mSettings.mPackages.get(pkgName); 15431 if (ps != null) { 15432 res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 15433 } 15434 15435 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 15436 for (int i = 0; i < childCount; i++) { 15437 PackageParser.Package childPkg = pkg.childPackages.get(i); 15438 PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName); 15439 PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName); 15440 if (childPs != null) { 15441 childRes.newUsers = childPs.queryInstalledUsers( 15442 sUserManager.getUserIds(), true); 15443 } 15444 } 15445 } 15446 } 15447 15448 private void startIntentFilterVerifications(int userId, boolean replacing, 15449 PackageParser.Package pkg) { 15450 if (mIntentFilterVerifierComponent == null) { 15451 Slog.w(TAG, "No IntentFilter verification will not be done as " 15452 + "there is no IntentFilterVerifier available!"); 15453 return; 15454 } 15455 15456 final int verifierUid = getPackageUid( 15457 mIntentFilterVerifierComponent.getPackageName(), 15458 MATCH_DEBUG_TRIAGED_MISSING, 15459 (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId); 15460 15461 Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 15462 msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid); 15463 mHandler.sendMessage(msg); 15464 15465 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 15466 for (int i = 0; i < childCount; i++) { 15467 PackageParser.Package childPkg = pkg.childPackages.get(i); 15468 msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); 15469 msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid); 15470 mHandler.sendMessage(msg); 15471 } 15472 } 15473 15474 private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing, 15475 PackageParser.Package pkg) { 15476 int size = pkg.activities.size(); 15477 if (size == 0) { 15478 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 15479 "No activity, so no need to verify any IntentFilter!"); 15480 return; 15481 } 15482 15483 final boolean hasDomainURLs = hasDomainURLs(pkg); 15484 if (!hasDomainURLs) { 15485 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 15486 "No domain URLs, so no need to verify any IntentFilter!"); 15487 return; 15488 } 15489 15490 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId 15491 + " if any IntentFilter from the " + size 15492 + " Activities needs verification ..."); 15493 15494 int count = 0; 15495 final String packageName = pkg.packageName; 15496 15497 synchronized (mPackages) { 15498 // If this is a new install and we see that we've already run verification for this 15499 // package, we have nothing to do: it means the state was restored from backup. 15500 if (!replacing) { 15501 IntentFilterVerificationInfo ivi = 15502 mSettings.getIntentFilterVerificationLPr(packageName); 15503 if (ivi != null) { 15504 if (DEBUG_DOMAIN_VERIFICATION) { 15505 Slog.i(TAG, "Package " + packageName+ " already verified: status=" 15506 + ivi.getStatusString()); 15507 } 15508 return; 15509 } 15510 } 15511 15512 // If any filters need to be verified, then all need to be. 15513 boolean needToVerify = false; 15514 for (PackageParser.Activity a : pkg.activities) { 15515 for (ActivityIntentInfo filter : a.intents) { 15516 if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) { 15517 if (DEBUG_DOMAIN_VERIFICATION) { 15518 Slog.d(TAG, "Intent filter needs verification, so processing all filters"); 15519 } 15520 needToVerify = true; 15521 break; 15522 } 15523 } 15524 } 15525 15526 if (needToVerify) { 15527 final int verificationId = mIntentFilterVerificationToken++; 15528 for (PackageParser.Activity a : pkg.activities) { 15529 for (ActivityIntentInfo filter : a.intents) { 15530 if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) { 15531 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, 15532 "Verification needed for IntentFilter:" + filter.toString()); 15533 mIntentFilterVerifier.addOneIntentFilterVerification( 15534 verifierUid, userId, verificationId, filter, packageName); 15535 count++; 15536 } 15537 } 15538 } 15539 } 15540 } 15541 15542 if (count > 0) { 15543 if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count 15544 + " IntentFilter verification" + (count > 1 ? "s" : "") 15545 + " for userId:" + userId); 15546 mIntentFilterVerifier.startVerifications(userId); 15547 } else { 15548 if (DEBUG_DOMAIN_VERIFICATION) { 15549 Slog.d(TAG, "No filters or not all autoVerify for " + packageName); 15550 } 15551 } 15552 } 15553 15554 private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) { 15555 final ComponentName cn = filter.activity.getComponentName(); 15556 final String packageName = cn.getPackageName(); 15557 15558 IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr( 15559 packageName); 15560 if (ivi == null) { 15561 return true; 15562 } 15563 int status = ivi.getStatus(); 15564 switch (status) { 15565 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 15566 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 15567 return true; 15568 15569 default: 15570 // Nothing to do 15571 return false; 15572 } 15573 } 15574 15575 private static boolean isMultiArch(ApplicationInfo info) { 15576 return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0; 15577 } 15578 15579 private static boolean isExternal(PackageParser.Package pkg) { 15580 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 15581 } 15582 15583 private static boolean isExternal(PackageSetting ps) { 15584 return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; 15585 } 15586 15587 private static boolean isEphemeral(PackageParser.Package pkg) { 15588 return pkg.applicationInfo.isEphemeralApp(); 15589 } 15590 15591 private static boolean isEphemeral(PackageSetting ps) { 15592 return ps.pkg != null && isEphemeral(ps.pkg); 15593 } 15594 15595 private static boolean isSystemApp(PackageParser.Package pkg) { 15596 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 15597 } 15598 15599 private static boolean isPrivilegedApp(PackageParser.Package pkg) { 15600 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; 15601 } 15602 15603 private static boolean hasDomainURLs(PackageParser.Package pkg) { 15604 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0; 15605 } 15606 15607 private static boolean isSystemApp(PackageSetting ps) { 15608 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0; 15609 } 15610 15611 private static boolean isUpdatedSystemApp(PackageSetting ps) { 15612 return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; 15613 } 15614 15615 private int packageFlagsToInstallFlags(PackageSetting ps) { 15616 int installFlags = 0; 15617 if (isEphemeral(ps)) { 15618 installFlags |= PackageManager.INSTALL_EPHEMERAL; 15619 } 15620 if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) { 15621 // This existing package was an external ASEC install when we have 15622 // the external flag without a UUID 15623 installFlags |= PackageManager.INSTALL_EXTERNAL; 15624 } 15625 if (ps.isForwardLocked()) { 15626 installFlags |= PackageManager.INSTALL_FORWARD_LOCK; 15627 } 15628 return installFlags; 15629 } 15630 15631 private String getVolumeUuidForPackage(PackageParser.Package pkg) { 15632 if (isExternal(pkg)) { 15633 if (TextUtils.isEmpty(pkg.volumeUuid)) { 15634 return StorageManager.UUID_PRIMARY_PHYSICAL; 15635 } else { 15636 return pkg.volumeUuid; 15637 } 15638 } else { 15639 return StorageManager.UUID_PRIVATE_INTERNAL; 15640 } 15641 } 15642 15643 private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) { 15644 if (isExternal(pkg)) { 15645 if (TextUtils.isEmpty(pkg.volumeUuid)) { 15646 return mSettings.getExternalVersion(); 15647 } else { 15648 return mSettings.findOrCreateVersion(pkg.volumeUuid); 15649 } 15650 } else { 15651 return mSettings.getInternalVersion(); 15652 } 15653 } 15654 15655 private void deleteTempPackageFiles() { 15656 final FilenameFilter filter = new FilenameFilter() { 15657 public boolean accept(File dir, String name) { 15658 return name.startsWith("vmdl") && name.endsWith(".tmp"); 15659 } 15660 }; 15661 for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) { 15662 file.delete(); 15663 } 15664 } 15665 15666 @Override 15667 public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int userId, 15668 int flags) { 15669 deletePackage(packageName, new LegacyPackageDeleteObserver(observer).getBinder(), userId, 15670 flags); 15671 } 15672 15673 @Override 15674 public void deletePackage(final String packageName, 15675 final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) { 15676 mContext.enforceCallingOrSelfPermission( 15677 android.Manifest.permission.DELETE_PACKAGES, null); 15678 Preconditions.checkNotNull(packageName); 15679 Preconditions.checkNotNull(observer); 15680 final int uid = Binder.getCallingUid(); 15681 if (!isOrphaned(packageName) 15682 && !isCallerAllowedToSilentlyUninstall(uid, packageName)) { 15683 try { 15684 final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE); 15685 intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null)); 15686 intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder()); 15687 observer.onUserActionRequired(intent); 15688 } catch (RemoteException re) { 15689 } 15690 return; 15691 } 15692 final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0; 15693 final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId }; 15694 if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) { 15695 mContext.enforceCallingOrSelfPermission( 15696 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 15697 "deletePackage for user " + userId); 15698 } 15699 15700 if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) { 15701 try { 15702 observer.onPackageDeleted(packageName, 15703 PackageManager.DELETE_FAILED_USER_RESTRICTED, null); 15704 } catch (RemoteException re) { 15705 } 15706 return; 15707 } 15708 15709 if (!deleteAllUsers && getBlockUninstallForUser(packageName, userId)) { 15710 try { 15711 observer.onPackageDeleted(packageName, 15712 PackageManager.DELETE_FAILED_OWNER_BLOCKED, null); 15713 } catch (RemoteException re) { 15714 } 15715 return; 15716 } 15717 15718 if (DEBUG_REMOVE) { 15719 Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId 15720 + " deleteAllUsers: " + deleteAllUsers ); 15721 } 15722 // Queue up an async operation since the package deletion may take a little while. 15723 mHandler.post(new Runnable() { 15724 public void run() { 15725 mHandler.removeCallbacks(this); 15726 int returnCode; 15727 if (!deleteAllUsers) { 15728 returnCode = deletePackageX(packageName, userId, deleteFlags); 15729 } else { 15730 int[] blockUninstallUserIds = getBlockUninstallForUsers(packageName, users); 15731 // If nobody is blocking uninstall, proceed with delete for all users 15732 if (ArrayUtils.isEmpty(blockUninstallUserIds)) { 15733 returnCode = deletePackageX(packageName, userId, deleteFlags); 15734 } else { 15735 // Otherwise uninstall individually for users with blockUninstalls=false 15736 final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS; 15737 for (int userId : users) { 15738 if (!ArrayUtils.contains(blockUninstallUserIds, userId)) { 15739 returnCode = deletePackageX(packageName, userId, userFlags); 15740 if (returnCode != PackageManager.DELETE_SUCCEEDED) { 15741 Slog.w(TAG, "Package delete failed for user " + userId 15742 + ", returnCode " + returnCode); 15743 } 15744 } 15745 } 15746 // The app has only been marked uninstalled for certain users. 15747 // We still need to report that delete was blocked 15748 returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED; 15749 } 15750 } 15751 try { 15752 observer.onPackageDeleted(packageName, returnCode, null); 15753 } catch (RemoteException e) { 15754 Log.i(TAG, "Observer no longer exists."); 15755 } //end catch 15756 } //end run 15757 }); 15758 } 15759 15760 private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) { 15761 if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID 15762 || callingUid == Process.SYSTEM_UID) { 15763 return true; 15764 } 15765 final int callingUserId = UserHandle.getUserId(callingUid); 15766 // If the caller installed the pkgName, then allow it to silently uninstall. 15767 if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) { 15768 return true; 15769 } 15770 15771 // Allow package verifier to silently uninstall. 15772 if (mRequiredVerifierPackage != null && 15773 callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) { 15774 return true; 15775 } 15776 15777 // Allow package uninstaller to silently uninstall. 15778 if (mRequiredUninstallerPackage != null && 15779 callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) { 15780 return true; 15781 } 15782 15783 // Allow storage manager to silently uninstall. 15784 if (mStorageManagerPackage != null && 15785 callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) { 15786 return true; 15787 } 15788 return false; 15789 } 15790 15791 private int[] getBlockUninstallForUsers(String packageName, int[] userIds) { 15792 int[] result = EMPTY_INT_ARRAY; 15793 for (int userId : userIds) { 15794 if (getBlockUninstallForUser(packageName, userId)) { 15795 result = ArrayUtils.appendInt(result, userId); 15796 } 15797 } 15798 return result; 15799 } 15800 15801 @Override 15802 public boolean isPackageDeviceAdminOnAnyUser(String packageName) { 15803 return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL); 15804 } 15805 15806 private boolean isPackageDeviceAdmin(String packageName, int userId) { 15807 IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface( 15808 ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); 15809 try { 15810 if (dpm != null) { 15811 final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent( 15812 /* callingUserOnly =*/ false); 15813 final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null 15814 : deviceOwnerComponentName.getPackageName(); 15815 // Does the package contains the device owner? 15816 // TODO Do we have to do it even if userId != UserHandle.USER_ALL? Otherwise, 15817 // this check is probably not needed, since DO should be registered as a device 15818 // admin on some user too. (Original bug for this: b/17657954) 15819 if (packageName.equals(deviceOwnerPackageName)) { 15820 return true; 15821 } 15822 // Does it contain a device admin for any user? 15823 int[] users; 15824 if (userId == UserHandle.USER_ALL) { 15825 users = sUserManager.getUserIds(); 15826 } else { 15827 users = new int[]{userId}; 15828 } 15829 for (int i = 0; i < users.length; ++i) { 15830 if (dpm.packageHasActiveAdmins(packageName, users[i])) { 15831 return true; 15832 } 15833 } 15834 } 15835 } catch (RemoteException e) { 15836 } 15837 return false; 15838 } 15839 15840 private boolean shouldKeepUninstalledPackageLPr(String packageName) { 15841 return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName); 15842 } 15843 15844 /** 15845 * This method is an internal method that could be get invoked either 15846 * to delete an installed package or to clean up a failed installation. 15847 * After deleting an installed package, a broadcast is sent to notify any 15848 * listeners that the package has been removed. For cleaning up a failed 15849 * installation, the broadcast is not necessary since the package's 15850 * installation wouldn't have sent the initial broadcast either 15851 * The key steps in deleting a package are 15852 * deleting the package information in internal structures like mPackages, 15853 * deleting the packages base directories through installd 15854 * updating mSettings to reflect current status 15855 * persisting settings for later use 15856 * sending a broadcast if necessary 15857 */ 15858 private int deletePackageX(String packageName, int userId, int deleteFlags) { 15859 final PackageRemovedInfo info = new PackageRemovedInfo(); 15860 final boolean res; 15861 15862 final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0 15863 ? UserHandle.USER_ALL : userId; 15864 15865 if (isPackageDeviceAdmin(packageName, removeUser)) { 15866 Slog.w(TAG, "Not removing package " + packageName + ": has active device admin"); 15867 return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER; 15868 } 15869 15870 PackageSetting uninstalledPs = null; 15871 15872 // for the uninstall-updates case and restricted profiles, remember the per- 15873 // user handle installed state 15874 int[] allUsers; 15875 synchronized (mPackages) { 15876 uninstalledPs = mSettings.mPackages.get(packageName); 15877 if (uninstalledPs == null) { 15878 Slog.w(TAG, "Not removing non-existent package " + packageName); 15879 return PackageManager.DELETE_FAILED_INTERNAL_ERROR; 15880 } 15881 allUsers = sUserManager.getUserIds(); 15882 info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true); 15883 } 15884 15885 final int freezeUser; 15886 if (isUpdatedSystemApp(uninstalledPs) 15887 && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) { 15888 // We're downgrading a system app, which will apply to all users, so 15889 // freeze them all during the downgrade 15890 freezeUser = UserHandle.USER_ALL; 15891 } else { 15892 freezeUser = removeUser; 15893 } 15894 15895 synchronized (mInstallLock) { 15896 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId); 15897 try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser, 15898 deleteFlags, "deletePackageX")) { 15899 res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers, 15900 deleteFlags | REMOVE_CHATTY, info, true, null); 15901 } 15902 synchronized (mPackages) { 15903 if (res) { 15904 mEphemeralApplicationRegistry.onPackageUninstalledLPw(uninstalledPs.pkg); 15905 } 15906 } 15907 } 15908 15909 if (res) { 15910 final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0; 15911 info.sendPackageRemovedBroadcasts(killApp); 15912 info.sendSystemPackageUpdatedBroadcasts(); 15913 info.sendSystemPackageAppearedBroadcasts(); 15914 } 15915 // Force a gc here. 15916 Runtime.getRuntime().gc(); 15917 // Delete the resources here after sending the broadcast to let 15918 // other processes clean up before deleting resources. 15919 if (info.args != null) { 15920 synchronized (mInstallLock) { 15921 info.args.doPostDeleteLI(true); 15922 } 15923 } 15924 15925 return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR; 15926 } 15927 15928 class PackageRemovedInfo { 15929 String removedPackage; 15930 int uid = -1; 15931 int removedAppId = -1; 15932 int[] origUsers; 15933 int[] removedUsers = null; 15934 boolean isRemovedPackageSystemUpdate = false; 15935 boolean isUpdate; 15936 boolean dataRemoved; 15937 boolean removedForAllUsers; 15938 // Clean up resources deleted packages. 15939 InstallArgs args = null; 15940 ArrayMap<String, PackageRemovedInfo> removedChildPackages; 15941 ArrayMap<String, PackageInstalledInfo> appearedChildPackages; 15942 15943 void sendPackageRemovedBroadcasts(boolean killApp) { 15944 sendPackageRemovedBroadcastInternal(killApp); 15945 final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0; 15946 for (int i = 0; i < childCount; i++) { 15947 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i); 15948 childInfo.sendPackageRemovedBroadcastInternal(killApp); 15949 } 15950 } 15951 15952 void sendSystemPackageUpdatedBroadcasts() { 15953 if (isRemovedPackageSystemUpdate) { 15954 sendSystemPackageUpdatedBroadcastsInternal(); 15955 final int childCount = (removedChildPackages != null) 15956 ? removedChildPackages.size() : 0; 15957 for (int i = 0; i < childCount; i++) { 15958 PackageRemovedInfo childInfo = removedChildPackages.valueAt(i); 15959 if (childInfo.isRemovedPackageSystemUpdate) { 15960 childInfo.sendSystemPackageUpdatedBroadcastsInternal(); 15961 } 15962 } 15963 } 15964 } 15965 15966 void sendSystemPackageAppearedBroadcasts() { 15967 final int packageCount = (appearedChildPackages != null) 15968 ? appearedChildPackages.size() : 0; 15969 for (int i = 0; i < packageCount; i++) { 15970 PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i); 15971 sendPackageAddedForNewUsers(installedInfo.name, true, 15972 UserHandle.getAppId(installedInfo.uid), installedInfo.newUsers); 15973 } 15974 } 15975 15976 private void sendSystemPackageUpdatedBroadcastsInternal() { 15977 Bundle extras = new Bundle(2); 15978 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 15979 extras.putBoolean(Intent.EXTRA_REPLACING, true); 15980 sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, removedPackage, 15981 extras, 0, null, null, null); 15982 sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, removedPackage, 15983 extras, 0, null, null, null); 15984 sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null, 15985 null, 0, removedPackage, null, null); 15986 } 15987 15988 private void sendPackageRemovedBroadcastInternal(boolean killApp) { 15989 Bundle extras = new Bundle(2); 15990 extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid); 15991 extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved); 15992 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp); 15993 if (isUpdate || isRemovedPackageSystemUpdate) { 15994 extras.putBoolean(Intent.EXTRA_REPLACING, true); 15995 } 15996 extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers); 15997 if (removedPackage != null) { 15998 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage, 15999 extras, 0, null, null, removedUsers); 16000 if (dataRemoved && !isRemovedPackageSystemUpdate) { 16001 sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED, 16002 removedPackage, extras, 0, null, null, removedUsers); 16003 } 16004 } 16005 if (removedAppId >= 0) { 16006 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, 0, null, null, 16007 removedUsers); 16008 } 16009 } 16010 } 16011 16012 /* 16013 * This method deletes the package from internal data structures. If the DONT_DELETE_DATA 16014 * flag is not set, the data directory is removed as well. 16015 * make sure this flag is set for partially installed apps. If not its meaningless to 16016 * delete a partially installed application. 16017 */ 16018 private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles, 16019 PackageRemovedInfo outInfo, int flags, boolean writeSettings) { 16020 String packageName = ps.name; 16021 if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps); 16022 // Retrieve object to delete permissions for shared user later on 16023 final PackageParser.Package deletedPkg; 16024 final PackageSetting deletedPs; 16025 // reader 16026 synchronized (mPackages) { 16027 deletedPkg = mPackages.get(packageName); 16028 deletedPs = mSettings.mPackages.get(packageName); 16029 if (outInfo != null) { 16030 outInfo.removedPackage = packageName; 16031 outInfo.removedUsers = deletedPs != null 16032 ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true) 16033 : null; 16034 } 16035 } 16036 16037 removePackageLI(ps, (flags & REMOVE_CHATTY) != 0); 16038 16039 if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) { 16040 final PackageParser.Package resolvedPkg; 16041 if (deletedPkg != null) { 16042 resolvedPkg = deletedPkg; 16043 } else { 16044 // We don't have a parsed package when it lives on an ejected 16045 // adopted storage device, so fake something together 16046 resolvedPkg = new PackageParser.Package(ps.name); 16047 resolvedPkg.setVolumeUuid(ps.volumeUuid); 16048 } 16049 destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL, 16050 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 16051 destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL); 16052 if (outInfo != null) { 16053 outInfo.dataRemoved = true; 16054 } 16055 schedulePackageCleaning(packageName, UserHandle.USER_ALL, true); 16056 } 16057 16058 // writer 16059 synchronized (mPackages) { 16060 if (deletedPs != null) { 16061 if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) { 16062 clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL); 16063 clearDefaultBrowserIfNeeded(packageName); 16064 if (outInfo != null) { 16065 mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName); 16066 outInfo.removedAppId = mSettings.removePackageLPw(packageName); 16067 } 16068 updatePermissionsLPw(deletedPs.name, null, 0); 16069 if (deletedPs.sharedUser != null) { 16070 // Remove permissions associated with package. Since runtime 16071 // permissions are per user we have to kill the removed package 16072 // or packages running under the shared user of the removed 16073 // package if revoking the permissions requested only by the removed 16074 // package is successful and this causes a change in gids. 16075 for (int userId : UserManagerService.getInstance().getUserIds()) { 16076 final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs, 16077 userId); 16078 if (userIdToKill == UserHandle.USER_ALL 16079 || userIdToKill >= UserHandle.USER_SYSTEM) { 16080 // If gids changed for this user, kill all affected packages. 16081 mHandler.post(new Runnable() { 16082 @Override 16083 public void run() { 16084 // This has to happen with no lock held. 16085 killApplication(deletedPs.name, deletedPs.appId, 16086 KILL_APP_REASON_GIDS_CHANGED); 16087 } 16088 }); 16089 break; 16090 } 16091 } 16092 } 16093 clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL); 16094 } 16095 // make sure to preserve per-user disabled state if this removal was just 16096 // a downgrade of a system app to the factory package 16097 if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) { 16098 if (DEBUG_REMOVE) { 16099 Slog.d(TAG, "Propagating install state across downgrade"); 16100 } 16101 for (int userId : allUserHandles) { 16102 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId); 16103 if (DEBUG_REMOVE) { 16104 Slog.d(TAG, " user " + userId + " => " + installed); 16105 } 16106 ps.setInstalled(installed, userId); 16107 } 16108 } 16109 } 16110 // can downgrade to reader 16111 if (writeSettings) { 16112 // Save settings now 16113 mSettings.writeLPr(); 16114 } 16115 } 16116 if (outInfo != null) { 16117 // A user ID was deleted here. Go through all users and remove it 16118 // from KeyStore. 16119 removeKeystoreDataIfNeeded(UserHandle.USER_ALL, outInfo.removedAppId); 16120 } 16121 } 16122 16123 static boolean locationIsPrivileged(File path) { 16124 try { 16125 final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app") 16126 .getCanonicalPath(); 16127 return path.getCanonicalPath().startsWith(privilegedAppDir); 16128 } catch (IOException e) { 16129 Slog.e(TAG, "Unable to access code path " + path); 16130 } 16131 return false; 16132 } 16133 16134 /* 16135 * Tries to delete system package. 16136 */ 16137 private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg, 16138 PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo, 16139 boolean writeSettings) { 16140 if (deletedPs.parentPackageName != null) { 16141 Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName); 16142 return false; 16143 } 16144 16145 final boolean applyUserRestrictions 16146 = (allUserHandles != null) && (outInfo.origUsers != null); 16147 final PackageSetting disabledPs; 16148 // Confirm if the system package has been updated 16149 // An updated system app can be deleted. This will also have to restore 16150 // the system pkg from system partition 16151 // reader 16152 synchronized (mPackages) { 16153 disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name); 16154 } 16155 16156 if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName 16157 + " disabledPs=" + disabledPs); 16158 16159 if (disabledPs == null) { 16160 Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName); 16161 return false; 16162 } else if (DEBUG_REMOVE) { 16163 Slog.d(TAG, "Deleting system pkg from data partition"); 16164 } 16165 16166 if (DEBUG_REMOVE) { 16167 if (applyUserRestrictions) { 16168 Slog.d(TAG, "Remembering install states:"); 16169 for (int userId : allUserHandles) { 16170 final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId); 16171 Slog.d(TAG, " u=" + userId + " inst=" + finstalled); 16172 } 16173 } 16174 } 16175 16176 // Delete the updated package 16177 outInfo.isRemovedPackageSystemUpdate = true; 16178 if (outInfo.removedChildPackages != null) { 16179 final int childCount = (deletedPs.childPackageNames != null) 16180 ? deletedPs.childPackageNames.size() : 0; 16181 for (int i = 0; i < childCount; i++) { 16182 String childPackageName = deletedPs.childPackageNames.get(i); 16183 if (disabledPs.childPackageNames != null && disabledPs.childPackageNames 16184 .contains(childPackageName)) { 16185 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get( 16186 childPackageName); 16187 if (childInfo != null) { 16188 childInfo.isRemovedPackageSystemUpdate = true; 16189 } 16190 } 16191 } 16192 } 16193 16194 if (disabledPs.versionCode < deletedPs.versionCode) { 16195 // Delete data for downgrades 16196 flags &= ~PackageManager.DELETE_KEEP_DATA; 16197 } else { 16198 // Preserve data by setting flag 16199 flags |= PackageManager.DELETE_KEEP_DATA; 16200 } 16201 16202 boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles, 16203 outInfo, writeSettings, disabledPs.pkg); 16204 if (!ret) { 16205 return false; 16206 } 16207 16208 // writer 16209 synchronized (mPackages) { 16210 // Reinstate the old system package 16211 enableSystemPackageLPw(disabledPs.pkg); 16212 // Remove any native libraries from the upgraded package. 16213 removeNativeBinariesLI(deletedPs); 16214 } 16215 16216 // Install the system package 16217 if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs); 16218 int parseFlags = mDefParseFlags 16219 | PackageParser.PARSE_MUST_BE_APK 16220 | PackageParser.PARSE_IS_SYSTEM 16221 | PackageParser.PARSE_IS_SYSTEM_DIR; 16222 if (locationIsPrivileged(disabledPs.codePath)) { 16223 parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; 16224 } 16225 16226 final PackageParser.Package newPkg; 16227 try { 16228 newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, SCAN_NO_PATHS, 0, null); 16229 } catch (PackageManagerException e) { 16230 Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": " 16231 + e.getMessage()); 16232 return false; 16233 } 16234 try { 16235 // update shared libraries for the newly re-installed system package 16236 updateSharedLibrariesLPr(newPkg, null); 16237 } catch (PackageManagerException e) { 16238 Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage()); 16239 } 16240 16241 prepareAppDataAfterInstallLIF(newPkg); 16242 16243 // writer 16244 synchronized (mPackages) { 16245 PackageSetting ps = mSettings.mPackages.get(newPkg.packageName); 16246 16247 // Propagate the permissions state as we do not want to drop on the floor 16248 // runtime permissions. The update permissions method below will take 16249 // care of removing obsolete permissions and grant install permissions. 16250 ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState()); 16251 updatePermissionsLPw(newPkg.packageName, newPkg, 16252 UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG); 16253 16254 if (applyUserRestrictions) { 16255 if (DEBUG_REMOVE) { 16256 Slog.d(TAG, "Propagating install state across reinstall"); 16257 } 16258 for (int userId : allUserHandles) { 16259 final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId); 16260 if (DEBUG_REMOVE) { 16261 Slog.d(TAG, " user " + userId + " => " + installed); 16262 } 16263 ps.setInstalled(installed, userId); 16264 16265 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 16266 } 16267 // Regardless of writeSettings we need to ensure that this restriction 16268 // state propagation is persisted 16269 mSettings.writeAllUsersPackageRestrictionsLPr(); 16270 } 16271 // can downgrade to reader here 16272 if (writeSettings) { 16273 mSettings.writeLPr(); 16274 } 16275 } 16276 return true; 16277 } 16278 16279 private boolean deleteInstalledPackageLIF(PackageSetting ps, 16280 boolean deleteCodeAndResources, int flags, int[] allUserHandles, 16281 PackageRemovedInfo outInfo, boolean writeSettings, 16282 PackageParser.Package replacingPackage) { 16283 synchronized (mPackages) { 16284 if (outInfo != null) { 16285 outInfo.uid = ps.appId; 16286 } 16287 16288 if (outInfo != null && outInfo.removedChildPackages != null) { 16289 final int childCount = (ps.childPackageNames != null) 16290 ? ps.childPackageNames.size() : 0; 16291 for (int i = 0; i < childCount; i++) { 16292 String childPackageName = ps.childPackageNames.get(i); 16293 PackageSetting childPs = mSettings.mPackages.get(childPackageName); 16294 if (childPs == null) { 16295 return false; 16296 } 16297 PackageRemovedInfo childInfo = outInfo.removedChildPackages.get( 16298 childPackageName); 16299 if (childInfo != null) { 16300 childInfo.uid = childPs.appId; 16301 } 16302 } 16303 } 16304 } 16305 16306 // Delete package data from internal structures and also remove data if flag is set 16307 removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings); 16308 16309 // Delete the child packages data 16310 final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0; 16311 for (int i = 0; i < childCount; i++) { 16312 PackageSetting childPs; 16313 synchronized (mPackages) { 16314 childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i)); 16315 } 16316 if (childPs != null) { 16317 PackageRemovedInfo childOutInfo = (outInfo != null 16318 && outInfo.removedChildPackages != null) 16319 ? outInfo.removedChildPackages.get(childPs.name) : null; 16320 final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0 16321 && (replacingPackage != null 16322 && !replacingPackage.hasChildPackage(childPs.name)) 16323 ? flags & ~DELETE_KEEP_DATA : flags; 16324 removePackageDataLIF(childPs, allUserHandles, childOutInfo, 16325 deleteFlags, writeSettings); 16326 } 16327 } 16328 16329 // Delete application code and resources only for parent packages 16330 if (ps.parentPackageName == null) { 16331 if (deleteCodeAndResources && (outInfo != null)) { 16332 outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps), 16333 ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps)); 16334 if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args); 16335 } 16336 } 16337 16338 return true; 16339 } 16340 16341 @Override 16342 public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall, 16343 int userId) { 16344 mContext.enforceCallingOrSelfPermission( 16345 android.Manifest.permission.DELETE_PACKAGES, null); 16346 synchronized (mPackages) { 16347 PackageSetting ps = mSettings.mPackages.get(packageName); 16348 if (ps == null) { 16349 Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName); 16350 return false; 16351 } 16352 if (!ps.getInstalled(userId)) { 16353 // Can't block uninstall for an app that is not installed or enabled. 16354 Log.i(TAG, "Package not installed in set block uninstall " + packageName); 16355 return false; 16356 } 16357 ps.setBlockUninstall(blockUninstall, userId); 16358 mSettings.writePackageRestrictionsLPr(userId); 16359 } 16360 return true; 16361 } 16362 16363 @Override 16364 public boolean getBlockUninstallForUser(String packageName, int userId) { 16365 synchronized (mPackages) { 16366 PackageSetting ps = mSettings.mPackages.get(packageName); 16367 if (ps == null) { 16368 Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName); 16369 return false; 16370 } 16371 return ps.getBlockUninstall(userId); 16372 } 16373 } 16374 16375 @Override 16376 public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) { 16377 int callingUid = Binder.getCallingUid(); 16378 if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) { 16379 throw new SecurityException( 16380 "setRequiredForSystemUser can only be run by the system or root"); 16381 } 16382 synchronized (mPackages) { 16383 PackageSetting ps = mSettings.mPackages.get(packageName); 16384 if (ps == null) { 16385 Log.w(TAG, "Package doesn't exist: " + packageName); 16386 return false; 16387 } 16388 if (systemUserApp) { 16389 ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER; 16390 } else { 16391 ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER; 16392 } 16393 mSettings.writeLPr(); 16394 } 16395 return true; 16396 } 16397 16398 /* 16399 * This method handles package deletion in general 16400 */ 16401 private boolean deletePackageLIF(String packageName, UserHandle user, 16402 boolean deleteCodeAndResources, int[] allUserHandles, int flags, 16403 PackageRemovedInfo outInfo, boolean writeSettings, 16404 PackageParser.Package replacingPackage) { 16405 if (packageName == null) { 16406 Slog.w(TAG, "Attempt to delete null packageName."); 16407 return false; 16408 } 16409 16410 if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user); 16411 16412 PackageSetting ps; 16413 16414 synchronized (mPackages) { 16415 ps = mSettings.mPackages.get(packageName); 16416 if (ps == null) { 16417 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 16418 return false; 16419 } 16420 16421 if (ps.parentPackageName != null && (!isSystemApp(ps) 16422 || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) { 16423 if (DEBUG_REMOVE) { 16424 Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:" 16425 + ((user == null) ? UserHandle.USER_ALL : user)); 16426 } 16427 final int removedUserId = (user != null) ? user.getIdentifier() 16428 : UserHandle.USER_ALL; 16429 if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) { 16430 return false; 16431 } 16432 markPackageUninstalledForUserLPw(ps, user); 16433 scheduleWritePackageRestrictionsLocked(user); 16434 return true; 16435 } 16436 } 16437 16438 if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null 16439 && user.getIdentifier() != UserHandle.USER_ALL)) { 16440 // The caller is asking that the package only be deleted for a single 16441 // user. To do this, we just mark its uninstalled state and delete 16442 // its data. If this is a system app, we only allow this to happen if 16443 // they have set the special DELETE_SYSTEM_APP which requests different 16444 // semantics than normal for uninstalling system apps. 16445 markPackageUninstalledForUserLPw(ps, user); 16446 16447 if (!isSystemApp(ps)) { 16448 // Do not uninstall the APK if an app should be cached 16449 boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName); 16450 if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) { 16451 // Other user still have this package installed, so all 16452 // we need to do is clear this user's data and save that 16453 // it is uninstalled. 16454 if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users"); 16455 if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) { 16456 return false; 16457 } 16458 scheduleWritePackageRestrictionsLocked(user); 16459 return true; 16460 } else { 16461 // We need to set it back to 'installed' so the uninstall 16462 // broadcasts will be sent correctly. 16463 if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete"); 16464 ps.setInstalled(true, user.getIdentifier()); 16465 } 16466 } else { 16467 // This is a system app, so we assume that the 16468 // other users still have this package installed, so all 16469 // we need to do is clear this user's data and save that 16470 // it is uninstalled. 16471 if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app"); 16472 if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) { 16473 return false; 16474 } 16475 scheduleWritePackageRestrictionsLocked(user); 16476 return true; 16477 } 16478 } 16479 16480 // If we are deleting a composite package for all users, keep track 16481 // of result for each child. 16482 if (ps.childPackageNames != null && outInfo != null) { 16483 synchronized (mPackages) { 16484 final int childCount = ps.childPackageNames.size(); 16485 outInfo.removedChildPackages = new ArrayMap<>(childCount); 16486 for (int i = 0; i < childCount; i++) { 16487 String childPackageName = ps.childPackageNames.get(i); 16488 PackageRemovedInfo childInfo = new PackageRemovedInfo(); 16489 childInfo.removedPackage = childPackageName; 16490 outInfo.removedChildPackages.put(childPackageName, childInfo); 16491 PackageSetting childPs = mSettings.getPackageLPr(childPackageName); 16492 if (childPs != null) { 16493 childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true); 16494 } 16495 } 16496 } 16497 } 16498 16499 boolean ret = false; 16500 if (isSystemApp(ps)) { 16501 if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name); 16502 // When an updated system application is deleted we delete the existing resources 16503 // as well and fall back to existing code in system partition 16504 ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings); 16505 } else { 16506 if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name); 16507 ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles, 16508 outInfo, writeSettings, replacingPackage); 16509 } 16510 16511 // Take a note whether we deleted the package for all users 16512 if (outInfo != null) { 16513 outInfo.removedForAllUsers = mPackages.get(ps.name) == null; 16514 if (outInfo.removedChildPackages != null) { 16515 synchronized (mPackages) { 16516 final int childCount = outInfo.removedChildPackages.size(); 16517 for (int i = 0; i < childCount; i++) { 16518 PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i); 16519 if (childInfo != null) { 16520 childInfo.removedForAllUsers = mPackages.get( 16521 childInfo.removedPackage) == null; 16522 } 16523 } 16524 } 16525 } 16526 // If we uninstalled an update to a system app there may be some 16527 // child packages that appeared as they are declared in the system 16528 // app but were not declared in the update. 16529 if (isSystemApp(ps)) { 16530 synchronized (mPackages) { 16531 PackageSetting updatedPs = mSettings.getPackageLPr(ps.name); 16532 final int childCount = (updatedPs.childPackageNames != null) 16533 ? updatedPs.childPackageNames.size() : 0; 16534 for (int i = 0; i < childCount; i++) { 16535 String childPackageName = updatedPs.childPackageNames.get(i); 16536 if (outInfo.removedChildPackages == null 16537 || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) { 16538 PackageSetting childPs = mSettings.getPackageLPr(childPackageName); 16539 if (childPs == null) { 16540 continue; 16541 } 16542 PackageInstalledInfo installRes = new PackageInstalledInfo(); 16543 installRes.name = childPackageName; 16544 installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true); 16545 installRes.pkg = mPackages.get(childPackageName); 16546 installRes.uid = childPs.pkg.applicationInfo.uid; 16547 if (outInfo.appearedChildPackages == null) { 16548 outInfo.appearedChildPackages = new ArrayMap<>(); 16549 } 16550 outInfo.appearedChildPackages.put(childPackageName, installRes); 16551 } 16552 } 16553 } 16554 } 16555 } 16556 16557 return ret; 16558 } 16559 16560 private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) { 16561 final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL) 16562 ? sUserManager.getUserIds() : new int[] {user.getIdentifier()}; 16563 for (int nextUserId : userIds) { 16564 if (DEBUG_REMOVE) { 16565 Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId); 16566 } 16567 ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT, 16568 false /*installed*/, true /*stopped*/, true /*notLaunched*/, 16569 false /*hidden*/, false /*suspended*/, null, null, null, 16570 false /*blockUninstall*/, 16571 ps.readUserState(nextUserId).domainVerificationStatus, 0); 16572 } 16573 } 16574 16575 private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId, 16576 PackageRemovedInfo outInfo) { 16577 final PackageParser.Package pkg; 16578 synchronized (mPackages) { 16579 pkg = mPackages.get(ps.name); 16580 } 16581 16582 final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() 16583 : new int[] {userId}; 16584 for (int nextUserId : userIds) { 16585 if (DEBUG_REMOVE) { 16586 Slog.d(TAG, "Updating package:" + ps.name + " install state for user:" 16587 + nextUserId); 16588 } 16589 16590 destroyAppDataLIF(pkg, userId, 16591 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 16592 destroyAppProfilesLIF(pkg, userId); 16593 removeKeystoreDataIfNeeded(nextUserId, ps.appId); 16594 schedulePackageCleaning(ps.name, nextUserId, false); 16595 synchronized (mPackages) { 16596 if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) { 16597 scheduleWritePackageRestrictionsLocked(nextUserId); 16598 } 16599 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId); 16600 } 16601 } 16602 16603 if (outInfo != null) { 16604 outInfo.removedPackage = ps.name; 16605 outInfo.removedAppId = ps.appId; 16606 outInfo.removedUsers = userIds; 16607 } 16608 16609 return true; 16610 } 16611 16612 private final class ClearStorageConnection implements ServiceConnection { 16613 IMediaContainerService mContainerService; 16614 16615 @Override 16616 public void onServiceConnected(ComponentName name, IBinder service) { 16617 synchronized (this) { 16618 mContainerService = IMediaContainerService.Stub.asInterface(service); 16619 notifyAll(); 16620 } 16621 } 16622 16623 @Override 16624 public void onServiceDisconnected(ComponentName name) { 16625 } 16626 } 16627 16628 private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) { 16629 if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return; 16630 16631 final boolean mounted; 16632 if (Environment.isExternalStorageEmulated()) { 16633 mounted = true; 16634 } else { 16635 final String status = Environment.getExternalStorageState(); 16636 16637 mounted = status.equals(Environment.MEDIA_MOUNTED) 16638 || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY); 16639 } 16640 16641 if (!mounted) { 16642 return; 16643 } 16644 16645 final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); 16646 int[] users; 16647 if (userId == UserHandle.USER_ALL) { 16648 users = sUserManager.getUserIds(); 16649 } else { 16650 users = new int[] { userId }; 16651 } 16652 final ClearStorageConnection conn = new ClearStorageConnection(); 16653 if (mContext.bindServiceAsUser( 16654 containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) { 16655 try { 16656 for (int curUser : users) { 16657 long timeout = SystemClock.uptimeMillis() + 5000; 16658 synchronized (conn) { 16659 long now; 16660 while (conn.mContainerService == null && 16661 (now = SystemClock.uptimeMillis()) < timeout) { 16662 try { 16663 conn.wait(timeout - now); 16664 } catch (InterruptedException e) { 16665 } 16666 } 16667 } 16668 if (conn.mContainerService == null) { 16669 return; 16670 } 16671 16672 final UserEnvironment userEnv = new UserEnvironment(curUser); 16673 clearDirectory(conn.mContainerService, 16674 userEnv.buildExternalStorageAppCacheDirs(packageName)); 16675 if (allData) { 16676 clearDirectory(conn.mContainerService, 16677 userEnv.buildExternalStorageAppDataDirs(packageName)); 16678 clearDirectory(conn.mContainerService, 16679 userEnv.buildExternalStorageAppMediaDirs(packageName)); 16680 } 16681 } 16682 } finally { 16683 mContext.unbindService(conn); 16684 } 16685 } 16686 } 16687 16688 @Override 16689 public void clearApplicationProfileData(String packageName) { 16690 enforceSystemOrRoot("Only the system can clear all profile data"); 16691 16692 final PackageParser.Package pkg; 16693 synchronized (mPackages) { 16694 pkg = mPackages.get(packageName); 16695 } 16696 16697 try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) { 16698 synchronized (mInstallLock) { 16699 clearAppProfilesLIF(pkg, UserHandle.USER_ALL); 16700 destroyAppReferenceProfileLeafLIF(pkg, UserHandle.USER_ALL, 16701 true /* removeBaseMarker */); 16702 } 16703 } 16704 } 16705 16706 @Override 16707 public void clearApplicationUserData(final String packageName, 16708 final IPackageDataObserver observer, final int userId) { 16709 mContext.enforceCallingOrSelfPermission( 16710 android.Manifest.permission.CLEAR_APP_USER_DATA, null); 16711 16712 enforceCrossUserPermission(Binder.getCallingUid(), userId, 16713 true /* requireFullPermission */, false /* checkShell */, "clear application data"); 16714 16715 if (mProtectedPackages.isPackageDataProtected(userId, packageName)) { 16716 throw new SecurityException("Cannot clear data for a protected package: " 16717 + packageName); 16718 } 16719 // Queue up an async operation since the package deletion may take a little while. 16720 mHandler.post(new Runnable() { 16721 public void run() { 16722 mHandler.removeCallbacks(this); 16723 final boolean succeeded; 16724 try (PackageFreezer freezer = freezePackage(packageName, 16725 "clearApplicationUserData")) { 16726 synchronized (mInstallLock) { 16727 succeeded = clearApplicationUserDataLIF(packageName, userId); 16728 } 16729 clearExternalStorageDataSync(packageName, userId, true); 16730 } 16731 if (succeeded) { 16732 // invoke DeviceStorageMonitor's update method to clear any notifications 16733 DeviceStorageMonitorInternal dsm = LocalServices 16734 .getService(DeviceStorageMonitorInternal.class); 16735 if (dsm != null) { 16736 dsm.checkMemory(); 16737 } 16738 } 16739 if(observer != null) { 16740 try { 16741 observer.onRemoveCompleted(packageName, succeeded); 16742 } catch (RemoteException e) { 16743 Log.i(TAG, "Observer no longer exists."); 16744 } 16745 } //end if observer 16746 } //end run 16747 }); 16748 } 16749 16750 private boolean clearApplicationUserDataLIF(String packageName, int userId) { 16751 if (packageName == null) { 16752 Slog.w(TAG, "Attempt to delete null packageName."); 16753 return false; 16754 } 16755 16756 // Try finding details about the requested package 16757 PackageParser.Package pkg; 16758 synchronized (mPackages) { 16759 pkg = mPackages.get(packageName); 16760 if (pkg == null) { 16761 final PackageSetting ps = mSettings.mPackages.get(packageName); 16762 if (ps != null) { 16763 pkg = ps.pkg; 16764 } 16765 } 16766 16767 if (pkg == null) { 16768 Slog.w(TAG, "Package named '" + packageName + "' doesn't exist."); 16769 return false; 16770 } 16771 16772 PackageSetting ps = (PackageSetting) pkg.mExtras; 16773 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 16774 } 16775 16776 clearAppDataLIF(pkg, userId, 16777 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 16778 16779 final int appId = UserHandle.getAppId(pkg.applicationInfo.uid); 16780 removeKeystoreDataIfNeeded(userId, appId); 16781 16782 UserManagerInternal umInternal = getUserManagerInternal(); 16783 final int flags; 16784 if (umInternal.isUserUnlockingOrUnlocked(userId)) { 16785 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 16786 } else if (umInternal.isUserRunning(userId)) { 16787 flags = StorageManager.FLAG_STORAGE_DE; 16788 } else { 16789 flags = 0; 16790 } 16791 prepareAppDataContentsLIF(pkg, userId, flags); 16792 16793 return true; 16794 } 16795 16796 /** 16797 * Reverts user permission state changes (permissions and flags) in 16798 * all packages for a given user. 16799 * 16800 * @param userId The device user for which to do a reset. 16801 */ 16802 private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) { 16803 final int packageCount = mPackages.size(); 16804 for (int i = 0; i < packageCount; i++) { 16805 PackageParser.Package pkg = mPackages.valueAt(i); 16806 PackageSetting ps = (PackageSetting) pkg.mExtras; 16807 resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId); 16808 } 16809 } 16810 16811 private void resetNetworkPolicies(int userId) { 16812 LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId); 16813 } 16814 16815 /** 16816 * Reverts user permission state changes (permissions and flags). 16817 * 16818 * @param ps The package for which to reset. 16819 * @param userId The device user for which to do a reset. 16820 */ 16821 private void resetUserChangesToRuntimePermissionsAndFlagsLPw( 16822 final PackageSetting ps, final int userId) { 16823 if (ps.pkg == null) { 16824 return; 16825 } 16826 16827 // These are flags that can change base on user actions. 16828 final int userSettableMask = FLAG_PERMISSION_USER_SET 16829 | FLAG_PERMISSION_USER_FIXED 16830 | FLAG_PERMISSION_REVOKE_ON_UPGRADE 16831 | FLAG_PERMISSION_REVIEW_REQUIRED; 16832 16833 final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED 16834 | FLAG_PERMISSION_POLICY_FIXED; 16835 16836 boolean writeInstallPermissions = false; 16837 boolean writeRuntimePermissions = false; 16838 16839 final int permissionCount = ps.pkg.requestedPermissions.size(); 16840 for (int i = 0; i < permissionCount; i++) { 16841 String permission = ps.pkg.requestedPermissions.get(i); 16842 16843 BasePermission bp = mSettings.mPermissions.get(permission); 16844 if (bp == null) { 16845 continue; 16846 } 16847 16848 // If shared user we just reset the state to which only this app contributed. 16849 if (ps.sharedUser != null) { 16850 boolean used = false; 16851 final int packageCount = ps.sharedUser.packages.size(); 16852 for (int j = 0; j < packageCount; j++) { 16853 PackageSetting pkg = ps.sharedUser.packages.valueAt(j); 16854 if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName) 16855 && pkg.pkg.requestedPermissions.contains(permission)) { 16856 used = true; 16857 break; 16858 } 16859 } 16860 if (used) { 16861 continue; 16862 } 16863 } 16864 16865 PermissionsState permissionsState = ps.getPermissionsState(); 16866 16867 final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId); 16868 16869 // Always clear the user settable flags. 16870 final boolean hasInstallState = permissionsState.getInstallPermissionState( 16871 bp.name) != null; 16872 // If permission review is enabled and this is a legacy app, mark the 16873 // permission as requiring a review as this is the initial state. 16874 int flags = 0; 16875 if (mPermissionReviewRequired 16876 && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { 16877 flags |= FLAG_PERMISSION_REVIEW_REQUIRED; 16878 } 16879 if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) { 16880 if (hasInstallState) { 16881 writeInstallPermissions = true; 16882 } else { 16883 writeRuntimePermissions = true; 16884 } 16885 } 16886 16887 // Below is only runtime permission handling. 16888 if (!bp.isRuntime()) { 16889 continue; 16890 } 16891 16892 // Never clobber system or policy. 16893 if ((oldFlags & policyOrSystemFlags) != 0) { 16894 continue; 16895 } 16896 16897 // If this permission was granted by default, make sure it is. 16898 if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) { 16899 if (permissionsState.grantRuntimePermission(bp, userId) 16900 != PERMISSION_OPERATION_FAILURE) { 16901 writeRuntimePermissions = true; 16902 } 16903 // If permission review is enabled the permissions for a legacy apps 16904 // are represented as constantly granted runtime ones, so don't revoke. 16905 } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) { 16906 // Otherwise, reset the permission. 16907 final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId); 16908 switch (revokeResult) { 16909 case PERMISSION_OPERATION_SUCCESS: 16910 case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { 16911 writeRuntimePermissions = true; 16912 final int appId = ps.appId; 16913 mHandler.post(new Runnable() { 16914 @Override 16915 public void run() { 16916 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED); 16917 } 16918 }); 16919 } break; 16920 } 16921 } 16922 } 16923 16924 // Synchronously write as we are taking permissions away. 16925 if (writeRuntimePermissions) { 16926 mSettings.writeRuntimePermissionsForUserLPr(userId, true); 16927 } 16928 16929 // Synchronously write as we are taking permissions away. 16930 if (writeInstallPermissions) { 16931 mSettings.writeLPr(); 16932 } 16933 } 16934 16935 /** 16936 * Remove entries from the keystore daemon. Will only remove it if the 16937 * {@code appId} is valid. 16938 */ 16939 private static void removeKeystoreDataIfNeeded(int userId, int appId) { 16940 if (appId < 0) { 16941 return; 16942 } 16943 16944 final KeyStore keyStore = KeyStore.getInstance(); 16945 if (keyStore != null) { 16946 if (userId == UserHandle.USER_ALL) { 16947 for (final int individual : sUserManager.getUserIds()) { 16948 keyStore.clearUid(UserHandle.getUid(individual, appId)); 16949 } 16950 } else { 16951 keyStore.clearUid(UserHandle.getUid(userId, appId)); 16952 } 16953 } else { 16954 Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId); 16955 } 16956 } 16957 16958 @Override 16959 public void deleteApplicationCacheFiles(final String packageName, 16960 final IPackageDataObserver observer) { 16961 final int userId = UserHandle.getCallingUserId(); 16962 deleteApplicationCacheFilesAsUser(packageName, userId, observer); 16963 } 16964 16965 @Override 16966 public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId, 16967 final IPackageDataObserver observer) { 16968 mContext.enforceCallingOrSelfPermission( 16969 android.Manifest.permission.DELETE_CACHE_FILES, null); 16970 enforceCrossUserPermission(Binder.getCallingUid(), userId, 16971 /* requireFullPermission= */ true, /* checkShell= */ false, 16972 "delete application cache files"); 16973 16974 final PackageParser.Package pkg; 16975 synchronized (mPackages) { 16976 pkg = mPackages.get(packageName); 16977 } 16978 16979 // Queue up an async operation since the package deletion may take a little while. 16980 mHandler.post(new Runnable() { 16981 public void run() { 16982 synchronized (mInstallLock) { 16983 final int flags = StorageManager.FLAG_STORAGE_DE 16984 | StorageManager.FLAG_STORAGE_CE; 16985 // We're only clearing cache files, so we don't care if the 16986 // app is unfrozen and still able to run 16987 clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY); 16988 clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 16989 } 16990 clearExternalStorageDataSync(packageName, userId, false); 16991 if (observer != null) { 16992 try { 16993 observer.onRemoveCompleted(packageName, true); 16994 } catch (RemoteException e) { 16995 Log.i(TAG, "Observer no longer exists."); 16996 } 16997 } 16998 } 16999 }); 17000 } 17001 17002 @Override 17003 public void getPackageSizeInfo(final String packageName, int userHandle, 17004 final IPackageStatsObserver observer) { 17005 mContext.enforceCallingOrSelfPermission( 17006 android.Manifest.permission.GET_PACKAGE_SIZE, null); 17007 if (packageName == null) { 17008 throw new IllegalArgumentException("Attempt to get size of null packageName"); 17009 } 17010 17011 PackageStats stats = new PackageStats(packageName, userHandle); 17012 17013 /* 17014 * Queue up an async operation since the package measurement may take a 17015 * little while. 17016 */ 17017 Message msg = mHandler.obtainMessage(INIT_COPY); 17018 msg.obj = new MeasureParams(stats, observer); 17019 mHandler.sendMessage(msg); 17020 } 17021 17022 private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) { 17023 final PackageSetting ps; 17024 synchronized (mPackages) { 17025 ps = mSettings.mPackages.get(packageName); 17026 if (ps == null) { 17027 Slog.w(TAG, "Failed to find settings for " + packageName); 17028 return false; 17029 } 17030 } 17031 try { 17032 mInstaller.getAppSize(ps.volumeUuid, packageName, userId, 17033 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 17034 ps.getCeDataInode(userId), ps.codePathString, stats); 17035 } catch (InstallerException e) { 17036 Slog.w(TAG, String.valueOf(e)); 17037 return false; 17038 } 17039 17040 // For now, ignore code size of packages on system partition 17041 if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) { 17042 stats.codeSize = 0; 17043 } 17044 17045 return true; 17046 } 17047 17048 private int getUidTargetSdkVersionLockedLPr(int uid) { 17049 Object obj = mSettings.getUserIdLPr(uid); 17050 if (obj instanceof SharedUserSetting) { 17051 final SharedUserSetting sus = (SharedUserSetting) obj; 17052 int vers = Build.VERSION_CODES.CUR_DEVELOPMENT; 17053 final Iterator<PackageSetting> it = sus.packages.iterator(); 17054 while (it.hasNext()) { 17055 final PackageSetting ps = it.next(); 17056 if (ps.pkg != null) { 17057 int v = ps.pkg.applicationInfo.targetSdkVersion; 17058 if (v < vers) vers = v; 17059 } 17060 } 17061 return vers; 17062 } else if (obj instanceof PackageSetting) { 17063 final PackageSetting ps = (PackageSetting) obj; 17064 if (ps.pkg != null) { 17065 return ps.pkg.applicationInfo.targetSdkVersion; 17066 } 17067 } 17068 return Build.VERSION_CODES.CUR_DEVELOPMENT; 17069 } 17070 17071 @Override 17072 public void addPreferredActivity(IntentFilter filter, int match, 17073 ComponentName[] set, ComponentName activity, int userId) { 17074 addPreferredActivityInternal(filter, match, set, activity, true, userId, 17075 "Adding preferred"); 17076 } 17077 17078 private void addPreferredActivityInternal(IntentFilter filter, int match, 17079 ComponentName[] set, ComponentName activity, boolean always, int userId, 17080 String opname) { 17081 // writer 17082 int callingUid = Binder.getCallingUid(); 17083 enforceCrossUserPermission(callingUid, userId, 17084 true /* requireFullPermission */, false /* checkShell */, "add preferred activity"); 17085 if (filter.countActions() == 0) { 17086 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 17087 return; 17088 } 17089 synchronized (mPackages) { 17090 if (mContext.checkCallingOrSelfPermission( 17091 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 17092 != PackageManager.PERMISSION_GRANTED) { 17093 if (getUidTargetSdkVersionLockedLPr(callingUid) 17094 < Build.VERSION_CODES.FROYO) { 17095 Slog.w(TAG, "Ignoring addPreferredActivity() from uid " 17096 + callingUid); 17097 return; 17098 } 17099 mContext.enforceCallingOrSelfPermission( 17100 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 17101 } 17102 17103 PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId); 17104 Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user " 17105 + userId + ":"); 17106 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 17107 pir.addFilter(new PreferredActivity(filter, match, set, activity, always)); 17108 scheduleWritePackageRestrictionsLocked(userId); 17109 postPreferredActivityChangedBroadcast(userId); 17110 } 17111 } 17112 17113 private void postPreferredActivityChangedBroadcast(int userId) { 17114 mHandler.post(() -> { 17115 final IActivityManager am = ActivityManagerNative.getDefault(); 17116 if (am == null) { 17117 return; 17118 } 17119 17120 final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED); 17121 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17122 try { 17123 am.broadcastIntent(null, intent, null, null, 17124 0, null, null, null, android.app.AppOpsManager.OP_NONE, 17125 null, false, false, userId); 17126 } catch (RemoteException e) { 17127 } 17128 }); 17129 } 17130 17131 @Override 17132 public void replacePreferredActivity(IntentFilter filter, int match, 17133 ComponentName[] set, ComponentName activity, int userId) { 17134 if (filter.countActions() != 1) { 17135 throw new IllegalArgumentException( 17136 "replacePreferredActivity expects filter to have only 1 action."); 17137 } 17138 if (filter.countDataAuthorities() != 0 17139 || filter.countDataPaths() != 0 17140 || filter.countDataSchemes() > 1 17141 || filter.countDataTypes() != 0) { 17142 throw new IllegalArgumentException( 17143 "replacePreferredActivity expects filter to have no data authorities, " + 17144 "paths, or types; and at most one scheme."); 17145 } 17146 17147 final int callingUid = Binder.getCallingUid(); 17148 enforceCrossUserPermission(callingUid, userId, 17149 true /* requireFullPermission */, false /* checkShell */, 17150 "replace preferred activity"); 17151 synchronized (mPackages) { 17152 if (mContext.checkCallingOrSelfPermission( 17153 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 17154 != PackageManager.PERMISSION_GRANTED) { 17155 if (getUidTargetSdkVersionLockedLPr(callingUid) 17156 < Build.VERSION_CODES.FROYO) { 17157 Slog.w(TAG, "Ignoring replacePreferredActivity() from uid " 17158 + Binder.getCallingUid()); 17159 return; 17160 } 17161 mContext.enforceCallingOrSelfPermission( 17162 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 17163 } 17164 17165 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 17166 if (pir != null) { 17167 // Get all of the existing entries that exactly match this filter. 17168 ArrayList<PreferredActivity> existing = pir.findFilters(filter); 17169 if (existing != null && existing.size() == 1) { 17170 PreferredActivity cur = existing.get(0); 17171 if (DEBUG_PREFERRED) { 17172 Slog.i(TAG, "Checking replace of preferred:"); 17173 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 17174 if (!cur.mPref.mAlways) { 17175 Slog.i(TAG, " -- CUR; not mAlways!"); 17176 } else { 17177 Slog.i(TAG, " -- CUR: mMatch=" + cur.mPref.mMatch); 17178 Slog.i(TAG, " -- CUR: mSet=" 17179 + Arrays.toString(cur.mPref.mSetComponents)); 17180 Slog.i(TAG, " -- CUR: mComponent=" + cur.mPref.mShortComponent); 17181 Slog.i(TAG, " -- NEW: mMatch=" 17182 + (match&IntentFilter.MATCH_CATEGORY_MASK)); 17183 Slog.i(TAG, " -- CUR: mSet=" + Arrays.toString(set)); 17184 Slog.i(TAG, " -- CUR: mComponent=" + activity.flattenToShortString()); 17185 } 17186 } 17187 if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity) 17188 && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK) 17189 && cur.mPref.sameSet(set)) { 17190 // Setting the preferred activity to what it happens to be already 17191 if (DEBUG_PREFERRED) { 17192 Slog.i(TAG, "Replacing with same preferred activity " 17193 + cur.mPref.mShortComponent + " for user " 17194 + userId + ":"); 17195 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 17196 } 17197 return; 17198 } 17199 } 17200 17201 if (existing != null) { 17202 if (DEBUG_PREFERRED) { 17203 Slog.i(TAG, existing.size() + " existing preferred matches for:"); 17204 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 17205 } 17206 for (int i = 0; i < existing.size(); i++) { 17207 PreferredActivity pa = existing.get(i); 17208 if (DEBUG_PREFERRED) { 17209 Slog.i(TAG, "Removing existing preferred activity " 17210 + pa.mPref.mComponent + ":"); 17211 pa.dump(new LogPrinter(Log.INFO, TAG), " "); 17212 } 17213 pir.removeFilter(pa); 17214 } 17215 } 17216 } 17217 addPreferredActivityInternal(filter, match, set, activity, true, userId, 17218 "Replacing preferred"); 17219 } 17220 } 17221 17222 @Override 17223 public void clearPackagePreferredActivities(String packageName) { 17224 final int uid = Binder.getCallingUid(); 17225 // writer 17226 synchronized (mPackages) { 17227 PackageParser.Package pkg = mPackages.get(packageName); 17228 if (pkg == null || pkg.applicationInfo.uid != uid) { 17229 if (mContext.checkCallingOrSelfPermission( 17230 android.Manifest.permission.SET_PREFERRED_APPLICATIONS) 17231 != PackageManager.PERMISSION_GRANTED) { 17232 if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid()) 17233 < Build.VERSION_CODES.FROYO) { 17234 Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid " 17235 + Binder.getCallingUid()); 17236 return; 17237 } 17238 mContext.enforceCallingOrSelfPermission( 17239 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 17240 } 17241 } 17242 17243 int user = UserHandle.getCallingUserId(); 17244 if (clearPackagePreferredActivitiesLPw(packageName, user)) { 17245 scheduleWritePackageRestrictionsLocked(user); 17246 } 17247 } 17248 } 17249 17250 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 17251 boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) { 17252 ArrayList<PreferredActivity> removed = null; 17253 boolean changed = false; 17254 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 17255 final int thisUserId = mSettings.mPreferredActivities.keyAt(i); 17256 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 17257 if (userId != UserHandle.USER_ALL && userId != thisUserId) { 17258 continue; 17259 } 17260 Iterator<PreferredActivity> it = pir.filterIterator(); 17261 while (it.hasNext()) { 17262 PreferredActivity pa = it.next(); 17263 // Mark entry for removal only if it matches the package name 17264 // and the entry is of type "always". 17265 if (packageName == null || 17266 (pa.mPref.mComponent.getPackageName().equals(packageName) 17267 && pa.mPref.mAlways)) { 17268 if (removed == null) { 17269 removed = new ArrayList<PreferredActivity>(); 17270 } 17271 removed.add(pa); 17272 } 17273 } 17274 if (removed != null) { 17275 for (int j=0; j<removed.size(); j++) { 17276 PreferredActivity pa = removed.get(j); 17277 pir.removeFilter(pa); 17278 } 17279 changed = true; 17280 } 17281 } 17282 if (changed) { 17283 postPreferredActivityChangedBroadcast(userId); 17284 } 17285 return changed; 17286 } 17287 17288 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 17289 private void clearIntentFilterVerificationsLPw(int userId) { 17290 final int packageCount = mPackages.size(); 17291 for (int i = 0; i < packageCount; i++) { 17292 PackageParser.Package pkg = mPackages.valueAt(i); 17293 clearIntentFilterVerificationsLPw(pkg.packageName, userId); 17294 } 17295 } 17296 17297 /** This method takes a specific user id as well as UserHandle.USER_ALL. */ 17298 void clearIntentFilterVerificationsLPw(String packageName, int userId) { 17299 if (userId == UserHandle.USER_ALL) { 17300 if (mSettings.removeIntentFilterVerificationLPw(packageName, 17301 sUserManager.getUserIds())) { 17302 for (int oneUserId : sUserManager.getUserIds()) { 17303 scheduleWritePackageRestrictionsLocked(oneUserId); 17304 } 17305 } 17306 } else { 17307 if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) { 17308 scheduleWritePackageRestrictionsLocked(userId); 17309 } 17310 } 17311 } 17312 17313 void clearDefaultBrowserIfNeeded(String packageName) { 17314 for (int oneUserId : sUserManager.getUserIds()) { 17315 String defaultBrowserPackageName = getDefaultBrowserPackageName(oneUserId); 17316 if (TextUtils.isEmpty(defaultBrowserPackageName)) continue; 17317 if (packageName.equals(defaultBrowserPackageName)) { 17318 setDefaultBrowserPackageName(null, oneUserId); 17319 } 17320 } 17321 } 17322 17323 @Override 17324 public void resetApplicationPreferences(int userId) { 17325 mContext.enforceCallingOrSelfPermission( 17326 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null); 17327 final long identity = Binder.clearCallingIdentity(); 17328 // writer 17329 try { 17330 synchronized (mPackages) { 17331 clearPackagePreferredActivitiesLPw(null, userId); 17332 mSettings.applyDefaultPreferredAppsLPw(this, userId); 17333 // TODO: We have to reset the default SMS and Phone. This requires 17334 // significant refactoring to keep all default apps in the package 17335 // manager (cleaner but more work) or have the services provide 17336 // callbacks to the package manager to request a default app reset. 17337 applyFactoryDefaultBrowserLPw(userId); 17338 clearIntentFilterVerificationsLPw(userId); 17339 primeDomainVerificationsLPw(userId); 17340 resetUserChangesToRuntimePermissionsAndFlagsLPw(userId); 17341 scheduleWritePackageRestrictionsLocked(userId); 17342 } 17343 resetNetworkPolicies(userId); 17344 } finally { 17345 Binder.restoreCallingIdentity(identity); 17346 } 17347 } 17348 17349 @Override 17350 public int getPreferredActivities(List<IntentFilter> outFilters, 17351 List<ComponentName> outActivities, String packageName) { 17352 17353 int num = 0; 17354 final int userId = UserHandle.getCallingUserId(); 17355 // reader 17356 synchronized (mPackages) { 17357 PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId); 17358 if (pir != null) { 17359 final Iterator<PreferredActivity> it = pir.filterIterator(); 17360 while (it.hasNext()) { 17361 final PreferredActivity pa = it.next(); 17362 if (packageName == null 17363 || (pa.mPref.mComponent.getPackageName().equals(packageName) 17364 && pa.mPref.mAlways)) { 17365 if (outFilters != null) { 17366 outFilters.add(new IntentFilter(pa)); 17367 } 17368 if (outActivities != null) { 17369 outActivities.add(pa.mPref.mComponent); 17370 } 17371 } 17372 } 17373 } 17374 } 17375 17376 return num; 17377 } 17378 17379 @Override 17380 public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity, 17381 int userId) { 17382 int callingUid = Binder.getCallingUid(); 17383 if (callingUid != Process.SYSTEM_UID) { 17384 throw new SecurityException( 17385 "addPersistentPreferredActivity can only be run by the system"); 17386 } 17387 if (filter.countActions() == 0) { 17388 Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); 17389 return; 17390 } 17391 synchronized (mPackages) { 17392 Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId + 17393 ":"); 17394 filter.dump(new LogPrinter(Log.INFO, TAG), " "); 17395 mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter( 17396 new PersistentPreferredActivity(filter, activity)); 17397 scheduleWritePackageRestrictionsLocked(userId); 17398 postPreferredActivityChangedBroadcast(userId); 17399 } 17400 } 17401 17402 @Override 17403 public void clearPackagePersistentPreferredActivities(String packageName, int userId) { 17404 int callingUid = Binder.getCallingUid(); 17405 if (callingUid != Process.SYSTEM_UID) { 17406 throw new SecurityException( 17407 "clearPackagePersistentPreferredActivities can only be run by the system"); 17408 } 17409 ArrayList<PersistentPreferredActivity> removed = null; 17410 boolean changed = false; 17411 synchronized (mPackages) { 17412 for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) { 17413 final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i); 17414 PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities 17415 .valueAt(i); 17416 if (userId != thisUserId) { 17417 continue; 17418 } 17419 Iterator<PersistentPreferredActivity> it = ppir.filterIterator(); 17420 while (it.hasNext()) { 17421 PersistentPreferredActivity ppa = it.next(); 17422 // Mark entry for removal only if it matches the package name. 17423 if (ppa.mComponent.getPackageName().equals(packageName)) { 17424 if (removed == null) { 17425 removed = new ArrayList<PersistentPreferredActivity>(); 17426 } 17427 removed.add(ppa); 17428 } 17429 } 17430 if (removed != null) { 17431 for (int j=0; j<removed.size(); j++) { 17432 PersistentPreferredActivity ppa = removed.get(j); 17433 ppir.removeFilter(ppa); 17434 } 17435 changed = true; 17436 } 17437 } 17438 17439 if (changed) { 17440 scheduleWritePackageRestrictionsLocked(userId); 17441 postPreferredActivityChangedBroadcast(userId); 17442 } 17443 } 17444 } 17445 17446 /** 17447 * Common machinery for picking apart a restored XML blob and passing 17448 * it to a caller-supplied functor to be applied to the running system. 17449 */ 17450 private void restoreFromXml(XmlPullParser parser, int userId, 17451 String expectedStartTag, BlobXmlRestorer functor) 17452 throws IOException, XmlPullParserException { 17453 int type; 17454 while ((type = parser.next()) != XmlPullParser.START_TAG 17455 && type != XmlPullParser.END_DOCUMENT) { 17456 } 17457 if (type != XmlPullParser.START_TAG) { 17458 // oops didn't find a start tag?! 17459 if (DEBUG_BACKUP) { 17460 Slog.e(TAG, "Didn't find start tag during restore"); 17461 } 17462 return; 17463 } 17464Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName()); 17465 // this is supposed to be TAG_PREFERRED_BACKUP 17466 if (!expectedStartTag.equals(parser.getName())) { 17467 if (DEBUG_BACKUP) { 17468 Slog.e(TAG, "Found unexpected tag " + parser.getName()); 17469 } 17470 return; 17471 } 17472 17473 // skip interfering stuff, then we're aligned with the backing implementation 17474 while ((type = parser.next()) == XmlPullParser.TEXT) { } 17475Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); 17476 functor.apply(parser, userId); 17477 } 17478 17479 private interface BlobXmlRestorer { 17480 public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException; 17481 } 17482 17483 /** 17484 * Non-Binder method, support for the backup/restore mechanism: write the 17485 * full set of preferred activities in its canonical XML format. Returns the 17486 * XML output as a byte array, or null if there is none. 17487 */ 17488 @Override 17489 public byte[] getPreferredActivityBackup(int userId) { 17490 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17491 throw new SecurityException("Only the system may call getPreferredActivityBackup()"); 17492 } 17493 17494 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 17495 try { 17496 final XmlSerializer serializer = new FastXmlSerializer(); 17497 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 17498 serializer.startDocument(null, true); 17499 serializer.startTag(null, TAG_PREFERRED_BACKUP); 17500 17501 synchronized (mPackages) { 17502 mSettings.writePreferredActivitiesLPr(serializer, userId, true); 17503 } 17504 17505 serializer.endTag(null, TAG_PREFERRED_BACKUP); 17506 serializer.endDocument(); 17507 serializer.flush(); 17508 } catch (Exception e) { 17509 if (DEBUG_BACKUP) { 17510 Slog.e(TAG, "Unable to write preferred activities for backup", e); 17511 } 17512 return null; 17513 } 17514 17515 return dataStream.toByteArray(); 17516 } 17517 17518 @Override 17519 public void restorePreferredActivities(byte[] backup, int userId) { 17520 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17521 throw new SecurityException("Only the system may call restorePreferredActivities()"); 17522 } 17523 17524 try { 17525 final XmlPullParser parser = Xml.newPullParser(); 17526 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 17527 restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP, 17528 new BlobXmlRestorer() { 17529 @Override 17530 public void apply(XmlPullParser parser, int userId) 17531 throws XmlPullParserException, IOException { 17532 synchronized (mPackages) { 17533 mSettings.readPreferredActivitiesLPw(parser, userId); 17534 } 17535 } 17536 } ); 17537 } catch (Exception e) { 17538 if (DEBUG_BACKUP) { 17539 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 17540 } 17541 } 17542 } 17543 17544 /** 17545 * Non-Binder method, support for the backup/restore mechanism: write the 17546 * default browser (etc) settings in its canonical XML format. Returns the default 17547 * browser XML representation as a byte array, or null if there is none. 17548 */ 17549 @Override 17550 public byte[] getDefaultAppsBackup(int userId) { 17551 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17552 throw new SecurityException("Only the system may call getDefaultAppsBackup()"); 17553 } 17554 17555 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 17556 try { 17557 final XmlSerializer serializer = new FastXmlSerializer(); 17558 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 17559 serializer.startDocument(null, true); 17560 serializer.startTag(null, TAG_DEFAULT_APPS); 17561 17562 synchronized (mPackages) { 17563 mSettings.writeDefaultAppsLPr(serializer, userId); 17564 } 17565 17566 serializer.endTag(null, TAG_DEFAULT_APPS); 17567 serializer.endDocument(); 17568 serializer.flush(); 17569 } catch (Exception e) { 17570 if (DEBUG_BACKUP) { 17571 Slog.e(TAG, "Unable to write default apps for backup", e); 17572 } 17573 return null; 17574 } 17575 17576 return dataStream.toByteArray(); 17577 } 17578 17579 @Override 17580 public void restoreDefaultApps(byte[] backup, int userId) { 17581 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17582 throw new SecurityException("Only the system may call restoreDefaultApps()"); 17583 } 17584 17585 try { 17586 final XmlPullParser parser = Xml.newPullParser(); 17587 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 17588 restoreFromXml(parser, userId, TAG_DEFAULT_APPS, 17589 new BlobXmlRestorer() { 17590 @Override 17591 public void apply(XmlPullParser parser, int userId) 17592 throws XmlPullParserException, IOException { 17593 synchronized (mPackages) { 17594 mSettings.readDefaultAppsLPw(parser, userId); 17595 } 17596 } 17597 } ); 17598 } catch (Exception e) { 17599 if (DEBUG_BACKUP) { 17600 Slog.e(TAG, "Exception restoring default apps: " + e.getMessage()); 17601 } 17602 } 17603 } 17604 17605 @Override 17606 public byte[] getIntentFilterVerificationBackup(int userId) { 17607 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17608 throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()"); 17609 } 17610 17611 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 17612 try { 17613 final XmlSerializer serializer = new FastXmlSerializer(); 17614 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 17615 serializer.startDocument(null, true); 17616 serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION); 17617 17618 synchronized (mPackages) { 17619 mSettings.writeAllDomainVerificationsLPr(serializer, userId); 17620 } 17621 17622 serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION); 17623 serializer.endDocument(); 17624 serializer.flush(); 17625 } catch (Exception e) { 17626 if (DEBUG_BACKUP) { 17627 Slog.e(TAG, "Unable to write default apps for backup", e); 17628 } 17629 return null; 17630 } 17631 17632 return dataStream.toByteArray(); 17633 } 17634 17635 @Override 17636 public void restoreIntentFilterVerification(byte[] backup, int userId) { 17637 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17638 throw new SecurityException("Only the system may call restorePreferredActivities()"); 17639 } 17640 17641 try { 17642 final XmlPullParser parser = Xml.newPullParser(); 17643 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 17644 restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION, 17645 new BlobXmlRestorer() { 17646 @Override 17647 public void apply(XmlPullParser parser, int userId) 17648 throws XmlPullParserException, IOException { 17649 synchronized (mPackages) { 17650 mSettings.readAllDomainVerificationsLPr(parser, userId); 17651 mSettings.writeLPr(); 17652 } 17653 } 17654 } ); 17655 } catch (Exception e) { 17656 if (DEBUG_BACKUP) { 17657 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 17658 } 17659 } 17660 } 17661 17662 @Override 17663 public byte[] getPermissionGrantBackup(int userId) { 17664 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17665 throw new SecurityException("Only the system may call getPermissionGrantBackup()"); 17666 } 17667 17668 ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); 17669 try { 17670 final XmlSerializer serializer = new FastXmlSerializer(); 17671 serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); 17672 serializer.startDocument(null, true); 17673 serializer.startTag(null, TAG_PERMISSION_BACKUP); 17674 17675 synchronized (mPackages) { 17676 serializeRuntimePermissionGrantsLPr(serializer, userId); 17677 } 17678 17679 serializer.endTag(null, TAG_PERMISSION_BACKUP); 17680 serializer.endDocument(); 17681 serializer.flush(); 17682 } catch (Exception e) { 17683 if (DEBUG_BACKUP) { 17684 Slog.e(TAG, "Unable to write default apps for backup", e); 17685 } 17686 return null; 17687 } 17688 17689 return dataStream.toByteArray(); 17690 } 17691 17692 @Override 17693 public void restorePermissionGrants(byte[] backup, int userId) { 17694 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 17695 throw new SecurityException("Only the system may call restorePermissionGrants()"); 17696 } 17697 17698 try { 17699 final XmlPullParser parser = Xml.newPullParser(); 17700 parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); 17701 restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP, 17702 new BlobXmlRestorer() { 17703 @Override 17704 public void apply(XmlPullParser parser, int userId) 17705 throws XmlPullParserException, IOException { 17706 synchronized (mPackages) { 17707 processRestoredPermissionGrantsLPr(parser, userId); 17708 } 17709 } 17710 } ); 17711 } catch (Exception e) { 17712 if (DEBUG_BACKUP) { 17713 Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); 17714 } 17715 } 17716 } 17717 17718 private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId) 17719 throws IOException { 17720 serializer.startTag(null, TAG_ALL_GRANTS); 17721 17722 final int N = mSettings.mPackages.size(); 17723 for (int i = 0; i < N; i++) { 17724 final PackageSetting ps = mSettings.mPackages.valueAt(i); 17725 boolean pkgGrantsKnown = false; 17726 17727 PermissionsState packagePerms = ps.getPermissionsState(); 17728 17729 for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) { 17730 final int grantFlags = state.getFlags(); 17731 // only look at grants that are not system/policy fixed 17732 if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) { 17733 final boolean isGranted = state.isGranted(); 17734 // And only back up the user-twiddled state bits 17735 if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) { 17736 final String packageName = mSettings.mPackages.keyAt(i); 17737 if (!pkgGrantsKnown) { 17738 serializer.startTag(null, TAG_GRANT); 17739 serializer.attribute(null, ATTR_PACKAGE_NAME, packageName); 17740 pkgGrantsKnown = true; 17741 } 17742 17743 final boolean userSet = 17744 (grantFlags & FLAG_PERMISSION_USER_SET) != 0; 17745 final boolean userFixed = 17746 (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0; 17747 final boolean revoke = 17748 (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0; 17749 17750 serializer.startTag(null, TAG_PERMISSION); 17751 serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName()); 17752 if (isGranted) { 17753 serializer.attribute(null, ATTR_IS_GRANTED, "true"); 17754 } 17755 if (userSet) { 17756 serializer.attribute(null, ATTR_USER_SET, "true"); 17757 } 17758 if (userFixed) { 17759 serializer.attribute(null, ATTR_USER_FIXED, "true"); 17760 } 17761 if (revoke) { 17762 serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true"); 17763 } 17764 serializer.endTag(null, TAG_PERMISSION); 17765 } 17766 } 17767 } 17768 17769 if (pkgGrantsKnown) { 17770 serializer.endTag(null, TAG_GRANT); 17771 } 17772 } 17773 17774 serializer.endTag(null, TAG_ALL_GRANTS); 17775 } 17776 17777 private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId) 17778 throws XmlPullParserException, IOException { 17779 String pkgName = null; 17780 int outerDepth = parser.getDepth(); 17781 int type; 17782 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 17783 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 17784 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 17785 continue; 17786 } 17787 17788 final String tagName = parser.getName(); 17789 if (tagName.equals(TAG_GRANT)) { 17790 pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME); 17791 if (DEBUG_BACKUP) { 17792 Slog.v(TAG, "+++ Restoring grants for package " + pkgName); 17793 } 17794 } else if (tagName.equals(TAG_PERMISSION)) { 17795 17796 final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED)); 17797 final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME); 17798 17799 int newFlagSet = 0; 17800 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) { 17801 newFlagSet |= FLAG_PERMISSION_USER_SET; 17802 } 17803 if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) { 17804 newFlagSet |= FLAG_PERMISSION_USER_FIXED; 17805 } 17806 if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) { 17807 newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE; 17808 } 17809 if (DEBUG_BACKUP) { 17810 Slog.v(TAG, " + Restoring grant: pkg=" + pkgName + " perm=" + permName 17811 + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet)); 17812 } 17813 final PackageSetting ps = mSettings.mPackages.get(pkgName); 17814 if (ps != null) { 17815 // Already installed so we apply the grant immediately 17816 if (DEBUG_BACKUP) { 17817 Slog.v(TAG, " + already installed; applying"); 17818 } 17819 PermissionsState perms = ps.getPermissionsState(); 17820 BasePermission bp = mSettings.mPermissions.get(permName); 17821 if (bp != null) { 17822 if (isGranted) { 17823 perms.grantRuntimePermission(bp, userId); 17824 } 17825 if (newFlagSet != 0) { 17826 perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet); 17827 } 17828 } 17829 } else { 17830 // Need to wait for post-restore install to apply the grant 17831 if (DEBUG_BACKUP) { 17832 Slog.v(TAG, " - not yet installed; saving for later"); 17833 } 17834 mSettings.processRestoredPermissionGrantLPr(pkgName, permName, 17835 isGranted, newFlagSet, userId); 17836 } 17837 } else { 17838 PackageManagerService.reportSettingsProblem(Log.WARN, 17839 "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName); 17840 XmlUtils.skipCurrentTag(parser); 17841 } 17842 } 17843 17844 scheduleWriteSettingsLocked(); 17845 mSettings.writeRuntimePermissionsForUserLPr(userId, false); 17846 } 17847 17848 @Override 17849 public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage, 17850 int sourceUserId, int targetUserId, int flags) { 17851 mContext.enforceCallingOrSelfPermission( 17852 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 17853 int callingUid = Binder.getCallingUid(); 17854 enforceOwnerRights(ownerPackage, callingUid); 17855 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 17856 if (intentFilter.countActions() == 0) { 17857 Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions"); 17858 return; 17859 } 17860 synchronized (mPackages) { 17861 CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter, 17862 ownerPackage, targetUserId, flags); 17863 CrossProfileIntentResolver resolver = 17864 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 17865 ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter); 17866 // We have all those whose filter is equal. Now checking if the rest is equal as well. 17867 if (existing != null) { 17868 int size = existing.size(); 17869 for (int i = 0; i < size; i++) { 17870 if (newFilter.equalsIgnoreFilter(existing.get(i))) { 17871 return; 17872 } 17873 } 17874 } 17875 resolver.addFilter(newFilter); 17876 scheduleWritePackageRestrictionsLocked(sourceUserId); 17877 } 17878 } 17879 17880 @Override 17881 public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) { 17882 mContext.enforceCallingOrSelfPermission( 17883 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); 17884 int callingUid = Binder.getCallingUid(); 17885 enforceOwnerRights(ownerPackage, callingUid); 17886 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId); 17887 synchronized (mPackages) { 17888 CrossProfileIntentResolver resolver = 17889 mSettings.editCrossProfileIntentResolverLPw(sourceUserId); 17890 ArraySet<CrossProfileIntentFilter> set = 17891 new ArraySet<CrossProfileIntentFilter>(resolver.filterSet()); 17892 for (CrossProfileIntentFilter filter : set) { 17893 if (filter.getOwnerPackage().equals(ownerPackage)) { 17894 resolver.removeFilter(filter); 17895 } 17896 } 17897 scheduleWritePackageRestrictionsLocked(sourceUserId); 17898 } 17899 } 17900 17901 // Enforcing that callingUid is owning pkg on userId 17902 private void enforceOwnerRights(String pkg, int callingUid) { 17903 // The system owns everything. 17904 if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) { 17905 return; 17906 } 17907 int callingUserId = UserHandle.getUserId(callingUid); 17908 PackageInfo pi = getPackageInfo(pkg, 0, callingUserId); 17909 if (pi == null) { 17910 throw new IllegalArgumentException("Unknown package " + pkg + " on user " 17911 + callingUserId); 17912 } 17913 if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) { 17914 throw new SecurityException("Calling uid " + callingUid 17915 + " does not own package " + pkg); 17916 } 17917 } 17918 17919 @Override 17920 public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) { 17921 return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId()); 17922 } 17923 17924 private Intent getHomeIntent() { 17925 Intent intent = new Intent(Intent.ACTION_MAIN); 17926 intent.addCategory(Intent.CATEGORY_HOME); 17927 intent.addCategory(Intent.CATEGORY_DEFAULT); 17928 return intent; 17929 } 17930 17931 private IntentFilter getHomeFilter() { 17932 IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN); 17933 filter.addCategory(Intent.CATEGORY_HOME); 17934 filter.addCategory(Intent.CATEGORY_DEFAULT); 17935 return filter; 17936 } 17937 17938 ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, 17939 int userId) { 17940 Intent intent = getHomeIntent(); 17941 List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null, 17942 PackageManager.GET_META_DATA, userId); 17943 ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0, 17944 true, false, false, userId); 17945 17946 allHomeCandidates.clear(); 17947 if (list != null) { 17948 for (ResolveInfo ri : list) { 17949 allHomeCandidates.add(ri); 17950 } 17951 } 17952 return (preferred == null || preferred.activityInfo == null) 17953 ? null 17954 : new ComponentName(preferred.activityInfo.packageName, 17955 preferred.activityInfo.name); 17956 } 17957 17958 @Override 17959 public void setHomeActivity(ComponentName comp, int userId) { 17960 ArrayList<ResolveInfo> homeActivities = new ArrayList<>(); 17961 getHomeActivitiesAsUser(homeActivities, userId); 17962 17963 boolean found = false; 17964 17965 final int size = homeActivities.size(); 17966 final ComponentName[] set = new ComponentName[size]; 17967 for (int i = 0; i < size; i++) { 17968 final ResolveInfo candidate = homeActivities.get(i); 17969 final ActivityInfo info = candidate.activityInfo; 17970 final ComponentName activityName = new ComponentName(info.packageName, info.name); 17971 set[i] = activityName; 17972 if (!found && activityName.equals(comp)) { 17973 found = true; 17974 } 17975 } 17976 if (!found) { 17977 throw new IllegalArgumentException("Component " + comp + " cannot be home on user " 17978 + userId); 17979 } 17980 replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY, 17981 set, comp, userId); 17982 } 17983 17984 private @Nullable String getSetupWizardPackageName() { 17985 final Intent intent = new Intent(Intent.ACTION_MAIN); 17986 intent.addCategory(Intent.CATEGORY_SETUP_WIZARD); 17987 17988 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, 17989 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE 17990 | MATCH_DISABLED_COMPONENTS, 17991 UserHandle.myUserId()); 17992 if (matches.size() == 1) { 17993 return matches.get(0).getComponentInfo().packageName; 17994 } else { 17995 Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size() 17996 + ": matches=" + matches); 17997 return null; 17998 } 17999 } 18000 18001 private @Nullable String getStorageManagerPackageName() { 18002 final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE); 18003 18004 final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, 18005 MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE 18006 | MATCH_DISABLED_COMPONENTS, 18007 UserHandle.myUserId()); 18008 if (matches.size() == 1) { 18009 return matches.get(0).getComponentInfo().packageName; 18010 } else { 18011 Slog.e(TAG, "There should probably be exactly one storage manager; found " 18012 + matches.size() + ": matches=" + matches); 18013 return null; 18014 } 18015 } 18016 18017 @Override 18018 public void setApplicationEnabledSetting(String appPackageName, 18019 int newState, int flags, int userId, String callingPackage) { 18020 if (!sUserManager.exists(userId)) return; 18021 if (callingPackage == null) { 18022 callingPackage = Integer.toString(Binder.getCallingUid()); 18023 } 18024 setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage); 18025 } 18026 18027 @Override 18028 public void setComponentEnabledSetting(ComponentName componentName, 18029 int newState, int flags, int userId) { 18030 if (!sUserManager.exists(userId)) return; 18031 setEnabledSetting(componentName.getPackageName(), 18032 componentName.getClassName(), newState, flags, userId, null); 18033 } 18034 18035 private void setEnabledSetting(final String packageName, String className, int newState, 18036 final int flags, int userId, String callingPackage) { 18037 if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT 18038 || newState == COMPONENT_ENABLED_STATE_ENABLED 18039 || newState == COMPONENT_ENABLED_STATE_DISABLED 18040 || newState == COMPONENT_ENABLED_STATE_DISABLED_USER 18041 || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) { 18042 throw new IllegalArgumentException("Invalid new component state: " 18043 + newState); 18044 } 18045 PackageSetting pkgSetting; 18046 final int uid = Binder.getCallingUid(); 18047 final int permission; 18048 if (uid == Process.SYSTEM_UID) { 18049 permission = PackageManager.PERMISSION_GRANTED; 18050 } else { 18051 permission = mContext.checkCallingOrSelfPermission( 18052 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 18053 } 18054 enforceCrossUserPermission(uid, userId, 18055 false /* requireFullPermission */, true /* checkShell */, "set enabled"); 18056 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 18057 boolean sendNow = false; 18058 boolean isApp = (className == null); 18059 String componentName = isApp ? packageName : className; 18060 int packageUid = -1; 18061 ArrayList<String> components; 18062 18063 // writer 18064 synchronized (mPackages) { 18065 pkgSetting = mSettings.mPackages.get(packageName); 18066 if (pkgSetting == null) { 18067 if (className == null) { 18068 throw new IllegalArgumentException("Unknown package: " + packageName); 18069 } 18070 throw new IllegalArgumentException( 18071 "Unknown component: " + packageName + "/" + className); 18072 } 18073 } 18074 18075 // Limit who can change which apps 18076 if (!UserHandle.isSameApp(uid, pkgSetting.appId)) { 18077 // Don't allow apps that don't have permission to modify other apps 18078 if (!allowedByPermission) { 18079 throw new SecurityException( 18080 "Permission Denial: attempt to change component state from pid=" 18081 + Binder.getCallingPid() 18082 + ", uid=" + uid + ", package uid=" + pkgSetting.appId); 18083 } 18084 // Don't allow changing protected packages. 18085 if (mProtectedPackages.isPackageStateProtected(userId, packageName)) { 18086 throw new SecurityException("Cannot disable a protected package: " + packageName); 18087 } 18088 } 18089 18090 synchronized (mPackages) { 18091 if (uid == Process.SHELL_UID 18092 && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) { 18093 // Shell can only change whole packages between ENABLED and DISABLED_USER states 18094 // unless it is a test package. 18095 int oldState = pkgSetting.getEnabled(userId); 18096 if (className == null 18097 && 18098 (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER 18099 || oldState == COMPONENT_ENABLED_STATE_DEFAULT 18100 || oldState == COMPONENT_ENABLED_STATE_ENABLED) 18101 && 18102 (newState == COMPONENT_ENABLED_STATE_DISABLED_USER 18103 || newState == COMPONENT_ENABLED_STATE_DEFAULT 18104 || newState == COMPONENT_ENABLED_STATE_ENABLED)) { 18105 // ok 18106 } else { 18107 throw new SecurityException( 18108 "Shell cannot change component state for " + packageName + "/" 18109 + className + " to " + newState); 18110 } 18111 } 18112 if (className == null) { 18113 // We're dealing with an application/package level state change 18114 if (pkgSetting.getEnabled(userId) == newState) { 18115 // Nothing to do 18116 return; 18117 } 18118 if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT 18119 || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { 18120 // Don't care about who enables an app. 18121 callingPackage = null; 18122 } 18123 pkgSetting.setEnabled(newState, userId, callingPackage); 18124 // pkgSetting.pkg.mSetEnabled = newState; 18125 } else { 18126 // We're dealing with a component level state change 18127 // First, verify that this is a valid class name. 18128 PackageParser.Package pkg = pkgSetting.pkg; 18129 if (pkg == null || !pkg.hasComponentClassName(className)) { 18130 if (pkg != null && 18131 pkg.applicationInfo.targetSdkVersion >= 18132 Build.VERSION_CODES.JELLY_BEAN) { 18133 throw new IllegalArgumentException("Component class " + className 18134 + " does not exist in " + packageName); 18135 } else { 18136 Slog.w(TAG, "Failed setComponentEnabledSetting: component class " 18137 + className + " does not exist in " + packageName); 18138 } 18139 } 18140 switch (newState) { 18141 case COMPONENT_ENABLED_STATE_ENABLED: 18142 if (!pkgSetting.enableComponentLPw(className, userId)) { 18143 return; 18144 } 18145 break; 18146 case COMPONENT_ENABLED_STATE_DISABLED: 18147 if (!pkgSetting.disableComponentLPw(className, userId)) { 18148 return; 18149 } 18150 break; 18151 case COMPONENT_ENABLED_STATE_DEFAULT: 18152 if (!pkgSetting.restoreComponentLPw(className, userId)) { 18153 return; 18154 } 18155 break; 18156 default: 18157 Slog.e(TAG, "Invalid new component state: " + newState); 18158 return; 18159 } 18160 } 18161 scheduleWritePackageRestrictionsLocked(userId); 18162 components = mPendingBroadcasts.get(userId, packageName); 18163 final boolean newPackage = components == null; 18164 if (newPackage) { 18165 components = new ArrayList<String>(); 18166 } 18167 if (!components.contains(componentName)) { 18168 components.add(componentName); 18169 } 18170 if ((flags&PackageManager.DONT_KILL_APP) == 0) { 18171 sendNow = true; 18172 // Purge entry from pending broadcast list if another one exists already 18173 // since we are sending one right away. 18174 mPendingBroadcasts.remove(userId, packageName); 18175 } else { 18176 if (newPackage) { 18177 mPendingBroadcasts.put(userId, packageName, components); 18178 } 18179 if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) { 18180 // Schedule a message 18181 mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY); 18182 } 18183 } 18184 } 18185 18186 long callingId = Binder.clearCallingIdentity(); 18187 try { 18188 if (sendNow) { 18189 packageUid = UserHandle.getUid(userId, pkgSetting.appId); 18190 sendPackageChangedBroadcast(packageName, 18191 (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid); 18192 } 18193 } finally { 18194 Binder.restoreCallingIdentity(callingId); 18195 } 18196 } 18197 18198 @Override 18199 public void flushPackageRestrictionsAsUser(int userId) { 18200 if (!sUserManager.exists(userId)) { 18201 return; 18202 } 18203 enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/, 18204 false /* checkShell */, "flushPackageRestrictions"); 18205 synchronized (mPackages) { 18206 mSettings.writePackageRestrictionsLPr(userId); 18207 mDirtyUsers.remove(userId); 18208 if (mDirtyUsers.isEmpty()) { 18209 mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS); 18210 } 18211 } 18212 } 18213 18214 private void sendPackageChangedBroadcast(String packageName, 18215 boolean killFlag, ArrayList<String> componentNames, int packageUid) { 18216 if (DEBUG_INSTALL) 18217 Log.v(TAG, "Sending package changed: package=" + packageName + " components=" 18218 + componentNames); 18219 Bundle extras = new Bundle(4); 18220 extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0)); 18221 String nameList[] = new String[componentNames.size()]; 18222 componentNames.toArray(nameList); 18223 extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList); 18224 extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag); 18225 extras.putInt(Intent.EXTRA_UID, packageUid); 18226 // If this is not reporting a change of the overall package, then only send it 18227 // to registered receivers. We don't want to launch a swath of apps for every 18228 // little component state change. 18229 final int flags = !componentNames.contains(packageName) 18230 ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0; 18231 sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageName, extras, flags, null, null, 18232 new int[] {UserHandle.getUserId(packageUid)}); 18233 } 18234 18235 @Override 18236 public void setPackageStoppedState(String packageName, boolean stopped, int userId) { 18237 if (!sUserManager.exists(userId)) return; 18238 final int uid = Binder.getCallingUid(); 18239 final int permission = mContext.checkCallingOrSelfPermission( 18240 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); 18241 final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); 18242 enforceCrossUserPermission(uid, userId, 18243 true /* requireFullPermission */, true /* checkShell */, "stop package"); 18244 // writer 18245 synchronized (mPackages) { 18246 if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped, 18247 allowedByPermission, uid, userId)) { 18248 scheduleWritePackageRestrictionsLocked(userId); 18249 } 18250 } 18251 } 18252 18253 @Override 18254 public String getInstallerPackageName(String packageName) { 18255 // reader 18256 synchronized (mPackages) { 18257 return mSettings.getInstallerPackageNameLPr(packageName); 18258 } 18259 } 18260 18261 public boolean isOrphaned(String packageName) { 18262 // reader 18263 synchronized (mPackages) { 18264 return mSettings.isOrphaned(packageName); 18265 } 18266 } 18267 18268 @Override 18269 public int getApplicationEnabledSetting(String packageName, int userId) { 18270 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 18271 int uid = Binder.getCallingUid(); 18272 enforceCrossUserPermission(uid, userId, 18273 false /* requireFullPermission */, false /* checkShell */, "get enabled"); 18274 // reader 18275 synchronized (mPackages) { 18276 return mSettings.getApplicationEnabledSettingLPr(packageName, userId); 18277 } 18278 } 18279 18280 @Override 18281 public int getComponentEnabledSetting(ComponentName componentName, int userId) { 18282 if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; 18283 int uid = Binder.getCallingUid(); 18284 enforceCrossUserPermission(uid, userId, 18285 false /* requireFullPermission */, false /* checkShell */, "get component enabled"); 18286 // reader 18287 synchronized (mPackages) { 18288 return mSettings.getComponentEnabledSettingLPr(componentName, userId); 18289 } 18290 } 18291 18292 @Override 18293 public void enterSafeMode() { 18294 enforceSystemOrRoot("Only the system can request entering safe mode"); 18295 18296 if (!mSystemReady) { 18297 mSafeMode = true; 18298 } 18299 } 18300 18301 @Override 18302 public void systemReady() { 18303 mSystemReady = true; 18304 18305 // Disable any carrier apps. We do this very early in boot to prevent the apps from being 18306 // disabled after already being started. 18307 CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this, 18308 mContext.getContentResolver(), UserHandle.USER_SYSTEM); 18309 18310 // Read the compatibilty setting when the system is ready. 18311 boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt( 18312 mContext.getContentResolver(), 18313 android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1; 18314 PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled); 18315 if (DEBUG_SETTINGS) { 18316 Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled); 18317 } 18318 18319 int[] grantPermissionsUserIds = EMPTY_INT_ARRAY; 18320 18321 synchronized (mPackages) { 18322 // Verify that all of the preferred activity components actually 18323 // exist. It is possible for applications to be updated and at 18324 // that point remove a previously declared activity component that 18325 // had been set as a preferred activity. We try to clean this up 18326 // the next time we encounter that preferred activity, but it is 18327 // possible for the user flow to never be able to return to that 18328 // situation so here we do a sanity check to make sure we haven't 18329 // left any junk around. 18330 ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>(); 18331 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 18332 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 18333 removed.clear(); 18334 for (PreferredActivity pa : pir.filterSet()) { 18335 if (mActivities.mActivities.get(pa.mPref.mComponent) == null) { 18336 removed.add(pa); 18337 } 18338 } 18339 if (removed.size() > 0) { 18340 for (int r=0; r<removed.size(); r++) { 18341 PreferredActivity pa = removed.get(r); 18342 Slog.w(TAG, "Removing dangling preferred activity: " 18343 + pa.mPref.mComponent); 18344 pir.removeFilter(pa); 18345 } 18346 mSettings.writePackageRestrictionsLPr( 18347 mSettings.mPreferredActivities.keyAt(i)); 18348 } 18349 } 18350 18351 for (int userId : UserManagerService.getInstance().getUserIds()) { 18352 if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) { 18353 grantPermissionsUserIds = ArrayUtils.appendInt( 18354 grantPermissionsUserIds, userId); 18355 } 18356 } 18357 } 18358 sUserManager.systemReady(); 18359 18360 // If we upgraded grant all default permissions before kicking off. 18361 for (int userId : grantPermissionsUserIds) { 18362 mDefaultPermissionPolicy.grantDefaultPermissions(userId); 18363 } 18364 18365 // If we did not grant default permissions, we preload from this the 18366 // default permission exceptions lazily to ensure we don't hit the 18367 // disk on a new user creation. 18368 if (grantPermissionsUserIds == EMPTY_INT_ARRAY) { 18369 mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions(); 18370 } 18371 18372 // Kick off any messages waiting for system ready 18373 if (mPostSystemReadyMessages != null) { 18374 for (Message msg : mPostSystemReadyMessages) { 18375 msg.sendToTarget(); 18376 } 18377 mPostSystemReadyMessages = null; 18378 } 18379 18380 // Watch for external volumes that come and go over time 18381 final StorageManager storage = mContext.getSystemService(StorageManager.class); 18382 storage.registerListener(mStorageListener); 18383 18384 mInstallerService.systemReady(); 18385 mPackageDexOptimizer.systemReady(); 18386 18387 MountServiceInternal mountServiceInternal = LocalServices.getService( 18388 MountServiceInternal.class); 18389 mountServiceInternal.addExternalStoragePolicy( 18390 new MountServiceInternal.ExternalStorageMountPolicy() { 18391 @Override 18392 public int getMountMode(int uid, String packageName) { 18393 if (Process.isIsolated(uid)) { 18394 return Zygote.MOUNT_EXTERNAL_NONE; 18395 } 18396 if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) { 18397 return Zygote.MOUNT_EXTERNAL_DEFAULT; 18398 } 18399 if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { 18400 return Zygote.MOUNT_EXTERNAL_DEFAULT; 18401 } 18402 if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) { 18403 return Zygote.MOUNT_EXTERNAL_READ; 18404 } 18405 return Zygote.MOUNT_EXTERNAL_WRITE; 18406 } 18407 18408 @Override 18409 public boolean hasExternalStorage(int uid, String packageName) { 18410 return true; 18411 } 18412 }); 18413 18414 // Now that we're mostly running, clean up stale users and apps 18415 reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL); 18416 reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL); 18417 } 18418 18419 @Override 18420 public boolean isSafeMode() { 18421 return mSafeMode; 18422 } 18423 18424 @Override 18425 public boolean hasSystemUidErrors() { 18426 return mHasSystemUidErrors; 18427 } 18428 18429 static String arrayToString(int[] array) { 18430 StringBuffer buf = new StringBuffer(128); 18431 buf.append('['); 18432 if (array != null) { 18433 for (int i=0; i<array.length; i++) { 18434 if (i > 0) buf.append(", "); 18435 buf.append(array[i]); 18436 } 18437 } 18438 buf.append(']'); 18439 return buf.toString(); 18440 } 18441 18442 static class DumpState { 18443 public static final int DUMP_LIBS = 1 << 0; 18444 public static final int DUMP_FEATURES = 1 << 1; 18445 public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2; 18446 public static final int DUMP_SERVICE_RESOLVERS = 1 << 3; 18447 public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4; 18448 public static final int DUMP_CONTENT_RESOLVERS = 1 << 5; 18449 public static final int DUMP_PERMISSIONS = 1 << 6; 18450 public static final int DUMP_PACKAGES = 1 << 7; 18451 public static final int DUMP_SHARED_USERS = 1 << 8; 18452 public static final int DUMP_MESSAGES = 1 << 9; 18453 public static final int DUMP_PROVIDERS = 1 << 10; 18454 public static final int DUMP_VERIFIERS = 1 << 11; 18455 public static final int DUMP_PREFERRED = 1 << 12; 18456 public static final int DUMP_PREFERRED_XML = 1 << 13; 18457 public static final int DUMP_KEYSETS = 1 << 14; 18458 public static final int DUMP_VERSION = 1 << 15; 18459 public static final int DUMP_INSTALLS = 1 << 16; 18460 public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17; 18461 public static final int DUMP_DOMAIN_PREFERRED = 1 << 18; 18462 public static final int DUMP_FROZEN = 1 << 19; 18463 public static final int DUMP_DEXOPT = 1 << 20; 18464 public static final int DUMP_COMPILER_STATS = 1 << 21; 18465 18466 public static final int OPTION_SHOW_FILTERS = 1 << 0; 18467 18468 private int mTypes; 18469 18470 private int mOptions; 18471 18472 private boolean mTitlePrinted; 18473 18474 private SharedUserSetting mSharedUser; 18475 18476 public boolean isDumping(int type) { 18477 if (mTypes == 0 && type != DUMP_PREFERRED_XML) { 18478 return true; 18479 } 18480 18481 return (mTypes & type) != 0; 18482 } 18483 18484 public void setDump(int type) { 18485 mTypes |= type; 18486 } 18487 18488 public boolean isOptionEnabled(int option) { 18489 return (mOptions & option) != 0; 18490 } 18491 18492 public void setOptionEnabled(int option) { 18493 mOptions |= option; 18494 } 18495 18496 public boolean onTitlePrinted() { 18497 final boolean printed = mTitlePrinted; 18498 mTitlePrinted = true; 18499 return printed; 18500 } 18501 18502 public boolean getTitlePrinted() { 18503 return mTitlePrinted; 18504 } 18505 18506 public void setTitlePrinted(boolean enabled) { 18507 mTitlePrinted = enabled; 18508 } 18509 18510 public SharedUserSetting getSharedUser() { 18511 return mSharedUser; 18512 } 18513 18514 public void setSharedUser(SharedUserSetting user) { 18515 mSharedUser = user; 18516 } 18517 } 18518 18519 @Override 18520 public void onShellCommand(FileDescriptor in, FileDescriptor out, 18521 FileDescriptor err, String[] args, ShellCallback callback, 18522 ResultReceiver resultReceiver) { 18523 (new PackageManagerShellCommand(this)).exec( 18524 this, in, out, err, args, callback, resultReceiver); 18525 } 18526 18527 @Override 18528 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 18529 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 18530 != PackageManager.PERMISSION_GRANTED) { 18531 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 18532 + Binder.getCallingPid() 18533 + ", uid=" + Binder.getCallingUid() 18534 + " without permission " 18535 + android.Manifest.permission.DUMP); 18536 return; 18537 } 18538 18539 DumpState dumpState = new DumpState(); 18540 boolean fullPreferred = false; 18541 boolean checkin = false; 18542 18543 String packageName = null; 18544 ArraySet<String> permissionNames = null; 18545 18546 int opti = 0; 18547 while (opti < args.length) { 18548 String opt = args[opti]; 18549 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 18550 break; 18551 } 18552 opti++; 18553 18554 if ("-a".equals(opt)) { 18555 // Right now we only know how to print all. 18556 } else if ("-h".equals(opt)) { 18557 pw.println("Package manager dump options:"); 18558 pw.println(" [-h] [-f] [--checkin] [cmd] ..."); 18559 pw.println(" --checkin: dump for a checkin"); 18560 pw.println(" -f: print details of intent filters"); 18561 pw.println(" -h: print this help"); 18562 pw.println(" cmd may be one of:"); 18563 pw.println(" l[ibraries]: list known shared libraries"); 18564 pw.println(" f[eatures]: list device features"); 18565 pw.println(" k[eysets]: print known keysets"); 18566 pw.println(" r[esolvers] [activity|service|receiver|content]: dump intent resolvers"); 18567 pw.println(" perm[issions]: dump permissions"); 18568 pw.println(" permission [name ...]: dump declaration and use of given permission"); 18569 pw.println(" pref[erred]: print preferred package settings"); 18570 pw.println(" preferred-xml [--full]: print preferred package settings as xml"); 18571 pw.println(" prov[iders]: dump content providers"); 18572 pw.println(" p[ackages]: dump installed packages"); 18573 pw.println(" s[hared-users]: dump shared user IDs"); 18574 pw.println(" m[essages]: print collected runtime messages"); 18575 pw.println(" v[erifiers]: print package verifier info"); 18576 pw.println(" d[omain-preferred-apps]: print domains preferred apps"); 18577 pw.println(" i[ntent-filter-verifiers]|ifv: print intent filter verifier info"); 18578 pw.println(" version: print database version info"); 18579 pw.println(" write: write current settings now"); 18580 pw.println(" installs: details about install sessions"); 18581 pw.println(" check-permission <permission> <package> [<user>]: does pkg hold perm?"); 18582 pw.println(" dexopt: dump dexopt state"); 18583 pw.println(" compiler-stats: dump compiler statistics"); 18584 pw.println(" <package.name>: info about given package"); 18585 return; 18586 } else if ("--checkin".equals(opt)) { 18587 checkin = true; 18588 } else if ("-f".equals(opt)) { 18589 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 18590 } else { 18591 pw.println("Unknown argument: " + opt + "; use -h for help"); 18592 } 18593 } 18594 18595 // Is the caller requesting to dump a particular piece of data? 18596 if (opti < args.length) { 18597 String cmd = args[opti]; 18598 opti++; 18599 // Is this a package name? 18600 if ("android".equals(cmd) || cmd.contains(".")) { 18601 packageName = cmd; 18602 // When dumping a single package, we always dump all of its 18603 // filter information since the amount of data will be reasonable. 18604 dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 18605 } else if ("check-permission".equals(cmd)) { 18606 if (opti >= args.length) { 18607 pw.println("Error: check-permission missing permission argument"); 18608 return; 18609 } 18610 String perm = args[opti]; 18611 opti++; 18612 if (opti >= args.length) { 18613 pw.println("Error: check-permission missing package argument"); 18614 return; 18615 } 18616 String pkg = args[opti]; 18617 opti++; 18618 int user = UserHandle.getUserId(Binder.getCallingUid()); 18619 if (opti < args.length) { 18620 try { 18621 user = Integer.parseInt(args[opti]); 18622 } catch (NumberFormatException e) { 18623 pw.println("Error: check-permission user argument is not a number: " 18624 + args[opti]); 18625 return; 18626 } 18627 } 18628 pw.println(checkPermission(perm, pkg, user)); 18629 return; 18630 } else if ("l".equals(cmd) || "libraries".equals(cmd)) { 18631 dumpState.setDump(DumpState.DUMP_LIBS); 18632 } else if ("f".equals(cmd) || "features".equals(cmd)) { 18633 dumpState.setDump(DumpState.DUMP_FEATURES); 18634 } else if ("r".equals(cmd) || "resolvers".equals(cmd)) { 18635 if (opti >= args.length) { 18636 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS 18637 | DumpState.DUMP_SERVICE_RESOLVERS 18638 | DumpState.DUMP_RECEIVER_RESOLVERS 18639 | DumpState.DUMP_CONTENT_RESOLVERS); 18640 } else { 18641 while (opti < args.length) { 18642 String name = args[opti]; 18643 if ("a".equals(name) || "activity".equals(name)) { 18644 dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS); 18645 } else if ("s".equals(name) || "service".equals(name)) { 18646 dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS); 18647 } else if ("r".equals(name) || "receiver".equals(name)) { 18648 dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS); 18649 } else if ("c".equals(name) || "content".equals(name)) { 18650 dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS); 18651 } else { 18652 pw.println("Error: unknown resolver table type: " + name); 18653 return; 18654 } 18655 opti++; 18656 } 18657 } 18658 } else if ("perm".equals(cmd) || "permissions".equals(cmd)) { 18659 dumpState.setDump(DumpState.DUMP_PERMISSIONS); 18660 } else if ("permission".equals(cmd)) { 18661 if (opti >= args.length) { 18662 pw.println("Error: permission requires permission name"); 18663 return; 18664 } 18665 permissionNames = new ArraySet<>(); 18666 while (opti < args.length) { 18667 permissionNames.add(args[opti]); 18668 opti++; 18669 } 18670 dumpState.setDump(DumpState.DUMP_PERMISSIONS 18671 | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS); 18672 } else if ("pref".equals(cmd) || "preferred".equals(cmd)) { 18673 dumpState.setDump(DumpState.DUMP_PREFERRED); 18674 } else if ("preferred-xml".equals(cmd)) { 18675 dumpState.setDump(DumpState.DUMP_PREFERRED_XML); 18676 if (opti < args.length && "--full".equals(args[opti])) { 18677 fullPreferred = true; 18678 opti++; 18679 } 18680 } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) { 18681 dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED); 18682 } else if ("p".equals(cmd) || "packages".equals(cmd)) { 18683 dumpState.setDump(DumpState.DUMP_PACKAGES); 18684 } else if ("s".equals(cmd) || "shared-users".equals(cmd)) { 18685 dumpState.setDump(DumpState.DUMP_SHARED_USERS); 18686 } else if ("prov".equals(cmd) || "providers".equals(cmd)) { 18687 dumpState.setDump(DumpState.DUMP_PROVIDERS); 18688 } else if ("m".equals(cmd) || "messages".equals(cmd)) { 18689 dumpState.setDump(DumpState.DUMP_MESSAGES); 18690 } else if ("v".equals(cmd) || "verifiers".equals(cmd)) { 18691 dumpState.setDump(DumpState.DUMP_VERIFIERS); 18692 } else if ("i".equals(cmd) || "ifv".equals(cmd) 18693 || "intent-filter-verifiers".equals(cmd)) { 18694 dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS); 18695 } else if ("version".equals(cmd)) { 18696 dumpState.setDump(DumpState.DUMP_VERSION); 18697 } else if ("k".equals(cmd) || "keysets".equals(cmd)) { 18698 dumpState.setDump(DumpState.DUMP_KEYSETS); 18699 } else if ("installs".equals(cmd)) { 18700 dumpState.setDump(DumpState.DUMP_INSTALLS); 18701 } else if ("frozen".equals(cmd)) { 18702 dumpState.setDump(DumpState.DUMP_FROZEN); 18703 } else if ("dexopt".equals(cmd)) { 18704 dumpState.setDump(DumpState.DUMP_DEXOPT); 18705 } else if ("compiler-stats".equals(cmd)) { 18706 dumpState.setDump(DumpState.DUMP_COMPILER_STATS); 18707 } else if ("write".equals(cmd)) { 18708 synchronized (mPackages) { 18709 mSettings.writeLPr(); 18710 pw.println("Settings written."); 18711 return; 18712 } 18713 } 18714 } 18715 18716 if (checkin) { 18717 pw.println("vers,1"); 18718 } 18719 18720 // reader 18721 synchronized (mPackages) { 18722 if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) { 18723 if (!checkin) { 18724 if (dumpState.onTitlePrinted()) 18725 pw.println(); 18726 pw.println("Database versions:"); 18727 mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, " ")); 18728 } 18729 } 18730 18731 if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) { 18732 if (!checkin) { 18733 if (dumpState.onTitlePrinted()) 18734 pw.println(); 18735 pw.println("Verifiers:"); 18736 pw.print(" Required: "); 18737 pw.print(mRequiredVerifierPackage); 18738 pw.print(" (uid="); 18739 pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 18740 UserHandle.USER_SYSTEM)); 18741 pw.println(")"); 18742 } else if (mRequiredVerifierPackage != null) { 18743 pw.print("vrfy,"); pw.print(mRequiredVerifierPackage); 18744 pw.print(","); 18745 pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING, 18746 UserHandle.USER_SYSTEM)); 18747 } 18748 } 18749 18750 if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) && 18751 packageName == null) { 18752 if (mIntentFilterVerifierComponent != null) { 18753 String verifierPackageName = mIntentFilterVerifierComponent.getPackageName(); 18754 if (!checkin) { 18755 if (dumpState.onTitlePrinted()) 18756 pw.println(); 18757 pw.println("Intent Filter Verifier:"); 18758 pw.print(" Using: "); 18759 pw.print(verifierPackageName); 18760 pw.print(" (uid="); 18761 pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING, 18762 UserHandle.USER_SYSTEM)); 18763 pw.println(")"); 18764 } else if (verifierPackageName != null) { 18765 pw.print("ifv,"); pw.print(verifierPackageName); 18766 pw.print(","); 18767 pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING, 18768 UserHandle.USER_SYSTEM)); 18769 } 18770 } else { 18771 pw.println(); 18772 pw.println("No Intent Filter Verifier available!"); 18773 } 18774 } 18775 18776 if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) { 18777 boolean printedHeader = false; 18778 final Iterator<String> it = mSharedLibraries.keySet().iterator(); 18779 while (it.hasNext()) { 18780 String name = it.next(); 18781 SharedLibraryEntry ent = mSharedLibraries.get(name); 18782 if (!checkin) { 18783 if (!printedHeader) { 18784 if (dumpState.onTitlePrinted()) 18785 pw.println(); 18786 pw.println("Libraries:"); 18787 printedHeader = true; 18788 } 18789 pw.print(" "); 18790 } else { 18791 pw.print("lib,"); 18792 } 18793 pw.print(name); 18794 if (!checkin) { 18795 pw.print(" -> "); 18796 } 18797 if (ent.path != null) { 18798 if (!checkin) { 18799 pw.print("(jar) "); 18800 pw.print(ent.path); 18801 } else { 18802 pw.print(",jar,"); 18803 pw.print(ent.path); 18804 } 18805 } else { 18806 if (!checkin) { 18807 pw.print("(apk) "); 18808 pw.print(ent.apk); 18809 } else { 18810 pw.print(",apk,"); 18811 pw.print(ent.apk); 18812 } 18813 } 18814 pw.println(); 18815 } 18816 } 18817 18818 if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) { 18819 if (dumpState.onTitlePrinted()) 18820 pw.println(); 18821 if (!checkin) { 18822 pw.println("Features:"); 18823 } 18824 18825 for (FeatureInfo feat : mAvailableFeatures.values()) { 18826 if (checkin) { 18827 pw.print("feat,"); 18828 pw.print(feat.name); 18829 pw.print(","); 18830 pw.println(feat.version); 18831 } else { 18832 pw.print(" "); 18833 pw.print(feat.name); 18834 if (feat.version > 0) { 18835 pw.print(" version="); 18836 pw.print(feat.version); 18837 } 18838 pw.println(); 18839 } 18840 } 18841 } 18842 18843 if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) { 18844 if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:" 18845 : "Activity Resolver Table:", " ", packageName, 18846 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 18847 dumpState.setTitlePrinted(true); 18848 } 18849 } 18850 if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) { 18851 if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:" 18852 : "Receiver Resolver Table:", " ", packageName, 18853 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 18854 dumpState.setTitlePrinted(true); 18855 } 18856 } 18857 if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) { 18858 if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:" 18859 : "Service Resolver Table:", " ", packageName, 18860 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 18861 dumpState.setTitlePrinted(true); 18862 } 18863 } 18864 if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) { 18865 if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:" 18866 : "Provider Resolver Table:", " ", packageName, 18867 dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { 18868 dumpState.setTitlePrinted(true); 18869 } 18870 } 18871 18872 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) { 18873 for (int i=0; i<mSettings.mPreferredActivities.size(); i++) { 18874 PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i); 18875 int user = mSettings.mPreferredActivities.keyAt(i); 18876 if (pir.dump(pw, 18877 dumpState.getTitlePrinted() 18878 ? "\nPreferred Activities User " + user + ":" 18879 : "Preferred Activities User " + user + ":", " ", 18880 packageName, true, false)) { 18881 dumpState.setTitlePrinted(true); 18882 } 18883 } 18884 } 18885 18886 if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) { 18887 pw.flush(); 18888 FileOutputStream fout = new FileOutputStream(fd); 18889 BufferedOutputStream str = new BufferedOutputStream(fout); 18890 XmlSerializer serializer = new FastXmlSerializer(); 18891 try { 18892 serializer.setOutput(str, StandardCharsets.UTF_8.name()); 18893 serializer.startDocument(null, true); 18894 serializer.setFeature( 18895 "http://xmlpull.org/v1/doc/features.html#indent-output", true); 18896 mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred); 18897 serializer.endDocument(); 18898 serializer.flush(); 18899 } catch (IllegalArgumentException e) { 18900 pw.println("Failed writing: " + e); 18901 } catch (IllegalStateException e) { 18902 pw.println("Failed writing: " + e); 18903 } catch (IOException e) { 18904 pw.println("Failed writing: " + e); 18905 } 18906 } 18907 18908 if (!checkin 18909 && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED) 18910 && packageName == null) { 18911 pw.println(); 18912 int count = mSettings.mPackages.size(); 18913 if (count == 0) { 18914 pw.println("No applications!"); 18915 pw.println(); 18916 } else { 18917 final String prefix = " "; 18918 Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values(); 18919 if (allPackageSettings.size() == 0) { 18920 pw.println("No domain preferred apps!"); 18921 pw.println(); 18922 } else { 18923 pw.println("App verification status:"); 18924 pw.println(); 18925 count = 0; 18926 for (PackageSetting ps : allPackageSettings) { 18927 IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo(); 18928 if (ivi == null || ivi.getPackageName() == null) continue; 18929 pw.println(prefix + "Package: " + ivi.getPackageName()); 18930 pw.println(prefix + "Domains: " + ivi.getDomainsString()); 18931 pw.println(prefix + "Status: " + ivi.getStatusString()); 18932 pw.println(); 18933 count++; 18934 } 18935 if (count == 0) { 18936 pw.println(prefix + "No app verification established."); 18937 pw.println(); 18938 } 18939 for (int userId : sUserManager.getUserIds()) { 18940 pw.println("App linkages for user " + userId + ":"); 18941 pw.println(); 18942 count = 0; 18943 for (PackageSetting ps : allPackageSettings) { 18944 final long status = ps.getDomainVerificationStatusForUser(userId); 18945 if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) { 18946 continue; 18947 } 18948 pw.println(prefix + "Package: " + ps.name); 18949 pw.println(prefix + "Domains: " + dumpDomainString(ps.name)); 18950 String statusStr = IntentFilterVerificationInfo. 18951 getStatusStringFromValue(status); 18952 pw.println(prefix + "Status: " + statusStr); 18953 pw.println(); 18954 count++; 18955 } 18956 if (count == 0) { 18957 pw.println(prefix + "No configured app linkages."); 18958 pw.println(); 18959 } 18960 } 18961 } 18962 } 18963 } 18964 18965 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) { 18966 mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState); 18967 if (packageName == null && permissionNames == null) { 18968 for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) { 18969 if (iperm == 0) { 18970 if (dumpState.onTitlePrinted()) 18971 pw.println(); 18972 pw.println("AppOp Permissions:"); 18973 } 18974 pw.print(" AppOp Permission "); 18975 pw.print(mAppOpPermissionPackages.keyAt(iperm)); 18976 pw.println(":"); 18977 ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm); 18978 for (int ipkg=0; ipkg<pkgs.size(); ipkg++) { 18979 pw.print(" "); pw.println(pkgs.valueAt(ipkg)); 18980 } 18981 } 18982 } 18983 } 18984 18985 if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) { 18986 boolean printedSomething = false; 18987 for (PackageParser.Provider p : mProviders.mProviders.values()) { 18988 if (packageName != null && !packageName.equals(p.info.packageName)) { 18989 continue; 18990 } 18991 if (!printedSomething) { 18992 if (dumpState.onTitlePrinted()) 18993 pw.println(); 18994 pw.println("Registered ContentProviders:"); 18995 printedSomething = true; 18996 } 18997 pw.print(" "); p.printComponentShortName(pw); pw.println(":"); 18998 pw.print(" "); pw.println(p.toString()); 18999 } 19000 printedSomething = false; 19001 for (Map.Entry<String, PackageParser.Provider> entry : 19002 mProvidersByAuthority.entrySet()) { 19003 PackageParser.Provider p = entry.getValue(); 19004 if (packageName != null && !packageName.equals(p.info.packageName)) { 19005 continue; 19006 } 19007 if (!printedSomething) { 19008 if (dumpState.onTitlePrinted()) 19009 pw.println(); 19010 pw.println("ContentProvider Authorities:"); 19011 printedSomething = true; 19012 } 19013 pw.print(" ["); pw.print(entry.getKey()); pw.println("]:"); 19014 pw.print(" "); pw.println(p.toString()); 19015 if (p.info != null && p.info.applicationInfo != null) { 19016 final String appInfo = p.info.applicationInfo.toString(); 19017 pw.print(" applicationInfo="); pw.println(appInfo); 19018 } 19019 } 19020 } 19021 19022 if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) { 19023 mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState); 19024 } 19025 19026 if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) { 19027 mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin); 19028 } 19029 19030 if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) { 19031 mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin); 19032 } 19033 19034 if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) { 19035 mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState); 19036 } 19037 19038 if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) { 19039 // XXX should handle packageName != null by dumping only install data that 19040 // the given package is involved with. 19041 if (dumpState.onTitlePrinted()) pw.println(); 19042 mInstallerService.dump(new IndentingPrintWriter(pw, " ", 120)); 19043 } 19044 19045 if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) { 19046 // XXX should handle packageName != null by dumping only install data that 19047 // the given package is involved with. 19048 if (dumpState.onTitlePrinted()) pw.println(); 19049 19050 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120); 19051 ipw.println(); 19052 ipw.println("Frozen packages:"); 19053 ipw.increaseIndent(); 19054 if (mFrozenPackages.size() == 0) { 19055 ipw.println("(none)"); 19056 } else { 19057 for (int i = 0; i < mFrozenPackages.size(); i++) { 19058 ipw.println(mFrozenPackages.valueAt(i)); 19059 } 19060 } 19061 ipw.decreaseIndent(); 19062 } 19063 19064 if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) { 19065 if (dumpState.onTitlePrinted()) pw.println(); 19066 dumpDexoptStateLPr(pw, packageName); 19067 } 19068 19069 if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) { 19070 if (dumpState.onTitlePrinted()) pw.println(); 19071 dumpCompilerStatsLPr(pw, packageName); 19072 } 19073 19074 if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) { 19075 if (dumpState.onTitlePrinted()) pw.println(); 19076 mSettings.dumpReadMessagesLPr(pw, dumpState); 19077 19078 pw.println(); 19079 pw.println("Package warning messages:"); 19080 BufferedReader in = null; 19081 String line = null; 19082 try { 19083 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 19084 while ((line = in.readLine()) != null) { 19085 if (line.contains("ignored: updated version")) continue; 19086 pw.println(line); 19087 } 19088 } catch (IOException ignored) { 19089 } finally { 19090 IoUtils.closeQuietly(in); 19091 } 19092 } 19093 19094 if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) { 19095 BufferedReader in = null; 19096 String line = null; 19097 try { 19098 in = new BufferedReader(new FileReader(getSettingsProblemFile())); 19099 while ((line = in.readLine()) != null) { 19100 if (line.contains("ignored: updated version")) continue; 19101 pw.print("msg,"); 19102 pw.println(line); 19103 } 19104 } catch (IOException ignored) { 19105 } finally { 19106 IoUtils.closeQuietly(in); 19107 } 19108 } 19109 } 19110 } 19111 19112 private void dumpDexoptStateLPr(PrintWriter pw, String packageName) { 19113 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120); 19114 ipw.println(); 19115 ipw.println("Dexopt state:"); 19116 ipw.increaseIndent(); 19117 Collection<PackageParser.Package> packages = null; 19118 if (packageName != null) { 19119 PackageParser.Package targetPackage = mPackages.get(packageName); 19120 if (targetPackage != null) { 19121 packages = Collections.singletonList(targetPackage); 19122 } else { 19123 ipw.println("Unable to find package: " + packageName); 19124 return; 19125 } 19126 } else { 19127 packages = mPackages.values(); 19128 } 19129 19130 for (PackageParser.Package pkg : packages) { 19131 ipw.println("[" + pkg.packageName + "]"); 19132 ipw.increaseIndent(); 19133 mPackageDexOptimizer.dumpDexoptState(ipw, pkg); 19134 ipw.decreaseIndent(); 19135 } 19136 } 19137 19138 private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) { 19139 final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120); 19140 ipw.println(); 19141 ipw.println("Compiler stats:"); 19142 ipw.increaseIndent(); 19143 Collection<PackageParser.Package> packages = null; 19144 if (packageName != null) { 19145 PackageParser.Package targetPackage = mPackages.get(packageName); 19146 if (targetPackage != null) { 19147 packages = Collections.singletonList(targetPackage); 19148 } else { 19149 ipw.println("Unable to find package: " + packageName); 19150 return; 19151 } 19152 } else { 19153 packages = mPackages.values(); 19154 } 19155 19156 for (PackageParser.Package pkg : packages) { 19157 ipw.println("[" + pkg.packageName + "]"); 19158 ipw.increaseIndent(); 19159 19160 CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName); 19161 if (stats == null) { 19162 ipw.println("(No recorded stats)"); 19163 } else { 19164 stats.dump(ipw); 19165 } 19166 ipw.decreaseIndent(); 19167 } 19168 } 19169 19170 private String dumpDomainString(String packageName) { 19171 List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName) 19172 .getList(); 19173 List<IntentFilter> filters = getAllIntentFilters(packageName).getList(); 19174 19175 ArraySet<String> result = new ArraySet<>(); 19176 if (iviList.size() > 0) { 19177 for (IntentFilterVerificationInfo ivi : iviList) { 19178 for (String host : ivi.getDomains()) { 19179 result.add(host); 19180 } 19181 } 19182 } 19183 if (filters != null && filters.size() > 0) { 19184 for (IntentFilter filter : filters) { 19185 if (filter.hasCategory(Intent.CATEGORY_BROWSABLE) 19186 && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || 19187 filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) { 19188 result.addAll(filter.getHostsList()); 19189 } 19190 } 19191 } 19192 19193 StringBuilder sb = new StringBuilder(result.size() * 16); 19194 for (String domain : result) { 19195 if (sb.length() > 0) sb.append(" "); 19196 sb.append(domain); 19197 } 19198 return sb.toString(); 19199 } 19200 19201 // ------- apps on sdcard specific code ------- 19202 static final boolean DEBUG_SD_INSTALL = false; 19203 19204 private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD"; 19205 19206 private static final String SD_ENCRYPTION_ALGORITHM = "AES"; 19207 19208 private boolean mMediaMounted = false; 19209 19210 static String getEncryptKey() { 19211 try { 19212 String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString( 19213 SD_ENCRYPTION_KEYSTORE_NAME); 19214 if (sdEncKey == null) { 19215 sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128, 19216 SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME); 19217 if (sdEncKey == null) { 19218 Slog.e(TAG, "Failed to create encryption keys"); 19219 return null; 19220 } 19221 } 19222 return sdEncKey; 19223 } catch (NoSuchAlgorithmException nsae) { 19224 Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae); 19225 return null; 19226 } catch (IOException ioe) { 19227 Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe); 19228 return null; 19229 } 19230 } 19231 19232 /* 19233 * Update media status on PackageManager. 19234 */ 19235 @Override 19236 public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) { 19237 int callingUid = Binder.getCallingUid(); 19238 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 19239 throw new SecurityException("Media status can only be updated by the system"); 19240 } 19241 // reader; this apparently protects mMediaMounted, but should probably 19242 // be a different lock in that case. 19243 synchronized (mPackages) { 19244 Log.i(TAG, "Updating external media status from " 19245 + (mMediaMounted ? "mounted" : "unmounted") + " to " 19246 + (mediaStatus ? "mounted" : "unmounted")); 19247 if (DEBUG_SD_INSTALL) 19248 Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus 19249 + ", mMediaMounted=" + mMediaMounted); 19250 if (mediaStatus == mMediaMounted) { 19251 final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 19252 : 0, -1); 19253 mHandler.sendMessage(msg); 19254 return; 19255 } 19256 mMediaMounted = mediaStatus; 19257 } 19258 // Queue up an async operation since the package installation may take a 19259 // little while. 19260 mHandler.post(new Runnable() { 19261 public void run() { 19262 updateExternalMediaStatusInner(mediaStatus, reportStatus, true); 19263 } 19264 }); 19265 } 19266 19267 /** 19268 * Called by MountService when the initial ASECs to scan are available. 19269 * Should block until all the ASEC containers are finished being scanned. 19270 */ 19271 public void scanAvailableAsecs() { 19272 updateExternalMediaStatusInner(true, false, false); 19273 } 19274 19275 /* 19276 * Collect information of applications on external media, map them against 19277 * existing containers and update information based on current mount status. 19278 * Please note that we always have to report status if reportStatus has been 19279 * set to true especially when unloading packages. 19280 */ 19281 private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus, 19282 boolean externalStorage) { 19283 ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>(); 19284 int[] uidArr = EmptyArray.INT; 19285 19286 final String[] list = PackageHelper.getSecureContainerList(); 19287 if (ArrayUtils.isEmpty(list)) { 19288 Log.i(TAG, "No secure containers found"); 19289 } else { 19290 // Process list of secure containers and categorize them 19291 // as active or stale based on their package internal state. 19292 19293 // reader 19294 synchronized (mPackages) { 19295 for (String cid : list) { 19296 // Leave stages untouched for now; installer service owns them 19297 if (PackageInstallerService.isStageName(cid)) continue; 19298 19299 if (DEBUG_SD_INSTALL) 19300 Log.i(TAG, "Processing container " + cid); 19301 String pkgName = getAsecPackageName(cid); 19302 if (pkgName == null) { 19303 Slog.i(TAG, "Found stale container " + cid + " with no package name"); 19304 continue; 19305 } 19306 if (DEBUG_SD_INSTALL) 19307 Log.i(TAG, "Looking for pkg : " + pkgName); 19308 19309 final PackageSetting ps = mSettings.mPackages.get(pkgName); 19310 if (ps == null) { 19311 Slog.i(TAG, "Found stale container " + cid + " with no matching settings"); 19312 continue; 19313 } 19314 19315 /* 19316 * Skip packages that are not external if we're unmounting 19317 * external storage. 19318 */ 19319 if (externalStorage && !isMounted && !isExternal(ps)) { 19320 continue; 19321 } 19322 19323 final AsecInstallArgs args = new AsecInstallArgs(cid, 19324 getAppDexInstructionSets(ps), ps.isForwardLocked()); 19325 // The package status is changed only if the code path 19326 // matches between settings and the container id. 19327 if (ps.codePathString != null 19328 && ps.codePathString.startsWith(args.getCodePath())) { 19329 if (DEBUG_SD_INSTALL) { 19330 Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName 19331 + " at code path: " + ps.codePathString); 19332 } 19333 19334 // We do have a valid package installed on sdcard 19335 processCids.put(args, ps.codePathString); 19336 final int uid = ps.appId; 19337 if (uid != -1) { 19338 uidArr = ArrayUtils.appendInt(uidArr, uid); 19339 } 19340 } else { 19341 Slog.i(TAG, "Found stale container " + cid + ": expected codePath=" 19342 + ps.codePathString); 19343 } 19344 } 19345 } 19346 19347 Arrays.sort(uidArr); 19348 } 19349 19350 // Process packages with valid entries. 19351 if (isMounted) { 19352 if (DEBUG_SD_INSTALL) 19353 Log.i(TAG, "Loading packages"); 19354 loadMediaPackages(processCids, uidArr, externalStorage); 19355 startCleaningPackages(); 19356 mInstallerService.onSecureContainersAvailable(); 19357 } else { 19358 if (DEBUG_SD_INSTALL) 19359 Log.i(TAG, "Unloading packages"); 19360 unloadMediaPackages(processCids, uidArr, reportStatus); 19361 } 19362 } 19363 19364 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 19365 ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) { 19366 final int size = infos.size(); 19367 final String[] packageNames = new String[size]; 19368 final int[] packageUids = new int[size]; 19369 for (int i = 0; i < size; i++) { 19370 final ApplicationInfo info = infos.get(i); 19371 packageNames[i] = info.packageName; 19372 packageUids[i] = info.uid; 19373 } 19374 sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids, 19375 finishedReceiver); 19376 } 19377 19378 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 19379 ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 19380 sendResourcesChangedBroadcast(mediaStatus, replacing, 19381 pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver); 19382 } 19383 19384 private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing, 19385 String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) { 19386 int size = pkgList.length; 19387 if (size > 0) { 19388 // Send broadcasts here 19389 Bundle extras = new Bundle(); 19390 extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList); 19391 if (uidArr != null) { 19392 extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr); 19393 } 19394 if (replacing) { 19395 extras.putBoolean(Intent.EXTRA_REPLACING, replacing); 19396 } 19397 String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE 19398 : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE; 19399 sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null); 19400 } 19401 } 19402 19403 /* 19404 * Look at potentially valid container ids from processCids If package 19405 * information doesn't match the one on record or package scanning fails, 19406 * the cid is added to list of removeCids. We currently don't delete stale 19407 * containers. 19408 */ 19409 private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr, 19410 boolean externalStorage) { 19411 ArrayList<String> pkgList = new ArrayList<String>(); 19412 Set<AsecInstallArgs> keys = processCids.keySet(); 19413 19414 for (AsecInstallArgs args : keys) { 19415 String codePath = processCids.get(args); 19416 if (DEBUG_SD_INSTALL) 19417 Log.i(TAG, "Loading container : " + args.cid); 19418 int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR; 19419 try { 19420 // Make sure there are no container errors first. 19421 if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) { 19422 Slog.e(TAG, "Failed to mount cid : " + args.cid 19423 + " when installing from sdcard"); 19424 continue; 19425 } 19426 // Check code path here. 19427 if (codePath == null || !codePath.startsWith(args.getCodePath())) { 19428 Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath() 19429 + " does not match one in settings " + codePath); 19430 continue; 19431 } 19432 // Parse package 19433 int parseFlags = mDefParseFlags; 19434 if (args.isExternalAsec()) { 19435 parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE; 19436 } 19437 if (args.isFwdLocked()) { 19438 parseFlags |= PackageParser.PARSE_FORWARD_LOCK; 19439 } 19440 19441 synchronized (mInstallLock) { 19442 PackageParser.Package pkg = null; 19443 try { 19444 // Sadly we don't know the package name yet to freeze it 19445 pkg = scanPackageTracedLI(new File(codePath), parseFlags, 19446 SCAN_IGNORE_FROZEN, 0, null); 19447 } catch (PackageManagerException e) { 19448 Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage()); 19449 } 19450 // Scan the package 19451 if (pkg != null) { 19452 /* 19453 * TODO why is the lock being held? doPostInstall is 19454 * called in other places without the lock. This needs 19455 * to be straightened out. 19456 */ 19457 // writer 19458 synchronized (mPackages) { 19459 retCode = PackageManager.INSTALL_SUCCEEDED; 19460 pkgList.add(pkg.packageName); 19461 // Post process args 19462 args.doPostInstall(PackageManager.INSTALL_SUCCEEDED, 19463 pkg.applicationInfo.uid); 19464 } 19465 } else { 19466 Slog.i(TAG, "Failed to install pkg from " + codePath + " from sdcard"); 19467 } 19468 } 19469 19470 } finally { 19471 if (retCode != PackageManager.INSTALL_SUCCEEDED) { 19472 Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode); 19473 } 19474 } 19475 } 19476 // writer 19477 synchronized (mPackages) { 19478 // If the platform SDK has changed since the last time we booted, 19479 // we need to re-grant app permission to catch any new ones that 19480 // appear. This is really a hack, and means that apps can in some 19481 // cases get permissions that the user didn't initially explicitly 19482 // allow... it would be nice to have some better way to handle 19483 // this situation. 19484 final VersionInfo ver = externalStorage ? mSettings.getExternalVersion() 19485 : mSettings.getInternalVersion(); 19486 final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL 19487 : StorageManager.UUID_PRIVATE_INTERNAL; 19488 19489 int updateFlags = UPDATE_PERMISSIONS_ALL; 19490 if (ver.sdkVersion != mSdkVersion) { 19491 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " 19492 + mSdkVersion + "; regranting permissions for external"); 19493 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 19494 } 19495 updatePermissionsLPw(null, null, volumeUuid, updateFlags); 19496 19497 // Yay, everything is now upgraded 19498 ver.forceCurrent(); 19499 19500 // can downgrade to reader 19501 // Persist settings 19502 mSettings.writeLPr(); 19503 } 19504 // Send a broadcast to let everyone know we are done processing 19505 if (pkgList.size() > 0) { 19506 sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null); 19507 } 19508 } 19509 19510 /* 19511 * Utility method to unload a list of specified containers 19512 */ 19513 private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) { 19514 // Just unmount all valid containers. 19515 for (AsecInstallArgs arg : cidArgs) { 19516 synchronized (mInstallLock) { 19517 arg.doPostDeleteLI(false); 19518 } 19519 } 19520 } 19521 19522 /* 19523 * Unload packages mounted on external media. This involves deleting package 19524 * data from internal structures, sending broadcasts about disabled packages, 19525 * gc'ing to free up references, unmounting all secure containers 19526 * corresponding to packages on external media, and posting a 19527 * UPDATED_MEDIA_STATUS message if status has been requested. Please note 19528 * that we always have to post this message if status has been requested no 19529 * matter what. 19530 */ 19531 private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[], 19532 final boolean reportStatus) { 19533 if (DEBUG_SD_INSTALL) 19534 Log.i(TAG, "unloading media packages"); 19535 ArrayList<String> pkgList = new ArrayList<String>(); 19536 ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>(); 19537 final Set<AsecInstallArgs> keys = processCids.keySet(); 19538 for (AsecInstallArgs args : keys) { 19539 String pkgName = args.getPackageName(); 19540 if (DEBUG_SD_INSTALL) 19541 Log.i(TAG, "Trying to unload pkg : " + pkgName); 19542 // Delete package internally 19543 PackageRemovedInfo outInfo = new PackageRemovedInfo(); 19544 synchronized (mInstallLock) { 19545 final int deleteFlags = PackageManager.DELETE_KEEP_DATA; 19546 final boolean res; 19547 try (PackageFreezer freezer = freezePackageForDelete(pkgName, deleteFlags, 19548 "unloadMediaPackages")) { 19549 res = deletePackageLIF(pkgName, null, false, null, deleteFlags, outInfo, false, 19550 null); 19551 } 19552 if (res) { 19553 pkgList.add(pkgName); 19554 } else { 19555 Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName); 19556 failedList.add(args); 19557 } 19558 } 19559 } 19560 19561 // reader 19562 synchronized (mPackages) { 19563 // We didn't update the settings after removing each package; 19564 // write them now for all packages. 19565 mSettings.writeLPr(); 19566 } 19567 19568 // We have to absolutely send UPDATED_MEDIA_STATUS only 19569 // after confirming that all the receivers processed the ordered 19570 // broadcast when packages get disabled, force a gc to clean things up. 19571 // and unload all the containers. 19572 if (pkgList.size() > 0) { 19573 sendResourcesChangedBroadcast(false, false, pkgList, uidArr, 19574 new IIntentReceiver.Stub() { 19575 public void performReceive(Intent intent, int resultCode, String data, 19576 Bundle extras, boolean ordered, boolean sticky, 19577 int sendingUser) throws RemoteException { 19578 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, 19579 reportStatus ? 1 : 0, 1, keys); 19580 mHandler.sendMessage(msg); 19581 } 19582 }); 19583 } else { 19584 Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1, 19585 keys); 19586 mHandler.sendMessage(msg); 19587 } 19588 } 19589 19590 private void loadPrivatePackages(final VolumeInfo vol) { 19591 mHandler.post(new Runnable() { 19592 @Override 19593 public void run() { 19594 loadPrivatePackagesInner(vol); 19595 } 19596 }); 19597 } 19598 19599 private void loadPrivatePackagesInner(VolumeInfo vol) { 19600 final String volumeUuid = vol.fsUuid; 19601 if (TextUtils.isEmpty(volumeUuid)) { 19602 Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring"); 19603 return; 19604 } 19605 19606 final ArrayList<PackageFreezer> freezers = new ArrayList<>(); 19607 final ArrayList<ApplicationInfo> loaded = new ArrayList<>(); 19608 final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE; 19609 19610 final VersionInfo ver; 19611 final List<PackageSetting> packages; 19612 synchronized (mPackages) { 19613 ver = mSettings.findOrCreateVersion(volumeUuid); 19614 packages = mSettings.getVolumePackagesLPr(volumeUuid); 19615 } 19616 19617 for (PackageSetting ps : packages) { 19618 freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner")); 19619 synchronized (mInstallLock) { 19620 final PackageParser.Package pkg; 19621 try { 19622 pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null); 19623 loaded.add(pkg.applicationInfo); 19624 19625 } catch (PackageManagerException e) { 19626 Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage()); 19627 } 19628 19629 if (!Build.FINGERPRINT.equals(ver.fingerprint)) { 19630 clearAppDataLIF(ps.pkg, UserHandle.USER_ALL, 19631 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE 19632 | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); 19633 } 19634 } 19635 } 19636 19637 // Reconcile app data for all started/unlocked users 19638 final StorageManager sm = mContext.getSystemService(StorageManager.class); 19639 final UserManager um = mContext.getSystemService(UserManager.class); 19640 UserManagerInternal umInternal = getUserManagerInternal(); 19641 for (UserInfo user : um.getUsers()) { 19642 final int flags; 19643 if (umInternal.isUserUnlockingOrUnlocked(user.id)) { 19644 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 19645 } else if (umInternal.isUserRunning(user.id)) { 19646 flags = StorageManager.FLAG_STORAGE_DE; 19647 } else { 19648 continue; 19649 } 19650 19651 try { 19652 sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags); 19653 synchronized (mInstallLock) { 19654 reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */); 19655 } 19656 } catch (IllegalStateException e) { 19657 // Device was probably ejected, and we'll process that event momentarily 19658 Slog.w(TAG, "Failed to prepare storage: " + e); 19659 } 19660 } 19661 19662 synchronized (mPackages) { 19663 int updateFlags = UPDATE_PERMISSIONS_ALL; 19664 if (ver.sdkVersion != mSdkVersion) { 19665 logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " 19666 + mSdkVersion + "; regranting permissions for " + volumeUuid); 19667 updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL; 19668 } 19669 updatePermissionsLPw(null, null, volumeUuid, updateFlags); 19670 19671 // Yay, everything is now upgraded 19672 ver.forceCurrent(); 19673 19674 mSettings.writeLPr(); 19675 } 19676 19677 for (PackageFreezer freezer : freezers) { 19678 freezer.close(); 19679 } 19680 19681 if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded); 19682 sendResourcesChangedBroadcast(true, false, loaded, null); 19683 } 19684 19685 private void unloadPrivatePackages(final VolumeInfo vol) { 19686 mHandler.post(new Runnable() { 19687 @Override 19688 public void run() { 19689 unloadPrivatePackagesInner(vol); 19690 } 19691 }); 19692 } 19693 19694 private void unloadPrivatePackagesInner(VolumeInfo vol) { 19695 final String volumeUuid = vol.fsUuid; 19696 if (TextUtils.isEmpty(volumeUuid)) { 19697 Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring"); 19698 return; 19699 } 19700 19701 final ArrayList<ApplicationInfo> unloaded = new ArrayList<>(); 19702 synchronized (mInstallLock) { 19703 synchronized (mPackages) { 19704 final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid); 19705 for (PackageSetting ps : packages) { 19706 if (ps.pkg == null) continue; 19707 19708 final ApplicationInfo info = ps.pkg.applicationInfo; 19709 final int deleteFlags = PackageManager.DELETE_KEEP_DATA; 19710 final PackageRemovedInfo outInfo = new PackageRemovedInfo(); 19711 19712 try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags, 19713 "unloadPrivatePackagesInner")) { 19714 if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo, 19715 false, null)) { 19716 unloaded.add(info); 19717 } else { 19718 Slog.w(TAG, "Failed to unload " + ps.codePath); 19719 } 19720 } 19721 19722 // Try very hard to release any references to this package 19723 // so we don't risk the system server being killed due to 19724 // open FDs 19725 AttributeCache.instance().removePackage(ps.name); 19726 } 19727 19728 mSettings.writeLPr(); 19729 } 19730 } 19731 19732 if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded); 19733 sendResourcesChangedBroadcast(false, false, unloaded, null); 19734 19735 // Try very hard to release any references to this path so we don't risk 19736 // the system server being killed due to open FDs 19737 ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath()); 19738 19739 for (int i = 0; i < 3; i++) { 19740 System.gc(); 19741 System.runFinalization(); 19742 } 19743 } 19744 19745 /** 19746 * Prepare storage areas for given user on all mounted devices. 19747 */ 19748 void prepareUserData(int userId, int userSerial, int flags) { 19749 synchronized (mInstallLock) { 19750 final StorageManager storage = mContext.getSystemService(StorageManager.class); 19751 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 19752 final String volumeUuid = vol.getFsUuid(); 19753 prepareUserDataLI(volumeUuid, userId, userSerial, flags, true); 19754 } 19755 } 19756 } 19757 19758 private void prepareUserDataLI(String volumeUuid, int userId, int userSerial, int flags, 19759 boolean allowRecover) { 19760 // Prepare storage and verify that serial numbers are consistent; if 19761 // there's a mismatch we need to destroy to avoid leaking data 19762 final StorageManager storage = mContext.getSystemService(StorageManager.class); 19763 try { 19764 storage.prepareUserStorage(volumeUuid, userId, userSerial, flags); 19765 19766 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0 && !mOnlyCore) { 19767 UserManagerService.enforceSerialNumber( 19768 Environment.getDataUserDeDirectory(volumeUuid, userId), userSerial); 19769 if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) { 19770 UserManagerService.enforceSerialNumber( 19771 Environment.getDataSystemDeDirectory(userId), userSerial); 19772 } 19773 } 19774 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && !mOnlyCore) { 19775 UserManagerService.enforceSerialNumber( 19776 Environment.getDataUserCeDirectory(volumeUuid, userId), userSerial); 19777 if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) { 19778 UserManagerService.enforceSerialNumber( 19779 Environment.getDataSystemCeDirectory(userId), userSerial); 19780 } 19781 } 19782 19783 synchronized (mInstallLock) { 19784 mInstaller.createUserData(volumeUuid, userId, userSerial, flags); 19785 } 19786 } catch (Exception e) { 19787 logCriticalInfo(Log.WARN, "Destroying user " + userId + " on volume " + volumeUuid 19788 + " because we failed to prepare: " + e); 19789 destroyUserDataLI(volumeUuid, userId, 19790 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 19791 19792 if (allowRecover) { 19793 // Try one last time; if we fail again we're really in trouble 19794 prepareUserDataLI(volumeUuid, userId, userSerial, flags, false); 19795 } 19796 } 19797 } 19798 19799 /** 19800 * Destroy storage areas for given user on all mounted devices. 19801 */ 19802 void destroyUserData(int userId, int flags) { 19803 synchronized (mInstallLock) { 19804 final StorageManager storage = mContext.getSystemService(StorageManager.class); 19805 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 19806 final String volumeUuid = vol.getFsUuid(); 19807 destroyUserDataLI(volumeUuid, userId, flags); 19808 } 19809 } 19810 } 19811 19812 private void destroyUserDataLI(String volumeUuid, int userId, int flags) { 19813 final StorageManager storage = mContext.getSystemService(StorageManager.class); 19814 try { 19815 // Clean up app data, profile data, and media data 19816 mInstaller.destroyUserData(volumeUuid, userId, flags); 19817 19818 // Clean up system data 19819 if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) { 19820 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) { 19821 FileUtils.deleteContentsAndDir(Environment.getUserSystemDirectory(userId)); 19822 FileUtils.deleteContentsAndDir(Environment.getDataSystemDeDirectory(userId)); 19823 } 19824 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 19825 FileUtils.deleteContentsAndDir(Environment.getDataSystemCeDirectory(userId)); 19826 } 19827 } 19828 19829 // Data with special labels is now gone, so finish the job 19830 storage.destroyUserStorage(volumeUuid, userId, flags); 19831 19832 } catch (Exception e) { 19833 logCriticalInfo(Log.WARN, 19834 "Failed to destroy user " + userId + " on volume " + volumeUuid + ": " + e); 19835 } 19836 } 19837 19838 /** 19839 * Examine all users present on given mounted volume, and destroy data 19840 * belonging to users that are no longer valid, or whose user ID has been 19841 * recycled. 19842 */ 19843 private void reconcileUsers(String volumeUuid) { 19844 final List<File> files = new ArrayList<>(); 19845 Collections.addAll(files, FileUtils 19846 .listFilesOrEmpty(Environment.getDataUserDeDirectory(volumeUuid))); 19847 Collections.addAll(files, FileUtils 19848 .listFilesOrEmpty(Environment.getDataUserCeDirectory(volumeUuid))); 19849 Collections.addAll(files, FileUtils 19850 .listFilesOrEmpty(Environment.getDataSystemDeDirectory())); 19851 Collections.addAll(files, FileUtils 19852 .listFilesOrEmpty(Environment.getDataSystemCeDirectory())); 19853 for (File file : files) { 19854 if (!file.isDirectory()) continue; 19855 19856 final int userId; 19857 final UserInfo info; 19858 try { 19859 userId = Integer.parseInt(file.getName()); 19860 info = sUserManager.getUserInfo(userId); 19861 } catch (NumberFormatException e) { 19862 Slog.w(TAG, "Invalid user directory " + file); 19863 continue; 19864 } 19865 19866 boolean destroyUser = false; 19867 if (info == null) { 19868 logCriticalInfo(Log.WARN, "Destroying user directory " + file 19869 + " because no matching user was found"); 19870 destroyUser = true; 19871 } else if (!mOnlyCore) { 19872 try { 19873 UserManagerService.enforceSerialNumber(file, info.serialNumber); 19874 } catch (IOException e) { 19875 logCriticalInfo(Log.WARN, "Destroying user directory " + file 19876 + " because we failed to enforce serial number: " + e); 19877 destroyUser = true; 19878 } 19879 } 19880 19881 if (destroyUser) { 19882 synchronized (mInstallLock) { 19883 destroyUserDataLI(volumeUuid, userId, 19884 StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); 19885 } 19886 } 19887 } 19888 } 19889 19890 private void assertPackageKnown(String volumeUuid, String packageName) 19891 throws PackageManagerException { 19892 synchronized (mPackages) { 19893 final PackageSetting ps = mSettings.mPackages.get(packageName); 19894 if (ps == null) { 19895 throw new PackageManagerException("Package " + packageName + " is unknown"); 19896 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) { 19897 throw new PackageManagerException( 19898 "Package " + packageName + " found on unknown volume " + volumeUuid 19899 + "; expected volume " + ps.volumeUuid); 19900 } 19901 } 19902 } 19903 19904 private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId) 19905 throws PackageManagerException { 19906 synchronized (mPackages) { 19907 final PackageSetting ps = mSettings.mPackages.get(packageName); 19908 if (ps == null) { 19909 throw new PackageManagerException("Package " + packageName + " is unknown"); 19910 } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) { 19911 throw new PackageManagerException( 19912 "Package " + packageName + " found on unknown volume " + volumeUuid 19913 + "; expected volume " + ps.volumeUuid); 19914 } else if (!ps.getInstalled(userId)) { 19915 throw new PackageManagerException( 19916 "Package " + packageName + " not installed for user " + userId); 19917 } 19918 } 19919 } 19920 19921 /** 19922 * Examine all apps present on given mounted volume, and destroy apps that 19923 * aren't expected, either due to uninstallation or reinstallation on 19924 * another volume. 19925 */ 19926 private void reconcileApps(String volumeUuid) { 19927 final File[] files = FileUtils 19928 .listFilesOrEmpty(Environment.getDataAppDirectory(volumeUuid)); 19929 for (File file : files) { 19930 final boolean isPackage = (isApkFile(file) || file.isDirectory()) 19931 && !PackageInstallerService.isStageName(file.getName()); 19932 if (!isPackage) { 19933 // Ignore entries which are not packages 19934 continue; 19935 } 19936 19937 try { 19938 final PackageLite pkg = PackageParser.parsePackageLite(file, 19939 PackageParser.PARSE_MUST_BE_APK); 19940 assertPackageKnown(volumeUuid, pkg.packageName); 19941 19942 } catch (PackageParserException | PackageManagerException e) { 19943 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 19944 synchronized (mInstallLock) { 19945 removeCodePathLI(file); 19946 } 19947 } 19948 } 19949 } 19950 19951 /** 19952 * Reconcile all app data for the given user. 19953 * <p> 19954 * Verifies that directories exist and that ownership and labeling is 19955 * correct for all installed apps on all mounted volumes. 19956 */ 19957 void reconcileAppsData(int userId, int flags, boolean migrateAppsData) { 19958 final StorageManager storage = mContext.getSystemService(StorageManager.class); 19959 for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { 19960 final String volumeUuid = vol.getFsUuid(); 19961 synchronized (mInstallLock) { 19962 reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData); 19963 } 19964 } 19965 } 19966 19967 /** 19968 * Reconcile all app data on given mounted volume. 19969 * <p> 19970 * Destroys app data that isn't expected, either due to uninstallation or 19971 * reinstallation on another volume. 19972 * <p> 19973 * Verifies that directories exist and that ownership and labeling is 19974 * correct for all installed apps. 19975 */ 19976 private void reconcileAppsDataLI(String volumeUuid, int userId, int flags, 19977 boolean migrateAppData) { 19978 Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x" 19979 + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData); 19980 19981 final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId); 19982 final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId); 19983 19984 // First look for stale data that doesn't belong, and check if things 19985 // have changed since we did our last restorecon 19986 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 19987 if (StorageManager.isFileEncryptedNativeOrEmulated() 19988 && !StorageManager.isUserKeyUnlocked(userId)) { 19989 throw new RuntimeException( 19990 "Yikes, someone asked us to reconcile CE storage while " + userId 19991 + " was still locked; this would have caused massive data loss!"); 19992 } 19993 19994 final File[] files = FileUtils.listFilesOrEmpty(ceDir); 19995 for (File file : files) { 19996 final String packageName = file.getName(); 19997 try { 19998 assertPackageKnownAndInstalled(volumeUuid, packageName, userId); 19999 } catch (PackageManagerException e) { 20000 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 20001 try { 20002 mInstaller.destroyAppData(volumeUuid, packageName, userId, 20003 StorageManager.FLAG_STORAGE_CE, 0); 20004 } catch (InstallerException e2) { 20005 logCriticalInfo(Log.WARN, "Failed to destroy: " + e2); 20006 } 20007 } 20008 } 20009 } 20010 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) { 20011 final File[] files = FileUtils.listFilesOrEmpty(deDir); 20012 for (File file : files) { 20013 final String packageName = file.getName(); 20014 try { 20015 assertPackageKnownAndInstalled(volumeUuid, packageName, userId); 20016 } catch (PackageManagerException e) { 20017 logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e); 20018 try { 20019 mInstaller.destroyAppData(volumeUuid, packageName, userId, 20020 StorageManager.FLAG_STORAGE_DE, 0); 20021 } catch (InstallerException e2) { 20022 logCriticalInfo(Log.WARN, "Failed to destroy: " + e2); 20023 } 20024 } 20025 } 20026 } 20027 20028 // Ensure that data directories are ready to roll for all packages 20029 // installed for this volume and user 20030 final List<PackageSetting> packages; 20031 synchronized (mPackages) { 20032 packages = mSettings.getVolumePackagesLPr(volumeUuid); 20033 } 20034 int preparedCount = 0; 20035 for (PackageSetting ps : packages) { 20036 final String packageName = ps.name; 20037 if (ps.pkg == null) { 20038 Slog.w(TAG, "Odd, missing scanned package " + packageName); 20039 // TODO: might be due to legacy ASEC apps; we should circle back 20040 // and reconcile again once they're scanned 20041 continue; 20042 } 20043 20044 if (ps.getInstalled(userId)) { 20045 prepareAppDataLIF(ps.pkg, userId, flags); 20046 20047 if (migrateAppData && maybeMigrateAppDataLIF(ps.pkg, userId)) { 20048 // We may have just shuffled around app data directories, so 20049 // prepare them one more time 20050 prepareAppDataLIF(ps.pkg, userId, flags); 20051 } 20052 20053 preparedCount++; 20054 } 20055 } 20056 20057 Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages"); 20058 } 20059 20060 /** 20061 * Prepare app data for the given app just after it was installed or 20062 * upgraded. This method carefully only touches users that it's installed 20063 * for, and it forces a restorecon to handle any seinfo changes. 20064 * <p> 20065 * Verifies that directories exist and that ownership and labeling is 20066 * correct for all installed apps. If there is an ownership mismatch, it 20067 * will try recovering system apps by wiping data; third-party app data is 20068 * left intact. 20069 * <p> 20070 * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em> 20071 */ 20072 private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) { 20073 final PackageSetting ps; 20074 synchronized (mPackages) { 20075 ps = mSettings.mPackages.get(pkg.packageName); 20076 mSettings.writeKernelMappingLPr(ps); 20077 } 20078 20079 final UserManager um = mContext.getSystemService(UserManager.class); 20080 UserManagerInternal umInternal = getUserManagerInternal(); 20081 for (UserInfo user : um.getUsers()) { 20082 final int flags; 20083 if (umInternal.isUserUnlockingOrUnlocked(user.id)) { 20084 flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; 20085 } else if (umInternal.isUserRunning(user.id)) { 20086 flags = StorageManager.FLAG_STORAGE_DE; 20087 } else { 20088 continue; 20089 } 20090 20091 if (ps.getInstalled(user.id)) { 20092 // TODO: when user data is locked, mark that we're still dirty 20093 prepareAppDataLIF(pkg, user.id, flags); 20094 } 20095 } 20096 } 20097 20098 /** 20099 * Prepare app data for the given app. 20100 * <p> 20101 * Verifies that directories exist and that ownership and labeling is 20102 * correct for all installed apps. If there is an ownership mismatch, this 20103 * will try recovering system apps by wiping data; third-party app data is 20104 * left intact. 20105 */ 20106 private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) { 20107 if (pkg == null) { 20108 Slog.wtf(TAG, "Package was null!", new Throwable()); 20109 return; 20110 } 20111 prepareAppDataLeafLIF(pkg, userId, flags); 20112 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 20113 for (int i = 0; i < childCount; i++) { 20114 prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags); 20115 } 20116 } 20117 20118 private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) { 20119 if (DEBUG_APP_DATA) { 20120 Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x" 20121 + Integer.toHexString(flags)); 20122 } 20123 20124 final String volumeUuid = pkg.volumeUuid; 20125 final String packageName = pkg.packageName; 20126 final ApplicationInfo app = pkg.applicationInfo; 20127 final int appId = UserHandle.getAppId(app.uid); 20128 20129 Preconditions.checkNotNull(app.seinfo); 20130 20131 try { 20132 mInstaller.createAppData(volumeUuid, packageName, userId, flags, 20133 appId, app.seinfo, app.targetSdkVersion); 20134 } catch (InstallerException e) { 20135 if (app.isSystemApp()) { 20136 logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName 20137 + ", but trying to recover: " + e); 20138 destroyAppDataLeafLIF(pkg, userId, flags); 20139 try { 20140 mInstaller.createAppData(volumeUuid, packageName, userId, flags, 20141 appId, app.seinfo, app.targetSdkVersion); 20142 logCriticalInfo(Log.DEBUG, "Recovery succeeded!"); 20143 } catch (InstallerException e2) { 20144 logCriticalInfo(Log.DEBUG, "Recovery failed!"); 20145 } 20146 } else { 20147 Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e); 20148 } 20149 } 20150 20151 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 20152 try { 20153 // CE storage is unlocked right now, so read out the inode and 20154 // remember for use later when it's locked 20155 // TODO: mark this structure as dirty so we persist it! 20156 final long ceDataInode = mInstaller.getAppDataInode(volumeUuid, packageName, userId, 20157 StorageManager.FLAG_STORAGE_CE); 20158 synchronized (mPackages) { 20159 final PackageSetting ps = mSettings.mPackages.get(packageName); 20160 if (ps != null) { 20161 ps.setCeDataInode(ceDataInode, userId); 20162 } 20163 } 20164 } catch (InstallerException e) { 20165 Slog.e(TAG, "Failed to find inode for " + packageName + ": " + e); 20166 } 20167 } 20168 20169 prepareAppDataContentsLeafLIF(pkg, userId, flags); 20170 } 20171 20172 private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) { 20173 if (pkg == null) { 20174 Slog.wtf(TAG, "Package was null!", new Throwable()); 20175 return; 20176 } 20177 prepareAppDataContentsLeafLIF(pkg, userId, flags); 20178 final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0; 20179 for (int i = 0; i < childCount; i++) { 20180 prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags); 20181 } 20182 } 20183 20184 private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) { 20185 final String volumeUuid = pkg.volumeUuid; 20186 final String packageName = pkg.packageName; 20187 final ApplicationInfo app = pkg.applicationInfo; 20188 20189 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) { 20190 // Create a native library symlink only if we have native libraries 20191 // and if the native libraries are 32 bit libraries. We do not provide 20192 // this symlink for 64 bit libraries. 20193 if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) { 20194 final String nativeLibPath = app.nativeLibraryDir; 20195 try { 20196 mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName, 20197 nativeLibPath, userId); 20198 } catch (InstallerException e) { 20199 Slog.e(TAG, "Failed to link native for " + packageName + ": " + e); 20200 } 20201 } 20202 } 20203 } 20204 20205 /** 20206 * For system apps on non-FBE devices, this method migrates any existing 20207 * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag 20208 * requested by the app. 20209 */ 20210 private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) { 20211 if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated() 20212 && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) { 20213 final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage() 20214 ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE; 20215 try { 20216 mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId, 20217 storageTarget); 20218 } catch (InstallerException e) { 20219 logCriticalInfo(Log.WARN, 20220 "Failed to migrate " + pkg.packageName + ": " + e.getMessage()); 20221 } 20222 return true; 20223 } else { 20224 return false; 20225 } 20226 } 20227 20228 public PackageFreezer freezePackage(String packageName, String killReason) { 20229 return freezePackage(packageName, UserHandle.USER_ALL, killReason); 20230 } 20231 20232 public PackageFreezer freezePackage(String packageName, int userId, String killReason) { 20233 return new PackageFreezer(packageName, userId, killReason); 20234 } 20235 20236 public PackageFreezer freezePackageForInstall(String packageName, int installFlags, 20237 String killReason) { 20238 return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason); 20239 } 20240 20241 public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags, 20242 String killReason) { 20243 if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) { 20244 return new PackageFreezer(); 20245 } else { 20246 return freezePackage(packageName, userId, killReason); 20247 } 20248 } 20249 20250 public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags, 20251 String killReason) { 20252 return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason); 20253 } 20254 20255 public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags, 20256 String killReason) { 20257 if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) { 20258 return new PackageFreezer(); 20259 } else { 20260 return freezePackage(packageName, userId, killReason); 20261 } 20262 } 20263 20264 /** 20265 * Class that freezes and kills the given package upon creation, and 20266 * unfreezes it upon closing. This is typically used when doing surgery on 20267 * app code/data to prevent the app from running while you're working. 20268 */ 20269 private class PackageFreezer implements AutoCloseable { 20270 private final String mPackageName; 20271 private final PackageFreezer[] mChildren; 20272 20273 private final boolean mWeFroze; 20274 20275 private final AtomicBoolean mClosed = new AtomicBoolean(); 20276 private final CloseGuard mCloseGuard = CloseGuard.get(); 20277 20278 /** 20279 * Create and return a stub freezer that doesn't actually do anything, 20280 * typically used when someone requested 20281 * {@link PackageManager#INSTALL_DONT_KILL_APP} or 20282 * {@link PackageManager#DELETE_DONT_KILL_APP}. 20283 */ 20284 public PackageFreezer() { 20285 mPackageName = null; 20286 mChildren = null; 20287 mWeFroze = false; 20288 mCloseGuard.open("close"); 20289 } 20290 20291 public PackageFreezer(String packageName, int userId, String killReason) { 20292 synchronized (mPackages) { 20293 mPackageName = packageName; 20294 mWeFroze = mFrozenPackages.add(mPackageName); 20295 20296 final PackageSetting ps = mSettings.mPackages.get(mPackageName); 20297 if (ps != null) { 20298 killApplication(ps.name, ps.appId, userId, killReason); 20299 } 20300 20301 final PackageParser.Package p = mPackages.get(packageName); 20302 if (p != null && p.childPackages != null) { 20303 final int N = p.childPackages.size(); 20304 mChildren = new PackageFreezer[N]; 20305 for (int i = 0; i < N; i++) { 20306 mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName, 20307 userId, killReason); 20308 } 20309 } else { 20310 mChildren = null; 20311 } 20312 } 20313 mCloseGuard.open("close"); 20314 } 20315 20316 @Override 20317 protected void finalize() throws Throwable { 20318 try { 20319 mCloseGuard.warnIfOpen(); 20320 close(); 20321 } finally { 20322 super.finalize(); 20323 } 20324 } 20325 20326 @Override 20327 public void close() { 20328 mCloseGuard.close(); 20329 if (mClosed.compareAndSet(false, true)) { 20330 synchronized (mPackages) { 20331 if (mWeFroze) { 20332 mFrozenPackages.remove(mPackageName); 20333 } 20334 20335 if (mChildren != null) { 20336 for (PackageFreezer freezer : mChildren) { 20337 freezer.close(); 20338 } 20339 } 20340 } 20341 } 20342 } 20343 } 20344 20345 /** 20346 * Verify that given package is currently frozen. 20347 */ 20348 private void checkPackageFrozen(String packageName) { 20349 synchronized (mPackages) { 20350 if (!mFrozenPackages.contains(packageName)) { 20351 Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable()); 20352 } 20353 } 20354 } 20355 20356 @Override 20357 public int movePackage(final String packageName, final String volumeUuid) { 20358 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 20359 20360 final UserHandle user = new UserHandle(UserHandle.getCallingUserId()); 20361 final int moveId = mNextMoveId.getAndIncrement(); 20362 mHandler.post(new Runnable() { 20363 @Override 20364 public void run() { 20365 try { 20366 movePackageInternal(packageName, volumeUuid, moveId, user); 20367 } catch (PackageManagerException e) { 20368 Slog.w(TAG, "Failed to move " + packageName, e); 20369 mMoveCallbacks.notifyStatusChanged(moveId, 20370 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 20371 } 20372 } 20373 }); 20374 return moveId; 20375 } 20376 20377 private void movePackageInternal(final String packageName, final String volumeUuid, 20378 final int moveId, UserHandle user) throws PackageManagerException { 20379 final StorageManager storage = mContext.getSystemService(StorageManager.class); 20380 final PackageManager pm = mContext.getPackageManager(); 20381 20382 final boolean currentAsec; 20383 final String currentVolumeUuid; 20384 final File codeFile; 20385 final String installerPackageName; 20386 final String packageAbiOverride; 20387 final int appId; 20388 final String seinfo; 20389 final String label; 20390 final int targetSdkVersion; 20391 final PackageFreezer freezer; 20392 final int[] installedUserIds; 20393 20394 // reader 20395 synchronized (mPackages) { 20396 final PackageParser.Package pkg = mPackages.get(packageName); 20397 final PackageSetting ps = mSettings.mPackages.get(packageName); 20398 if (pkg == null || ps == null) { 20399 throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package"); 20400 } 20401 20402 if (pkg.applicationInfo.isSystemApp()) { 20403 throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE, 20404 "Cannot move system application"); 20405 } 20406 20407 if (pkg.applicationInfo.isExternalAsec()) { 20408 currentAsec = true; 20409 currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL; 20410 } else if (pkg.applicationInfo.isForwardLocked()) { 20411 currentAsec = true; 20412 currentVolumeUuid = "forward_locked"; 20413 } else { 20414 currentAsec = false; 20415 currentVolumeUuid = ps.volumeUuid; 20416 20417 final File probe = new File(pkg.codePath); 20418 final File probeOat = new File(probe, "oat"); 20419 if (!probe.isDirectory() || !probeOat.isDirectory()) { 20420 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 20421 "Move only supported for modern cluster style installs"); 20422 } 20423 } 20424 20425 if (Objects.equals(currentVolumeUuid, volumeUuid)) { 20426 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 20427 "Package already moved to " + volumeUuid); 20428 } 20429 if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) { 20430 throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN, 20431 "Device admin cannot be moved"); 20432 } 20433 20434 if (mFrozenPackages.contains(packageName)) { 20435 throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING, 20436 "Failed to move already frozen package"); 20437 } 20438 20439 codeFile = new File(pkg.codePath); 20440 installerPackageName = ps.installerPackageName; 20441 packageAbiOverride = ps.cpuAbiOverrideString; 20442 appId = UserHandle.getAppId(pkg.applicationInfo.uid); 20443 seinfo = pkg.applicationInfo.seinfo; 20444 label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo)); 20445 targetSdkVersion = pkg.applicationInfo.targetSdkVersion; 20446 freezer = freezePackage(packageName, "movePackageInternal"); 20447 installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true); 20448 } 20449 20450 final Bundle extras = new Bundle(); 20451 extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName); 20452 extras.putString(Intent.EXTRA_TITLE, label); 20453 mMoveCallbacks.notifyCreated(moveId, extras); 20454 20455 int installFlags; 20456 final boolean moveCompleteApp; 20457 final File measurePath; 20458 20459 if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) { 20460 installFlags = INSTALL_INTERNAL; 20461 moveCompleteApp = !currentAsec; 20462 measurePath = Environment.getDataAppDirectory(volumeUuid); 20463 } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) { 20464 installFlags = INSTALL_EXTERNAL; 20465 moveCompleteApp = false; 20466 measurePath = storage.getPrimaryPhysicalVolume().getPath(); 20467 } else { 20468 final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid); 20469 if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE 20470 || !volume.isMountedWritable()) { 20471 freezer.close(); 20472 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 20473 "Move location not mounted private volume"); 20474 } 20475 20476 Preconditions.checkState(!currentAsec); 20477 20478 installFlags = INSTALL_INTERNAL; 20479 moveCompleteApp = true; 20480 measurePath = Environment.getDataAppDirectory(volumeUuid); 20481 } 20482 20483 final PackageStats stats = new PackageStats(null, -1); 20484 synchronized (mInstaller) { 20485 for (int userId : installedUserIds) { 20486 if (!getPackageSizeInfoLI(packageName, userId, stats)) { 20487 freezer.close(); 20488 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 20489 "Failed to measure package size"); 20490 } 20491 } 20492 } 20493 20494 if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size " 20495 + stats.dataSize); 20496 20497 final long startFreeBytes = measurePath.getFreeSpace(); 20498 final long sizeBytes; 20499 if (moveCompleteApp) { 20500 sizeBytes = stats.codeSize + stats.dataSize; 20501 } else { 20502 sizeBytes = stats.codeSize; 20503 } 20504 20505 if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) { 20506 freezer.close(); 20507 throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, 20508 "Not enough free space to move"); 20509 } 20510 20511 mMoveCallbacks.notifyStatusChanged(moveId, 10); 20512 20513 final CountDownLatch installedLatch = new CountDownLatch(1); 20514 final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() { 20515 @Override 20516 public void onUserActionRequired(Intent intent) throws RemoteException { 20517 throw new IllegalStateException(); 20518 } 20519 20520 @Override 20521 public void onPackageInstalled(String basePackageName, int returnCode, String msg, 20522 Bundle extras) throws RemoteException { 20523 if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: " 20524 + PackageManager.installStatusToString(returnCode, msg)); 20525 20526 installedLatch.countDown(); 20527 freezer.close(); 20528 20529 final int status = PackageManager.installStatusToPublicStatus(returnCode); 20530 switch (status) { 20531 case PackageInstaller.STATUS_SUCCESS: 20532 mMoveCallbacks.notifyStatusChanged(moveId, 20533 PackageManager.MOVE_SUCCEEDED); 20534 break; 20535 case PackageInstaller.STATUS_FAILURE_STORAGE: 20536 mMoveCallbacks.notifyStatusChanged(moveId, 20537 PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE); 20538 break; 20539 default: 20540 mMoveCallbacks.notifyStatusChanged(moveId, 20541 PackageManager.MOVE_FAILED_INTERNAL_ERROR); 20542 break; 20543 } 20544 } 20545 }; 20546 20547 final MoveInfo move; 20548 if (moveCompleteApp) { 20549 // Kick off a thread to report progress estimates 20550 new Thread() { 20551 @Override 20552 public void run() { 20553 while (true) { 20554 try { 20555 if (installedLatch.await(1, TimeUnit.SECONDS)) { 20556 break; 20557 } 20558 } catch (InterruptedException ignored) { 20559 } 20560 20561 final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace(); 20562 final int progress = 10 + (int) MathUtils.constrain( 20563 ((deltaFreeBytes * 80) / sizeBytes), 0, 80); 20564 mMoveCallbacks.notifyStatusChanged(moveId, progress); 20565 } 20566 } 20567 }.start(); 20568 20569 final String dataAppName = codeFile.getName(); 20570 move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName, 20571 dataAppName, appId, seinfo, targetSdkVersion); 20572 } else { 20573 move = null; 20574 } 20575 20576 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; 20577 20578 final Message msg = mHandler.obtainMessage(INIT_COPY); 20579 final OriginInfo origin = OriginInfo.fromExistingFile(codeFile); 20580 final InstallParams params = new InstallParams(origin, move, installObserver, installFlags, 20581 installerPackageName, volumeUuid, null /*verificationInfo*/, user, 20582 packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/); 20583 params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params)); 20584 msg.obj = params; 20585 20586 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage", 20587 System.identityHashCode(msg.obj)); 20588 Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", 20589 System.identityHashCode(msg.obj)); 20590 20591 mHandler.sendMessage(msg); 20592 } 20593 20594 @Override 20595 public int movePrimaryStorage(String volumeUuid) throws RemoteException { 20596 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null); 20597 20598 final int realMoveId = mNextMoveId.getAndIncrement(); 20599 final Bundle extras = new Bundle(); 20600 extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid); 20601 mMoveCallbacks.notifyCreated(realMoveId, extras); 20602 20603 final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() { 20604 @Override 20605 public void onCreated(int moveId, Bundle extras) { 20606 // Ignored 20607 } 20608 20609 @Override 20610 public void onStatusChanged(int moveId, int status, long estMillis) { 20611 mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis); 20612 } 20613 }; 20614 20615 final StorageManager storage = mContext.getSystemService(StorageManager.class); 20616 storage.setPrimaryStorageUuid(volumeUuid, callback); 20617 return realMoveId; 20618 } 20619 20620 @Override 20621 public int getMoveStatus(int moveId) { 20622 mContext.enforceCallingOrSelfPermission( 20623 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 20624 return mMoveCallbacks.mLastStatus.get(moveId); 20625 } 20626 20627 @Override 20628 public void registerMoveCallback(IPackageMoveObserver callback) { 20629 mContext.enforceCallingOrSelfPermission( 20630 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 20631 mMoveCallbacks.register(callback); 20632 } 20633 20634 @Override 20635 public void unregisterMoveCallback(IPackageMoveObserver callback) { 20636 mContext.enforceCallingOrSelfPermission( 20637 android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null); 20638 mMoveCallbacks.unregister(callback); 20639 } 20640 20641 @Override 20642 public boolean setInstallLocation(int loc) { 20643 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, 20644 null); 20645 if (getInstallLocation() == loc) { 20646 return true; 20647 } 20648 if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL 20649 || loc == PackageHelper.APP_INSTALL_EXTERNAL) { 20650 android.provider.Settings.Global.putInt(mContext.getContentResolver(), 20651 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc); 20652 return true; 20653 } 20654 return false; 20655 } 20656 20657 @Override 20658 public int getInstallLocation() { 20659 return android.provider.Settings.Global.getInt(mContext.getContentResolver(), 20660 android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, 20661 PackageHelper.APP_INSTALL_AUTO); 20662 } 20663 20664 /** Called by UserManagerService */ 20665 void cleanUpUser(UserManagerService userManager, int userHandle) { 20666 synchronized (mPackages) { 20667 mDirtyUsers.remove(userHandle); 20668 mUserNeedsBadging.delete(userHandle); 20669 mSettings.removeUserLPw(userHandle); 20670 mPendingBroadcasts.remove(userHandle); 20671 mEphemeralApplicationRegistry.onUserRemovedLPw(userHandle); 20672 removeUnusedPackagesLPw(userManager, userHandle); 20673 } 20674 } 20675 20676 /** 20677 * We're removing userHandle and would like to remove any downloaded packages 20678 * that are no longer in use by any other user. 20679 * @param userHandle the user being removed 20680 */ 20681 private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) { 20682 final boolean DEBUG_CLEAN_APKS = false; 20683 int [] users = userManager.getUserIds(); 20684 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); 20685 while (psit.hasNext()) { 20686 PackageSetting ps = psit.next(); 20687 if (ps.pkg == null) { 20688 continue; 20689 } 20690 final String packageName = ps.pkg.packageName; 20691 // Skip over if system app 20692 if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) { 20693 continue; 20694 } 20695 if (DEBUG_CLEAN_APKS) { 20696 Slog.i(TAG, "Checking package " + packageName); 20697 } 20698 boolean keep = shouldKeepUninstalledPackageLPr(packageName); 20699 if (keep) { 20700 if (DEBUG_CLEAN_APKS) { 20701 Slog.i(TAG, " Keeping package " + packageName + " - requested by DO"); 20702 } 20703 } else { 20704 for (int i = 0; i < users.length; i++) { 20705 if (users[i] != userHandle && ps.getInstalled(users[i])) { 20706 keep = true; 20707 if (DEBUG_CLEAN_APKS) { 20708 Slog.i(TAG, " Keeping package " + packageName + " for user " 20709 + users[i]); 20710 } 20711 break; 20712 } 20713 } 20714 } 20715 if (!keep) { 20716 if (DEBUG_CLEAN_APKS) { 20717 Slog.i(TAG, " Removing package " + packageName); 20718 } 20719 mHandler.post(new Runnable() { 20720 public void run() { 20721 deletePackageX(packageName, userHandle, 0); 20722 } //end run 20723 }); 20724 } 20725 } 20726 } 20727 20728 /** Called by UserManagerService */ 20729 void createNewUser(int userId, String[] disallowedPackages) { 20730 synchronized (mInstallLock) { 20731 mSettings.createNewUserLI(this, mInstaller, userId, disallowedPackages); 20732 } 20733 synchronized (mPackages) { 20734 scheduleWritePackageRestrictionsLocked(userId); 20735 scheduleWritePackageListLocked(userId); 20736 applyFactoryDefaultBrowserLPw(userId); 20737 primeDomainVerificationsLPw(userId); 20738 } 20739 } 20740 20741 void onNewUserCreated(final int userId) { 20742 mDefaultPermissionPolicy.grantDefaultPermissions(userId); 20743 // If permission review for legacy apps is required, we represent 20744 // dagerous permissions for such apps as always granted runtime 20745 // permissions to keep per user flag state whether review is needed. 20746 // Hence, if a new user is added we have to propagate dangerous 20747 // permission grants for these legacy apps. 20748 if (mPermissionReviewRequired) { 20749 updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL 20750 | UPDATE_PERMISSIONS_REPLACE_ALL); 20751 } 20752 } 20753 20754 @Override 20755 public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException { 20756 mContext.enforceCallingOrSelfPermission( 20757 android.Manifest.permission.PACKAGE_VERIFICATION_AGENT, 20758 "Only package verification agents can read the verifier device identity"); 20759 20760 synchronized (mPackages) { 20761 return mSettings.getVerifierDeviceIdentityLPw(); 20762 } 20763 } 20764 20765 @Override 20766 public void setPermissionEnforced(String permission, boolean enforced) { 20767 // TODO: Now that we no longer change GID for storage, this should to away. 20768 mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS, 20769 "setPermissionEnforced"); 20770 if (READ_EXTERNAL_STORAGE.equals(permission)) { 20771 synchronized (mPackages) { 20772 if (mSettings.mReadExternalStorageEnforced == null 20773 || mSettings.mReadExternalStorageEnforced != enforced) { 20774 mSettings.mReadExternalStorageEnforced = enforced; 20775 mSettings.writeLPr(); 20776 } 20777 } 20778 // kill any non-foreground processes so we restart them and 20779 // grant/revoke the GID. 20780 final IActivityManager am = ActivityManagerNative.getDefault(); 20781 if (am != null) { 20782 final long token = Binder.clearCallingIdentity(); 20783 try { 20784 am.killProcessesBelowForeground("setPermissionEnforcement"); 20785 } catch (RemoteException e) { 20786 } finally { 20787 Binder.restoreCallingIdentity(token); 20788 } 20789 } 20790 } else { 20791 throw new IllegalArgumentException("No selective enforcement for " + permission); 20792 } 20793 } 20794 20795 @Override 20796 @Deprecated 20797 public boolean isPermissionEnforced(String permission) { 20798 return true; 20799 } 20800 20801 @Override 20802 public boolean isStorageLow() { 20803 final long token = Binder.clearCallingIdentity(); 20804 try { 20805 final DeviceStorageMonitorInternal 20806 dsm = LocalServices.getService(DeviceStorageMonitorInternal.class); 20807 if (dsm != null) { 20808 return dsm.isMemoryLow(); 20809 } else { 20810 return false; 20811 } 20812 } finally { 20813 Binder.restoreCallingIdentity(token); 20814 } 20815 } 20816 20817 @Override 20818 public IPackageInstaller getPackageInstaller() { 20819 return mInstallerService; 20820 } 20821 20822 private boolean userNeedsBadging(int userId) { 20823 int index = mUserNeedsBadging.indexOfKey(userId); 20824 if (index < 0) { 20825 final UserInfo userInfo; 20826 final long token = Binder.clearCallingIdentity(); 20827 try { 20828 userInfo = sUserManager.getUserInfo(userId); 20829 } finally { 20830 Binder.restoreCallingIdentity(token); 20831 } 20832 final boolean b; 20833 if (userInfo != null && userInfo.isManagedProfile()) { 20834 b = true; 20835 } else { 20836 b = false; 20837 } 20838 mUserNeedsBadging.put(userId, b); 20839 return b; 20840 } 20841 return mUserNeedsBadging.valueAt(index); 20842 } 20843 20844 @Override 20845 public KeySet getKeySetByAlias(String packageName, String alias) { 20846 if (packageName == null || alias == null) { 20847 return null; 20848 } 20849 synchronized(mPackages) { 20850 final PackageParser.Package pkg = mPackages.get(packageName); 20851 if (pkg == null) { 20852 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 20853 throw new IllegalArgumentException("Unknown package: " + packageName); 20854 } 20855 KeySetManagerService ksms = mSettings.mKeySetManagerService; 20856 return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias)); 20857 } 20858 } 20859 20860 @Override 20861 public KeySet getSigningKeySet(String packageName) { 20862 if (packageName == null) { 20863 return null; 20864 } 20865 synchronized(mPackages) { 20866 final PackageParser.Package pkg = mPackages.get(packageName); 20867 if (pkg == null) { 20868 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 20869 throw new IllegalArgumentException("Unknown package: " + packageName); 20870 } 20871 if (pkg.applicationInfo.uid != Binder.getCallingUid() 20872 && Process.SYSTEM_UID != Binder.getCallingUid()) { 20873 throw new SecurityException("May not access signing KeySet of other apps."); 20874 } 20875 KeySetManagerService ksms = mSettings.mKeySetManagerService; 20876 return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName)); 20877 } 20878 } 20879 20880 @Override 20881 public boolean isPackageSignedByKeySet(String packageName, KeySet ks) { 20882 if (packageName == null || ks == null) { 20883 return false; 20884 } 20885 synchronized(mPackages) { 20886 final PackageParser.Package pkg = mPackages.get(packageName); 20887 if (pkg == null) { 20888 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 20889 throw new IllegalArgumentException("Unknown package: " + packageName); 20890 } 20891 IBinder ksh = ks.getToken(); 20892 if (ksh instanceof KeySetHandle) { 20893 KeySetManagerService ksms = mSettings.mKeySetManagerService; 20894 return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh); 20895 } 20896 return false; 20897 } 20898 } 20899 20900 @Override 20901 public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) { 20902 if (packageName == null || ks == null) { 20903 return false; 20904 } 20905 synchronized(mPackages) { 20906 final PackageParser.Package pkg = mPackages.get(packageName); 20907 if (pkg == null) { 20908 Slog.w(TAG, "KeySet requested for unknown package: " + packageName); 20909 throw new IllegalArgumentException("Unknown package: " + packageName); 20910 } 20911 IBinder ksh = ks.getToken(); 20912 if (ksh instanceof KeySetHandle) { 20913 KeySetManagerService ksms = mSettings.mKeySetManagerService; 20914 return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh); 20915 } 20916 return false; 20917 } 20918 } 20919 20920 private void deletePackageIfUnusedLPr(final String packageName) { 20921 PackageSetting ps = mSettings.mPackages.get(packageName); 20922 if (ps == null) { 20923 return; 20924 } 20925 if (!ps.isAnyInstalled(sUserManager.getUserIds())) { 20926 // TODO Implement atomic delete if package is unused 20927 // It is currently possible that the package will be deleted even if it is installed 20928 // after this method returns. 20929 mHandler.post(new Runnable() { 20930 public void run() { 20931 deletePackageX(packageName, 0, PackageManager.DELETE_ALL_USERS); 20932 } 20933 }); 20934 } 20935 } 20936 20937 /** 20938 * Check and throw if the given before/after packages would be considered a 20939 * downgrade. 20940 */ 20941 private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after) 20942 throws PackageManagerException { 20943 if (after.versionCode < before.mVersionCode) { 20944 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 20945 "Update version code " + after.versionCode + " is older than current " 20946 + before.mVersionCode); 20947 } else if (after.versionCode == before.mVersionCode) { 20948 if (after.baseRevisionCode < before.baseRevisionCode) { 20949 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 20950 "Update base revision code " + after.baseRevisionCode 20951 + " is older than current " + before.baseRevisionCode); 20952 } 20953 20954 if (!ArrayUtils.isEmpty(after.splitNames)) { 20955 for (int i = 0; i < after.splitNames.length; i++) { 20956 final String splitName = after.splitNames[i]; 20957 final int j = ArrayUtils.indexOf(before.splitNames, splitName); 20958 if (j != -1) { 20959 if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) { 20960 throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE, 20961 "Update split " + splitName + " revision code " 20962 + after.splitRevisionCodes[i] + " is older than current " 20963 + before.splitRevisionCodes[j]); 20964 } 20965 } 20966 } 20967 } 20968 } 20969 } 20970 20971 private static class MoveCallbacks extends Handler { 20972 private static final int MSG_CREATED = 1; 20973 private static final int MSG_STATUS_CHANGED = 2; 20974 20975 private final RemoteCallbackList<IPackageMoveObserver> 20976 mCallbacks = new RemoteCallbackList<>(); 20977 20978 private final SparseIntArray mLastStatus = new SparseIntArray(); 20979 20980 public MoveCallbacks(Looper looper) { 20981 super(looper); 20982 } 20983 20984 public void register(IPackageMoveObserver callback) { 20985 mCallbacks.register(callback); 20986 } 20987 20988 public void unregister(IPackageMoveObserver callback) { 20989 mCallbacks.unregister(callback); 20990 } 20991 20992 @Override 20993 public void handleMessage(Message msg) { 20994 final SomeArgs args = (SomeArgs) msg.obj; 20995 final int n = mCallbacks.beginBroadcast(); 20996 for (int i = 0; i < n; i++) { 20997 final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i); 20998 try { 20999 invokeCallback(callback, msg.what, args); 21000 } catch (RemoteException ignored) { 21001 } 21002 } 21003 mCallbacks.finishBroadcast(); 21004 args.recycle(); 21005 } 21006 21007 private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args) 21008 throws RemoteException { 21009 switch (what) { 21010 case MSG_CREATED: { 21011 callback.onCreated(args.argi1, (Bundle) args.arg2); 21012 break; 21013 } 21014 case MSG_STATUS_CHANGED: { 21015 callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3); 21016 break; 21017 } 21018 } 21019 } 21020 21021 private void notifyCreated(int moveId, Bundle extras) { 21022 Slog.v(TAG, "Move " + moveId + " created " + extras.toString()); 21023 21024 final SomeArgs args = SomeArgs.obtain(); 21025 args.argi1 = moveId; 21026 args.arg2 = extras; 21027 obtainMessage(MSG_CREATED, args).sendToTarget(); 21028 } 21029 21030 private void notifyStatusChanged(int moveId, int status) { 21031 notifyStatusChanged(moveId, status, -1); 21032 } 21033 21034 private void notifyStatusChanged(int moveId, int status, long estMillis) { 21035 Slog.v(TAG, "Move " + moveId + " status " + status); 21036 21037 final SomeArgs args = SomeArgs.obtain(); 21038 args.argi1 = moveId; 21039 args.argi2 = status; 21040 args.arg3 = estMillis; 21041 obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget(); 21042 21043 synchronized (mLastStatus) { 21044 mLastStatus.put(moveId, status); 21045 } 21046 } 21047 } 21048 21049 private final static class OnPermissionChangeListeners extends Handler { 21050 private static final int MSG_ON_PERMISSIONS_CHANGED = 1; 21051 21052 private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners = 21053 new RemoteCallbackList<>(); 21054 21055 public OnPermissionChangeListeners(Looper looper) { 21056 super(looper); 21057 } 21058 21059 @Override 21060 public void handleMessage(Message msg) { 21061 switch (msg.what) { 21062 case MSG_ON_PERMISSIONS_CHANGED: { 21063 final int uid = msg.arg1; 21064 handleOnPermissionsChanged(uid); 21065 } break; 21066 } 21067 } 21068 21069 public void addListenerLocked(IOnPermissionsChangeListener listener) { 21070 mPermissionListeners.register(listener); 21071 21072 } 21073 21074 public void removeListenerLocked(IOnPermissionsChangeListener listener) { 21075 mPermissionListeners.unregister(listener); 21076 } 21077 21078 public void onPermissionsChanged(int uid) { 21079 if (mPermissionListeners.getRegisteredCallbackCount() > 0) { 21080 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget(); 21081 } 21082 } 21083 21084 private void handleOnPermissionsChanged(int uid) { 21085 final int count = mPermissionListeners.beginBroadcast(); 21086 try { 21087 for (int i = 0; i < count; i++) { 21088 IOnPermissionsChangeListener callback = mPermissionListeners 21089 .getBroadcastItem(i); 21090 try { 21091 callback.onPermissionsChanged(uid); 21092 } catch (RemoteException e) { 21093 Log.e(TAG, "Permission listener is dead", e); 21094 } 21095 } 21096 } finally { 21097 mPermissionListeners.finishBroadcast(); 21098 } 21099 } 21100 } 21101 21102 private class PackageManagerInternalImpl extends PackageManagerInternal { 21103 @Override 21104 public void setLocationPackagesProvider(PackagesProvider provider) { 21105 synchronized (mPackages) { 21106 mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider); 21107 } 21108 } 21109 21110 @Override 21111 public void setVoiceInteractionPackagesProvider(PackagesProvider provider) { 21112 synchronized (mPackages) { 21113 mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider); 21114 } 21115 } 21116 21117 @Override 21118 public void setSmsAppPackagesProvider(PackagesProvider provider) { 21119 synchronized (mPackages) { 21120 mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider); 21121 } 21122 } 21123 21124 @Override 21125 public void setDialerAppPackagesProvider(PackagesProvider provider) { 21126 synchronized (mPackages) { 21127 mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider); 21128 } 21129 } 21130 21131 @Override 21132 public void setSimCallManagerPackagesProvider(PackagesProvider provider) { 21133 synchronized (mPackages) { 21134 mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider); 21135 } 21136 } 21137 21138 @Override 21139 public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) { 21140 synchronized (mPackages) { 21141 mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider); 21142 } 21143 } 21144 21145 @Override 21146 public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) { 21147 synchronized (mPackages) { 21148 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr( 21149 packageName, userId); 21150 } 21151 } 21152 21153 @Override 21154 public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) { 21155 synchronized (mPackages) { 21156 mSettings.setDefaultDialerPackageNameLPw(packageName, userId); 21157 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr( 21158 packageName, userId); 21159 } 21160 } 21161 21162 @Override 21163 public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) { 21164 synchronized (mPackages) { 21165 mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr( 21166 packageName, userId); 21167 } 21168 } 21169 21170 @Override 21171 public void setKeepUninstalledPackages(final List<String> packageList) { 21172 Preconditions.checkNotNull(packageList); 21173 List<String> removedFromList = null; 21174 synchronized (mPackages) { 21175 if (mKeepUninstalledPackages != null) { 21176 final int packagesCount = mKeepUninstalledPackages.size(); 21177 for (int i = 0; i < packagesCount; i++) { 21178 String oldPackage = mKeepUninstalledPackages.get(i); 21179 if (packageList != null && packageList.contains(oldPackage)) { 21180 continue; 21181 } 21182 if (removedFromList == null) { 21183 removedFromList = new ArrayList<>(); 21184 } 21185 removedFromList.add(oldPackage); 21186 } 21187 } 21188 mKeepUninstalledPackages = new ArrayList<>(packageList); 21189 if (removedFromList != null) { 21190 final int removedCount = removedFromList.size(); 21191 for (int i = 0; i < removedCount; i++) { 21192 deletePackageIfUnusedLPr(removedFromList.get(i)); 21193 } 21194 } 21195 } 21196 } 21197 21198 @Override 21199 public boolean isPermissionsReviewRequired(String packageName, int userId) { 21200 synchronized (mPackages) { 21201 // If we do not support permission review, done. 21202 if (!mPermissionReviewRequired) { 21203 return false; 21204 } 21205 21206 PackageSetting packageSetting = mSettings.mPackages.get(packageName); 21207 if (packageSetting == null) { 21208 return false; 21209 } 21210 21211 // Permission review applies only to apps not supporting the new permission model. 21212 if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) { 21213 return false; 21214 } 21215 21216 // Legacy apps have the permission and get user consent on launch. 21217 PermissionsState permissionsState = packageSetting.getPermissionsState(); 21218 return permissionsState.isPermissionReviewRequired(userId); 21219 } 21220 } 21221 21222 @Override 21223 public ApplicationInfo getApplicationInfo(String packageName, int userId) { 21224 return PackageManagerService.this.getApplicationInfo(packageName, 0 /*flags*/, userId); 21225 } 21226 21227 @Override 21228 public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates, 21229 int userId) { 21230 return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId); 21231 } 21232 21233 @Override 21234 public void setDeviceAndProfileOwnerPackages( 21235 int deviceOwnerUserId, String deviceOwnerPackage, 21236 SparseArray<String> profileOwnerPackages) { 21237 mProtectedPackages.setDeviceAndProfileOwnerPackages( 21238 deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages); 21239 } 21240 21241 @Override 21242 public boolean isPackageDataProtected(int userId, String packageName) { 21243 return mProtectedPackages.isPackageDataProtected(userId, packageName); 21244 } 21245 21246 @Override 21247 public boolean wasPackageEverLaunched(String packageName, int userId) { 21248 synchronized (mPackages) { 21249 return mSettings.wasPackageEverLaunchedLPr(packageName, userId); 21250 } 21251 } 21252 21253 @Override 21254 public void grantRuntimePermission(String packageName, String name, int userId, 21255 boolean overridePolicy) { 21256 PackageManagerService.this.grantRuntimePermission(packageName, name, userId, 21257 overridePolicy); 21258 } 21259 21260 @Override 21261 public void revokeRuntimePermission(String packageName, String name, int userId, 21262 boolean overridePolicy) { 21263 PackageManagerService.this.revokeRuntimePermission(packageName, name, userId, 21264 overridePolicy); 21265 } 21266 21267 @Override 21268 public String getNameForUid(int uid) { 21269 return PackageManagerService.this.getNameForUid(uid); 21270 } 21271 } 21272 21273 @Override 21274 public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) { 21275 enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps"); 21276 synchronized (mPackages) { 21277 final long identity = Binder.clearCallingIdentity(); 21278 try { 21279 mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr( 21280 packageNames, userId); 21281 } finally { 21282 Binder.restoreCallingIdentity(identity); 21283 } 21284 } 21285 } 21286 21287 private static void enforceSystemOrPhoneCaller(String tag) { 21288 int callingUid = Binder.getCallingUid(); 21289 if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) { 21290 throw new SecurityException( 21291 "Cannot call " + tag + " from UID " + callingUid); 21292 } 21293 } 21294 21295 boolean isHistoricalPackageUsageAvailable() { 21296 return mPackageUsage.isHistoricalPackageUsageAvailable(); 21297 } 21298 21299 /** 21300 * Return a <b>copy</b> of the collection of packages known to the package manager. 21301 * @return A copy of the values of mPackages. 21302 */ 21303 Collection<PackageParser.Package> getPackages() { 21304 synchronized (mPackages) { 21305 return new ArrayList<>(mPackages.values()); 21306 } 21307 } 21308 21309 /** 21310 * Logs process start information (including base APK hash) to the security log. 21311 * @hide 21312 */ 21313 public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo, 21314 String apkFile, int pid) { 21315 if (!SecurityLog.isLoggingEnabled()) { 21316 return; 21317 } 21318 Bundle data = new Bundle(); 21319 data.putLong("startTimestamp", System.currentTimeMillis()); 21320 data.putString("processName", processName); 21321 data.putInt("uid", uid); 21322 data.putString("seinfo", seinfo); 21323 data.putString("apkFile", apkFile); 21324 data.putInt("pid", pid); 21325 Message msg = mProcessLoggingHandler.obtainMessage( 21326 ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG); 21327 msg.setData(data); 21328 mProcessLoggingHandler.sendMessage(msg); 21329 } 21330 21331 public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) { 21332 return mCompilerStats.getPackageStats(pkgName); 21333 } 21334 21335 public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) { 21336 return getOrCreateCompilerPackageStats(pkg.packageName); 21337 } 21338 21339 public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) { 21340 return mCompilerStats.getOrCreatePackageStats(pkgName); 21341 } 21342 21343 public void deleteCompilerPackageStats(String pkgName) { 21344 mCompilerStats.deletePackageStats(pkgName); 21345 } 21346} 21347